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
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.Row
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.LazyListState
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.ElevatedButton
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.layouts.DisappearingScaffold
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.screen.SaveableFeedState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -80,10 +82,67 @@ private fun RenderDraftListScreen(
) {
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(
isInvertedLayout = false,
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,
) {
@@ -104,7 +163,6 @@ private fun RenderDraftListScreen(
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun DraftFeedLoaded(
loaded: FeedState.Loaded,
@@ -114,60 +172,12 @@ private fun DraftFeedLoaded(
) {
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(
contentPadding = FeedPadding,
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 ->
Row(Modifier.fillMaxWidth().animateItem()) {
Row(Modifier.fillMaxWidth()) {
SwipeToDeleteWithConfirmation(
modifier = Modifier.fillMaxWidth().animateContentSize(),
onDelete = { accountViewModel.delete(item) },