diff --git a/CLAUDE.md b/CLAUDE.md
index 3c68fa57..de57265a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -132,6 +132,28 @@ ScreenStateTransition(viewModel.uiState) { uiState ->
It only works where the `when` is the composable's whole body — `AnimatedContent` is a
layout node, so wrapping one inside a `Column` takes its branches out of `ColumnScope`.
+## A pushed screen has a way back
+
+```kotlin
+TopAppBar(
+ title = { Text(stringResource(Res.string.add_post)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) }, // yes
+)
+TopAppBar(title = { … }) // no, on a pushed screen
+```
+
+A screen reached by `navController.navigate(...)` takes an `onNavigateBack: () -> Unit`
+and puts `NavigateBackButton` in its app bar's leading slot; the host passes
+`popBackStack()`. Android has a system back and iOS an edge swipe, but the desktop target
+has neither, and a pushed screen with no button there is a dead end. Twenty-two were.
+
+The button is *only* for pushed screens. The three top-level destinations have the
+navigation bar instead, and a screen that cleared the stack to get there -- onboarding,
+the loading gate -- has nothing under it to pop to. Where one composable is reached both
+ways, the callback is nullable and the caller decides: `ChatRoomMessagingScreen` is a
+destination on a phone and the home screen's detail pane in a wide window, and in the
+pane the list beside it is the way back.
+
## Layout adapts to the window, not to the composable
```kotlin
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 3651aa15..f74dd05c 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -679,4 +679,6 @@
You have not backed up your nostr secret key
These are your keys. Keep them safe so they can keep unlocking this profile, even when you lose or change your phone.
You said you stored it
+
+ New note
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AcceptCuratedSuggestionScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AcceptCuratedSuggestionScreen.kt
index 9b21092f..dd0d5544 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AcceptCuratedSuggestionScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AcceptCuratedSuggestionScreen.kt
@@ -20,7 +20,6 @@ import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Delete
@@ -111,6 +110,7 @@ import press.mantra.compose.ui.composable.widgets.Decorative
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.rememberNotifier
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -221,11 +221,7 @@ fun AcceptCuratedSuggestionScreen(
topBar = {
TopAppBar(
title = { state.localChatRoom.RenderChatRoomTitleText() },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
},
bottomBar = {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ActiveProfileScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ActiveProfileScreen.kt
index ecbb13ae..6f4b486f 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ActiveProfileScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ActiveProfileScreen.kt
@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Bento
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Hub
@@ -23,7 +22,6 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -72,6 +70,7 @@ import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.ButtonDefaults
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@@ -109,18 +108,7 @@ fun ActiveProfileScreen(
text = stringResource(Res.string.profile)
)
},
- navigationIcon = {
- IconButton(
- onClick = {
- onNavigateBack.invoke()
- }
- ) {
- Icon(
- Icons.Default.ArrowBack,
- contentDescription = "Back"
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddArtifactScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddArtifactScreen.kt
index 693afa49..60024cbb 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddArtifactScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddArtifactScreen.kt
@@ -84,6 +84,7 @@ import mantra.composeapp.generated.resources.source_dialect
import mantra.composeapp.generated.resources.url
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -101,6 +102,7 @@ fun AddArtifactScreen(
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val addArtifactViewModel: AddArtifactViewModel = viewModel(
factory = AddArtifactViewModel.factory(
@@ -160,9 +162,7 @@ fun AddArtifactScreen(
title = {
addArtifactUIState.localChatRoom.RenderChatRoomTitleText()
},
- actions = {
-
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -430,7 +430,8 @@ private fun AddArtifactScreenPreview() {
mantraRepository = MantraRepository.NO_OP_MANTRA_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
onNavigateToRouteAndPopUpInclusive = {},
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddChapterScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddChapterScreen.kt
index f46431ef..4fa54ce0 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddChapterScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddChapterScreen.kt
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.DriveFileRenameOutline
import androidx.compose.material3.BottomAppBar
@@ -19,7 +18,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
@@ -67,6 +65,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -146,14 +145,7 @@ fun AddChapterScreen(
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.add_chapter_to, addChapterUIState.artifact.name)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddDialectScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddDialectScreen.kt
index f352dd58..ebd8d934 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddDialectScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddDialectScreen.kt
@@ -68,6 +68,7 @@ import mantra.composeapp.generated.resources.language
import mantra.composeapp.generated.resources.propose_dialect
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -84,6 +85,7 @@ fun AddDialectScreen(
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val addDialectViewModel: AddDialectViewModel = viewModel(
factory = AddDialectViewModel.factory(
@@ -131,9 +133,7 @@ fun AddDialectScreen(
title = {
addDialectUIState.localChatRoom.RenderChatRoomTitleText()
},
- actions = {
-
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -364,7 +364,8 @@ private fun AddDialectScreenPreview() {
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
onNavigateToRouteAndPopUpInclusive = {},
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddGroupPostScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddGroupPostScreen.kt
index ac0bdc77..208b9346 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddGroupPostScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddGroupPostScreen.kt
@@ -52,6 +52,7 @@ import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar
import press.mantra.compose.ui.composable.widgets.rememberNotifier
@@ -96,6 +97,7 @@ fun AddGroupPostScreen(
chatRepository: ChatRepository,
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val addGroupPostViewModel: AddGroupPostViewModel = viewModel(
factory = AddGroupPostViewModel.factory(
@@ -138,7 +140,8 @@ fun AddGroupPostScreen(
modifier = Modifier.imePadding(),
topBar = {
TopAppBar(
- title = { Text(text = stringResource(Res.string.add_post)) }
+ title = { Text(text = stringResource(Res.string.add_post)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -326,7 +329,8 @@ private fun AddGroupPostScreenPreview() {
),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddMemberToChatRoomConfirmationScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddMemberToChatRoomConfirmationScreen.kt
index d8c93b38..21f5dffc 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddMemberToChatRoomConfirmationScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddMemberToChatRoomConfirmationScreen.kt
@@ -18,6 +18,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
@@ -43,10 +44,12 @@ import mantra.composeapp.generated.resources.direct_message_detail
import mantra.composeapp.generated.resources.direct_message_functionality_will_be_here
import mantra.composeapp.generated.resources.invite
import mantra.composeapp.generated.resources.invite_2
+import mantra.composeapp.generated.resources.invite_new_member
import mantra.composeapp.generated.resources.once_invited_will_be_able_to_receive_and
import mantra.composeapp.generated.resources.to_join_the_chat_room
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -62,6 +65,7 @@ fun AddMemberToChatRoomConfirmationScreen(
nostrRepository: NostrRepository,
chatRepository: ChatRepository,
onInviteSent: () -> Unit,
+ onNavigateBack: () -> Unit,
) {
val addMemberToChatRoomConfirmationViewModel: AddMemberToChatRoomConfirmationViewModel = viewModel(
factory = AddMemberToChatRoomConfirmationViewModel.factory(
@@ -94,22 +98,14 @@ fun AddMemberToChatRoomConfirmationScreen(
is AddMemberToChatRoomConfirmationUIState.Loaded -> {
Scaffold(
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
- // topBar = {
- // TopAppBar(
- // title = {
- // val title = if (addMemberToChatRoomConfirmationUIState.localChatRoom.chatRoom.subject != null) {
- // "Invite new member to ${addMemberToChatRoomConfirmationUIState.localChatRoom.chatRoom.subject}"
- // } else {
- // "Invite new member to chat"
- // }
- // Text(
- // text = title,
- // )
- // },
- // actions = {
- // }
- // )
- // }
+ topBar = {
+ // The body already names who is being invited to which room,
+ // so the bar says only what the screen is for.
+ TopAppBar(
+ title = { Text(stringResource(Res.string.invite_new_member)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
bottomBar = {
BottomAppBar(
floatingActionButton = {
@@ -252,7 +248,8 @@ private fun ChatRoomDetailScreenPreview() {
),
nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
- onInviteSent = {}
+ onInviteSent = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddTranslationArtifactVersionScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddTranslationArtifactVersionScreen.kt
index 7f46159b..2dfc9a4a 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddTranslationArtifactVersionScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/AddTranslationArtifactVersionScreen.kt
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Translate
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.ButtonDefaults
@@ -19,7 +18,6 @@ import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -68,6 +66,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@@ -145,14 +144,7 @@ fun AddTranslationArtifactVersionScreen(
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.translate, addTranslationUIState.artifact.name)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ArtifactDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ArtifactDetailScreen.kt
index 442aba14..b8fd9da9 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ArtifactDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ArtifactDetailScreen.kt
@@ -11,7 +11,6 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Article
import androidx.compose.material.icons.filled.PostAdd
import androidx.compose.material.icons.filled.Translate
@@ -19,7 +18,6 @@ import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -67,6 +65,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -111,14 +110,7 @@ fun ArtifactDetailScreen(
topBar = {
TopAppBar(
title = { Text(artifact.name) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/BroadcastGroupSignedEventScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/BroadcastGroupSignedEventScreen.kt
index 17733468..cfc9e191 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/BroadcastGroupSignedEventScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/BroadcastGroupSignedEventScreen.kt
@@ -17,7 +17,6 @@ import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.clearText
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.CellTower
import androidx.compose.material.icons.filled.ContentCopy
@@ -98,6 +97,7 @@ import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.rememberNotifier
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.MantraTheme
import press.mantra.compose.ui.theme.readableContent
@@ -216,11 +216,7 @@ fun BroadcastGroupSignedEventScreen(
title = {
broadcastGroupSignedEventUIState.localChatRoom.RenderChatRoomTitleText()
},
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
},
bottomBar = {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChapterDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChapterDetailScreen.kt
index 37ae0687..fd5feb3b 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChapterDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChapterDetailScreen.kt
@@ -10,13 +10,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Segment
import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -51,6 +49,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -94,14 +93,7 @@ fun ChapterDetailScreen(
topBar = {
TopAppBar(
title = { Text(chapter.name) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomCreationScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomCreationScreen.kt
index 008dfb7c..2027e905 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomCreationScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomCreationScreen.kt
@@ -12,12 +12,14 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Badge
import androidx.compose.material.icons.filled.Description
import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -33,19 +35,23 @@ import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.choose_who_to_chat_with
import mantra.composeapp.generated.resources.enter_the_name_you_want_to_use_for_your
import mantra.composeapp.generated.resources.name_eg_group_discussions
+import mantra.composeapp.generated.resources.new_chat
import mantra.composeapp.generated.resources.this_will_be_shown_when_people_open_the_chat
import mantra.composeapp.generated.resources.this_will_be_the_display_name_for_this_chat
import mantra.composeapp.generated.resources.what_should_people_know_about_you
import mantra.composeapp.generated.resources.what_will_be_discussed_in_this_chat_room
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChatRoomCreationScreen(
activeUserPublicKey: HexKey,
- onNavigateToRoute: (Route) -> Unit
+ onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val chatRoomCreationViewModel: ChatRoomCreationViewModel = viewModel (
factory = ChatRoomCreationViewModel.factory()
@@ -55,7 +61,16 @@ fun ChatRoomCreationScreen(
// keyboard covers whatever is being typed into.
Scaffold(
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
- modifier = Modifier.imePadding()) { innerPadding ->
+ modifier = Modifier.imePadding(),
+ topBar = {
+ // Named after the button that opens it, which is the first of three steps;
+ // the next two name themselves after the chat this one is creating.
+ TopAppBar(
+ title = { Text(stringResource(Res.string.new_chat)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
+ ) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding).readableContent().fillMaxWidth()
) {
@@ -181,7 +196,8 @@ private fun LoadingScreenPreview() {
) {
ChatRoomCreationScreen(
activeUserPublicKey = "",
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt
index 2540e326..b2148a64 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomDetailScreen.kt
@@ -192,6 +192,7 @@ import mantra.composeapp.generated.resources.recovered_of_event_s
import mantra.composeapp.generated.resources.recovered_of_still_unreadable
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -208,7 +209,8 @@ fun ChatRoomDetailScreen(
chatRepository: ChatRepository,
mantraRepository: MantraRepository,
onNavigateToRoute: (Route) -> Unit,
- onPopBackToRoute: (Route) -> Unit
+ onPopBackToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val chatRoomDetailViewModel: ChatRoomDetailViewModel = viewModel(
factory = ChatRoomDetailViewModel.factory(
@@ -245,6 +247,7 @@ fun ChatRoomDetailScreen(
title = {
chatRoomDetailUIState.localChatRoom.RenderChatRoomTitleText()
},
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
@@ -2213,7 +2216,8 @@ private fun ChatRoomMessagingScreenPreview() {
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
mantraRepository = MantraRepository.NO_OP_MANTRA_REPOSITORY,
onNavigateToRoute = {},
- onPopBackToRoute = {}
+ onPopBackToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomMessagingScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomMessagingScreen.kt
index e2a70c8f..e678a623 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomMessagingScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ChatRoomMessagingScreen.kt
@@ -69,6 +69,7 @@ import mantra.composeapp.generated.resources.private_message_to
import mantra.composeapp.generated.resources.private_to
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -86,6 +87,13 @@ fun ChatRoomMessagingScreen(
dkgRepository: DkgRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
onNavigateToRoute: (Route) -> Unit,
+ /**
+ * `null` when this is the home screen's detail pane rather than a pushed route. In
+ * the pane the room list is beside the transcript and there is nothing to pop, so
+ * the bar draws no back button -- M3's list-detail has the list do that job. On a
+ * phone the same screen is a destination, and the button is what leaves it.
+ */
+ onNavigateBack: (() -> Unit)?,
) {
val chatRoomMessagingViewModel: ChatRoomMessagingViewModel = viewModel(
factory = ChatRoomMessagingViewModel.factory(
@@ -133,6 +141,9 @@ fun ChatRoomMessagingScreen(
title = {
chatRoomDetailUIState.localChatRoom.RenderChatRoomTitleText()
},
+ navigationIcon = {
+ if (onNavigateBack != null) NavigateBackButton(onNavigateBack)
+ },
actions = {
IconButton(
onClick = {
@@ -491,7 +502,8 @@ private fun ChatRoomMessagingScreenPreview() {
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY,
onNavigateToRouteAndPopUpInclusive = {},
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CreateProfileScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CreateProfileScreen.kt
index da11d54a..28cc9ee3 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CreateProfileScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CreateProfileScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.material.icons.filled.Badge
import androidx.compose.material.icons.filled.Description
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@@ -23,6 +24,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -60,14 +62,16 @@ import mantra.composeapp.generated.resources.you_are_about_to_create_a_nostr_pro
import mantra.composeapp.generated.resources.you_will_be_in_full_control_of_this_profile
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
+@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
fun CreateProfileScreen(
initialCreateProfileUIState: CreateProfileUIState = CreateProfileUIState.Declaration,
onNavigateToEndThis: () -> Unit,
+ onNavigateBack: () -> Unit,
nostrRepository: press.mantra.compose.repository.NostrRepository,
marmotRepository: MarmotRepository,
writeSeed: (mnemonics: List, onSeedWritten: () -> Unit, onSeedWriteError: () -> Unit) -> Unit
@@ -83,7 +87,18 @@ fun CreateProfileScreen(
// keyboard covers whatever is being typed into.
Scaffold(
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
- modifier = Modifier.imePadding()) { innerPadding ->
+ modifier = Modifier.imePadding(),
+ topBar = {
+ // The name is in the bar, as it is on the sign-in screen beside this one on
+ // the landing page, and the steps below no longer repeat it as a headline.
+ // Back pops to the landing page; nothing is written until the last step
+ // confirms, so there is nothing to lose by leaving.
+ TopAppBar(
+ title = { Text(stringResource(Res.string.create_profile)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
+ ) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding)
.readableContent()
@@ -99,12 +114,6 @@ fun CreateProfileScreen(
when (val createAccountUIState = createProfileViewModel.createProfileUIState.value) {
is CreateProfileUIState.Declaration -> {
-
- Text(
- stringResource(Res.string.create_profile),
- style = MaterialTheme.typography.headlineSmall
- )
-
Text(
stringResource(Res.string.you_are_about_to_create_a_nostr_profile),
style = MaterialTheme.typography.bodyMedium,
@@ -133,11 +142,6 @@ fun CreateProfileScreen(
}
}
is CreateProfileUIState.InputPrompt -> {
- Text(
- stringResource(Res.string.create_profile),
- style = MaterialTheme.typography.headlineSmall
- )
-
TextField(
modifier = Modifier.fillMaxWidth(),
state = createProfileViewModel.createProfileFormState.nameField.textFieldState,
@@ -438,6 +442,7 @@ fun CreateAccountScreenPreview() {
// )
// ),
onNavigateToEndThis = {},
+ onNavigateBack = {},
writeSeed = { _, _, _ -> },
nostrRepository = press.mantra.compose.repository.NostrRepository.NO_OP_NOSTR_REPOSITORY,
marmotRepository = MarmotRepository.NO_OP_MARMOT_KEY_PACKAGE_BUNDLE
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CuratedSuggestionListScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CuratedSuggestionListScreen.kt
index 06de3aa2..8f7b69c6 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CuratedSuggestionListScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/CuratedSuggestionListScreen.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Draw
import androidx.compose.material3.Button
@@ -20,7 +19,6 @@ import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -85,6 +83,7 @@ import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.dialogs.ModalBottomSheet
import press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.MantraTheme
import press.mantra.compose.ui.theme.readableContent
@@ -153,11 +152,7 @@ fun CuratedSuggestionListScreen(
overflow = TextOverflow.Ellipsis
)
},
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { padding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgApprovalScaffold.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgApprovalScaffold.kt
index b3766198..cc358aa5 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgApprovalScaffold.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgApprovalScaffold.kt
@@ -45,6 +45,7 @@ import mantra.composeapp.generated.resources.back
import mantra.composeapp.generated.resources.not_now
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
/**
@@ -92,7 +93,10 @@ internal fun DkgApprovalScaffold(
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
topBar = {
TopAppBar(
- title = { Text(text = title, maxLines = 1, overflow = TextOverflow.Ellipsis) }
+ title = { Text(text = title, maxLines = 1, overflow = TextOverflow.Ellipsis) },
+ // The same leave as "Not now" below, reachable from the loading and error
+ // states too -- which have no other way off the screen on desktop.
+ navigationIcon = { NavigateBackButton(onDone) },
)
}
) { padding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgRitualScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgRitualScreen.kt
index 342b6702..64ce688d 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgRitualScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/DkgRitualScreen.kt
@@ -114,6 +114,7 @@ import mantra.composeapp.generated.resources.of_members_will_be_needed_to_sign_w
import mantra.composeapp.generated.resources.shared_key_for
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -139,6 +140,7 @@ fun DkgRitualScreen(
chatRepository: ChatRepository,
dkgRepository: DkgRepository,
onNavigateToRoute: (Route) -> Unit = {},
+ onNavigateBack: () -> Unit,
) {
val dkgRitualViewModel: DkgRitualViewModel = viewModel(
factory = DkgRitualViewModel.factory(
@@ -179,7 +181,8 @@ fun DkgRitualScreen(
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -884,7 +887,8 @@ private fun DkgRitualScreenPreview() {
),
activeIdentityStateFlow = MutableStateFlow(null),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
- dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY
+ dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY,
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreen.kt
index be868d9b..6a113f52 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreen.kt
@@ -104,6 +104,7 @@ import press.mantra.compose.ui.composable.widgets.Decorative
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.dialogs.ModalBottomSheet
import press.mantra.compose.ui.composable.widgets.rememberNotifier
@@ -268,6 +269,7 @@ fun EditGroupCuratedSchemaScreen(
chatRepository: ChatRepository,
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val editGroupCuratedSchemaViewModel: EditGroupCuratedSchemaViewModel = viewModel(
factory = EditGroupCuratedSchemaViewModel.factory(
@@ -344,7 +346,8 @@ fun EditGroupCuratedSchemaScreen(
TopAppBar(
title = {
editGroupCuratedSchemaUIState.localChatRoom.RenderChatRoomTitleText()
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -1514,7 +1517,8 @@ private fun EditGroupCuratedSchemaScreenPreview() {
),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupNostrProfileScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupNostrProfileScreen.kt
index 33e8d287..6914b722 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupNostrProfileScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupNostrProfileScreen.kt
@@ -59,6 +59,7 @@ import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.rememberNotifier
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -113,6 +114,7 @@ fun EditGroupNostrProfileScreen(
chatRepository: ChatRepository,
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val editGroupNostrProfileViewModel: EditGroupNostrProfileViewModel = viewModel(
factory = EditGroupNostrProfileViewModel.factory(
@@ -170,7 +172,8 @@ fun EditGroupNostrProfileScreen(
title = {
editGroupNostrProfileUIState.localChatRoom
.RenderChatRoomTitleText()
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -416,7 +419,8 @@ private fun EditGroupNostrProfileScreenPreview() {
),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupRelaysScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupRelaysScreen.kt
index 6a0003f3..7b076c84 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupRelaysScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/EditGroupRelaysScreen.kt
@@ -68,6 +68,7 @@ import press.mantra.compose.ui.composable.widgets.EmptyState
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.rememberNotifier
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -133,6 +134,7 @@ fun EditGroupRelaysScreen(
chatRepository: ChatRepository,
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val editGroupRelaysViewModel: EditGroupRelaysViewModel = viewModel(
factory = EditGroupRelaysViewModel.factory(
@@ -192,7 +194,8 @@ fun EditGroupRelaysScreen(
TopAppBar(
title = {
editGroupRelaysUIState.localChatRoom.RenderChatRoomTitleText()
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -570,7 +573,8 @@ private fun EditGroupRelaysScreenPreview() {
),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/FrostSigningScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/FrostSigningScreen.kt
index f9917824..fbecea82 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/FrostSigningScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/FrostSigningScreen.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Draw
import androidx.compose.material.icons.filled.ErrorOutline
@@ -25,7 +24,6 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -70,6 +68,7 @@ import mantra.composeapp.generated.resources.signed_their_part
import mantra.composeapp.generated.resources.events_signed_together
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -125,11 +124,7 @@ fun FrostSigningScreen(
overflow = TextOverflow.Ellipsis
)
},
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { padding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/HomeScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/HomeScreen.kt
index fc20e8ec..2b91c937 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/HomeScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/HomeScreen.kt
@@ -302,6 +302,8 @@ fun HomeScreen(
// created and has an id at last.
onNavigateToRouteAndPopUpInclusive = onOpenChatRoom,
onNavigateToRoute = onNavigateToRoute,
+ // The list is beside it; there is nothing to pop.
+ onNavigateBack = null,
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ImplementationPendingScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ImplementationPendingScreen.kt
index cd4c2015..98216fc5 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ImplementationPendingScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ImplementationPendingScreen.kt
@@ -4,10 +4,12 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -18,15 +20,35 @@ import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.functionality_coming_soon_2
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
+/**
+ * @param onNavigateBack `null` when this screen is the root of the stack, which it is
+ * when the navigation machine lands on an error and clears everything under it. Pushed
+ * from a "learn more" or an "edit profile", there is a screen to return to and this is
+ * how. Only the host knows which, so it decides.
+ */
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ImplementationPendingScreen(
- text: String
+ text: String,
+ onNavigateBack: (() -> Unit)?,
) {
- Scaffold(snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) }) { innerPadding ->
+ Scaffold(
+ snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
+ topBar = {
+ TopAppBar(
+ // The name of the thing that is not built yet, which is what was tapped.
+ title = { Text(text) },
+ navigationIcon = {
+ if (onNavigateBack != null) NavigateBackButton(onNavigateBack)
+ },
+ )
+ },
+ ) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding).readableContent().fillMaxSize()
) {
@@ -52,7 +74,8 @@ private fun ImplementationPendingScreenPreview() {
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
ImplementationPendingScreen(
- "Sign in"
+ text = "Sign in",
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyPackageManagementScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyPackageManagementScreen.kt
index e787472d..b45367e9 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyPackageManagementScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyPackageManagementScreen.kt
@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.DoneAll
import androidx.compose.material.icons.filled.LockReset
import androidx.compose.material.icons.filled.Unpublished
@@ -59,6 +58,7 @@ import mantra.composeapp.generated.resources.key_package_published
import mantra.composeapp.generated.resources.key_package_rotated
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@@ -102,18 +102,7 @@ fun KeyPackageManagementScreen(
text = stringResource(Res.string.key_package_management)
)
},
- navigationIcon = {
- IconButton(
- onClick = {
- onNavigateBack.invoke()
- }
- ) {
- Icon(
- Icons.Default.ArrowBack,
- contentDescription = "Back"
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyRecoveryScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyRecoveryScreen.kt
index b7e12aa3..b70a798c 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyRecoveryScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/KeyRecoveryScreen.kt
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AddToDrive
-import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.LocalHospital
import androidx.compose.material.icons.filled.Key
@@ -25,7 +24,6 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -71,6 +69,7 @@ import press.mantra.compose.ui.composable.navigation.routes.NostrSecretRoute
import press.mantra.compose.ui.composable.navigation.routes.RecoveryPhraseRoute
import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.composable.widgets.Decorative
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.spacing
@@ -109,18 +108,7 @@ fun KeyRecoveryScreen(
text = stringResource(Res.string.key_recovery)
)
},
- navigationIcon = {
- IconButton(
- onClick = {
- onNavigateBack.invoke()
- }
- ) {
- Icon(
- Icons.Default.ArrowBack,
- contentDescription = "Back"
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrEventDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrEventDetailScreen.kt
index 348a912a..f141fb24 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrEventDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrEventDetailScreen.kt
@@ -9,6 +9,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
@@ -34,12 +35,14 @@ import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
import mantra.composeapp.generated.resources.functionality_coming_soon
+import mantra.composeapp.generated.resources.post
import mantra.composeapp.generated.resources.post_functionality_coming_soon
import mantra.composeapp.generated.resources.something_went_wrong
import mantra.composeapp.generated.resources.we_couldn_t_find_your_nostr_event_please_try
import press.mantra.compose.ui.composable.widgets.ErrorState
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -95,20 +98,41 @@ fun NostrEventDetailScreen(
nostrRepository = nostrRepository
)
}
+ // The two kinds with a detail of their own draw their bar inside it. The
+ // rest are a placeholder, and a placeholder pushed onto the stack still
+ // needs the way off it.
RepostEvent.KIND -> {
// TODO: RePost...
- Column(
- modifier = Modifier.fillMaxSize(),
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Text(feedListUIState.localNostrEvent.nostrEvent.content)
+ Scaffold(
+ snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
+ topBar = {
+ TopAppBar(
+ title = { Text(stringResource(Res.string.post)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
+ ) { innerPadding ->
+ Column(
+ modifier = Modifier.padding(innerPadding).readableContent().fillMaxSize(),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(feedListUIState.localNostrEvent.nostrEvent.content)
- Text(stringResource(Res.string.post_functionality_coming_soon))
+ Text(stringResource(Res.string.post_functionality_coming_soon))
+ }
}
}
else -> {
- Scaffold(snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) }) { innerPadding ->
+ Scaffold(
+ snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
+ topBar = {
+ TopAppBar(
+ title = { Text(stringResource(Res.string.post)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
+ ) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding).readableContent().fillMaxSize()
) {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrSecretScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrSecretScreen.kt
index 12d49d6c..bf04707a 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrSecretScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/NostrSecretScreen.kt
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material.icons.filled.DeleteForever
import androidx.compose.material.icons.filled.Visibility
@@ -27,7 +26,6 @@ import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
@@ -48,7 +46,6 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign
import androidx.lifecycle.viewmodel.compose.viewModel
import mantra.composeapp.generated.resources.Res
-import mantra.composeapp.generated.resources.back
import mantra.composeapp.generated.resources.backup_confirmation
import mantra.composeapp.generated.resources.cancel
import mantra.composeapp.generated.resources.copied_the_nsec
@@ -86,6 +83,7 @@ import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.composable.widgets.rememberNotifier
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.spacing
@@ -201,14 +199,7 @@ private fun NostrSecretContent(
topBar = {
TopAppBar(
title = { Text(text = stringResource(Res.string.nostr_secret_key)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = stringResource(Res.string.back)
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposalListScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposalListScreen.kt
index 2ac182c3..a330a4c3 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposalListScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposalListScreen.kt
@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.Draw
@@ -22,7 +21,6 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
@@ -64,6 +62,7 @@ import mantra.composeapp.generated.resources.waiting_for_you
import mantra.composeapp.generated.resources.of_them_could_not_be_read
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -119,11 +118,7 @@ fun ProposalListScreen(
overflow = TextOverflow.Ellipsis
)
},
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { padding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreen.kt
index b82b529e..6b4f4a86 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreen.kt
@@ -58,6 +58,7 @@ import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar
import press.mantra.compose.ui.composable.widgets.rememberNotifier
@@ -115,6 +116,7 @@ fun ProposeGroupEventScreen(
chatRepository: ChatRepository,
frostSigningRepository: FrostSigningRepository,
onNavigateToRouteAndPopUpInclusive: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val proposeGroupEventViewModel: ProposeGroupEventViewModel = viewModel(
factory = ProposeGroupEventViewModel.factory(
@@ -164,7 +166,8 @@ fun ProposeGroupEventScreen(
modifier = Modifier.imePadding(),
topBar = {
TopAppBar(
- title = { Text(text = stringResource(Res.string.propose_event)) }
+ title = { Text(text = stringResource(Res.string.propose_event)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -458,7 +461,8 @@ private fun ProposeGroupEventScreenPreview() {
),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/RecoveryPhraseScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/RecoveryPhraseScreen.kt
index 415d9973..543a75ca 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/RecoveryPhraseScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/RecoveryPhraseScreen.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.filled.Warning
@@ -23,7 +22,6 @@ import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -66,6 +64,7 @@ import org.jetbrains.compose.resources.stringResource
import press.mantra.compose.ui.composable.widgets.Decorative
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.spacing
@@ -136,18 +135,7 @@ private fun RecoveryPhraseContent(
text = stringResource(Res.string.recovery_phrase)
)
},
- navigationIcon = {
- IconButton(
- onClick = {
- onNavigateBack.invoke()
- }
- ) {
- Icon(
- Icons.Default.ArrowBack,
- contentDescription = "Back"
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SearchMemberToAddToChatRoomScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SearchMemberToAddToChatRoomScreen.kt
index 67b25221..ea39c367 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SearchMemberToAddToChatRoomScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SearchMemberToAddToChatRoomScreen.kt
@@ -47,6 +47,7 @@ import mantra.composeapp.generated.resources.search_member_functionality
import mantra.composeapp.generated.resources.search_message_functionality_will_be_here
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -61,6 +62,7 @@ fun SearchMemberToAddToChatRoomScreen(
nostrRepository: NostrRepository,
chatRepository: ChatRepository,
onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val searchMemberToAddToChatRoomViewModel: SearchMemberToAddToChatRoomViewModel = viewModel(
factory = SearchMemberToAddToChatRoomViewModel.factory(
@@ -102,7 +104,8 @@ fun SearchMemberToAddToChatRoomScreen(
Text(
text = title,
)
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
@@ -256,7 +259,8 @@ private fun ChatRoomDetailScreenPreview() {
),
nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomMembersScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomMembersScreen.kt
index f1aa9dbc..772a2ce9 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomMembersScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomMembersScreen.kt
@@ -54,6 +54,7 @@ import mantra.composeapp.generated.resources.next_with
import mantra.composeapp.generated.resources.selected
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -74,6 +75,7 @@ fun SelectChatRoomMembersScreen(
initialSelectChatRoomMembersUIState: SelectChatRoomMembersUIState = SelectChatRoomMembersUIState.Loading,
nostrRepository: NostrRepository,
onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val selectChatRoomMembersViewModel: SelectChatRoomMembersViewModel = viewModel(
factory = SelectChatRoomMembersViewModel.factory(
@@ -114,7 +116,8 @@ fun SelectChatRoomMembersScreen(
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -302,7 +305,8 @@ private fun SelectChatRoomMembersScreenPreview() {
)
),
nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomTypeScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomTypeScreen.kt
index 0d62827e..5f5399fd 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomTypeScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectChatRoomTypeScreen.kt
@@ -71,6 +71,7 @@ import mantra.composeapp.generated.resources.was_created_but_its_shared_key_cere
import mantra.composeapp.generated.resources.you_and_others
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -92,6 +93,7 @@ fun SelectChatRoomTypeScreen(
chatRepository: ChatRepository,
dkgRepository: DkgRepository,
onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val selectChatRoomTypeViewModel: SelectChatRoomTypeViewModel = viewModel(
factory = SelectChatRoomTypeViewModel.factory(
@@ -142,7 +144,8 @@ fun SelectChatRoomTypeScreen(
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
- }
+ },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
@@ -494,7 +497,8 @@ private fun SelectChatRoomTypeScreenPreview() {
nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY,
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectSubgroupAdminsScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectSubgroupAdminsScreen.kt
index 94b311b8..44110cbf 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectSubgroupAdminsScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SelectSubgroupAdminsScreen.kt
@@ -59,6 +59,7 @@ import press.mantra.compose.ui.composable.widgets.Decorative
import press.mantra.compose.ui.composable.widgets.ErrorState
import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -84,7 +85,8 @@ fun SelectSubgroupAdminsScreen(
activeIdentityStateFlow: StateFlow,
chatRepository: ChatRepository,
dkgRepository: DkgRepository,
- onNavigateToRoute: (Route) -> Unit
+ onNavigateToRoute: (Route) -> Unit,
+ onNavigateBack: () -> Unit,
) {
val viewModel: SelectSubgroupAdminsViewModel = viewModel(
factory = SelectSubgroupAdminsViewModel.factory(
@@ -115,7 +117,10 @@ fun SelectSubgroupAdminsScreen(
is SelectSubgroupAdminsUIState.Loaded -> Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = {
- TopAppBar(title = { Text(stringResource(Res.string.new_subgroup)) })
+ TopAppBar(
+ title = { Text(stringResource(Res.string.new_subgroup)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
},
floatingActionButton = {
ExtendedFloatingActionButton(
@@ -334,7 +339,8 @@ private fun SelectSubgroupAdminsScreenPreview() {
activeIdentityStateFlow = kotlinx.coroutines.flow.MutableStateFlow(null),
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY,
- onNavigateToRoute = {}
+ onNavigateToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ShareProfileScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ShareProfileScreen.kt
index b458efb5..fc53f059 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ShareProfileScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/ShareProfileScreen.kt
@@ -10,13 +10,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -55,6 +53,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@@ -92,18 +91,7 @@ fun ShareProfileScreen(
text = stringResource(Res.string.profile)
)
},
- navigationIcon = {
- IconButton(
- onClick = {
- onNavigateBack.invoke()
- }
- ) {
- Icon(
- Icons.Default.ArrowBack,
- contentDescription = "Back"
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SignInScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SignInScreen.kt
index f60352fd..8dac4889 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SignInScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SignInScreen.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ContentPaste
import androidx.compose.material.icons.filled.Key
import androidx.compose.material.icons.filled.Spellcheck
@@ -40,7 +39,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import mantra.composeapp.generated.resources.Res
import mantra.composeapp.generated.resources.a_password_protected_key_ncryptsec_is_not
import mantra.composeapp.generated.resources.an_npub_is_a_public_key_mantra_needs_the
-import mantra.composeapp.generated.resources.back
import mantra.composeapp.generated.resources.enter_a_recovery_phrase_or_an_nsec_to_sign_in
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.paste
@@ -73,6 +71,7 @@ import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
import press.mantra.compose.ui.composable.widgets.rememberNotifier
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.spacing
@@ -121,14 +120,7 @@ fun SignInToProfileScreen(
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.sign_in)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = stringResource(Res.string.back)
- )
- }
- }
+ navigationIcon = { NavigateBackButton(onNavigateBack) }
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SovereignWalletStartupScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SovereignWalletStartupScreen.kt
index b2a030e1..9bd960f7 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SovereignWalletStartupScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/SovereignWalletStartupScreen.kt
@@ -70,7 +70,9 @@ fun SovereignWalletStartupScreen(
}
is ListWalletState.Error -> {
ImplementationPendingScreen(
- "Failed to load wallet data",
+ text = "Failed to load wallet data",
+ // Drawn inside the startup gate, which is the root of the stack.
+ onNavigateBack = null,
)
}
is ListWalletState.Success -> {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslateChunkScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslateChunkScreen.kt
index 0d767b3d..bd9bd0af 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslateChunkScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslateChunkScreen.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.ButtonDefaults
@@ -21,7 +20,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
@@ -65,6 +63,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -124,14 +123,7 @@ fun TranslateChunkScreen(
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.translate_chunk)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
},
bottomBar = {
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationArtifactVersionDetailScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationArtifactVersionDetailScreen.kt
index fef9c9d2..732a9f32 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationArtifactVersionDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationArtifactVersionDetailScreen.kt
@@ -10,14 +10,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Article
import androidx.compose.material.icons.filled.PlaylistAdd
import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -60,6 +58,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -108,14 +107,7 @@ fun TranslationArtifactVersionDetailScreen(
topBar = {
TopAppBar(
title = { Text(translation.name) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationChapterScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationChapterScreen.kt
index 1d0b5df7..c4805f6f 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationChapterScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/TranslationChapterScreen.kt
@@ -15,12 +15,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
@@ -55,6 +53,7 @@ import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.composable.widgets.ScreenStateTransition
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.ConformancePreviews
@OptIn(ExperimentalMaterial3Api::class)
@@ -98,14 +97,7 @@ fun TranslationChapterScreen(
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.chapter_translation)) },
- navigationIcon = {
- IconButton(onClick = onNavigateBack) {
- Icon(
- Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = "Back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
)
}
) { innerPadding ->
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/WriteNewNoteScreen.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/WriteNewNoteScreen.kt
index bdef27a3..4efd8f31 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/WriteNewNoteScreen.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/WriteNewNoteScreen.kt
@@ -20,6 +20,7 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@@ -29,6 +30,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.key
@@ -46,6 +48,7 @@ import kotlin.time.Clock
import press.mantra.compose.ui.theme.spacing
import mantra.composeapp.generated.resources.Res
import org.jetbrains.compose.resources.stringResource
+import mantra.composeapp.generated.resources.new_note
import mantra.composeapp.generated.resources.next
import mantra.composeapp.generated.resources.something_went_wrong_and_we_were_unable_to_3
import mantra.composeapp.generated.resources.the_above_will_be_your_new_note
@@ -57,10 +60,11 @@ import mantra.composeapp.generated.resources.what_vibrations_do_you_want_to_send
import mantra.composeapp.generated.resources.replying_to
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
-@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalFoundationApi::class)
+@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun WriteNewNoteScreen(
activeUserPublicKey: HexKey,
@@ -69,6 +73,7 @@ fun WriteNewNoteScreen(
quotedNostrEventId: HexKey?,
onNostrEventPublished: () -> Unit,
onNavigateToNostrEvent: (HexKey) -> Unit,
+ onNavigateBack: () -> Unit,
nostrRepository: press.mantra.compose.repository.NostrRepository
) {
val writeNewNoteViewModel: press.mantra.compose.ui.view.model.WriteNewNoteViewModel = viewModel (
@@ -84,7 +89,17 @@ fun WriteNewNoteScreen(
// keyboard covers whatever is being typed into.
Scaffold(
snackbarHost = { SnackbarHost(LocalSnackbarHostState.current) },
- modifier = Modifier.imePadding()) { innerPadding ->
+ modifier = Modifier.imePadding(),
+ topBar = {
+ // "New note" whether it is a reply, a quote or neither: the body says which
+ // above the field. Back pops the route and drops the draft, which is what
+ // the platform's own back does on this screen already.
+ TopAppBar(
+ title = { Text(stringResource(Res.string.new_note)) },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
+ )
+ },
+ ) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding)
.readableContent()
@@ -522,6 +537,7 @@ It has survived not only five centuries, but also the leap into electronic types
),
onNostrEventPublished = {},
onNavigateToNostrEvent = {},
+ onNavigateBack = {},
nostrRepository = press.mantra.compose.repository.NostrRepository.NO_OP_NOSTR_REPOSITORY
)
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt
index 5cdb1334..9dbcedd5 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/navigation/MantraNavHost.kt
@@ -500,6 +500,9 @@ fun MantraNavHost(
popUpTo(0)
}
},
+ onNavigateBack = {
+ navController.popBackStack()
+ },
nostrRepository = databaseNostrRepository,
marmotRepository = databaseMarmotRepository,
writeSeed = { words, onSeedWritten, onSeedWriteError ->
@@ -532,6 +535,9 @@ fun MantraNavHost(
navController.navigate(
selectMembersRoute
)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -547,6 +553,9 @@ fun MantraNavHost(
navController.navigate(
selectChatRoomTypeRoute
)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -561,6 +570,9 @@ fun MantraNavHost(
dkgRepository = databaseDkgRepository,
onNavigateToRoute = { nextRoute ->
navController.navigate(route = nextRoute)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -576,6 +588,9 @@ fun MantraNavHost(
dkgRepository = databaseDkgRepository,
onNavigateToRoute = { approvalRoute ->
navController.navigate(route = approvalRoute)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -644,6 +659,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -666,6 +684,9 @@ fun MantraNavHost(
)
)
},
+ onNavigateBack = {
+ navController.popBackStack()
+ },
nostrRepository = databaseNostrRepository
)
}
@@ -918,6 +939,11 @@ fun MantraNavHost(
navController.navigate(
route = actionRoute
)
+ },
+ // A pushed route, unlike the same screen inside the home screen's
+ // detail pane, so there is something to pop.
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -941,6 +967,9 @@ fun MantraNavHost(
route = popRoute,
inclusive = false
)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -958,6 +987,9 @@ fun MantraNavHost(
route = chatRoomDetailRoute
)
},
+ onNavigateBack = {
+ navController.popBackStack()
+ },
)
}
composable { backStackEntry ->
@@ -980,6 +1012,11 @@ fun MantraNavHost(
inclusive = true
)
},
+ // Back is to the search, not past it: a member who picked the wrong
+ // person wants the list again, not the room.
+ onNavigateBack = {
+ navController.popBackStack()
+ },
)
}
composable { backStackEntry ->
@@ -1008,6 +1045,9 @@ fun MantraNavHost(
navController.navigate(
route = actionRoute
)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1034,6 +1074,9 @@ fun MantraNavHost(
navController.navigate(
route = actionRoute
)
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1054,6 +1097,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1074,6 +1120,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1094,6 +1143,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1115,6 +1167,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1198,6 +1253,9 @@ fun MantraNavHost(
inclusive = true
}
}
+ },
+ onNavigateBack = {
+ navController.popBackStack()
}
)
}
@@ -1485,8 +1543,23 @@ fun MantraNavHost(
}
composable { backStackEntry ->
val route: ImplementationPendingRoute = backStackEntry.toRoute()
+
+ // Pushed from a "learn more" or an "edit profile", and also where the
+ // navigation observer above lands with `popUpTo(0)` on an error. Whether
+ // there is anything under this entry is what decides the back button, and
+ // it is remembered because the answer is read again while the screen is
+ // leaving, when the stack has already moved on.
+ val hasSomethingToReturnTo = remember {
+ navController.previousBackStackEntry != null
+ }
+
ImplementationPendingScreen(
- route.name
+ text = route.name,
+ onNavigateBack = if (hasSomethingToReturnTo) {
+ { navController.popBackStack() }
+ } else {
+ null
+ }
)
}
}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/NavigateBackButton.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/NavigateBackButton.kt
new file mode 100644
index 00000000..4f43fcf2
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/NavigateBackButton.kt
@@ -0,0 +1,50 @@
+package press.mantra.compose.ui.composable.widgets
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.runtime.Composable
+import mantra.composeapp.generated.resources.Res
+import mantra.composeapp.generated.resources.back
+import org.jetbrains.compose.resources.stringResource
+
+/**
+ * The button in a pushed screen's leading slot, the one M3 calls the navigation icon.
+ *
+ * Before this file, 18 screens drew it and 22 did not, and the 18 spelled it four ways:
+ * `ArrowBack`, the auto-mirrored `ArrowBack`, `ArrowBackIosNew`, and a `"Back"` literal
+ * against a `stringResource`. A screen that is reached by pushing a route and has no way
+ * to pop it is a dead end wherever the platform gives no back gesture -- which is the
+ * desktop target, where a window has neither a back button nor an edge to swipe from.
+ *
+ * Two of the four spellings are decisions this component makes once:
+ *
+ * - **The icon is the auto-mirrored one.** "Back" points at the leading edge, and the
+ * leading edge is on the right in an RTL locale. `Icons.Filled.ArrowBack` is
+ * deprecated for exactly this reason, and the navigation transitions already mirror
+ * through `slideIntoContainer`; an arrow that did not would point the wrong way at the
+ * screen that was sliding the right way.
+ * - **The description is the catalogue's.** "Back" is what a screen reader says, and it
+ * is text, so it lives in `strings.xml` like every other word the app says.
+ *
+ * `IconButton` reserves the 48dp target itself, so there is no modifier to remember.
+ *
+ * Put it in `TopAppBar(navigationIcon = …)`, and only on a screen the user pushed onto
+ * the stack. A top-level destination has the navigation bar instead, and a screen that
+ * replaced the whole stack -- onboarding, the loading gate -- has nothing under it to
+ * return to; a back button there would pop to an empty host.
+ *
+ * @param onNavigateBack what popping means for the screen, which is nearly always the
+ * host's `popBackStack()`. Hoisted rather than read from a controller here so the
+ * screen stays previewable and testable without one.
+ */
+@Composable
+fun NavigateBackButton(onNavigateBack: () -> Unit) {
+ IconButton(onClick = onNavigateBack) {
+ Icon(
+ imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ contentDescription = stringResource(Res.string.back),
+ )
+ }
+}
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/MetadataEventDetail.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/MetadataEventDetail.kt
index 2ad86228..d8c0c463 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/MetadataEventDetail.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/MetadataEventDetail.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBackIosNew
import androidx.compose.material.icons.filled.Block
import androidx.compose.material.icons.filled.Bolt
import androidx.compose.material.icons.filled.Error
@@ -22,7 +21,6 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.MaterialTheme
@@ -68,6 +66,7 @@ import mantra.composeapp.generated.resources.send_message
import mantra.composeapp.generated.resources.unfollow
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -101,16 +100,7 @@ fun MetadataEventDetail(
modifier = Modifier.fillMaxSize().nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
LargeTopAppBar(
- navigationIcon = {
- IconButton(
- onClick = onNavigateBack
- ) {
- Icon(
- Icons.Default.ArrowBackIosNew,
- contentDescription = "Navigate back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
title = {
Column(
modifier = Modifier,
diff --git a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/TextNoteEventDetail.kt b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/TextNoteEventDetail.kt
index 35304a9f..180c2475 100644
--- a/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/TextNoteEventDetail.kt
+++ b/composeApp/src/commonMain/kotlin/press/mantra/compose/ui/composable/widgets/detail/TextNoteEventDetail.kt
@@ -15,7 +15,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AddReaction
-import androidx.compose.material.icons.filled.ArrowBackIosNew
import androidx.compose.material.icons.filled.ChatBubble
import androidx.compose.material.icons.filled.CurrencyBitcoin
import androidx.compose.material.icons.filled.MoreVert
@@ -57,6 +56,7 @@ import mantra.composeapp.generated.resources.reply_to
import press.mantra.compose.ui.composable.widgets.ErrorState
import androidx.compose.material3.SnackbarHost
import press.mantra.compose.ui.composable.widgets.LocalSnackbarHostState
+import press.mantra.compose.ui.composable.widgets.NavigateBackButton
import press.mantra.compose.ui.theme.readableContent
import press.mantra.compose.ui.theme.ConformancePreviews
@@ -87,16 +87,7 @@ fun TextNoteEventDetail(
modifier = Modifier.fillMaxSize().nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
- navigationIcon = {
- IconButton(
- onClick = onNavigateBack
- ) {
- Icon(
- Icons.Default.ArrowBackIosNew,
- contentDescription = "Navigate back"
- )
- }
- },
+ navigationIcon = { NavigateBackButton(onNavigateBack) },
title = {
Text(stringResource(Res.string.post))
},
diff --git a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreenJvmTest.kt b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreenJvmTest.kt
index 342753a0..5afdce93 100644
--- a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreenJvmTest.kt
+++ b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/EditGroupCuratedSchemaScreenJvmTest.kt
@@ -226,7 +226,8 @@ class EditGroupCuratedSchemaScreenJvmTest {
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository =
FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/GroupNostrProfileSectionJvmTest.kt b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/GroupNostrProfileSectionJvmTest.kt
index 137aa291..79f58c1b 100644
--- a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/GroupNostrProfileSectionJvmTest.kt
+++ b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/GroupNostrProfileSectionJvmTest.kt
@@ -665,7 +665,8 @@ class GroupNostrProfileSectionJvmTest {
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
mantraRepository = MantraRepository.NO_OP_MANTRA_REPOSITORY,
onNavigateToRoute = {},
- onPopBackToRoute = {}
+ onPopBackToRoute = {},
+ onNavigateBack = {},
)
}
}
diff --git a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/NavigateBackButtonJvmTest.kt b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/NavigateBackButtonJvmTest.kt
new file mode 100644
index 00000000..2ed6f184
--- /dev/null
+++ b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/NavigateBackButtonJvmTest.kt
@@ -0,0 +1,111 @@
+package press.mantra.compose.ui.composable
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.runDesktopComposeUiTest
+import press.mantra.compose.database.model.ChatRoom
+import press.mantra.compose.database.model.intermdiate.LocalChatRoom
+import press.mantra.compose.repository.ChatRepository
+import press.mantra.compose.repository.DkgRepository
+import press.mantra.compose.repository.FrostSigningRepository
+import press.mantra.compose.repository.NostrRepository
+import press.mantra.compose.ui.composable.widgets.ProvideSnackbarHost
+import press.mantra.compose.ui.theme.MantraTheme
+import press.mantra.compose.ui.view.state.ChatRoomMessagingUIState
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+/**
+ * Where the back button is, on the two screens that have to decide.
+ *
+ * Every other pushed screen draws `NavigateBackButton` unconditionally, and there is
+ * nothing to assert about that beyond the compiler: the parameter is not optional. These
+ * two take a nullable callback because the same composable is reached two ways, and
+ * only the caller knows which:
+ *
+ * - the chat room is a destination on a phone and the home screen's detail pane in an
+ * expanded window. In the pane the room list is beside it, and a button that popped
+ * would pop the home screen;
+ * - the "coming soon" placeholder is pushed from a *learn more* and is also where the
+ * navigation machine lands, with the stack cleared, on an error.
+ *
+ * Read by the description a screen reader would announce, which is also the one thing
+ * about the button a test can check that the type system does not.
+ */
+@OptIn(ExperimentalTestApi::class)
+class NavigateBackButtonJvmTest {
+
+ @Test
+ fun `a pushed chat room has a back button, and it pops`() = runDesktopComposeUiTest(400, 900) {
+ var popped = false
+ setContent { Chat(onNavigateBack = { popped = true }) }
+
+ onNodeWithContentDescription("Back").assertIsDisplayed().performClick()
+ assertTrue(popped, "the button should have called the host's pop")
+ }
+
+ @Test
+ fun `the same chat room beside its list has none`() = runDesktopComposeUiTest(1000, 900) {
+ setContent { Chat(onNavigateBack = null) }
+
+ onNodeWithContentDescription("Back").assertDoesNotExist()
+ }
+
+ @Test
+ fun `a pushed placeholder has a back button`() = runDesktopComposeUiTest(400, 900) {
+ setContent { Placeholder(onNavigateBack = {}) }
+
+ onNodeWithContentDescription("Back").assertIsDisplayed()
+ }
+
+ @Test
+ fun `a placeholder at the root of the stack has none`() = runDesktopComposeUiTest(400, 900) {
+ setContent { Placeholder(onNavigateBack = null) }
+
+ onNodeWithContentDescription("Back").assertDoesNotExist()
+ }
+
+ @Composable
+ private fun Chat(onNavigateBack: (() -> Unit)?) {
+ MantraTheme {
+ ProvideSnackbarHost {
+ ChatRoomMessagingScreen(
+ activeUserPublicKey = "a".repeat(64),
+ chatRoomId = "b".repeat(64),
+ relayHint = null,
+ initialChatRoomMessagingUIState = ChatRoomMessagingUIState.Loaded(
+ localChatRoom = LocalChatRoom(
+ chatRoom = ChatRoom(
+ id = "b".repeat(64),
+ userPublicKey = "a".repeat(64),
+ subject = "Reading group",
+ description = null,
+ initialGiftWrapPayloadId = null,
+ mlsGroupState = null,
+ ),
+ ),
+ ),
+ nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
+ chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
+ frostSigningRepository = FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
+ dkgRepository = DkgRepository.NO_OP_DKG_REPOSITORY,
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateToRoute = {},
+ onNavigateBack = onNavigateBack,
+ )
+ }
+ }
+ }
+
+ @Composable
+ private fun Placeholder(onNavigateBack: (() -> Unit)?) {
+ MantraTheme {
+ ProvideSnackbarHost {
+ ImplementationPendingScreen(text = "Learn more", onNavigateBack = onNavigateBack)
+ }
+ }
+ }
+}
diff --git a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreenJvmTest.kt b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreenJvmTest.kt
index 6b471f77..19d7afd4 100644
--- a/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreenJvmTest.kt
+++ b/composeApp/src/jvmTest/kotlin/press/mantra/compose/ui/composable/ProposeGroupEventScreenJvmTest.kt
@@ -104,7 +104,8 @@ class ProposeGroupEventScreenJvmTest {
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
frostSigningRepository =
FrostSigningRepository.NO_OP_FROST_SIGNING_REPOSITORY,
- onNavigateToRouteAndPopUpInclusive = {}
+ onNavigateToRouteAndPopUpInclusive = {},
+ onNavigateBack = {},
)
}
}