diff --git a/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt b/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt
index df0f2764b9..d9a1aa7ec0 100644
--- a/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt
+++ b/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt
@@ -1,6 +1,5 @@
package com.flipcash.app.core.ui
-import androidx.annotation.DrawableRes
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
@@ -21,6 +20,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
@@ -32,6 +33,8 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.lerp
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
@@ -219,7 +222,7 @@ fun NavigationBar(
modifier = Modifier
.size(iconSize)
.graphicsLayer { alpha = iconAlpha },
- painter = painterResource(button.icon(selected)),
+ painter = button.icon(selected),
colorFilter = ColorFilter.tint(Color.White),
contentDescription = null,
)
@@ -255,16 +258,32 @@ internal val NavBarButton.testTag: String
}
/**
- * The glyph for [this] tab at the weight its selection calls for. Every tab is drawn as an outline
- * until it is selected, where it fills in; the dimming on top of that is the caller's alpha. The
- * unsuffixed drawable is the outline, so `ic_nav_scan` stays the outline the tutorial card reuses.
+ * The glyph for [this] tab at the weight its selection calls for (node 10000:111297). Every tab is
+ * drawn as an outline until it is selected, where it fills in; the dimming on top of that is the
+ * caller's alpha. The unsuffixed drawable is the outline, so `ic_nav_tipcard` is also the outline
+ * the tutorial card reuses.
+ *
+ * The scanner tab carries the tip card glyph because scanning one is what that tab is for. The You
+ * tab draws the user's own photo when there is one (see the avatar branch above) and falls back to
+ * a people circle, not to the tip card — the tab is the account, and the card is only its front.
+ *
+ * That fallback's selected weight comes from Material rather than from the design file, which draws
+ * the You tab only as an outline. `Icons.Filled.AccountCircle` is the same glyph solid: its disc
+ * lands on `ic_people_circle`'s outer edge (r 10 at 24x24, against the outline's 9.25 centreline
+ * plus a 1.5 stroke), and knocking the person out of a solid body is what `ic_nav_wallet_selected`
+ * and `ic_nav_tipcard_selected` already do. The head is the one thing that moves, 0.5 smaller.
*/
-@DrawableRes
-private fun NavBarButton.icon(selected: Boolean): Int = when (this) {
- NavBarButton.Scanner -> if (selected) R.drawable.ic_nav_scan_selected else R.drawable.ic_nav_scan
- NavBarButton.Wallet -> if (selected) R.drawable.ic_nav_wallet_selected else R.drawable.ic_nav_wallet
- NavBarButton.Chats -> if (selected) R.drawable.ic_nav_chat_selected else R.drawable.ic_nav_chat
- NavBarButton.TipCard -> if (selected) R.drawable.ic_nav_tipcard_selected else R.drawable.ic_nav_tipcard
+@Composable
+private fun NavBarButton.icon(selected: Boolean): Painter = when (this) {
+ NavBarButton.Scanner ->
+ painterResource(if (selected) R.drawable.ic_nav_tipcard_selected else R.drawable.ic_nav_tipcard)
+ NavBarButton.Wallet ->
+ painterResource(if (selected) R.drawable.ic_nav_wallet_selected else R.drawable.ic_nav_wallet)
+ NavBarButton.Chats ->
+ painterResource(if (selected) R.drawable.ic_nav_chat_selected else R.drawable.ic_nav_chat)
+ NavBarButton.TipCard ->
+ if (selected) rememberVectorPainter(Icons.Filled.AccountCircle)
+ else painterResource(R.drawable.ic_people_circle)
}
@Preview
@@ -302,3 +321,17 @@ private fun NavigationBarAvatarSelectedPreview() {
avatar = { modifier -> Box(modifier.background(Color(0xFF8E6E5B))) },
)
}
+
+/**
+ * The You tab with no photo to draw (node 10000:111297) — the people-circle fallback, selected, so
+ * the filled twin gets a preview of its own rather than only appearing in the screenshot test.
+ */
+@Preview(name = "No photo, You tab selected")
+@PreviewWrapper(FlipcashThemeWrapper::class)
+@Composable
+private fun NavigationBarNoAvatarSelectedPreview() {
+ NavigationBar(
+ state = rememberNavigationBarState(selectedTab = NavBarButton.TipCard),
+ onButtonClick = { },
+ )
+}
diff --git a/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/onboarding/NewUserTutorial.kt b/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/onboarding/NewUserTutorial.kt
index 633ecbeae4..0811bafcc4 100644
--- a/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/onboarding/NewUserTutorial.kt
+++ b/apps/flipcash/core-ui/src/main/kotlin/com/flipcash/app/core/ui/onboarding/NewUserTutorial.kt
@@ -72,7 +72,7 @@ sealed interface TutorialItem {
override val description: String
@Composable get() = stringResource(R.string.subtitle_scanTipCard)
override val icon: Painter
- @Composable get() = painterResource(R.drawable.ic_nav_scan)
+ @Composable get() = painterResource(R.drawable.ic_nav_tipcard)
}
class ProfilePicture(override val isCompleted: Boolean) : Profile {
diff --git a/apps/flipcash/core-ui/src/test/kotlin/com/flipcash/app/core/ui/NavigationBarAvatarScreenshotTest.kt b/apps/flipcash/core-ui/src/test/kotlin/com/flipcash/app/core/ui/NavigationBarAvatarScreenshotTest.kt
index 604f65ee91..634a3d3e0b 100644
--- a/apps/flipcash/core-ui/src/test/kotlin/com/flipcash/app/core/ui/NavigationBarAvatarScreenshotTest.kt
+++ b/apps/flipcash/core-ui/src/test/kotlin/com/flipcash/app/core/ui/NavigationBarAvatarScreenshotTest.kt
@@ -72,6 +72,11 @@ class NavigationBarAvatarScreenshotTest {
NavigationBar(
state = rememberNavigationBarState(selectedTab = NavBarButton.Wallet),
)
+ // No photo, You tab selected — the filled people-circle fallback, which is the
+ // one state neither the photo bars nor the unselected fallback shows.
+ NavigationBar(
+ state = rememberNavigationBarState(selectedTab = NavBarButton.TipCard),
+ )
}
}
}
diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt
index 2c06d17054..8fffa63638 100644
--- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt
+++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt
@@ -8,7 +8,7 @@ enum class NavBarButton {
;
companion object {
- /** The fixed tab set, in bar order. */
- val tabs = listOf(Scanner, Wallet, Chats, TipCard)
+ /** The fixed tab set, in bar order. Chats sits second, beside the scanner it now feeds. */
+ val tabs = listOf(Scanner, Chats, Wallet, TipCard)
}
}
diff --git a/apps/flipcash/core/src/main/res/drawable/ic_nav_scan.xml b/apps/flipcash/core/src/main/res/drawable/ic_nav_scan.xml
deleted file mode 100644
index 5924299475..0000000000
--- a/apps/flipcash/core/src/main/res/drawable/ic_nav_scan.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
diff --git a/apps/flipcash/core/src/main/res/drawable/ic_nav_scan_selected.xml b/apps/flipcash/core/src/main/res/drawable/ic_nav_scan_selected.xml
deleted file mode 100644
index 030b1dde94..0000000000
--- a/apps/flipcash/core/src/main/res/drawable/ic_nav_scan_selected.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-