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 f50ce234f..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
@@ -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,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.core.bill.Scannable
+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
@@ -46,12 +44,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 +70,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,28 +107,22 @@ 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
+ // 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 = 300.dp,
scannable = it,
)
}
}
- Spacer(Modifier.weight(1f))
}
}
}
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,
)
}
}