Skip to content

Commit 29e8805

Browse files
bmc08gtclaude
andcommitted
feat(lab): add nav bar settings sheet with drag-to-reorder
Add NavBarSettingsScreen and content with drag-to-reorder support. Register NavBarSettings route, add string resources, wire entry in Labs "Home Screen" section, and register screen in AppScreenContent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c80b95c commit 29e8805

7 files changed

Lines changed: 162 additions & 1 deletion

File tree

apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ import com.flipcash.app.contact.verification.VerificationFlowScreen
2828
import com.flipcash.app.currencycreator.CurrencyCreatorFlowScreen
2929
import com.flipcash.app.core.AppRoute
3030
import com.flipcash.app.currency.RegionSelectionScreen
31-
import com.flipcash.app.deposit.DepositDestinationScreen
3231
import com.flipcash.app.deposit.DepositFlowScreen
3332
import com.flipcash.app.discovery.TokenDiscoveryScreen
3433
import com.flipcash.app.internal.ui.navigation.decorators.rememberNavMessagingEntryDecorator
3534
import com.flipcash.app.lab.LabsScreen
35+
import com.flipcash.app.lab.NavBarSettingsScreen
3636
import com.flipcash.app.lab.StandaloneLabsScreen
3737
import com.flipcash.app.login.accesskey.AccessKeyScreen
3838
import com.flipcash.app.login.accesskey.PhotoAccessKeyScreen
@@ -125,6 +125,7 @@ fun appEntryProvider(
125125
// Menu
126126
annotatedEntry<AppRoute.Menu.AppSettings> { AppSettingsScreen() }
127127
annotatedEntry<AppRoute.Menu.Lab> { LabsScreen() }
128+
annotatedEntry<AppRoute.Menu.NavBarSettings> { NavBarSettingsScreen() }
128129
annotatedEntry<AppRoute.Menu.MyAccount> { MyAccountScreen() }
129130
annotatedEntry<AppRoute.Menu.BackupKey> { BackupKeyScreen() }
130131
annotatedEntry<AppRoute.Menu.AdvancedFeatures> { AdvancedFeaturesScreen() }

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ sealed interface AppRoute : NavKey, Parcelable {
193193
data object DeviceLogs : Menu
194194
@Serializable
195195
data object Lab : Menu
196+
@Serializable
197+
data object NavBarSettings : Menu, com.getcode.navigation.Sheet, com.getcode.navigation.WrapContentSheet
196198
}
197199

198200
@Serializable
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!--
2+
~ Copyright (C) 2026 The Android Open Source Project
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
17+
android:width="24dp"
18+
android:height="24dp"
19+
android:viewportWidth="960"
20+
android:viewportHeight="960">
21+
<path
22+
android:pathData="M200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h560q33,0 56.5,23.5T840,200v560q0,33 -23.5,56.5T760,840L200,840ZM200,600h560v-400L200,200v400ZM200,680v80h560v-80L200,680ZM200,680v80,-80Z"
23+
android:fillColor="#e8eaed"/>
24+
</vector>

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,11 +519,16 @@
519519
<string name="prompt_message_currencyCreateNotYetAvailable">Check back soon</string>
520520

521521
<string name="title_settingsSectionFeatures">Features</string>
522+
<string name="title_settingsSectionHomeScreen">Home Screen</string>
522523
<string name="title_settingsSectionDeveloper">Developer</string>
523524
<string name="subtitle_settingsUserFlags">User Flags</string>
524525
<string name="title_settingsSectionAccount">Account</string>
525526
<string name="title_userFlags">User Flags</string>
526527

528+
<string name="title_settingsButtonOrder">Button Order</string>
529+
<string name="subtitle_settingsButtonOrder">Hold and drag to reorder</string>
530+
<string name="title_settingsSectionGiveButtonLabel">Give Button Label</string>
531+
527532
<string name="title_purchase">Purchase</string>
528533
<string name="action_connectYourPhantomWallet">Connect Your Phantom Wallet</string>
529534

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.flipcash.app.lab
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.ui.Alignment
7+
import androidx.compose.ui.Modifier
8+
import com.flipcash.app.lab.internal.NavBarSettingsContent
9+
import com.getcode.navigation.scenes.LocalBottomSheetDismissDispatcher
10+
import com.getcode.ui.components.AppBarDefaults
11+
import com.getcode.ui.components.AppBarWithTitle
12+
13+
@Composable
14+
fun NavBarSettingsScreen() {
15+
val dismiss = LocalBottomSheetDismissDispatcher.current
16+
17+
Column(
18+
horizontalAlignment = Alignment.CenterHorizontally,
19+
) {
20+
AppBarWithTitle(
21+
title = "",
22+
titleAlignment = Alignment.CenterHorizontally,
23+
isInModal = true,
24+
endContent = {
25+
AppBarDefaults.Close { dismiss() }
26+
}
27+
)
28+
29+
NavBarSettingsContent()
30+
}
31+
}

apps/flipcash/features/lab/src/main/kotlin/com/flipcash/app/lab/internal/LabsScreenContent.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.items
1111
import androidx.compose.foundation.lazy.rememberLazyListState
1212
import androidx.compose.material.icons.Icons
1313
import androidx.compose.material.icons.filled.MarkEmailUnread
14+
import androidx.compose.material.icons.filled.Navigation
1415
import androidx.compose.material.icons.filled.PhonelinkErase
1516
import androidx.compose.material.icons.filled.Token
1617
import androidx.compose.material3.HorizontalDivider
@@ -20,6 +21,7 @@ import androidx.compose.runtime.getValue
2021
import androidx.compose.ui.Alignment
2122
import androidx.compose.ui.Modifier
2223
import androidx.compose.ui.graphics.vector.rememberVectorPainter
24+
import androidx.compose.ui.res.painterResource
2325
import androidx.compose.ui.res.stringResource
2426
import androidx.compose.ui.unit.dp
2527
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -87,6 +89,16 @@ internal fun LabsScreenContent(viewModel: LabsScreenViewModel) {
8789
)
8890
}
8991

