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 e55d15636..656f6e47c 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 @@ -159,6 +159,9 @@ fun NavigationBar( Row(modifier = Modifier.fillMaxWidth()) { order.fastForEach { button -> val selected = button == state.selectedTab + // Only the photo slot dims when unselected. Glyphs and labels stay white in both + // states, as the iOS 27 tab bar paints them: the outline-vs-filled glyph and the + // indicator pill carry the selection. val iconAlpha by animateFloatAsState( targetValue = if (selected) 1f else 0.5f, label = "navBarIconAlpha", @@ -221,9 +224,7 @@ fun NavigationBar( } } else { Image( - modifier = Modifier - .size(iconSize) - .graphicsLayer { alpha = iconAlpha }, + modifier = Modifier.size(iconSize), painter = button.icon(selected), colorFilter = ColorFilter.tint(Color.White), contentDescription = null, @@ -253,7 +254,6 @@ fun NavigationBar( color = Color.White, textAlign = TextAlign.Center, maxLines = 1, - modifier = Modifier.graphicsLayer { alpha = iconAlpha }, ) } } @@ -285,9 +285,8 @@ private val NavBarButton.label: Int /** * 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. + * drawn as an outline until it is selected, where it fills in, white in both states. 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 diff --git a/apps/flipcash/features/messenger/src/test/kotlin/com/flipcash/app/messenger/internal/ChatTypingGateTest.kt b/apps/flipcash/features/messenger/src/test/kotlin/com/flipcash/app/messenger/internal/ChatTypingGateTest.kt index b697912ee..7af68648a 100644 --- a/apps/flipcash/features/messenger/src/test/kotlin/com/flipcash/app/messenger/internal/ChatTypingGateTest.kt +++ b/apps/flipcash/features/messenger/src/test/kotlin/com/flipcash/app/messenger/internal/ChatTypingGateTest.kt @@ -28,6 +28,7 @@ import io.mockk.coEvery import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlin.test.assertFalse @@ -57,6 +58,8 @@ class ChatTypingGateTest { private val chatCoordinator = mockk(relaxed = true) { every { observeMediaSendProgress() } returns kotlinx.coroutines.flow.emptyFlow() + // No load ever lands; a relaxed Flow completes empty and fails the open's first { }. + every { newestPageLoads() } returns MutableSharedFlow() } private val tipPaymentDelegate = mockk(relaxed = true) private val transactionController = mockk(relaxed = true)