M6b: core:design fixes after the M7 wave

Bugs: viewerPercentOf reads basis points (Samples in bp); FullSplitPicker and the
split labels use editor_split_full_on_you ("Allt på dig"); AmountInput.of restores
money with both decimals (AmountInput.percent for ratio fields), replacing M7c's
moneyInput; quickRowCategories does the D-060 fill itself; KvittScaffold resolves
resource-backed snackbars (showKvittSnackbar) while shown.

Gaps: ConfirmDialog optional and styled body; KvittButton loading form (M7a uses it,
ProgressBottomButton removed); InviteCodeField wraps after a group, placeholder,
imeAction; EmptyState icon tile and actionEnabled; DateFormatter.monthName and
dayRangeLong; AnalyticsFilterBar periodOwnRow; segmentedItem builder; screen tokens
in KvittDimens (OnboardingDimens removed); common_ok, common_undo; module-proposed
keys recorded in strings.csv; quick-row labels end in an ellipsis on line two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-18 11:35:06 +02:00
parent c4ab35f66e
commit b24c8b5ba3
49 changed files with 655 additions and 261 deletions
@@ -53,6 +53,7 @@ import se.hagstedt.kvitt.design.component.Skeleton
import se.hagstedt.kvitt.design.component.SyncStatusPill
import se.hagstedt.kvitt.design.component.UpdateBanner
import se.hagstedt.kvitt.design.component.kvittLanguage
import se.hagstedt.kvitt.design.component.styledStringResource
import se.hagstedt.kvitt.design.format.DateFormatter
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
@@ -174,7 +175,7 @@ private fun HomeList(ui: HomeUi.Ready, partner: User, actions: HomeActions, padd
item(key = "hero") { BalanceHero(HeroState.Loading, ui.home.me, words, actions.onSettleUp) }
item(key = "pill") {
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Skeleton(spacing.s1, KvittDimens.pillMinHeight, Modifier.fillMaxWidth(SKELETON_PILL_FRACTION), pill = true)
Skeleton(KvittDimens.skeletonPillWidth, KvittDimens.pillMinHeight, pill = true)
}
}
item(key = "header") { SectionHeader(stringResource(R.string.home_accounts)) }
@@ -234,7 +235,6 @@ private fun HomeList(ui: HomeUi.Ready, partner: User, actions: HomeActions, padd
}
private const val SKELETON_CARDS = 3
private const val SKELETON_PILL_FRACTION = 0.5f
@Composable
private fun UpdateBannerItem(ui: HomeUi.Ready, actions: HomeActions) {
@@ -252,8 +252,7 @@ private fun HomeAccountCard(summary: AccountSummary, partner: User, colorIndex:
private fun expensesLine(count: Int): String {
val today = LocalKvittClock.current.today
val period = today.year.toString() + "-" + today.month.ordinal.plus(1).toString().padStart(2, '0')
// monthYear is "oktober 2026" / "October 2026"; running text needs the month alone.
val month = DateFormatter.monthYear(period, kvittLanguage()).substringBeforeLast(' ')
val month = DateFormatter.monthName(period, kvittLanguage())
return if (count > 0) pluralStringResource(R.plurals.home_account_expenses_month, count, count, month) else stringResource(R.string.home_account_no_expenses_month, month)
}
@@ -263,8 +262,8 @@ private fun WelcomeCard(me: User, partner: User) {
KvittCard(Modifier.fillMaxWidth().semantics(mergeDescendants = true) {}) {
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(KvittTheme.spacing.cardTileGap)) {
Box {
PersonAvatar(me, KvittDimens.accountTile)
PersonAvatar(partner, KvittDimens.accountTile, Modifier.padding(start = KvittDimens.accountTile - KvittTheme.spacing.s2))
PersonAvatar(me, KvittDimens.welcomeAvatar)
PersonAvatar(partner, KvittDimens.welcomeAvatar, Modifier.padding(start = KvittDimens.welcomeAvatar - KvittDimens.welcomeAvatarOverlap))
}
Column(verticalArrangement = Arrangement.spacedBy(KvittTheme.spacing.s1)) {
Text(stringResource(R.string.home_empty_welcome, partner.displayName), style = MaterialTheme.typography.titleMedium)
@@ -280,7 +279,8 @@ private fun InstallDialog(actions: HomeActions) {
ConfirmDialog(
icon = KvittIcon.InstallMobile,
title = stringResource(DesignR.string.update_permission_title),
body = stringResource(DesignR.string.update_permission_body),
body = null,
styledBody = styledStringResource(DesignR.string.update_permission_body),
confirm = stringResource(DesignR.string.common_continue),
dismiss = stringResource(DesignR.string.update_later),
onConfirm = actions.onInstallContinue,
@@ -57,8 +57,6 @@
<!-- opens the system date settings -->
<string name="home_sync_status_open_date_settings">Datum och tid</string>
<string name="home_sync_status_last_attempt_clock">Senaste försöket nekades: klockan</string>
<!-- PROPOSED (not in strings.csv): TalkBack state of the "Archived (n)" row -->
<string name="home_archived_expanded">utfälld</string>
<!-- PROPOSED (not in strings.csv): TalkBack state of the "Archived (n)" row -->
<string name="home_archived_collapsed">hopfälld</string>
</resources>
@@ -57,8 +57,6 @@
<!-- opens the system date settings -->
<string name="home_sync_status_open_date_settings">Date &amp; time</string>
<string name="home_sync_status_last_attempt_clock">Last attempt refused: the clock</string>
<!-- PROPOSED (not in strings.csv): TalkBack state of the "Archived (n)" row -->
<string name="home_archived_expanded">expanded</string>
<!-- PROPOSED (not in strings.csv): TalkBack state of the "Archived (n)" row -->
<string name="home_archived_collapsed">collapsed</string>
</resources>