92+
item { SectionHeader(stringResource(R.string.title_settingsSectionHomeScreen)) }
93+
item {
94+
ListItem(
95+
headline = stringResource(R.string.title_settingsButtonOrder),
96+
icon = painterResource(R.drawable.ic_bottom_navigation),
97+
) {
98+
navigator.navigate(AppRoute.Menu.NavBarSettings)
99+
}
100+
}
101+
90102
if (betaFlags.isEmpty()) {
91103
item {
92104
Box {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.flipcash.app.lab.internal
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.navigationBarsPadding
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.foundation.layout.wrapContentHeight
10+
import androidx.compose.material3.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.getValue
13+
import androidx.compose.runtime.remember
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.draw.clip
17+
import androidx.compose.ui.res.stringResource
18+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
19+
import com.flipcash.app.core.navigation.GiveButtonLabel
20+
import com.flipcash.app.core.navigation.NavBarConfig
21+
import com.flipcash.app.core.ui.NavigationBar
22+
import com.flipcash.app.featureflags.FeatureFlag
23+
import com.flipcash.app.featureflags.LocalFeatureFlags
24+
import com.flipcash.core.R
25+
import com.getcode.theme.CodeTheme
26+
import com.getcode.theme.White05
27+
import com.getcode.ui.components.text.SectionHeader
28+
import com.getcode.ui.theme.CodeSegmentedControl
29+
30+
@Composable
31+
internal fun NavBarSettingsContent() {
32+
val featureFlags = LocalFeatureFlags.current
33+
val configString by featureFlags.getOption(FeatureFlag.NavBar)
34+
.collectAsStateWithLifecycle()
35+
val config = remember(configString) { NavBarConfig.deserialize(configString) }
36+
37+
Column(
38+
modifier = Modifier
39+
.wrapContentHeight(),
40+
) {
41+
Text(
42+
text = stringResource(R.string.subtitle_settingsButtonOrder),
43+
style = CodeTheme.typography.textSmall,
44+
color = CodeTheme.colors.textSecondary,
45+
modifier = Modifier.padding(horizontal = CodeTheme.dimens.inset),
46+
)
47+
48+
Box(
49+
modifier = Modifier
50+
.fillMaxWidth()
51+
.padding(horizontal = CodeTheme.dimens.inset)
52+
.padding(top = CodeTheme.dimens.grid.x1)
53+
.clip(CodeTheme.shapes.large)
54+
.background(White05)
55+
.padding(vertical = CodeTheme.dimens.grid.x4),
56+
contentAlignment = Alignment.Center,
57+
) {
58+
NavigationBar(
59+
config = config,
60+
onOrderChanged = { newOrder ->
61+
val updated = config.copy(order = newOrder)
62+
featureFlags.setOption(FeatureFlag.NavBar, updated.serialize())
63+
},
64+
)
65+
}
66+
67+
SectionHeader(stringResource(R.string.title_settingsSectionGiveButtonLabel))
68+
69+
CodeSegmentedControl(
70+
options = GiveButtonLabel.entries,
71+
selected = config.giveButtonLabel,
72+
modifier = Modifier
73+
.fillMaxWidth()
74+
.padding(horizontal = CodeTheme.dimens.inset)
75+
.padding(bottom = CodeTheme.dimens.grid.x3)
76+
.navigationBarsPadding(),
77+
mapper = { option ->
78+
Text(text = stringResource(option.labelRes))
79+
},
80+
onSelectionChanged = { label ->
81+
val updated = config.copy(giveButtonLabel = label)
82+
featureFlags.setOption(FeatureFlag.NavBar, updated.serialize())
83+
},
84+
)
85+
}
86+
}

0 commit comments

Comments
 (0)