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 <noreply@anthropic.com>
This commit is contained in:
parent
077a408785
commit
4aec224f0d
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -276,6 +276,7 @@ private fun BucketListItems(
|
||||||
app.closer.ui.components.EmptyState(
|
app.closer.ui.components.EmptyState(
|
||||||
title = "Your shared list is empty",
|
title = "Your shared list is empty",
|
||||||
body = "Add something you've been dreaming about doing together — big or small. Tap + to start.",
|
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)
|
modifier = Modifier.padding(top = 80.dp)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,10 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import app.closer.R
|
||||||
import app.closer.core.navigation.AppRoute
|
import app.closer.core.navigation.AppRoute
|
||||||
import app.closer.domain.model.Conversation
|
import app.closer.domain.model.Conversation
|
||||||
|
import app.closer.ui.components.EmptyState
|
||||||
import app.closer.ui.theme.CloserPalette
|
import app.closer.ui.theme.CloserPalette
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
@ -74,6 +76,21 @@ fun MessagesInboxScreen(
|
||||||
return
|
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(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = PaddingValues(vertical = 4.dp)
|
contentPadding = PaddingValues(vertical = 4.dp)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue