From d5b28f745fb7fc2b113e3a965b88223b6a4967e0 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 10 Aug 2026 15:43:01 -0400 Subject: [PATCH] refactor(ui): internalize AppBar back-vs-close, drop backButton flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AppBarWithTitle now derives its leading control from context instead of each sheet screen hand-rolling `remember { navigator.backStack.size <= 1 }` to choose back-vs-close: - The signal is a non-null `onBackIconClicked` (the `backButton: Boolean` param is removed; every call site already passed a handler). - Icon adapts: a Close (X) when the screen can only leave its scope — the root of a sheet's own back stack (LocalSheetNavigator present) or a flow that opted into FlowDismissStyle.Close — and a back arrow otherwise. - Flow navigators are excluded from the sheet-root check so they keep driving the swap via flowDismissStyle (a flow's inner stack is always depth-1 at its first step; e.g. Swap opened from Token Info stays a back arrow, not a Close). - Removed the dead startContent/endContent overload (resolves an overload-ambiguity the signature change surfaced). Sheet screens (Labs, Token Discovery) collapse to a single AppBarWithTitle call; ~30 other callers just drop the redundant `backButton = true`. --- .../app/advanced/AdvancedFeaturesScreen.kt | 1 - .../app/appsettings/AppSettingsScreen.kt | 1 - .../flipcash/app/backupkey/BackupKeyScreen.kt | 1 - .../email/EmailMagicLinkScreen.kt | 1 - .../email/EmailVerificationScreen.kt | 1 - .../verification/phone/PhoneCodeScreen.kt | 1 - .../phone/PhoneCountryCodeScreen.kt | 1 - .../phone/PhoneVerificationScreen.kt | 1 - .../app/deposit/DepositDestinationScreen.kt | 1 - .../flipcash/app/deposit/DepositFlowScreen.kt | 1 - .../internal/UsdcDepositInformationScreen.kt | 1 - .../app/devicelogs/DeviceLogsScreen.kt | 1 - .../app/discovery/TokenDiscoveryScreen.kt | 25 +--- .../kotlin/com/flipcash/app/lab/LabsScreen.kt | 25 +--- .../app/login/OnboardingFlowScreen.kt | 1 - .../internal/screens/PhotoAccessKeyScreen.kt | 1 - .../screens/profile/ChatProfileScreen.kt | 2 +- .../app/purchase/PurchaseAccountScreen.kt | 1 - .../tipping/internal/screens/TipCardScreen.kt | 1 - .../app/tokens/PhantomWalletScreens.kt | 2 - .../flipcash/app/tokens/SwapEntryScreen.kt | 1 - .../app/tokens/TokenBuyReceiptScreen.kt | 1 - .../flipcash/app/tokens/TokenInfoScreen.kt | 4 +- .../flipcash/app/tokens/TokenSelectScreen.kt | 1 - .../app/tokens/TokenSellReceiptScreen.kt | 1 - .../transactions/TransactionHistoryScreen.kt | 1 - .../internal/name/NameEntryScreen.kt | 1 - .../internal/photo/PhotoSelectionScreen.kt | 1 - .../flipcash/app/userflags/UserFlagsScreen.kt | 1 - .../app/withdrawal/WithdrawalFlowScreen.kt | 1 - .../UsdcWithdrawalInformationScreen.kt | 1 - .../screens/WithdrawalConfirmationScreen.kt | 1 - .../screens/WithdrawalDestinationScreen.kt | 1 - .../internal/screens/WithdrawalEntryScreen.kt | 1 - .../app/currency/RegionSelectionScreen.kt | 1 - .../com/getcode/ui/components/TitleBar.kt | 111 +++++++++++------- 36 files changed, 84 insertions(+), 115 deletions(-) diff --git a/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/AdvancedFeaturesScreen.kt b/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/AdvancedFeaturesScreen.kt index fa5921b15..fef062cb9 100644 --- a/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/AdvancedFeaturesScreen.kt +++ b/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/AdvancedFeaturesScreen.kt @@ -34,7 +34,6 @@ fun AdvancedFeaturesScreen() { AppBarWithTitle( title = stringResource(R.string.title_advancedFeatures), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() } ) diff --git a/apps/flipcash/features/appsettings/src/main/kotlin/com/flipcash/app/appsettings/AppSettingsScreen.kt b/apps/flipcash/features/appsettings/src/main/kotlin/com/flipcash/app/appsettings/AppSettingsScreen.kt index 506beb434..c21b7ec02 100644 --- a/apps/flipcash/features/appsettings/src/main/kotlin/com/flipcash/app/appsettings/AppSettingsScreen.kt +++ b/apps/flipcash/features/appsettings/src/main/kotlin/com/flipcash/app/appsettings/AppSettingsScreen.kt @@ -22,7 +22,6 @@ fun AppSettingsScreen() { AppBarWithTitle( title = stringResource(R.string.title_appSettings), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = navigator::pop ) diff --git a/apps/flipcash/features/backupkey/src/main/kotlin/com/flipcash/app/backupkey/BackupKeyScreen.kt b/apps/flipcash/features/backupkey/src/main/kotlin/com/flipcash/app/backupkey/BackupKeyScreen.kt index f89b9732a..e1403eeb7 100644 --- a/apps/flipcash/features/backupkey/src/main/kotlin/com/flipcash/app/backupkey/BackupKeyScreen.kt +++ b/apps/flipcash/features/backupkey/src/main/kotlin/com/flipcash/app/backupkey/BackupKeyScreen.kt @@ -25,7 +25,6 @@ fun BackupKeyScreen() { AppBarWithTitle( title = stringResource(R.string.title_accessKey), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() }, ) BackupKeyScreenContent(viewModel) diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailMagicLinkScreen.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailMagicLinkScreen.kt index e992600e1..0ee0c5e21 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailMagicLinkScreen.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailMagicLinkScreen.kt @@ -53,7 +53,6 @@ fun EmailMagicLinkContent( AppBarWithTitle( title = stringResource(R.string.title_connectEmailAddress), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) EmailMagicLinkScreen(viewModel) diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailVerificationScreen.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailVerificationScreen.kt index 9404cb175..7279f7e5f 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailVerificationScreen.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailVerificationScreen.kt @@ -45,7 +45,6 @@ fun EmailVerificationContent( AppBarWithTitle( title = stringResource(R.string.title_connectEmailAddress), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { keyboard.hideIfVisible { codeNavigator.pop() diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCodeScreen.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCodeScreen.kt index 32b50d8b3..a056d373d 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCodeScreen.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCodeScreen.kt @@ -36,7 +36,6 @@ fun PhoneCodeContent( AppBarWithTitle( title = stringResource(R.string.title_enterTheCode), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) PhoneCodeScreen(viewModel) diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCountryCodeScreen.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCountryCodeScreen.kt index be94c1541..3a466148e 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCountryCodeScreen.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCountryCodeScreen.kt @@ -31,7 +31,6 @@ fun PhoneCountryCodeContent() { AppBarWithTitle( title = stringResource(R.string.title_verifyPhoneNumber), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) PhoneCountryCodeScreen(viewModel = viewModel) diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneVerificationScreen.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneVerificationScreen.kt index 1f1a5091f..f0c7b9698 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneVerificationScreen.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneVerificationScreen.kt @@ -38,7 +38,6 @@ fun PhoneVerificationContent() { AppBarWithTitle( title = stringResource(R.string.title_connectPhoneNumber), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { keyboard.hideIfVisible { codeNavigator.pop() diff --git a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositDestinationScreen.kt b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositDestinationScreen.kt index 0d4df34ea..770192c71 100644 --- a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositDestinationScreen.kt +++ b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositDestinationScreen.kt @@ -29,7 +29,6 @@ fun DepositDestinationScreen(mint: Mint) { AppBarWithTitle( title = stringResource(R.string.title_depositToken, state.tokenName.orEmpty()), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() }, ) DepositDestinationScreen(viewModel) diff --git a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt index 643c5a3a5..543d162f4 100644 --- a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt +++ b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt @@ -108,7 +108,6 @@ private fun DepositSelectTokenScreen() { ) { AppBarWithTitle( title = stringResource(R.string.title_selectCurrency), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/UsdcDepositInformationScreen.kt b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/UsdcDepositInformationScreen.kt index 4c1b19aac..ce692fef6 100644 --- a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/UsdcDepositInformationScreen.kt +++ b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/UsdcDepositInformationScreen.kt @@ -33,7 +33,6 @@ internal fun UsdcDepositInformationScreen(showOtherOptions: Boolean) { topBar = { AppBarWithTitle( title = stringResource(R.string.title_deposit), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/DeviceLogsScreen.kt b/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/DeviceLogsScreen.kt index 6b8000d92..8966ba6b0 100644 --- a/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/DeviceLogsScreen.kt +++ b/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/DeviceLogsScreen.kt @@ -45,7 +45,6 @@ fun DeviceLogsScreen() { AppBarWithTitle( title = stringResource(R.string.title_deviceLogs), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() }, endContent = { Box { diff --git a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt index 436e26a56..fdaebbb4e 100644 --- a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt +++ b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -16,7 +15,6 @@ import com.flipcash.core.R import com.getcode.navigation.core.CodeNavigator import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.opencode.model.ui.DiscoverCategory -import com.getcode.ui.components.AppBarDefaults import com.getcode.ui.components.AppBarWithTitle import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn @@ -27,28 +25,17 @@ import kotlinx.coroutines.flow.onEach fun TokenDiscoveryScreen() { val navigator = LocalCodeNavigator.current val viewModel = hiltViewModel() - val isSheetRoot = remember(navigator) { navigator.backStack.size <= 1 } Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { - if (isSheetRoot) { - AppBarWithTitle( - title = stringResource(R.string.title_discoverCurrencies), - titleAlignment = Alignment.CenterHorizontally, - endContent = { - AppBarDefaults.Close { navigator.hide() } - }, - ) - } else { - AppBarWithTitle( - title = stringResource(R.string.title_discoverCurrencies), - titleAlignment = Alignment.CenterHorizontally, - backButton = true, - onBackIconClicked = { navigator.pop() }, - ) - } + // Sheet-aware app bar: a Close (✕) at the sheet root, a back arrow when pushed deeper. + AppBarWithTitle( + title = stringResource(R.string.title_discoverCurrencies), + titleAlignment = Alignment.CenterHorizontally, + onBackIconClicked = { navigator.navigateBack() }, + ) TokenDiscoveryScreen(viewModel) } diff --git a/apps/flipcash/features/lab/src/main/kotlin/com/flipcash/app/lab/LabsScreen.kt b/apps/flipcash/features/lab/src/main/kotlin/com/flipcash/app/lab/LabsScreen.kt index e2ffb8e49..6b986f77c 100644 --- a/apps/flipcash/features/lab/src/main/kotlin/com/flipcash/app/lab/LabsScreen.kt +++ b/apps/flipcash/features/lab/src/main/kotlin/com/flipcash/app/lab/LabsScreen.kt @@ -3,7 +3,6 @@ package com.flipcash.app.lab import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -12,33 +11,21 @@ import com.flipcash.app.lab.internal.LabsScreenViewModel import com.getcode.navigation.extensions.getActivityScopedViewModel import com.flipcash.core.R import com.getcode.navigation.core.LocalCodeNavigator -import com.getcode.ui.components.AppBarDefaults import com.getcode.ui.components.AppBarWithTitle @Composable fun LabsScreen(onboarding: Boolean = false) { val navigator = LocalCodeNavigator.current - val isSheetRoot = remember(navigator) { navigator.backStack.size <= 1 } Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { - if (isSheetRoot) { - AppBarWithTitle( - title = stringResource(R.string.title_betaFlags), - titleAlignment = Alignment.CenterHorizontally, - endContent = { - AppBarDefaults.Close { navigator.hide() } - } - ) - } else { - AppBarWithTitle( - title = stringResource(R.string.title_betaFlags), - titleAlignment = Alignment.CenterHorizontally, - backButton = true, - onBackIconClicked = navigator::pop - ) - } + // Sheet-aware app bar: a Close (✕) at the sheet root, a back arrow when pushed deeper. + AppBarWithTitle( + title = stringResource(R.string.title_betaFlags), + titleAlignment = Alignment.CenterHorizontally, + onBackIconClicked = { navigator.navigateBack() }, + ) val viewModel = getActivityScopedViewModel() diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/OnboardingFlowScreen.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/OnboardingFlowScreen.kt index 74d2c6ace..b5c3e6567 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/OnboardingFlowScreen.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/OnboardingFlowScreen.kt @@ -387,7 +387,6 @@ private fun SeedInputStepContent() { Column { AppBarWithTitle( modifier = Modifier.fillMaxWidth(), - backButton = true, titleAlignment = Alignment.CenterHorizontally, onBackIconClicked = { flowNavigator.back() }, title = stringResource(R.string.title_enterAccessKeyWords), diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/internal/screens/PhotoAccessKeyScreen.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/internal/screens/PhotoAccessKeyScreen.kt index b6ab19630..e3ccc817d 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/internal/screens/PhotoAccessKeyScreen.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/internal/screens/PhotoAccessKeyScreen.kt @@ -51,7 +51,6 @@ private fun AccessKeyInPhotos( modifier = Modifier.fillMaxWidth(), title = stringResource(R.string.title_cantFindYourAccessKey), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = goBack, ) }, diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/profile/ChatProfileScreen.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/profile/ChatProfileScreen.kt index d48568adf..350eeeda3 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/profile/ChatProfileScreen.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/profile/ChatProfileScreen.kt @@ -40,7 +40,7 @@ internal fun ChatProfileScreen(viewModel: ChatProfileViewModel) { CodeScaffold( topBar = { - AppBarWithTitle(backButton = true, onBackIconClicked = { flowNavigator.back() }) + AppBarWithTitle(onBackIconClicked = { flowNavigator.back() }) }, ) { innerPadding -> MenuList( diff --git a/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/PurchaseAccountScreen.kt b/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/PurchaseAccountScreen.kt index 7b0608d32..5ae4a70f4 100644 --- a/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/PurchaseAccountScreen.kt +++ b/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/PurchaseAccountScreen.kt @@ -14,7 +14,6 @@ fun PurchaseAccountScreen( val navigator = LocalCodeNavigator.current Column { AppBarWithTitle( - backButton = true, onBackIconClicked = { if (fromLogin) { navigator.popAll() diff --git a/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/internal/screens/TipCardScreen.kt b/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/internal/screens/TipCardScreen.kt index 935cfcbd0..227c48e78 100644 --- a/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/internal/screens/TipCardScreen.kt +++ b/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/internal/screens/TipCardScreen.kt @@ -51,7 +51,6 @@ internal fun TipCardScreen() { AppBarWithTitle( title = stringResource(R.string.title_myTipCard), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) Text( diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/PhantomWalletScreens.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/PhantomWalletScreens.kt index 8a23ae83b..a9105c75f 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/PhantomWalletScreens.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/PhantomWalletScreens.kt @@ -81,7 +81,6 @@ internal fun PhantomConnectConfirmationScreen( } else { stringResource(R.string.title_purchase) }, - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) @@ -181,7 +180,6 @@ internal fun PhantomTransactionConfirmationScreen() { topBar = { AppBarWithTitle( title = stringResource(R.string.title_purchase), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapEntryScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapEntryScreen.kt index d85aa98ed..e6d014f6b 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapEntryScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapEntryScreen.kt @@ -55,7 +55,6 @@ internal fun SwapEntryScreen( is SwapPurpose.BalanceDecrease -> stringResource(R.string.title_amountToSell) }, titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { if (state.buyProgress.loading) { // swallow diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenBuyReceiptScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenBuyReceiptScreen.kt index 193a8de8c..315e67288 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenBuyReceiptScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenBuyReceiptScreen.kt @@ -34,7 +34,6 @@ internal fun BuyReceiptScreen() { AppBarWithTitle( title = stringResource(R.string.title_confirmPurchase), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() } ) diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt index 6aad0cf0b..c3485ac98 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt @@ -62,9 +62,6 @@ fun TokenInfoScreen( } }, titleAlignment = Alignment.CenterHorizontally, - leftIcon = { - AppBarDefaults.UpNavigation { navigator.pop() } - }, rightContents = { state.token.dataOrNull?.let { if (!state.isCashReserve) { @@ -74,6 +71,7 @@ fun TokenInfoScreen( } } } + AppBarDefaults.Close { navigator.pop() } }, ) diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSelectScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSelectScreen.kt index 044f9ca7c..87a6e8986 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSelectScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSelectScreen.kt @@ -53,7 +53,6 @@ fun TokenSelectScreen( is TokenPurpose.LaunchFunding -> stringResource(R.string.title_selectPaymentCurrency) else -> stringResource(R.string.title_selectCurrency) }, - backButton = true, onBackIconClicked = { navigator.pop() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSellReceiptScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSellReceiptScreen.kt index 04303129b..fed33c057 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSellReceiptScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenSellReceiptScreen.kt @@ -34,7 +34,6 @@ internal fun SellReceiptScreen() { AppBarWithTitle( title = stringResource(R.string.title_confirmSale), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { if (state.sellProgress.loading) { // swallow diff --git a/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/TransactionHistoryScreen.kt b/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/TransactionHistoryScreen.kt index 7249bed11..462cb7050 100644 --- a/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/TransactionHistoryScreen.kt +++ b/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/TransactionHistoryScreen.kt @@ -25,7 +25,6 @@ fun TransactionHistoryScreen(mint: Mint) { AppBarWithTitle( title = stringResource(R.string.title_transactionHistory), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() } ) val viewModel = hiltViewModel() diff --git a/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/name/NameEntryScreen.kt b/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/name/NameEntryScreen.kt index ba06f125a..44dfa619b 100644 --- a/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/name/NameEntryScreen.kt +++ b/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/name/NameEntryScreen.kt @@ -58,7 +58,6 @@ internal fun NameEntryScreen( Column { if (allowBack) { AppBarWithTitle( - backButton = true, onBackIconClicked = { keyboard.hideIfVisible { flowNavigator.back() diff --git a/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/photo/PhotoSelectionScreen.kt b/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/photo/PhotoSelectionScreen.kt index b0e534571..4cbbd6956 100644 --- a/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/photo/PhotoSelectionScreen.kt +++ b/apps/flipcash/features/user-profile/src/main/kotlin/com/flipcash/app/userprofile/internal/photo/PhotoSelectionScreen.kt @@ -67,7 +67,6 @@ internal fun PhotoSelectionScreen() { Column { AppBarWithTitle( - backButton = true, onBackIconClicked = { keyboard.hideIfVisible { flowNavigator.back() diff --git a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/UserFlagsScreen.kt b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/UserFlagsScreen.kt index a5dffbc3d..0c6cffbfc 100644 --- a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/UserFlagsScreen.kt +++ b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/UserFlagsScreen.kt @@ -26,7 +26,6 @@ fun UserFlagsScreen() { AppBarWithTitle( title = stringResource(R.string.title_userFlags), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = navigator::pop, endContent = { AppBarDefaults.Reset { viewModel.dispatchEvent(UserFlagsViewModel.Event.Reset) } diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt index 7af45aab7..e021550a1 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt @@ -115,7 +115,6 @@ private fun WithdrawalSelectTokenScreen() { ) { AppBarWithTitle( title = stringResource(R.string.title_selectCurrency), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/UsdcWithdrawalInformationScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/UsdcWithdrawalInformationScreen.kt index d4bc48723..016bf1820 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/UsdcWithdrawalInformationScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/UsdcWithdrawalInformationScreen.kt @@ -40,7 +40,6 @@ internal fun UsdcWithdrawalInformationScreen(showOtherOptions: Boolean) { topBar = { AppBarWithTitle( title = stringResource(R.string.title_withdraw), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalConfirmationScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalConfirmationScreen.kt index f9b4227d1..6a13b292a 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalConfirmationScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalConfirmationScreen.kt @@ -39,7 +39,6 @@ internal fun WithdrawalConfirmationScreen() { AppBarWithTitle( title = stringResource(R.string.title_withdraw), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) WithdrawalConfirmationScreen(viewModel) diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalDestinationScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalDestinationScreen.kt index 4fa7a8847..45709489e 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalDestinationScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalDestinationScreen.kt @@ -30,7 +30,6 @@ internal fun WithdrawalDestinationScreen() { AppBarWithTitle( title = stringResource(R.string.title_withdraw), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { flowNavigator.back() }, ) WithdrawalDestinationScreen(viewModel) diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt index a1313e856..4b1c20fa3 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt @@ -35,7 +35,6 @@ internal fun WithdrawalEntryScreen( ) { AppBarWithTitle( title = stringResource(R.string.title_withdraw), - backButton = true, onBackIconClicked = { flowNavigator.back() }, titleAlignment = Alignment.CenterHorizontally, ) diff --git a/apps/flipcash/shared/region-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt b/apps/flipcash/shared/region-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt index 9d49961ce..c4ecc64c3 100644 --- a/apps/flipcash/shared/region-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt +++ b/apps/flipcash/shared/region-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt @@ -23,7 +23,6 @@ fun RegionSelectionScreen() { AppBarWithTitle( title = stringResource(R.string.title_selectRegion), titleAlignment = Alignment.CenterHorizontally, - backButton = true, onBackIconClicked = { navigator.pop() } diff --git a/ui/components/src/main/kotlin/com/getcode/ui/components/TitleBar.kt b/ui/components/src/main/kotlin/com/getcode/ui/components/TitleBar.kt index 44e86486c..897dca80f 100644 --- a/ui/components/src/main/kotlin/com/getcode/ui/components/TitleBar.kt +++ b/ui/components/src/main/kotlin/com/getcode/ui/components/TitleBar.kt @@ -1,8 +1,11 @@ package com.getcode.ui.components +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -28,11 +31,13 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.navigation.flow.FlowDismissStyle import com.getcode.navigation.flow.LocalFlowDismissStyle import com.getcode.navigation.scenes.LocalSheetNavigator import com.getcode.theme.CodeTheme import com.getcode.theme.DesignSystem +import com.getcode.ui.components.AppBarDefaults.EndActionSlotHolder import com.getcode.ui.utils.calculateHorizontalPadding import kotlin.math.max @@ -47,7 +52,11 @@ object AppBarDefaults { @Composable fun UpNavigation(modifier: Modifier = Modifier, onClick: () -> Unit) { - CircularIconButton(modifier = modifier, onClick = onClick, testTag = "action_back") { size -> + CircularIconButton( + modifier = modifier, + onClick = onClick, + testTag = "action_back" + ) { size -> Icon( imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "", @@ -59,7 +68,11 @@ object AppBarDefaults { @Composable fun Close(modifier: Modifier = Modifier, onClick: () -> Unit) { - CircularIconButton(modifier = modifier, onClick = onClick, testTag = "action_close") { size -> + CircularIconButton( + modifier = modifier, + onClick = onClick, + testTag = "action_close" + ) { size -> Icon( imageVector = Icons.Outlined.Close, contentDescription = "", @@ -71,7 +84,11 @@ object AppBarDefaults { @Composable fun Share(modifier: Modifier = Modifier, onClick: () -> Unit) { - CircularIconButton(modifier = modifier, onClick = onClick, testTag = "action_share") { size -> + CircularIconButton( + modifier = modifier, + onClick = onClick, + testTag = "action_share" + ) { size -> Icon( painter = painterResource(R.drawable.ic_remote_send), contentDescription = "", @@ -150,6 +167,18 @@ object AppBarDefaults { overflow = TextOverflow.Ellipsis ) } + + @Composable + internal fun EndActionSlotHolder(content: @Composable RowScope.() -> Unit) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy( + CodeTheme.dimens.grid.x2 + ) + ) { + content() + } + } } @Composable @@ -158,18 +187,32 @@ fun AppBarWithTitle( title: String = "", titleAlignment: Alignment.Horizontal = Alignment.Start, contentPadding: PaddingValues = AppBarDefaults.ContentPadding, - backButton: Boolean = false, - onBackIconClicked: () -> Unit = {}, + onBackIconClicked: (() -> Unit)? = null, endContent: @Composable () -> Unit = { }, ) { + val navigator = LocalCodeNavigator.current val flowDismissStyle = LocalFlowDismissStyle.current - val showClose = backButton && flowDismissStyle == FlowDismissStyle.Close + + // A non-null [onBackIconClicked] asks for a leading nav control; its icon adapts to context. + // It's a Close (✕) when this screen can only leave its scope — the root of a sheet's own back + // stack, or a flow that opted into [FlowDismissStyle.Close] — and a back arrow (←) when it can + // pop within that scope. This internalizes the back-vs-close branch sheet screens used to + // hand-roll. We only treat it as a sheet root for plain bottom-sheet content + // ([LocalSheetNavigator] present); full-screen roots keep a back arrow, and a flow drives its + // own swap through [flowDismissStyle] — a flow's inner stack is always depth-1 at its first + // step, so reading its size here would wrongly show a Close even when the flow was pushed on + // top of other content (e.g. Swap opened from Token Info). + val isSheetRoot = LocalSheetNavigator.current != null && + !navigator.isFlowNavigator && + navigator.backStack.size <= 1 + val showBack = onBackIconClicked != null + val showClose = showBack && (flowDismissStyle == FlowDismissStyle.Close || isSheetRoot) TopAppBarBase( modifier = modifier, contentPadding = contentPadding, leftIcon = { - if (backButton && !showClose) { + if (showBack && !showClose) { AppBarDefaults.UpNavigation { onBackIconClicked() } } }, @@ -177,32 +220,15 @@ fun AppBarWithTitle( AppBarDefaults.Title(text = title) }, titleAlignment = titleAlignment, - rightContents = if (showClose) { - { AppBarDefaults.Close { onBackIconClicked() } } - } else { - endContent - }, - ) -} - -@Composable -fun AppBarWithTitle( - modifier: Modifier = Modifier, - title: String = "", - contentPadding: PaddingValues = AppBarDefaults.ContentPadding, - titleAlignment: Alignment.Horizontal = Alignment.Start, - startContent: @Composable () -> Unit = { }, - endContent: @Composable () -> Unit = { }, -) { - TopAppBarBase( - modifier = modifier, - leftIcon = startContent, - contentPadding = contentPadding, - titleRegion = { - AppBarDefaults.Title(text = title) + rightContents = { + EndActionSlotHolder { + if (showClose) { + AppBarDefaults.Close { onBackIconClicked() } + } else { + endContent() + } + } }, - titleAlignment = titleAlignment, - rightContents = endContent ) } @@ -213,7 +239,7 @@ fun AppBarWithTitle( titleAlignment: Alignment.Horizontal = Alignment.Start, contentPadding: PaddingValues = AppBarDefaults.ContentPadding, leftIcon: @Composable () -> Unit = { }, - rightContents: @Composable () -> Unit = { } + rightContents: @Composable RowScope.() -> Unit = { } ) { TopAppBarBase( modifier = modifier, @@ -232,7 +258,7 @@ private fun TopAppBarBase( contentPadding: PaddingValues = AppBarDefaults.ContentPadding, leftIcon: @Composable () -> Unit = { }, titleRegion: @Composable () -> Unit = { }, - rightContents: @Composable () -> Unit = { }, + rightContents: @Composable RowScope.() -> Unit = { }, titleAlignment: Alignment.Horizontal = Alignment.CenterHorizontally // New parameter ) { val inset = CodeTheme.dimens.inset @@ -251,11 +277,12 @@ private fun TopAppBarBase( val rightSlot = @Composable { Box(modifier = Modifier.padding(5.dp)) { - rightContents() + EndActionSlotHolder { + rightContents() + } } } - val isInsideSheet = LocalSheetNavigator.current != null SubcomposeLayout( @@ -268,9 +295,10 @@ private fun TopAppBarBase( .height(56.dp), ) { constraints -> // Measure left icon, if provided - val emptyLeftIconPlaceable = subcompose("empty_leftIcon", emptyLeftSlot).firstOrNull()?.measure( - constraints.copy(minWidth = 0, minHeight = 0) - ) + val emptyLeftIconPlaceable = + subcompose("empty_leftIcon", emptyLeftSlot).firstOrNull()?.measure( + constraints.copy(minWidth = 0, minHeight = 0) + ) val leftIconPlaceable = subcompose("leftIcon", leftSlot).firstOrNull()?.measure( constraints.copy(minWidth = 0, minHeight = 0) ) @@ -288,7 +316,8 @@ private fun TopAppBarBase( val remainingWidth = constraints.maxWidth - leftIconWidth - rightContentsWidth - (contentPadding.calculateLeftPadding( layoutDirection - ).roundToPx() * 2) - (contentPadding.calculateRightPadding(layoutDirection).roundToPx() * 2) + ).roundToPx() * 2) - (contentPadding.calculateRightPadding(layoutDirection) + .roundToPx() * 2) // Measure title region with the remaining space, if provided val titleRegionPlaceable = subcompose("titleRegion", titleRegion).firstOrNull()?.measure( @@ -343,6 +372,6 @@ fun Preview_TitleBar( ) { DesignSystem { - AppBarWithTitle(backButton = true, title = "Hey") + AppBarWithTitle(onBackIconClicked = {}, title = "Hey") } } \ No newline at end of file