fix(ui): polish screens, update ViewModels, add docs
This commit is contained in:
parent
5302526d32
commit
888ffa3c1a
|
|
@ -88,7 +88,7 @@ private fun AnswerHistoryContent(
|
|||
color = Color(0xFF27211F)
|
||||
)
|
||||
Text(
|
||||
text = "Saved local answers, including private drafts and revealed reflections.",
|
||||
text = "Private answers and revealed reflections, gathered in one place.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -159,7 +159,7 @@ private fun AnswerHistoryCard(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(14.dp)
|
||||
) {
|
||||
Text("Remove local answer")
|
||||
Text("Remove answer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ fun AnswerHistoryScreenPreview() {
|
|||
state = AnswerHistoryUiState(
|
||||
answers = listOf(
|
||||
LocalAnswer(
|
||||
questionId = "preview",
|
||||
questionId = "demo",
|
||||
questionText = "What helped you feel close this week?",
|
||||
category = "gratitude",
|
||||
answerType = "written",
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ fun AnswerRevealScreen(
|
|||
questionId = questionId,
|
||||
onReveal = viewModel::revealAnswer,
|
||||
onAnswerQuestion = {
|
||||
onNavigate(AppRoute.questionThread("local-preview", questionId))
|
||||
onNavigate(AppRoute.questionThread("couple", questionId))
|
||||
},
|
||||
onHistory = { onNavigate(AppRoute.ANSWER_HISTORY) },
|
||||
onHome = { onNavigate(AppRoute.HOME) }
|
||||
|
|
@ -95,7 +95,7 @@ private fun AnswerRevealContent(
|
|||
color = Color(0xFF27211F)
|
||||
)
|
||||
Text(
|
||||
text = "This is the local reveal state for a saved answer. Partner sync can land here later without changing the flow.",
|
||||
text = "Open a saved answer when you are ready to look at it together.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -149,7 +149,7 @@ private fun NoAnswerState(
|
|||
) {
|
||||
RevealMessageCard {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(14.dp)) {
|
||||
RevealPill("No local answer yet")
|
||||
RevealPill("No answer yet")
|
||||
Text(
|
||||
text = question?.text ?: "Question $questionId is ready when you are.",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
|
|
@ -157,7 +157,7 @@ private fun NoAnswerState(
|
|||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
Text(
|
||||
text = "Answer this prompt first, then come back here for the reveal state.",
|
||||
text = "Answer this prompt first, then come back when you are ready to reveal it.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -202,7 +202,7 @@ private fun ReadyToRevealState(
|
|||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
Text(
|
||||
text = "Your answer is saved locally. Tap reveal when you want to open it.",
|
||||
text = "Your answer is private for now. Reveal it when the moment feels right.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -240,7 +240,7 @@ private fun RevealedState(
|
|||
RevealMessageCard {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(14.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
RevealPill("Revealed locally")
|
||||
RevealPill("Revealed")
|
||||
RevealPill(answer.category.displayCategoryName())
|
||||
RevealPill(answer.answerType.displayQuestionType())
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ fun AnswerRevealScreenPreview() {
|
|||
state = AnswerRevealUiState(
|
||||
isLoading = false,
|
||||
answer = LocalAnswer(
|
||||
questionId = "preview",
|
||||
questionId = "demo",
|
||||
questionText = "What helped you feel close this week?",
|
||||
category = "gratitude",
|
||||
answerType = "written",
|
||||
|
|
@ -338,7 +338,7 @@ fun AnswerRevealScreenPreview() {
|
|||
isRevealed = true
|
||||
)
|
||||
),
|
||||
questionId = "preview",
|
||||
questionId = "demo",
|
||||
onReveal = {},
|
||||
onAnswerQuestion = {},
|
||||
onHistory = {},
|
||||
|
|
|
|||
|
|
@ -107,13 +107,13 @@ fun PlaceholderScreen(
|
|||
}
|
||||
|
||||
PreviewPanel(
|
||||
title = "Screen shape",
|
||||
title = "What belongs here",
|
||||
accent = accent,
|
||||
details = details.ifEmpty {
|
||||
listOf(
|
||||
"The main moment has a reserved place",
|
||||
"The first pieces have room to breathe",
|
||||
"The visual rhythm is ready"
|
||||
"The main moment is easy to find",
|
||||
"Important choices have room to breathe",
|
||||
"The path forward stays clear"
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -183,7 +183,7 @@ private fun PlaceholderHeader(
|
|||
) {
|
||||
SignalChip(label = section, accent = accent)
|
||||
Text(
|
||||
text = "Preview",
|
||||
text = "Guided",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.54f),
|
||||
maxLines = 1,
|
||||
|
|
@ -271,7 +271,7 @@ private fun PreviewPanel(
|
|||
.padding(horizontal = 10.dp, vertical = 6.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "First pass",
|
||||
text = "Ready",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = Color(0xFF3E3734)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ private fun DailyQuestionCard(
|
|||
question?.let { HomePill(it.category.displayCategoryName()) }
|
||||
}
|
||||
Text(
|
||||
text = question?.text ?: "The local question deck is ready.",
|
||||
text = question?.text ?: "Your next question is ready.",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color(0xFF27211F)
|
||||
|
|
@ -680,7 +680,7 @@ private fun LoadingHomeCard() {
|
|||
) {
|
||||
CircularProgressIndicator(color = Color(0xFF8F5FC8))
|
||||
Text(
|
||||
text = "Opening the local dashboard",
|
||||
text = "Opening your dashboard",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -751,7 +751,7 @@ fun HomeScreenPreview() {
|
|||
state = HomeUiState(
|
||||
isLoading = false,
|
||||
dailyQuestion = Question(
|
||||
id = "preview",
|
||||
id = "demo",
|
||||
text = "What is one tiny thing that would help us feel close tonight?",
|
||||
category = "emotional_intimacy",
|
||||
depthLevel = 2
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class HomeViewModel @Inject constructor(
|
|||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
error = e.message ?: "Could not load the local dashboard."
|
||||
error = e.message ?: "Could not load your dashboard."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ fun PartnerHomeScreen(
|
|||
secondaryAction = PlaceholderAction("Home", AppRoute.HOME),
|
||||
chips = listOf("Partner state", "Pairing bridge", "Shared rhythm"),
|
||||
details = listOf(
|
||||
"Pairing status can feel visible without feeling clinical",
|
||||
"Recent shared activity can stay separate from private drafts",
|
||||
"Home has a focused couple subspace"
|
||||
"Know whether you are connected at a glance",
|
||||
"Keep shared activity separate from private reflections",
|
||||
"Return to the couple space without extra searching"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ fun EmailInviteScreen(
|
|||
PlaceholderScreen(
|
||||
title = "Send the thread",
|
||||
section = "Pairing",
|
||||
description = "A draft email invite flow for adding a partner with care and clarity.",
|
||||
description = "Invite your partner with a clear message and a simple code.",
|
||||
route = AppRoute.EMAIL_INVITE,
|
||||
onNavigate = onNavigate,
|
||||
accent = Color(0xFF6C8EA4),
|
||||
primaryAction = PlaceholderAction("Confirm sample", AppRoute.inviteConfirm("ABC123")),
|
||||
primaryAction = PlaceholderAction("Confirm code", AppRoute.inviteConfirm("ABC123")),
|
||||
secondaryAction = PlaceholderAction("Create invite", AppRoute.CREATE_INVITE),
|
||||
chips = listOf("Email", "Code ABC123", "Preview"),
|
||||
chips = listOf("Email", "Code ABC123", "Invite"),
|
||||
details = listOf(
|
||||
"Recipient entry and preview can stay focused",
|
||||
"Delivery copy can be gentle and direct",
|
||||
"Sample confirmation keeps the invite code visible"
|
||||
"Keep the message short and easy to understand",
|
||||
"Make the code clear before it is sent",
|
||||
"Give your partner one simple next step"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,12 +137,12 @@ fun PaywallScreen(
|
|||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Coming soon",
|
||||
text = "Membership",
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = Color(0xFF271236).copy(alpha = 0.74f)
|
||||
)
|
||||
Text(
|
||||
text = "In-app purchase launching with the next build.",
|
||||
text = "Membership details are unavailable right now.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF271236),
|
||||
textAlign = TextAlign.Center
|
||||
|
|
@ -159,7 +159,7 @@ fun PaywallScreen(
|
|||
contentColor = Color(0xFF271236)
|
||||
)
|
||||
) {
|
||||
Text("Subscribe (coming soon)", color = Color(0xFF271236))
|
||||
Text("Keep exploring", color = Color(0xFF271236))
|
||||
}
|
||||
|
||||
TextButton(onClick = { onNavigate("back") }) {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ fun DailyQuestionScreen(
|
|||
LocalQuestionContent(
|
||||
state = state,
|
||||
title = "One question, enough space",
|
||||
subtitle = "A real prompt from the local question deck. Answer privately here, then move into a reveal or discussion path.",
|
||||
subtitle = "Answer privately first, then choose whether to reveal it or keep the conversation going.",
|
||||
primaryRouteLabel = "Discuss",
|
||||
onPrimaryRoute = { question ->
|
||||
onNavigate(AppRoute.questionThread(state.coupleId ?: "local-preview", question.id))
|
||||
onNavigate(AppRoute.questionThread(state.coupleId ?: "couple", question.id))
|
||||
},
|
||||
onSecondaryRoute = state.question?.let {
|
||||
{ onNavigate(AppRoute.answerReveal(it.id)) }
|
||||
|
|
@ -43,7 +43,7 @@ fun DailyQuestionScreenPreview() {
|
|||
state = LocalQuestionUiState(
|
||||
isLoading = false,
|
||||
question = Question(
|
||||
id = "preview",
|
||||
id = "demo",
|
||||
text = "What is one small thing that would help us feel close tonight?",
|
||||
category = "emotional_intimacy",
|
||||
depthLevel = 2,
|
||||
|
|
@ -51,7 +51,7 @@ fun DailyQuestionScreenPreview() {
|
|||
)
|
||||
),
|
||||
title = "One question, enough space",
|
||||
subtitle = "A real prompt from the local question deck.",
|
||||
subtitle = "Answer privately first, then choose what happens next.",
|
||||
primaryRouteLabel = "Discuss",
|
||||
onPrimaryRoute = {},
|
||||
onSecondaryRoute = {},
|
||||
|
|
|
|||
|
|
@ -89,15 +89,15 @@ fun LocalQuestionContent(
|
|||
LocalQuestionHeader(title = title, subtitle = subtitle)
|
||||
|
||||
when {
|
||||
state.isLoading -> LoadingState(message = "Opening the local question deck")
|
||||
state.isLoading -> LoadingState(message = "Opening your question")
|
||||
state.error != null -> ErrorState(
|
||||
title = "Question paused",
|
||||
message = state.error,
|
||||
onRetry = onRefresh
|
||||
)
|
||||
state.question == null -> EmptyState(
|
||||
title = "No local question found",
|
||||
body = "The local question database is ready, but this path did not return a prompt."
|
||||
title = "This question is not available",
|
||||
body = "Choose another prompt and keep the conversation moving gently."
|
||||
)
|
||||
else -> {
|
||||
val question = state.question
|
||||
|
|
@ -165,7 +165,7 @@ fun LocalQuestionContent(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
) {
|
||||
Text("Try another local question")
|
||||
Text("Try another question")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +257,7 @@ private fun SubmittedAnswerCard(
|
|||
)
|
||||
}
|
||||
Text(
|
||||
text = "Saved locally",
|
||||
text = "Saved privately",
|
||||
modifier = Modifier.padding(start = 10.dp),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = Color(0xFF27211F),
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ fun QuestionCategoryScreen(
|
|||
categoryId = categoryId,
|
||||
state = state,
|
||||
onQuestionSelected = { question ->
|
||||
onNavigate(AppRoute.questionThread("local-preview", question.id))
|
||||
onNavigate(AppRoute.questionThread("couple", question.id))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ private fun QuestionCategoryContent(
|
|||
)
|
||||
Text(
|
||||
text = state.category?.description
|
||||
?: "Browse real local prompts in this category.",
|
||||
?: "Browse prompts for this kind of conversation.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -110,14 +110,14 @@ private fun QuestionCategoryContent(
|
|||
state.questions.isEmpty() -> item {
|
||||
CategoryMessageCard(
|
||||
title = "No prompts found",
|
||||
message = "The local deck did not return prompts for ${categoryId.displayCategoryName()}."
|
||||
message = "No prompts are available for ${categoryId.displayCategoryName()} right now."
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
item {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
CategoryPill("${state.questions.size} prompts")
|
||||
CategoryPill(state.category?.access?.displayCategoryName() ?: "Local")
|
||||
state.category?.access?.let { CategoryPill(it.displayCategoryName()) }
|
||||
}
|
||||
}
|
||||
items(state.questions, key = { it.id }) { question ->
|
||||
|
|
@ -199,7 +199,7 @@ private fun CategoryLoadingCard() {
|
|||
) {
|
||||
CircularProgressIndicator(color = Color(0xFF8F5FC8))
|
||||
Text(
|
||||
text = "Loading local prompts",
|
||||
text = "Loading prompts",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -249,7 +249,7 @@ fun QuestionCategoryScreenPreview() {
|
|||
),
|
||||
questions = listOf(
|
||||
Question(
|
||||
id = "preview",
|
||||
id = "demo",
|
||||
text = "What is one gentle thing I could do this week that would help you feel chosen?",
|
||||
category = "emotional_intimacy",
|
||||
depthLevel = 2,
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ fun QuestionComposerScreen(
|
|||
PlaceholderScreen(
|
||||
title = "Ask it cleanly",
|
||||
section = "Questions",
|
||||
description = "A future composer for custom prompts, tone checks, and saving questions for later.",
|
||||
description = "Shape your own prompt with a tone that feels generous and clear.",
|
||||
route = AppRoute.QUESTION_COMPOSER,
|
||||
onNavigate = onNavigate,
|
||||
accent = Color(0xFF81B29A),
|
||||
primaryAction = PlaceholderAction("Thread sample", AppRoute.questionThread("couple-preview", "custom-preview")),
|
||||
primaryAction = PlaceholderAction("Open thread", AppRoute.questionThread("couple", "custom")),
|
||||
secondaryAction = PlaceholderAction("Packs", AppRoute.QUESTION_PACKS),
|
||||
chips = listOf("Custom prompt", "Tone aware", "Save later"),
|
||||
chips = listOf("Custom prompt", "Tone aware", "Save"),
|
||||
details = listOf(
|
||||
"Custom question creation stays separate from daily prompts",
|
||||
"Tone support can arrive as a focused enhancement",
|
||||
"Saved custom prompts can become shared threads"
|
||||
"Write a question in your own words",
|
||||
"Check whether the tone invites honesty",
|
||||
"Save prompts that deserve a real conversation"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ private fun QuestionPackLibraryContent(
|
|||
color = Color(0xFF27211F)
|
||||
)
|
||||
Text(
|
||||
text = "Real local question packs from the seeded deck, grouped by the kind of conversation you want to open.",
|
||||
text = "Choose a question pack by the kind of conversation you want to open together.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
@ -109,7 +109,7 @@ private fun QuestionPackLibraryContent(
|
|||
state.packs.isEmpty() -> item {
|
||||
PackMessageCard(
|
||||
title = "No packs found",
|
||||
message = "The local category table did not return any question packs."
|
||||
message = "Question packs are not available right now. Try again in a moment."
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -238,7 +238,7 @@ private fun LoadingPackCard() {
|
|||
) {
|
||||
CircularProgressIndicator(color = Color(0xFF8F5FC8))
|
||||
Text(
|
||||
text = "Loading local packs",
|
||||
text = "Loading question packs",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = Color(0xFF4E4642)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fun QuestionThreadScreen(
|
|||
|
||||
LocalQuestionContent(
|
||||
state = state,
|
||||
title = "Question thread",
|
||||
subtitle = "A local version of the answer-and-discuss flow. It uses the selected prompt now, with partner sync saved for a later batch.",
|
||||
title = "Answer with care",
|
||||
subtitle = "Take a moment for your own answer. When you are ready, move to the next prompt or revisit what you have saved.",
|
||||
primaryRouteLabel = nextQuestionId?.let { "Next" } ?: "History",
|
||||
onPrimaryRoute = {
|
||||
if (nextQuestionId != null) {
|
||||
|
|
@ -65,15 +65,15 @@ fun QuestionThreadScreenPreview() {
|
|||
state = LocalQuestionUiState(
|
||||
isLoading = false,
|
||||
question = Question(
|
||||
id = "preview",
|
||||
id = "demo",
|
||||
text = "What is one conversation you want us to handle more gently?",
|
||||
category = "communication",
|
||||
depthLevel = 3,
|
||||
type = "written"
|
||||
)
|
||||
),
|
||||
title = "Question thread",
|
||||
subtitle = "A local version of the answer-and-discuss flow.",
|
||||
title = "Answer with care",
|
||||
subtitle = "Take a moment for your own answer.",
|
||||
primaryRouteLabel = "History",
|
||||
onPrimaryRoute = {},
|
||||
onSecondaryRoute = {},
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ fun AccountScreen(
|
|||
PlaceholderScreen(
|
||||
title = "Your account",
|
||||
section = "Settings",
|
||||
description = "A focused place for identity, login methods, export, and account lifecycle controls.",
|
||||
description = "Manage identity, sign-in, exports, and account choices in one calm place.",
|
||||
route = AppRoute.ACCOUNT,
|
||||
onNavigate = onNavigate,
|
||||
accent = Color(0xFF6C8EA4),
|
||||
primaryAction = PlaceholderAction("Notifications", AppRoute.NOTIFICATIONS),
|
||||
secondaryAction = PlaceholderAction("Settings", AppRoute.SETTINGS),
|
||||
chips = listOf("Identity", "Export later", "Lifecycle"),
|
||||
chips = listOf("Identity", "Export", "Account care"),
|
||||
details = listOf(
|
||||
"Account controls can stay separate from relationship data",
|
||||
"Export and deletion flows can attach here",
|
||||
"Notification settings remain one route away"
|
||||
"Keep profile details separate from relationship reflections",
|
||||
"Find export and account care options together",
|
||||
"Adjust notification settings from the same area"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ fun NotificationSettingsScreen(
|
|||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
Text(
|
||||
text = "Push notification preferences are saved locally. Full scheduling requires the next app update.",
|
||||
text = "These preferences shape the reminders you see from the app.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(horizontal = 4.dp)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ fun SubscriptionScreen(
|
|||
PlaceholderScreen(
|
||||
title = "Manage the plan",
|
||||
section = "Settings",
|
||||
description = "A subscription management place for entitlement status, invoices, and plan changes.",
|
||||
description = "See plan access, restore purchases, and choose the level that fits your relationship.",
|
||||
route = AppRoute.SUBSCRIPTION,
|
||||
onNavigate = onNavigate,
|
||||
accent = Color(0xFFB98AF4),
|
||||
|
|
@ -22,9 +22,9 @@ fun SubscriptionScreen(
|
|||
secondaryAction = PlaceholderAction("Settings", AppRoute.SETTINGS),
|
||||
chips = listOf("Entitlement", "Plan", "Restore"),
|
||||
details = listOf(
|
||||
"Entitlement display can stay plain-spoken",
|
||||
"Plan changes and restore purchase can stay together",
|
||||
"The upgrade path stays nearby"
|
||||
"See what your plan includes in plain language",
|
||||
"Keep restore purchase close to plan details",
|
||||
"Open the upgrade path when you are ready"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class SpinWheelViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun startSession() {
|
||||
_uiState.update { it.copy(navigateTo = AppRoute.wheelSession("local")) }
|
||||
_uiState.update { it.copy(navigateTo = AppRoute.wheelSession("session")) }
|
||||
}
|
||||
|
||||
fun onNavigated() {
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class WheelSessionViewModel @Inject constructor(
|
|||
val state = _uiState.value
|
||||
sessionStore.lastAnswered = (state.currentIndex + 1).coerceAtMost(state.questions.size)
|
||||
sessionStore.lastTotal = state.questions.size
|
||||
_uiState.update { it.copy(navigateTo = AppRoute.wheelComplete("local")) }
|
||||
_uiState.update { it.copy(navigateTo = AppRoute.wheelComplete("session")) }
|
||||
}
|
||||
|
||||
fun onNavigated() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# Copy Guide
|
||||
|
||||
## Voice
|
||||
- Warm, calm, and direct.
|
||||
- Speak to the couple, not to the implementation.
|
||||
- Prefer concrete relationship language over product scaffolding.
|
||||
- Keep labels short enough for small Android screens.
|
||||
|
||||
## Do
|
||||
- Say "private answer", "saved reflection", "question pack", and "reveal".
|
||||
- Use verbs for buttons: "Answer", "Reveal", "Open", "Remove".
|
||||
- Let empty states offer a gentle next step.
|
||||
- Name emotional intent when it helps: care, honesty, repair, closeness.
|
||||
|
||||
## Avoid
|
||||
- Internal terms such as "local", "preview", "placeholder", "seeded", "database", and "later batch".
|
||||
- Roadmap copy inside the app.
|
||||
- Overexplaining technical state.
|
||||
- Destructive language as a primary action unless the screen is explicitly confirming deletion.
|
||||
|
||||
## Examples
|
||||
- Instead of "Loading local prompts": "Loading prompts".
|
||||
- Instead of "No local answer yet": "No answer yet".
|
||||
- Instead of "Partner sync can land here later": "Open a saved answer when you are ready to look at it together."
|
||||
Loading…
Reference in New Issue