Skip to content

Commit 9f1c25d

Browse files
authored
chore: design review fixes (phase 1) (#927)
* style(ui): update ChatInput to better match spec * padding around send button * send button asset Signed-off-by: Brandon McAnsh <git@bmcreations.dev> * chore: add Shapes.tiny; use as grouped bubble corner radius Signed-off-by: Brandon McAnsh <git@bmcreations.dev> * style(messenger): update cash bubbles to better align with figma spec * max width % * token icon size * token name color * currency flag icon size Signed-off-by: Brandon McAnsh <git@bmcreations.dev> * chore(messenger): split ReceiptLabel in to two Text() elements to better support mixed font weight in the future Signed-off-by: Brandon McAnsh <git@bmcreations.dev> * chore(contacts): remove border from ContactAvatar conditionally Signed-off-by: Brandon McAnsh <git@bmcreations.dev> * style(messenger): improve top bar fade/gradient Signed-off-by: Brandon McAnsh <git@bmcreations.dev> --------- Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent e231fd9 commit 9f1c25d

10 files changed

Lines changed: 98 additions & 37 deletions

File tree

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@
772772
<string name="subtitle_verb_youReceived">You received</string>
773773

774774
<string name="label_chatReceipt_delivered">Delivered</string>
775-
<string name="label_chatReceipt_read">Read %1$s</string>
775+
<string name="label_chatReceipt_read">Read</string>
776776
<string name="label_chatReceipt_yesterday">Yesterday</string>
777777
<string name="label_chatSeparator_today">Today</string>
778778

apps/flipcash/features/direct-send/src/main/kotlin/com/flipcash/app/directsend/internal/screens/ContactListScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ private fun ContactRowItem(
417417
modifier = Modifier
418418
.requiredSize(CodeTheme.dimens.staticGrid.x8)
419419
.clip(CircleShape),
420+
includeBorder = false,
420421
)
421422
}
422423

apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import androidx.compose.ui.Modifier
4242
import androidx.compose.ui.draw.clip
4343
import androidx.compose.ui.focus.FocusRequester
4444
import androidx.compose.ui.graphics.Brush
45+
import androidx.compose.ui.graphics.Color
4546
import androidx.compose.ui.graphics.TransformOrigin
4647
import androidx.compose.ui.layout.onSizeChanged
4748
import androidx.compose.ui.platform.LocalDensity
@@ -115,15 +116,19 @@ private fun ChatTopBar(
115116
chattingWith: DeviceContact?,
116117
) {
117118
var titleHeight by remember { mutableStateOf(0.dp) }
119+
val bgColor = CodeTheme.colors.background
118120
Box {
119121
Box(
120122
modifier = Modifier
121123
.fillMaxWidth()
122-
.height(titleHeight)
123-
.drawWithGradient(
124-
color = CodeTheme.colors.background,
125-
startY = { size.height * 1.5f },
126-
endY = { size.height * 0.25f }
124+
.height(titleHeight + 24.dp)
125+
.background(
126+
Brush.verticalGradient(
127+
colorStops = arrayOf(
128+
0f to bgColor,
129+
1f to Color.Transparent,
130+
)
131+
)
127132
)
128133
)
129134
AppBarWithTitle(

apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/MessageBubble.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.compose.ui.draw.clip
2525
import androidx.compose.ui.graphics.Shape
2626
import androidx.compose.ui.platform.LocalContext
2727
import androidx.compose.ui.res.stringResource
28+
import androidx.compose.ui.text.font.FontWeight
2829
import androidx.compose.ui.tooling.preview.Preview
2930
import androidx.compose.ui.tooling.preview.PreviewWrapper
3031
import androidx.compose.ui.unit.Dp
@@ -44,6 +45,7 @@ import com.getcode.ui.core.addIf
4445
internal enum class BubblePosition { Solo, First, Middle, Last }
4546

4647
private const val BUBBLE_MAX_WIDTH_FRACTION = 0.78f
48+
private const val CASH_BUBBLE_MAX_WIDTH_FRACTION = 0.64f
4749

4850
@Composable
4951
internal fun ContentBubble(
@@ -52,7 +54,10 @@ internal fun ContentBubble(
5254
modifier: Modifier = Modifier,
5355
) {
5456
BoxWithConstraints(modifier = modifier.fillMaxWidth()) {
55-
val bubbleMaxWidth = maxWidth * BUBBLE_MAX_WIDTH_FRACTION
57+
val bubbleMaxWidth = when (item.content) {
58+
is MessageContent.Text -> maxWidth * BUBBLE_MAX_WIDTH_FRACTION
59+
is MessageContent.Cash -> maxWidth * CASH_BUBBLE_MAX_WIDTH_FRACTION
60+
}
5661

5762
Row(
5863
modifier = Modifier.fillMaxWidth(),
@@ -119,9 +124,10 @@ private fun CashBubble(
119124
modifier = Modifier.align(Alignment.Start),
120125
tokenName = tokenName,
121126
tokenImage = tokenImageUrl,
122-
imageSize = 20.dp,
127+
imageSize = CodeTheme.dimens.staticGrid.x4,
123128
spacing = CodeTheme.dimens.grid.x1,
124-
textStyle = CodeTheme.typography.textSmall,
129+
textStyle = CodeTheme.typography.caption,
130+
textColor = CodeTheme.colors.textSecondary,
125131
)
126132
}
127133

@@ -140,9 +146,9 @@ private fun CashBubble(
140146
color = CodeTheme.colors.textSecondary,
141147
)
142148
PriceWithFlag(
143-
modifier = Modifier.padding(top = CodeTheme.dimens.grid.x1),
144149
amount = amount.formatted(),
145150
currencyCode = amount.currencyCode.name,
151+
iconSize = CodeTheme.dimens.staticGrid.x5,
146152
flag = exchange.getFlagByCurrency(amount.currencyCode.name),
147153
text = { text ->
148154
Text(
@@ -187,9 +193,9 @@ private fun Bubble(
187193

188194
@Composable
189195
private fun bubbleShape(position: BubblePosition, isFromSelf: Boolean): Shape {
190-
// CodeTheme.shapes.medium = 12dp, extraSmall = 6dp
196+
// CodeTheme.shapes.medium = 12dp, tiny = 4dp
191197
val l = 12.dp
192-
val s = 6.dp
198+
val s = 4.dp
193199

194200
// Corner radius morph — animate each corner with spring matching prototype
195201
val cornerSpec = spring<Dp>(dampingRatio = 0.68f, stiffness = 500f)

apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/ReceiptLabel.kt

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import androidx.compose.animation.fadeOut
1111
import androidx.compose.animation.scaleIn
1212
import androidx.compose.animation.scaleOut
1313
import androidx.compose.animation.togetherWith
14+
import androidx.compose.foundation.layout.Arrangement
1415
import androidx.compose.foundation.layout.Column
16+
import androidx.compose.foundation.layout.Row
1517
import androidx.compose.foundation.layout.padding
1618
import androidx.compose.material3.Text
1719
import androidx.compose.runtime.Composable
@@ -25,13 +27,13 @@ import androidx.compose.ui.platform.LocalContext
2527
import androidx.compose.ui.res.stringResource
2628
import androidx.compose.ui.tooling.preview.Preview
2729
import androidx.compose.ui.tooling.preview.PreviewWrapper
28-
import kotlinx.coroutines.delay
2930
import com.flipcash.app.theme.FlipcashThemeWrapper
3031
import com.flipcash.features.messenger.R
3132
import com.flipcash.services.models.chat.MessagePointer
3233
import com.flipcash.services.models.chat.PointerType
3334
import com.getcode.theme.CodeTheme
3435
import com.getcode.util.formatLocalized
36+
import kotlinx.coroutines.delay
3537
import kotlinx.datetime.TimeZone
3638
import kotlinx.datetime.toLocalDateTime
3739
import kotlin.time.Clock
@@ -60,7 +62,10 @@ internal fun ReceiptLabel(
6062

6163
AnimatedVisibility(
6264
visible = visible,
63-
modifier = modifier.padding(top = CodeTheme.dimens.grid.x1),
65+
modifier = modifier.padding(
66+
top = CodeTheme.dimens.grid.x1,
67+
end = CodeTheme.dimens.grid.x2,
68+
),
6469
enter = scaleIn(deliveredSpec, initialScale = 0.95f) + fadeIn(deliveredSpec),
6570
exit = fadeOut(snap()),
6671
) {
@@ -70,25 +75,36 @@ internal fun ReceiptLabel(
7075
targetState = status,
7176
transitionSpec = {
7277
(scaleIn(readSwapSpec, initialScale = 0.9f) + fadeIn(readSwapSpec)) togetherWith
73-
(scaleOut(readSwapSpec, targetScale = 0.9f) + fadeOut(readSwapSpec))
78+
(scaleOut(readSwapSpec, targetScale = 0.9f) + fadeOut(readSwapSpec))
7479
},
7580
label = "receiptStatus",
7681
) { animatedStatus ->
7782
val text = when (animatedStatus) {
7883
ReceiptStatus.SENT -> stringResource(R.string.label_chatReceipt_delivered)
79-
ReceiptStatus.READ -> {
80-
val readAtFormatted =
81-
readPointer?.timestamp?.let { formatReadTimestamp(it) } ?: ""
82-
stringResource(R.string.label_chatReceipt_read, readAtFormatted)
83-
}
84-
84+
ReceiptStatus.READ -> stringResource(R.string.label_chatReceipt_read)
8585
else -> return@AnimatedContent
8686
}
87-
Text(
88-
text = text,
89-
style = CodeTheme.typography.caption,
90-
color = CodeTheme.colors.textSecondary,
91-
)
87+
88+
val readAtFormatted =
89+
readPointer?.timestamp?.let { formatReadTimestamp(it) } ?: ""
90+
91+
// split text into two lines to eventually support a Theme driven
92+
// difference in font weights
93+
Row(horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x1)) {
94+
Text(
95+
text = text,
96+
style = CodeTheme.typography.caption,
97+
color = CodeTheme.colors.textSecondary,
98+
)
99+
100+
if (animatedStatus == ReceiptStatus.READ && readAtFormatted.isNotEmpty()) {
101+
Text(
102+
text = readAtFormatted,
103+
style = CodeTheme.typography.caption,
104+
color = CodeTheme.colors.textSecondary,
105+
)
106+
}
107+
}
92108
}
93109
}
94110
}

apps/flipcash/shared/contacts/src/main/kotlin/com/flipcash/app/contacts/ui/ContactAvatar.kt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,25 @@ import coil3.request.ImageRequest
3636
import coil3.request.crossfade
3737
import com.flipcash.app.contacts.device.DeviceContact
3838
import com.getcode.theme.CodeTheme
39+
import com.getcode.ui.core.addIf
3940

4041
@Composable
4142
fun ContactAvatar(
4243
contact: DeviceContact?,
4344
modifier: Modifier = Modifier,
45+
includeBorder: Boolean = true,
4446
) {
4547
if (contact == null || contact.isUnknown) {
4648
Box(
4749
modifier = modifier
48-
.background(Brush.linearGradient(CodeTheme.colors.contactAvatar.colors)),
50+
.background(Brush.linearGradient(CodeTheme.colors.contactAvatar.colors))
51+
.addIf(includeBorder) {
52+
Modifier.border(
53+
CodeTheme.dimens.border,
54+
CodeTheme.colors.divider,
55+
CircleShape,
56+
)
57+
},
4958
contentAlignment = Alignment.BottomCenter,
5059
) {
5160
Image(
@@ -66,11 +75,13 @@ fun ContactAvatar(
6675
} else {
6776
ContactAvatar(
6877
modifier = Modifier
69-
.border(
70-
CodeTheme.dimens.border,
71-
CodeTheme.colors.divider,
72-
CircleShape,
73-
).then(modifier),
78+
.addIf(includeBorder) {
79+
Modifier.border(
80+
CodeTheme.dimens.border,
81+
CodeTheme.colors.divider,
82+
CircleShape,
83+
)
84+
}.then(modifier),
7485
photoUri = contact.photoUri,
7586
displayName = contact.displayName,
7687
)

ui/components/src/main/kotlin/com/getcode/ui/components/chat/ChatInput.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ import androidx.compose.ui.focus.focusRequester
3636
import androidx.compose.ui.graphics.Color
3737
import androidx.compose.ui.graphics.CompositingStrategy
3838
import androidx.compose.ui.graphics.graphicsLayer
39+
import androidx.compose.ui.res.painterResource
3940
import androidx.compose.ui.text.input.KeyboardCapitalization
4041
import androidx.compose.ui.tooling.preview.Preview
4142
import androidx.compose.ui.unit.dp
4243
import com.getcode.theme.CodeTheme
4344
import com.getcode.theme.DesignSystem
4445
import com.getcode.theme.extraSmall
4546
import com.getcode.theme.inputColors
47+
import com.getcode.ui.components.R
4648
import com.getcode.ui.components.TextInput
4749

4850
@Composable
@@ -97,22 +99,23 @@ fun ChatInput(
9799
transitionSpec = {
98100
val spec = spring<Float>(dampingRatio = 0.66f, stiffness = 4000f)
99101
(fadeIn(spec) + scaleIn(spec, initialScale = 0.6f)) togetherWith
100-
(fadeOut(spec) + scaleOut(spec, targetScale = 0.6f))
102+
(fadeOut(spec) + scaleOut(spec, targetScale = 0.6f))
101103
}
102104
) { show ->
103105
if (show) {
104106
Icon(
105107
modifier = Modifier
106108
.padding(vertical = CodeTheme.dimens.grid.x1)
107-
.padding(end = CodeTheme.dimens.staticGrid.x2)
109+
.padding(end = CodeTheme.dimens.staticGrid.x1)
108110
.background(
109111
Color.White,
110112
shape = CodeTheme.shapes.extraSmall
111-
).clip(CodeTheme.shapes.extraSmall)
113+
)
114+
.clip(CodeTheme.shapes.extraSmall)
112115
.clickable { onSendMessage() }
113116
.padding(CodeTheme.dimens.staticGrid.x1)
114117
.size(CodeTheme.dimens.staticGrid.x5),
115-
imageVector = Icons.Rounded.ArrowUpward,
118+
painter = painterResource(R.drawable.ic_arrow_up),
116119
tint = Color.Black,
117120
contentDescription = "Send message"
118121
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="20dp"
3+
android:height="20dp"
4+
android:viewportWidth="20"
5+
android:viewportHeight="20">
6+
<path
7+
android:pathData="M10,4.167V16.667"
8+
android:strokeWidth="1.66667"
9+
android:fillColor="#00000000"
10+
android:strokeColor="#19191A"
11+
android:strokeLineCap="square"/>
12+
<path
13+
android:pathData="M5,8.333L10,3.333L15,8.333"
14+
android:strokeWidth="1.66667"
15+
android:fillColor="#00000000"
16+
android:strokeColor="#19191A"
17+
android:strokeLineCap="square"/>
18+
</vector>

ui/theme/src/main/kotlin/com/getcode/theme/Shape.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ internal val shapes = Shapes(
1919
large = RoundedCornerShape(15.dp)
2020
)
2121

22+
val Shapes.tiny: CornerBasedShape
23+
@Composable get() = RoundedCornerShape(4.dp)
2224
val Shapes.extraSmall: CornerBasedShape
2325
@Composable get() = RoundedCornerShape(6.dp)
2426

ui/theme/src/main/kotlin/com/getcode/theme/Type.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ val codeTypography = CodeTypography(
112112
lineHeight = 18.sp,
113113
fontFamily = Avenir,
114114
fontWeight = FontWeight.Medium,
115-
color = White50,
116115
),
117116
linkMedium = TextStyle(
118117
fontSize = 16.sp,

0 commit comments

Comments
 (0)