From 4aec224f0dd7ccde87d8a2a6fa4fb92d030b28a7 Mon Sep 17 00:00:00 2001 From: null Date: Fri, 26 Jun 2026 09:36:53 -0500 Subject: [PATCH] brand(art): wire Messages-empty (A8) + Bucket List-empty (A6); add BrandIllustration helper EmptyState already supports illustrationResId (rounded-tile clip), so Bucket List just passes illustration_bucket_list_empty. Messages inbox gained a proper empty state ("Your private conversation starts here") with illustration_messages_empty. Added BrandIllustration() helper (theme-safe rounded tile / tile=false for transparent art) for the upcoming header/hero placements. Verified live both themes: rounded illustration tile reads cleanly on dark (card) and light (white card on blush); 0 FATAL. Co-Authored-By: Claude Opus 4.8 --- .../closer/ui/components/BrandIllustration.kt | 49 +++++++++++++++++++ .../app/closer/ui/dates/BucketListScreen.kt | 1 + .../closer/ui/messages/MessagesInboxScreen.kt | 17 +++++++ 3 files changed, 67 insertions(+) create mode 100644 app/src/main/java/app/closer/ui/components/BrandIllustration.kt diff --git a/app/src/main/java/app/closer/ui/components/BrandIllustration.kt b/app/src/main/java/app/closer/ui/components/BrandIllustration.kt new file mode 100644 index 00000000..f9c66787 --- /dev/null +++ b/app/src/main/java/app/closer/ui/components/BrandIllustration.kt @@ -0,0 +1,49 @@ +package app.closer.ui.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * Brand illustration that reads on BOTH the light and dark themes. + * + * Most of the generated empty-state / header illustrations ship with a soft + * near-white background; rendered raw on the dark (aubergine) theme that background + * would float as a pale block. Clipping to a generous rounded tile with a hairline + * outline turns it into an intentional, modern illustration card on either surface. + * + * Transparent art (e.g. the pairing-success celebration) should pass [tile] = false + * so it floats freely with no card edge. + */ +@Composable +fun BrandIllustration( + @DrawableRes res: Int, + contentDescription: String?, + modifier: Modifier = Modifier, + tile: Boolean = true, + cornerRadius: Dp = 28.dp, +) { + val shape = RoundedCornerShape(cornerRadius) + val shaped = if (tile) { + modifier + .clip(shape) + .border(1.dp, MaterialTheme.colorScheme.outline.copy(alpha = 0.10f), shape) + } else { + modifier + } + Image( + painter = painterResource(res), + contentDescription = contentDescription, + contentScale = ContentScale.Fit, + modifier = shaped, + ) +} diff --git a/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt b/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt index 6ac2456e..62004002 100644 --- a/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/BucketListScreen.kt @@ -276,6 +276,7 @@ private fun BucketListItems( app.closer.ui.components.EmptyState( title = "Your shared list is empty", body = "Add something you've been dreaming about doing together — big or small. Tap + to start.", + illustrationResId = app.closer.R.drawable.illustration_bucket_list_empty, modifier = Modifier.padding(top = 80.dp) ) return diff --git a/app/src/main/java/app/closer/ui/messages/MessagesInboxScreen.kt b/app/src/main/java/app/closer/ui/messages/MessagesInboxScreen.kt index 14761ccc..d49d7ffd 100644 --- a/app/src/main/java/app/closer/ui/messages/MessagesInboxScreen.kt +++ b/app/src/main/java/app/closer/ui/messages/MessagesInboxScreen.kt @@ -30,8 +30,10 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import app.closer.R import app.closer.core.navigation.AppRoute import app.closer.domain.model.Conversation +import app.closer.ui.components.EmptyState import app.closer.ui.theme.CloserPalette import coil.compose.AsyncImage import java.util.concurrent.TimeUnit @@ -74,6 +76,21 @@ fun MessagesInboxScreen( return } + if (state.conversations.isEmpty()) { + Column( + modifier = Modifier.fillMaxSize().padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + EmptyState( + title = "Your private conversation starts here", + body = "Say hi, share a thought, or pick a question to talk through together. Everything you send stays end-to-end encrypted, just for the two of you.", + illustrationResId = R.drawable.illustration_messages_empty + ) + } + return + } + LazyColumn( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(vertical = 4.dp)