feat: convert UpdateReactionTypeDialog to a route
Replace the dialog-based UpdateReactionTypeDialog with a navigation route (Route.UpdateReactionType) that slides up from the bottom. UpdateReactionTypeScreen replaces the Dialog wrapper with a plain Scaffold. Call sites in AllSettingsScreen and ReactionsRow now navigate to the route instead of managing local dialog state. https://claude.ai/code/session_01TSjuYdBADTRXwT4w8Yx1vU
This commit is contained in:
@@ -55,6 +55,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.getRouteWithArguments
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.isBaseRoute
|
import com.vitorpamplona.amethyst.ui.navigation.routes.isBaseRoute
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.isSameRoute
|
import com.vitorpamplona.amethyst.ui.navigation.routes.isSameRoute
|
||||||
import com.vitorpamplona.amethyst.ui.note.PayViaIntentScreen
|
import com.vitorpamplona.amethyst.ui.note.PayViaIntentScreen
|
||||||
|
import com.vitorpamplona.amethyst.ui.note.UpdateReactionTypeScreen
|
||||||
import com.vitorpamplona.amethyst.ui.note.nip22Comments.ReplyCommentPostScreen
|
import com.vitorpamplona.amethyst.ui.note.nip22Comments.ReplyCommentPostScreen
|
||||||
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountSwitcherAndLeftDrawerLayout
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountSwitcherAndLeftDrawerLayout
|
||||||
@@ -174,6 +175,7 @@ fun AppNavigation(
|
|||||||
composableFromBottomArgs<Route.Nip47NWCSetup> { NIP47SetupScreen(accountViewModel, nav, it.nip47) }
|
composableFromBottomArgs<Route.Nip47NWCSetup> { NIP47SetupScreen(accountViewModel, nav, it.nip47) }
|
||||||
composableFromEndArgs<Route.EditRelays> { AllRelayListScreen(accountViewModel, nav) }
|
composableFromEndArgs<Route.EditRelays> { AllRelayListScreen(accountViewModel, nav) }
|
||||||
composableFromEndArgs<Route.EditMediaServers> { AllMediaServersScreen(accountViewModel, nav) }
|
composableFromEndArgs<Route.EditMediaServers> { AllMediaServersScreen(accountViewModel, nav) }
|
||||||
|
composableFromBottom<Route.UpdateReactionType> { UpdateReactionTypeScreen(accountViewModel, nav) }
|
||||||
|
|
||||||
composableFromEndArgs<Route.ContentDiscovery> { DvmContentDiscoveryScreen(it.id, accountViewModel, nav) }
|
composableFromEndArgs<Route.ContentDiscovery> { DvmContentDiscoveryScreen(it.id, accountViewModel, nav) }
|
||||||
composableFromEndArgs<Route.Profile> { ProfileScreen(it.id, accountViewModel, nav) }
|
composableFromEndArgs<Route.Profile> { ProfileScreen(it.id, accountViewModel, nav) }
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ sealed class Route {
|
|||||||
|
|
||||||
@Serializable object EditMediaServers : Route()
|
@Serializable object EditMediaServers : Route()
|
||||||
|
|
||||||
|
@Serializable object UpdateReactionType : Route()
|
||||||
|
|
||||||
@Serializable data class Nip47NWCSetup(
|
@Serializable data class Nip47NWCSetup(
|
||||||
val nip47: String? = null,
|
val nip47: String? = null,
|
||||||
) : Route()
|
) : Route()
|
||||||
@@ -351,6 +353,7 @@ fun getRouteWithArguments(navController: NavHostController): Route? {
|
|||||||
dest.hasRoute<Route.EventRedirect>() -> entry.toRoute<Route.EventRedirect>()
|
dest.hasRoute<Route.EventRedirect>() -> entry.toRoute<Route.EventRedirect>()
|
||||||
dest.hasRoute<Route.EditRelays>() -> entry.toRoute<Route.EditRelays>()
|
dest.hasRoute<Route.EditRelays>() -> entry.toRoute<Route.EditRelays>()
|
||||||
dest.hasRoute<Route.EditMediaServers>() -> entry.toRoute<Route.EditMediaServers>()
|
dest.hasRoute<Route.EditMediaServers>() -> entry.toRoute<Route.EditMediaServers>()
|
||||||
|
dest.hasRoute<Route.UpdateReactionType>() -> entry.toRoute<Route.UpdateReactionType>()
|
||||||
dest.hasRoute<Route.Nip47NWCSetup>() -> entry.toRoute<Route.Nip47NWCSetup>()
|
dest.hasRoute<Route.Nip47NWCSetup>() -> entry.toRoute<Route.Nip47NWCSetup>()
|
||||||
dest.hasRoute<Route.Room>() -> entry.toRoute<Route.Room>()
|
dest.hasRoute<Route.Room>() -> entry.toRoute<Route.Room>()
|
||||||
dest.hasRoute<Route.NewShortNote>() -> entry.toRoute<Route.NewShortNote>()
|
dest.hasRoute<Route.NewShortNote>() -> entry.toRoute<Route.NewShortNote>()
|
||||||
|
|||||||
@@ -871,7 +871,6 @@ fun LikeReaction(
|
|||||||
heartSizeModifier: Modifier = Size18Modifier,
|
heartSizeModifier: Modifier = Size18Modifier,
|
||||||
iconFontSize: TextUnit = Font14SP,
|
iconFontSize: TextUnit = Font14SP,
|
||||||
) {
|
) {
|
||||||
var wantsToChangeReactionSymbol by remember { mutableStateOf(false) }
|
|
||||||
var wantsToReact by remember { mutableStateOf(false) }
|
var wantsToReact by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
ClickableBox(
|
ClickableBox(
|
||||||
@@ -883,7 +882,7 @@ fun LikeReaction(
|
|||||||
onWantsToSignReaction = { accountViewModel.reactToOrDelete(baseNote) },
|
onWantsToSignReaction = { accountViewModel.reactToOrDelete(baseNote) },
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onLongClick = { wantsToChangeReactionSymbol = true },
|
onLongClick = { nav.nav(Route.UpdateReactionType) },
|
||||||
) {
|
) {
|
||||||
ObserveLikeIcon(baseNote, accountViewModel) { reactionType ->
|
ObserveLikeIcon(baseNote, accountViewModel) { reactionType ->
|
||||||
CrossfadeIfEnabled(targetState = reactionType, contentAlignment = Center, label = "LikeIcon", accountViewModel = accountViewModel) {
|
CrossfadeIfEnabled(targetState = reactionType, contentAlignment = Center, label = "LikeIcon", accountViewModel = accountViewModel) {
|
||||||
@@ -895,14 +894,6 @@ fun LikeReaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToChangeReactionSymbol) {
|
|
||||||
UpdateReactionTypeDialog(
|
|
||||||
{ wantsToChangeReactionSymbol = false },
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
nav,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wantsToReact) {
|
if (wantsToReact) {
|
||||||
ReactionChoicePopup(
|
ReactionChoicePopup(
|
||||||
baseNote,
|
baseNote,
|
||||||
@@ -911,7 +902,7 @@ fun LikeReaction(
|
|||||||
onDismiss = { wantsToReact = false },
|
onDismiss = { wantsToReact = false },
|
||||||
onChangeAmount = {
|
onChangeAmount = {
|
||||||
wantsToReact = false
|
wantsToReact = false
|
||||||
wantsToChangeReactionSymbol = true
|
nav.nav(Route.UpdateReactionType)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+79
-96
@@ -69,8 +69,6 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
|
||||||
import androidx.compose.ui.window.DialogProperties
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
@@ -81,7 +79,6 @@ import com.vitorpamplona.amethyst.service.firstFullChar
|
|||||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEventAndMapNotNull
|
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEventAndMapNotNull
|
||||||
import com.vitorpamplona.amethyst.ui.components.AnimatedBorderTextCornerRadius
|
import com.vitorpamplona.amethyst.ui.components.AnimatedBorderTextCornerRadius
|
||||||
import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
|
import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer
|
||||||
import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar
|
||||||
@@ -153,8 +150,7 @@ class UpdateReactionTypeViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UpdateReactionTypeDialog(
|
fun UpdateReactionTypeScreen(
|
||||||
onClose: () -> Unit,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -165,119 +161,106 @@ fun UpdateReactionTypeDialog(
|
|||||||
postViewModel.load()
|
postViewModel.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateReactionTypeDialog(postViewModel, onClose, accountViewModel, nav)
|
UpdateReactionTypeScreen(postViewModel, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun UpdateReactionTypeDialog(
|
fun UpdateReactionTypeScreen(
|
||||||
postViewModel: UpdateReactionTypeViewModel,
|
postViewModel: UpdateReactionTypeViewModel,
|
||||||
onClose: () -> Unit,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
Dialog(
|
Scaffold(
|
||||||
onDismissRequest = { onClose() },
|
topBar = {
|
||||||
properties =
|
SavingTopBar(
|
||||||
DialogProperties(
|
isActive = postViewModel::hasChanged,
|
||||||
usePlatformDefaultWidth = false,
|
onCancel = {
|
||||||
dismissOnClickOutside = false,
|
postViewModel.cancel()
|
||||||
decorFitsSystemWindows = false,
|
nav.popBack()
|
||||||
),
|
},
|
||||||
) {
|
onPost = {
|
||||||
SetDialogToEdgeToEdge()
|
postViewModel.sendPost()
|
||||||
|
nav.popBack()
|
||||||
Scaffold(
|
},
|
||||||
topBar = {
|
)
|
||||||
SavingTopBar(
|
},
|
||||||
isActive = postViewModel::hasChanged,
|
) { pad ->
|
||||||
onCancel = {
|
Surface(
|
||||||
postViewModel.cancel()
|
modifier =
|
||||||
onClose()
|
Modifier
|
||||||
},
|
.padding(pad)
|
||||||
onPost = {
|
.consumeWindowInsets(pad)
|
||||||
postViewModel.sendPost()
|
.imePadding(),
|
||||||
onClose()
|
) {
|
||||||
},
|
Column(
|
||||||
)
|
modifier = Modifier.padding(10.dp),
|
||||||
},
|
|
||||||
) { pad ->
|
|
||||||
Surface(
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.padding(pad)
|
|
||||||
.consumeWindowInsets(pad)
|
|
||||||
.imePadding(),
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Row(
|
||||||
modifier = Modifier.padding(10.dp),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
Row(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.verticalScroll(rememberScrollState()),
|
||||||
) {
|
) {
|
||||||
Column(
|
Row(modifier = Modifier.fillMaxWidth()) {
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState()),
|
Column(modifier = Modifier.animateContentSize()) {
|
||||||
) {
|
FlowRow(
|
||||||
Row(modifier = Modifier.fillMaxWidth()) {
|
modifier = Modifier.fillMaxWidth(),
|
||||||
Column(modifier = Modifier.animateContentSize()) {
|
horizontalArrangement = Arrangement.Center,
|
||||||
FlowRow(
|
) {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
postViewModel.reactionSet.forEach { reactionType ->
|
||||||
horizontalArrangement = Arrangement.Center,
|
RenderReactionOption(reactionType, postViewModel)
|
||||||
) {
|
|
||||||
postViewModel.reactionSet.forEach { reactionType ->
|
|
||||||
RenderReactionOption(reactionType, postViewModel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth().padding(vertical = 5.dp),
|
modifier = Modifier.fillMaxWidth().padding(vertical = 5.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
label = { Text(text = stringRes(R.string.new_reaction_symbol)) },
|
||||||
|
value = postViewModel.nextChoice,
|
||||||
|
onValueChange = { postViewModel.nextChoice = it },
|
||||||
|
keyboardOptions =
|
||||||
|
KeyboardOptions.Default.copy(
|
||||||
|
capitalization = KeyboardCapitalization.None,
|
||||||
|
keyboardType = KeyboardType.Text,
|
||||||
|
),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "\uD83D\uDCAF, \uD83C\uDF89, \uD83D\uDC4E",
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier.padding(end = 10.dp).weight(1f),
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { postViewModel.addChoice() },
|
||||||
|
shape = ButtonBorder,
|
||||||
|
colors =
|
||||||
|
ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
OutlinedTextField(
|
Text(text = stringRes(R.string.add), color = Color.White)
|
||||||
label = { Text(text = stringRes(R.string.new_reaction_symbol)) },
|
|
||||||
value = postViewModel.nextChoice,
|
|
||||||
onValueChange = { postViewModel.nextChoice = it },
|
|
||||||
keyboardOptions =
|
|
||||||
KeyboardOptions.Default.copy(
|
|
||||||
capitalization = KeyboardCapitalization.None,
|
|
||||||
keyboardType = KeyboardType.Text,
|
|
||||||
),
|
|
||||||
placeholder = {
|
|
||||||
Text(
|
|
||||||
text = "\uD83D\uDCAF, \uD83C\uDF89, \uD83D\uDC4E",
|
|
||||||
color = MaterialTheme.colorScheme.placeholderText,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
singleLine = true,
|
|
||||||
modifier = Modifier.padding(end = 10.dp).weight(1f),
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = { postViewModel.addChoice() },
|
|
||||||
shape = ButtonBorder,
|
|
||||||
colors =
|
|
||||||
ButtonDefaults.buttonColors(
|
|
||||||
containerColor = MaterialTheme.colorScheme.primary,
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
Text(text = stringRes(R.string.add), color = Color.White)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(StdVertSpacer)
|
Spacer(StdVertSpacer)
|
||||||
|
|
||||||
EmojiSelector(
|
EmojiSelector(
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
) {
|
) {
|
||||||
postViewModel.addChoice(it)
|
postViewModel.addChoice(it)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-11
@@ -57,7 +57,6 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
||||||
import com.vitorpamplona.amethyst.ui.note.UpdateReactionTypeDialog
|
|
||||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog
|
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog
|
||||||
import com.vitorpamplona.amethyst.ui.painterRes
|
import com.vitorpamplona.amethyst.ui.painterRes
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -84,17 +83,8 @@ fun AllSettingsScreen(
|
|||||||
) {
|
) {
|
||||||
val tint = MaterialTheme.colorScheme.onBackground
|
val tint = MaterialTheme.colorScheme.onBackground
|
||||||
|
|
||||||
var showReactionDialog by remember { mutableStateOf(false) }
|
|
||||||
var wantsToChangeZapAmount by remember { mutableStateOf(false) }
|
var wantsToChangeZapAmount by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (showReactionDialog) {
|
|
||||||
UpdateReactionTypeDialog(
|
|
||||||
onClose = { showReactionDialog = false },
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
nav = nav,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wantsToChangeZapAmount) {
|
if (wantsToChangeZapAmount) {
|
||||||
UpdateZapAmountDialog(
|
UpdateZapAmountDialog(
|
||||||
onClose = { wantsToChangeZapAmount = false },
|
onClose = { wantsToChangeZapAmount = false },
|
||||||
@@ -128,7 +118,7 @@ fun AllSettingsScreen(
|
|||||||
title = R.string.reactions,
|
title = R.string.reactions,
|
||||||
icon = Icons.Outlined.FavoriteBorder,
|
icon = Icons.Outlined.FavoriteBorder,
|
||||||
tint = tint,
|
tint = tint,
|
||||||
onClick = { showReactionDialog = true },
|
onClick = { nav.nav(Route.UpdateReactionType) },
|
||||||
)
|
)
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
SettingsNavigationRow(
|
SettingsNavigationRow(
|
||||||
|
|||||||
Reference in New Issue
Block a user