Skip to content

Commit afaa5fa

Browse files
committed
fix(chat-ui): size link cards off the transcript's full width
Link cards and the solo group's head card came out about 30dp narrower than iOS's on the same screen. iOS takes 78% of the transcript's full width for both (ChatViewController.maxBubbleWidthFraction). Android took 78% of the row after its side insets for link cards, and 72% for the head card. transcriptCardWidth() adds the insets back before applying the fraction, and both the card rows in ContentBubble and the head card in MessageList use it. Text and cash bubbles keep their existing widths.
1 parent f8d2cbd commit afaa5fa

2 files changed

Lines changed: 27 additions & 7 deletions

File tree

  • apps/flipcash
    • features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components
    • shared/chat-ui/src/main/kotlin/com/flipcash/shared/chat/ui

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.WindowInsets
1111
import androidx.compose.foundation.layout.fillMaxWidth
1212
import androidx.compose.foundation.layout.ime
1313
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.width
1415
import androidx.compose.foundation.lazy.LazyColumn
1516
import androidx.compose.foundation.lazy.LazyListLayoutInfo
1617
import androidx.compose.foundation.lazy.LazyListState
@@ -60,6 +61,7 @@ import com.flipcash.shared.chat.reactions.ReactionRefreshPlanner
6061
import com.flipcash.shared.chat.ui.ChatAnimations
6162
import com.flipcash.shared.chat.ui.GroupInviteCardDefaults
6263
import com.flipcash.shared.chat.ui.GroupInviteLinkCard
64+
import com.flipcash.shared.chat.ui.transcriptCardWidth
6365
import com.getcode.theme.CodeTheme
6466
import com.getcode.ui.utils.rememberKeyboardController
6567
import com.getcode.util.vibration.LocalVibrator
@@ -72,9 +74,6 @@ import kotlinx.coroutines.flow.first
7274
import kotlinx.coroutines.flow.mapNotNull
7375
import kotlinx.coroutines.withTimeoutOrNull
7476

75-
// The empty group's invite card, as a share of the row: 290 of 402 in node 10330:19164.
76-
private const val GROUP_INVITE_CARD_WIDTH = 0.72f
77-
7877
@Composable
7978
internal fun MessageList(
8079
modifier: Modifier = Modifier,
@@ -435,14 +434,20 @@ internal fun MessageList(
435434
currencyName = state.ruleCurrency?.nameInRequirement,
436435
)
437436
}
438-
Box(
437+
BoxWithConstraints(
439438
modifier = Modifier.fillParentMaxWidth(),
440439
contentAlignment = Alignment.Center,
441440
) {
442-
BoxWithConstraints(Modifier.fillMaxWidth(GROUP_INVITE_CARD_WIDTH)) {
441+
// The width a link card gets in a DM transcript, so this reads as the
442+
// same card sent there (iOS sizes both the same way).
443+
val cardWidth = transcriptCardWidth(
444+
rowWidth = maxWidth,
445+
rowInset = CodeTheme.dimens.inset,
446+
)
447+
Box(Modifier.width(cardWidth)) {
443448
GroupInviteLinkCard(
444449
card = card,
445-
minHeight = maxWidth * GroupInviteCardDefaults.ASPECT,
450+
minHeight = cardWidth * GroupInviteCardDefaults.ASPECT,
446451
ctaLabel = stringResource(R.string.action_linkCard_invitePeople),
447452
onStart = { onAction(ChatAction.InviteToGroup) }
448453
.takeIf { !selecting },

‎apps/flipcash/shared/chat-ui/src/main/kotlin/com/flipcash/shared/chat/ui/MessageBubble.kt‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ import com.getcode.ui.core.addIf
8282
enum class BubblePosition { Solo, First, Middle, Last }
8383

8484
private const val BUBBLE_MAX_WIDTH_FRACTION = 0.78f
85+
86+
/**
87+
* How wide a link card is drawn in a transcript whose rows are inset by [rowInset] on each side.
88+
*
89+
* The same fraction as a text bubble, but of the transcript's full width rather than of the inset
90+
* row, which is how iOS sizes its link cards and its group's head card
91+
* (`ChatViewController.maxBubbleWidthFraction`). Taken of the inset row, the cards came out about
92+
* 30dp narrower than iOS's on the same screen.
93+
*/
94+
fun transcriptCardWidth(rowWidth: Dp, rowInset: Dp): Dp =
95+
(rowWidth + rowInset * 2) * BUBBLE_MAX_WIDTH_FRACTION
96+
8597
private val EDITED_MARKER_GAP = 6.dp
8698
private const val CASH_BUBBLE_MAX_WIDTH_FRACTION = 0.64f
8799

@@ -106,7 +118,10 @@ fun ContentBubble(
106118
val actionHandler = LocalChatActionHandler.current
107119
val jumbo = remember(item) { item.rendersBareEmoji() }
108120
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
109-
val bubbleMaxWidth = when (item.content) {
121+
val isCardRow = item.linkCard != null && item.part == MessagePart.Card
122+
val bubbleMaxWidth = if (isCardRow) {
123+
transcriptCardWidth(rowWidth = maxWidth, rowInset = CodeTheme.dimens.inset)
124+
} else when (item.content) {
110125
is MessageContent.Text -> maxWidth * BUBBLE_MAX_WIDTH_FRACTION
111126
is MessageContent.Cash -> maxWidth * CASH_BUBBLE_MAX_WIDTH_FRACTION
112127
is MessageContent.Deleted -> maxWidth * BUBBLE_MAX_WIDTH_FRACTION

0 commit comments

Comments
 (0)