feat: move delete all button to top bar as icon in drafts screen

Replace the ElevatedButton in a sticky header with a delete icon
(Icons.Default.Delete) in the top bar actions area. The confirmation
dialog is preserved and now lives at the screen level, reading the
current feed state directly when confirmed.

https://claude.ai/code/session_01AbiBeDnT4KPKD16sKKaLD8
This commit is contained in:
Claude
2026-03-17 02:20:13 +00:00
parent d0297b7e34
commit 0459633d82
@@ -21,8 +21,6 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.drafts package com.vitorpamplona.amethyst.ui.screen.loggedIn.drafts
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
@@ -31,9 +29,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@@ -55,7 +56,8 @@ import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys.DRAFTS
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -80,10 +82,67 @@ private fun RenderDraftListScreen(
) { ) {
WatchLifecycleAndUpdateModel(feedState) WatchLifecycleAndUpdateModel(feedState)
var showDeleteDialog by remember { mutableStateOf(false) }
if (showDeleteDialog) {
AlertDialog(
onDismissRequest = {
showDeleteDialog = false
},
title = {
Text(text = stringResource(R.string.drafts))
},
text = {
Text(text = stringResource(R.string.delete_all_drafts_confirmation))
},
confirmButton = {
TextButton(
onClick = {
val currentState = feedState.feedContent.value
if (currentState is FeedState.Loaded) {
accountViewModel.delete(currentState.feed.value.list)
}
showDeleteDialog = false
},
) {
Text(text = stringResource(R.string.yes))
}
},
dismissButton = {
TextButton(
onClick = {
showDeleteDialog = false
},
) {
Text(text = stringResource(R.string.no))
}
},
)
}
DisappearingScaffold( DisappearingScaffold(
isInvertedLayout = false, isInvertedLayout = false,
topBar = { topBar = {
TopBarWithBackButton(stringRes(id = R.string.drafts), nav::popBack) ShorterTopAppBar(
title = {
Text(
text = stringRes(id = R.string.drafts),
)
},
navigationIcon = {
IconButton(onClick = nav::popBack) {
ArrowBackIcon()
}
},
actions = {
IconButton(onClick = { showDeleteDialog = true }) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = stringResource(R.string.delete_all),
)
}
},
)
}, },
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
) { ) {
@@ -104,7 +163,6 @@ private fun RenderDraftListScreen(
} }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
private fun DraftFeedLoaded( private fun DraftFeedLoaded(
loaded: FeedState.Loaded, loaded: FeedState.Loaded,
@@ -114,60 +172,12 @@ private fun DraftFeedLoaded(
) { ) {
val items by loaded.feed.collectAsStateWithLifecycle() val items by loaded.feed.collectAsStateWithLifecycle()
var showDeleteDialog by remember { mutableStateOf(false) }
if (showDeleteDialog) {
AlertDialog(
onDismissRequest = {
showDeleteDialog = false
},
title = {
Text(text = stringResource(R.string.drafts))
},
text = {
Text(text = stringResource(R.string.delete_all_drafts_confirmation))
},
confirmButton = {
TextButton(
onClick = {
accountViewModel.delete(items.list)
showDeleteDialog = false
},
) {
Text(text = stringResource(R.string.yes))
}
},
dismissButton = {
TextButton(
onClick = {
showDeleteDialog = false
},
) {
Text(text = stringResource(R.string.no))
}
},
)
}
LazyColumn( LazyColumn(
contentPadding = FeedPadding, contentPadding = FeedPadding,
state = listState, state = listState,
) { ) {
stickyHeader {
Row(
Modifier
.fillMaxWidth(),
Arrangement.Center,
) {
ElevatedButton(
onClick = { showDeleteDialog = true },
) {
Text(stringResource(R.string.delete_all))
}
}
}
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item -> itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
Row(Modifier.fillMaxWidth().animateItem()) { Row(Modifier.fillMaxWidth()) {
SwipeToDeleteWithConfirmation( SwipeToDeleteWithConfirmation(
modifier = Modifier.fillMaxWidth().animateContentSize(), modifier = Modifier.fillMaxWidth().animateContentSize(),
onDelete = { accountViewModel.delete(item) }, onDelete = { accountViewModel.delete(item) },