Kgothatso Ngako b5cd41cb3d fix(ui): a back button on every pushed screen, and one spelling of it
Eighteen screens drew a back arrow in their app bar's leading slot and twenty-two
pushed screens did not. On Android the system back stood in for it and on iOS the
edge swipe, but the desktop target has neither, and a screen reached by
`navigate(...)` with no way to pop it is a dead end there: seven group forms, six
chat screens, five DKG screens, and four screens with no app bar at all.

**One widget, `NavigateBackButton`, rather than a nineteenth inline copy.** The
eighteen that had the button spelled it four ways -- `Icons.Filled.ArrowBack`, the
auto-mirrored one, `ArrowBackIosNew`, and a `"Back"` literal against a
`stringResource`. The widget decides twice: the icon is the auto-mirrored one,
because "back" points at the leading edge and the leading edge is on the right in an
RTL locale, which is what `Icons.Filled.ArrowBack` is deprecated for; and the
description is the catalogue's, because it is text. All forty-one sites use it now,
the eighteen converted mechanically with the imports they no longer need dropped.

**Each screen takes `onNavigateBack` and the host passes `popBackStack()`.** Hoisted
rather than read from a controller in the screen, so every one stays previewable
and testable without a nav host, which is how the twenty-two were fixed without a
nav host in a single test.

**Four screens had no bar to put it in, and got one.** `ChatRoomCreationScreen` is
"New chat", after the button that opens it. `CreateProfileScreen` is "Create
profile", and the two body headlines that repeated the name are gone, which is the
shape `SignInScreen` beside it on the landing page already has. `WriteNewNoteScreen`
is "New note" whether it is a reply, a quote or neither, one new string. The
"coming soon" placeholder's bar is titled with the name of what was tapped.
`AddMemberToChatRoomConfirmationScreen`'s bar had been commented out; it is back,
titled "Invite new member" since the body already names who and which room.
`NostrEventDetailScreen`'s repost and unknown-kind branches were the last two
placeholders without a bar.

**Two screens are reached two ways, and only the caller knows which.** Their
callback is nullable, and null draws no button. `ChatRoomMessagingScreen` 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 the transcript and a button that popped would
pop the home screen, so the pane passes null. `ImplementationPendingScreen` is
pushed from "learn more" and "edit profile" and is also where the navigation
observer lands with `popUpTo(0)` on an error; the host reads
`previousBackStackEntry`, remembered at first composition because the departing
screen reads it again after the stack has moved on. The DKG approval screens reuse
their existing `onDone`, which "Not now" already called -- the bar makes the same
leave reachable from the loading and error states, which had no other way off.

**Left alone on purpose.** The three top-level destinations have the navigation
bar, which phase 6 put there instead of app-bar icons. The onboarding and loading
screens cleared the stack to get where they are and have nothing under them.
`SearchScreen` and `SearchResultScreen` keep their `ArrowBackIosNew`: it is a search
bar's collapse control in a `leadingIcon` slot, not a navigation icon.

`NavigateBackButtonJvmTest` covers the two conditional screens by the description a
screen reader would announce: present and popping when pushed, absent in the pane
and at the root. The rule is recorded in CLAUDE.md beside the others a new screen has
to follow.

Verified with :composeApp:compileDebugKotlinAndroid, :composeApp:jvmTest (938
tests, 4 new) and docs/scripts/m3-audit.sh --check, all budgets met.

Replayed onto Mantra by docs/curated-to-mantra.md: CuratedSuggestionListScreen.kt: taken as the original merge fedbe724 left it, this being the branch join; AcceptCuratedSuggestionScreen.kt: brought to the state the original merge fedbe724 left it in, an edit that merge made outside its conflicts; BroadcastGroupSignedEventScreen.kt: brought to the state the original merge fedbe724 left it in, an edit that merge made outside its conflicts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pulled-From: curated/curated@0634487e12
2026-09-13 12:01:41 +02:00
2026-09-09 17:04:09 +02:00
2026-03-24 04:47:19 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00

This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).

  • /composeApp is for code that will be shared across your Compose Multiplatform applications. It contains several subfolders:

    • commonMain is for code that’s common for all targets.
    • Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, the iosMain folder would be the right place for such calls. Similarly, if you want to edit the Desktop (JVM) specific part, the jvmMain folder is the appropriate location.
  • /iosApp contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.

Build and Run Android Application

To build and run the development version of the Android app, use the run configuration from the run widget in your IDE’s toolbar or build it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:assembleDebug
    
  • on Windows
    .\gradlew.bat :composeApp:assembleDebug
    

Build and Run Desktop (JVM) Application

To build and run the development version of the desktop app, use the run configuration from the run widget in your IDE’s toolbar or run it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:run
    
  • on Windows
    .\gradlew.bat :composeApp:run
    

Build and Run iOS Application

To build and run the development version of the iOS app, use the run configuration from the run widget in your IDE’s toolbar or open the /iosApp directory in Xcode and run it from there.


Learn more about Kotlin Multiplatform…

Description
Mantra as a kotlin multiplatform project
https://mantra.press
Readme 13 MiB
Languages
Kotlin 100%