From 57202ed2f7f537e2f1c22841aa0ae9d756dbad85 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 31 Aug 2026 16:16:05 -0400 Subject: [PATCH] feat(tipping): give the Chats tab the standard centred title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The large title was the only one of its kind in the app, and it left the list running to a hard cut at both edges. Drop `screenTitleLarge` so the bar falls back to `screenTitle`, and centre it: with no leading control the slot reserves no width, so a Start-aligned title sits flush at the inset and reads off-centre against the Add button. Fade the list with `verticalScrollStateGradient`, applied after the scaffold padding so the gradient lands on the viewport flush under the bar rather than on the bar's own space. It only draws at an edge that can still be scrolled toward, so the empty state — which fills the viewport and cannot scroll — is unfaded. `screenTitleLarge` now has no callers; left in place. --- .../com/flipcash/app/tipping/TipsScreen.kt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/TipsScreen.kt b/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/TipsScreen.kt index 50361e2b8..c03337b02 100644 --- a/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/TipsScreen.kt +++ b/apps/flipcash/features/tipping/src/main/kotlin/com/flipcash/app/tipping/TipsScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -39,12 +40,14 @@ import com.getcode.navigation.flow.flowSharedViewModel import com.getcode.theme.CodeTheme import com.getcode.ui.components.AppBarDefaults import com.getcode.ui.components.AppBarWithTitle +import com.getcode.ui.core.verticalScrollStateGradient import com.getcode.ui.theme.CodeScaffold /** * The tip DM conversation list — always a step in the tipping [TippingFlowScreen] flow, so it shares - * the flow's [TipFlowViewModel]. It is the "Chats" root tab: a flush large title over the list, no - * dismiss affordance (the root nav bar is the chrome); the tip card lives on its own tab. + * the flow's [TipFlowViewModel]. It is the "Chats" root tab: the standard centred screen title over + * the list, no dismiss affordance (the root nav bar is the chrome); the tip card lives on its own + * tab. */ @Composable fun TipsScreen() { @@ -56,7 +59,9 @@ fun TipsScreen() { topBar = { AppBarWithTitle( title = stringResource(R.string.title_chats), - titleTextStyle = CodeTheme.typography.screenTitleLarge, + // Centred rather than flush-start: an empty leading slot reserves no width, so a + // Start title sits at the inset and reads as off-centre against the Add button. + titleAlignment = Alignment.CenterHorizontally, // Node 9442:5779 — the only way to start a chat with someone who has never paid // you. A pushed route, not a step of this flow: this list is a tab home, and a step // pushed inside it would leave the tab bar over the entry screen. @@ -67,13 +72,19 @@ fun TipsScreen() { } ) { padding -> val chats = state.tipChats + val listState = rememberLazyListState() LazyColumn( modifier = Modifier .fillMaxSize() // Scroll anchor for UI tests: `send_contact_row` addresses a single row, this // addresses the scrollable list itself. .testTag("chat_list") - .padding(padding), + .padding(padding) + // After the padding so the fade lands on the list viewport — flush under the app + // bar — rather than on the bar's own space. Rows dissolve into the background at + // whichever edge is still scrollable instead of being cut off. + .verticalScrollStateGradient(scrollState = listState), + state = listState, // Clears the hoisted tab bar: keeps the last row reachable and centers the empty state // in the space the bar leaves visible. contentPadding = LocalTabBarPadding.current,