feat: home screen update, pairing views, activation illustrations

This commit is contained in:
null 2026-06-22 11:25:21 -05:00
parent af35ec029b
commit 60ca0b3582
4 changed files with 46 additions and 110 deletions

View File

@ -17,7 +17,7 @@ import app.closer.ui.questions.displayCategoryName
import app.closer.ui.theme.CloserPalette import app.closer.ui.theme.CloserPalette
import app.closer.ui.theme.closerBackgroundBrush import app.closer.ui.theme.closerBackgroundBrush
import app.closer.ui.theme.closerCardColor import app.closer.ui.theme.closerCardColor
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.layout.safeDrawingPadding
@ -38,8 +39,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.LocalFireDepartment import androidx.compose.material.icons.filled.LocalFireDepartment
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.PersonAdd
import app.closer.domain.model.OutcomeDay import app.closer.domain.model.OutcomeDay
import app.closer.ui.components.OutcomeCheckInDialog import app.closer.ui.components.OutcomeCheckInDialog
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -58,7 +57,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight 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.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -66,6 +68,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import app.closer.R
@Composable @Composable
fun HomeScreen( fun HomeScreen(
@ -522,31 +525,31 @@ private fun PartnerActivationCard(
} }
} }
Row( Image(
modifier = Modifier.fillMaxWidth(), painter = painterResource(R.drawable.illustration_partner_activation),
horizontalArrangement = Arrangement.spacedBy(16.dp), contentDescription = null,
verticalAlignment = Alignment.CenterVertically contentScale = ContentScale.Crop,
) { modifier = Modifier
PartnerActivationAvatars() .fillMaxWidth()
Column( .height(142.dp)
modifier = Modifier.weight(1f), .clip(RoundedCornerShape(22.dp))
verticalArrangement = Arrangement.spacedBy(8.dp) )
) {
Text( Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
text = "A private space for two", Text(
style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold), text = "A private space for two",
color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold),
maxLines = 2, color = MaterialTheme.colorScheme.onSurface,
overflow = TextOverflow.Ellipsis maxLines = 2,
) overflow = TextOverflow.Ellipsis
Text( )
text = "Invite your partner to unlock shared reveals, games, streaks, and answers you can both respond to.", Text(
style = MaterialTheme.typography.bodyMedium, text = "Invite your partner to unlock shared reveals, games, streaks, and answers you can both respond to.",
color = Color(0xFF4D4354), style = MaterialTheme.typography.bodyMedium,
maxLines = 4, color = Color(0xFF4D4354),
overflow = TextOverflow.Ellipsis maxLines = 4,
) overflow = TextOverflow.Ellipsis
} )
} }
Row( Row(
@ -579,45 +582,6 @@ private fun PartnerActivationCard(
} }
} }
@Composable
private fun PartnerActivationAvatars() {
Box(modifier = Modifier.size(width = 92.dp, height = 58.dp)) {
Surface(
modifier = Modifier
.size(52.dp)
.align(Alignment.CenterStart),
shape = RoundedCornerShape(999.dp),
color = CloserPalette.PurpleDeep
) {
Box(contentAlignment = Alignment.Center) {
Icon(
imageVector = Icons.Filled.Person,
contentDescription = null,
tint = MaterialTheme.colorScheme.surface,
modifier = Modifier.size(27.dp)
)
}
}
Surface(
modifier = Modifier
.size(52.dp)
.align(Alignment.CenterEnd),
shape = RoundedCornerShape(999.dp),
color = MaterialTheme.colorScheme.surface.copy(alpha = 0.9f),
border = BorderStroke(1.5.dp, CloserPalette.PurpleDeep.copy(alpha = 0.42f))
) {
Box(contentAlignment = Alignment.Center) {
Icon(
imageVector = Icons.Filled.PersonAdd,
contentDescription = null,
tint = CloserPalette.PurpleDeep,
modifier = Modifier.size(26.dp)
)
}
}
}
}
@Composable @Composable
private fun ActivationBenefitPill( private fun ActivationBenefitPill(
label: String, label: String,

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 KiB

View File

@ -79,20 +79,23 @@ struct PartnerActivationCard: View {
.clipShape(Capsule()) .clipShape(Capsule())
} }
HStack(alignment: .center, spacing: CloserSpacing.lg) { Image("illustration-partner-activation")
ActivationAvatarPair() .resizable()
.scaledToFill()
.frame(maxWidth: .infinity)
.frame(height: 148)
.clipShape(RoundedRectangle(cornerRadius: CloserRadius.large, style: .continuous))
VStack(alignment: .leading, spacing: CloserSpacing.sm) { VStack(alignment: .leading, spacing: CloserSpacing.sm) {
Text("A private space for two") Text("A private space for two")
.font(CloserFont.title2) .font(CloserFont.title2)
.foregroundColor(.closerText) .foregroundColor(.closerText)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)
Text("Invite your partner to unlock shared reveals, games, streaks, and answers you can both respond to.") Text("Invite your partner to unlock shared reveals, games, streaks, and answers you can both respond to.")
.font(CloserFont.callout) .font(CloserFont.callout)
.foregroundColor(.closerTextSecondary) .foregroundColor(.closerTextSecondary)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)
}
} }
HStack(spacing: CloserSpacing.sm) { HStack(spacing: CloserSpacing.sm) {
@ -130,37 +133,6 @@ struct PartnerActivationCard: View {
} }
} }
private struct ActivationAvatarPair: View {
var body: some View {
ZStack {
Circle()
.fill(Color.closerPrimary)
.frame(width: 54, height: 54)
.overlay {
Image(systemName: "person.fill")
.font(.system(size: 25, weight: .semibold))
.foregroundColor(.white)
}
.offset(x: -18)
Circle()
.fill(Color.closerBackground.opacity(0.9))
.frame(width: 54, height: 54)
.overlay {
Circle()
.stroke(Color.closerPrimary.opacity(0.42), lineWidth: 1.5)
}
.overlay {
Image(systemName: "person.crop.circle.badge.plus")
.font(.system(size: 23, weight: .semibold))
.foregroundColor(.closerPrimary)
}
.offset(x: 18)
}
.frame(width: 92, height: 62)
}
}
private struct ActivationBenefitChip: View { private struct ActivationBenefitChip: View {
let label: String let label: String

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 KiB