From f92c375693a0ae9a5536c0e9c286c10eda5d99df Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Thu, 30 Jul 2026 13:55:24 -0400 Subject: [PATCH 1/2] fix(tipping): move share button up and center the tip card Lift the 'Share Your Tip Card' subtitle into the top bar and vertically center the tip card so it sits evenly in the available space (and trim its width). --- .../tipping/internal/screens/TipCardScreen.kt | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) 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 f50ce234f..a56ef1671 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 @@ -1,10 +1,8 @@ package com.flipcash.app.tipping.internal.screens import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBarsPadding @@ -25,7 +23,6 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flipcash.app.bills.ScannableRenderer import com.flipcash.app.bills.components.cards.LocalTipCardBaseAlpha -import com.flipcash.app.core.bill.Scannable import com.flipcash.app.core.tipping.TipResult import com.flipcash.app.core.tipping.TipStep import com.flipcash.app.tipping.internal.TipFlowViewModel @@ -46,12 +43,22 @@ internal fun TipCardScreen() { CodeScaffold( topBar = { - AppBarWithTitle( - title = stringResource(R.string.title_myTipCard), - titleAlignment = Alignment.CenterHorizontally, - backButton = true, - onBackIconClicked = { flowNavigator.back() }, - ) + Column( + verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x10), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + AppBarWithTitle( + title = stringResource(R.string.title_myTipCard), + titleAlignment = Alignment.CenterHorizontally, + backButton = true, + onBackIconClicked = { flowNavigator.back() }, + ) + Text( + text = stringResource(R.string.subtitle_myTipCard), + style = CodeTheme.typography.textLarge, + color = CodeTheme.colors.textMain, + ) + } }, bottomBar = { Row( @@ -62,6 +69,7 @@ internal fun TipCardScreen() { verticalAlignment = Alignment.CenterVertically, ) { Column( + modifier = Modifier.padding(bottom = CodeTheme.dimens.grid.x3), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x3), ) { @@ -98,14 +106,8 @@ internal fun TipCardScreen() { .fillMaxSize() .padding(padding), horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center ) { - Text( - modifier = Modifier.padding(top = CodeTheme.dimens.grid.x10), - text = stringResource(R.string.subtitle_myTipCard), - style = CodeTheme.typography.textLarge, - color = CodeTheme.colors.textMain, - ) - Spacer(Modifier.weight(1f)) state.tipCard?.let { CompositionLocalProvider( LocalTipCardBaseAlpha provides 0.36f @@ -114,12 +116,11 @@ internal fun TipCardScreen() { // Fixed, device-independent card width matching iOS's TipcardScreen (300pt); // the card derives its QR, corner radius and avatar from this width, so both // platforms render the tip card at the same proportions. - tipCardWidth = 300.dp, + tipCardWidth = 270.dp, scannable = it, ) } } - Spacer(Modifier.weight(1f)) } } } From dc556ede9fd1b8f62bbe0b392a2680defca0b2ca Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Thu, 30 Jul 2026 14:46:00 -0400 Subject: [PATCH 2/2] fix(tipping): correct tip card color, sizing, and name row - Render the My Tip Card opaque at the design's flattened color (#101011) instead of a translucent fill that multiplied the app's Brand background and read too dark/purple. - Use Figma's proportions (TipCardAspectRatio = 333/269) and cap the card width at 270dp. - Show a single 'Tip {name}' label (ellipsized, 2 lines). --- .../core/src/main/res/values/strings.xml | 2 +- .../tipping/internal/screens/TipCardScreen.kt | 12 ++++---- .../app/bills/components/cards/TipCard.kt | 28 +++++-------------- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/apps/flipcash/core/src/main/res/values/strings.xml b/apps/flipcash/core/src/main/res/values/strings.xml index 9920fbee3..7e7158897 100644 --- a/apps/flipcash/core/src/main/res/values/strings.xml +++ b/apps/flipcash/core/src/main/res/values/strings.xml @@ -891,7 +891,7 @@ Your Name 500x500 Recommended My Tip Card - Tip + Tip %1$s Share Your Tip Card to Get Tipped Show My Tip Card Send a Tip 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 a56ef1671..935cfcbd0 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 @@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flipcash.app.bills.ScannableRenderer import com.flipcash.app.bills.components.cards.LocalTipCardBaseAlpha +import com.flipcash.app.bills.components.cards.LocalTipCardColor import com.flipcash.app.core.tipping.TipResult import com.flipcash.app.core.tipping.TipStep import com.flipcash.app.tipping.internal.TipFlowViewModel @@ -110,13 +111,14 @@ internal fun TipCardScreen() { ) { state.tipCard?.let { CompositionLocalProvider( - LocalTipCardBaseAlpha provides 0.36f + // Static display (no camera behind the card), so render it opaque at the design's + // flattened color rather than the translucent frosted fill — the 36% alpha + // otherwise multiplies the app's Brand background and reads incorrectly. + // Figma flattens the card to rgb(16,16,17). + LocalTipCardColor provides Color(0xFF101011), + LocalTipCardBaseAlpha provides 1f, ) { ScannableRenderer( - // Fixed, device-independent card width matching iOS's TipcardScreen (300pt); - // the card derives its QR, corner radius and avatar from this width, so both - // platforms render the tip card at the same proportions. - tipCardWidth = 270.dp, scannable = it, ) } diff --git a/apps/flipcash/shared/bills/src/main/kotlin/com/flipcash/app/bills/components/cards/TipCard.kt b/apps/flipcash/shared/bills/src/main/kotlin/com/flipcash/app/bills/components/cards/TipCard.kt index c2c4c7089..98df7c4b9 100644 --- a/apps/flipcash/shared/bills/src/main/kotlin/com/flipcash/app/bills/components/cards/TipCard.kt +++ b/apps/flipcash/shared/bills/src/main/kotlin/com/flipcash/app/bills/components/cards/TipCard.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.takeOrElse import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.flipcash.app.bills.components.ScannableCode @@ -70,17 +71,16 @@ val LocalTipCardColor = staticCompositionLocalOf { Color.Unspecified } val TipCardOpaqueFallback = Color(0xFF1A1A1C) /** - * The card's height-to-width proportion. Kept identical to iOS ([TipcardView.aspectRatio]) so the - * card renders with the same shape on both platforms. + * The card's height-to-width proportion, from Figma (269 x 333 dp). */ -private const val TipCardAspectRatio = 1.16f +private const val TipCardAspectRatio = 333f / 269f /** * Fraction of the available canvas width the card occupies when no explicit width is pinned (i.e. * on the scanner/camera). Capped at [TipCardMaxWidth]. Mirrors iOS `BillCanvas.tipcardSize`. */ private const val TipCardCanvasWidthFraction = 0.82f -private val TipCardMaxWidth: Dp = 320.dp +private val TipCardMaxWidth: Dp = 270.dp // The card derives its inner metrics from its width, matching iOS `TipcardView`. private const val TipCardCodeFraction = 0.68f // scannable code (square) @@ -148,25 +148,11 @@ internal fun TipCard( horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x1), ) { Text( - text = stringResource(R.string.label_tip), - style = CodeTheme.typography.textMedium, - color = CodeTheme.colors.textMain, - ) - - if (includePhoto) { - ContactAvatar( - modifier = Modifier - .padding(horizontal = CodeTheme.dimens.grid.x1) - .size(avatarSize) - .clip(CircleShape), - userProfile = user - ) - } - - Text( - text = user.displayName.orEmpty(), + text = stringResource(R.string.label_tipUser, user.displayName), style = CodeTheme.typography.textMedium, color = CodeTheme.colors.textMain, + maxLines = 2, + overflow = TextOverflow.Ellipsis, ) } }