From e08aaf099b95a3338b463de3dbba9cf28e648145 Mon Sep 17 00:00:00 2001 From: Jacob Hagstedt Date: Sun, 18 Oct 2026 23:04:32 +0200 Subject: [PATCH] Android overhaul: remove dead code (tokens, an icon, catalogue and fake samples, helpers, unused imports) Nothing referenced any of these: * :core:design KvittDimens iconMeta, seesawWidth, KEYPAD_COLUMNS, presetMinHeight, navIndicatorWidth/Height; KvittShapes largeIncreased, extraLargeIncreased, extraExtraLarge (the FAB's 20 is `fab`); KvittSpacing navigationBarHeight (ShortNavigationBar draws its own 64 dp); KvittMotion's spatial/effects springs, hero count, bunting stagger, shared-axis, sheet-enter and keypad-swap values (only the seesaw spring is used); the segmentedItem builder and snackbarMillis (KvittSnackbarVisuals maps the duration itself); KvittIcon.Description with its two drawables. * Catalogue sample Samples.renamedGroceries; fake scenarios SettleScenarios.partnerOwes and longAccountIds. * :data Clock.todayDate(). * Unused imports in Common.kt, Settle.kt, Timeline.kt, AnalyticsScenarios.kt, Clock.kt. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B --- .../kvitt/design/catalogue/Samples.kt | 1 - .../hagstedt/kvitt/design/component/Common.kt | 19 +------- .../hagstedt/kvitt/design/component/Settle.kt | 1 - .../kvitt/design/component/Timeline.kt | 1 - .../hagstedt/kvitt/design/icon/KvittIcons.kt | 1 - .../kvitt/design/theme/KvittDimens.kt | 8 +--- .../kvitt/design/theme/KvittMotion.kt | 45 ++----------------- .../kvitt/design/theme/KvittShapes.kt | 9 +--- .../kvitt/design/theme/KvittSpacing.kt | 3 +- .../src/main/res/drawable/ic_description.xml | 13 ------ .../res/drawable/ic_description_filled.xml | 13 ------ .../fakes/analytics/AnalyticsScenarios.kt | 1 - .../kvitt/fakes/settle/SettleScenarios.kt | 12 ----- .../se/hagstedt/kvitt/data/util/Clock.kt | 3 -- 14 files changed, 8 insertions(+), 122 deletions(-) delete mode 100644 android/core/design/src/main/res/drawable/ic_description.xml delete mode 100644 android/core/design/src/main/res/drawable/ic_description_filled.xml diff --git a/android/core/design/src/debug/kotlin/se/hagstedt/kvitt/design/catalogue/Samples.kt b/android/core/design/src/debug/kotlin/se/hagstedt/kvitt/design/catalogue/Samples.kt index bfc1433..a276526 100644 --- a/android/core/design/src/debug/kotlin/se/hagstedt/kvitt/design/catalogue/Samples.kt +++ b/android/core/design/src/debug/kotlin/se/hagstedt/kvitt/design/catalogue/Samples.kt @@ -57,7 +57,6 @@ object Samples { val fees = category("000000000014", DefaultCategoryKey.FEES, "account_balance", ColorToken.AMBER, 95) val other = category("00000000000a", DefaultCategoryKey.OTHER, "category", ColorToken.GREY, 100) val pant = Category(CategoryId("01920000-0000-7000-8000-0000000000c1"), null, "Pant", "water_drop", ColorToken.TEAL, 110, archived = true) - val renamedGroceries = groceries.copy(customName = "Matvaror") /** A long custom name: two lines with an ellipsis in the quick row (D-081). */ val renovation = Category(CategoryId("01920000-0000-7000-8000-0000000000c2"), null, "Renovering av sommarstugan", "build", ColorToken.BROWN, 120, archived = false) diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Common.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Common.kt index 7da1203..adfbc05 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Common.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Common.kt @@ -50,7 +50,6 @@ import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog @@ -88,22 +87,9 @@ fun KvittCard( /** The fill of a segmented group's items: `card` (default) or `surface-container-low` (soft). */ enum class GroupFill { Card, Soft } -/** One item of a [SegmentedGroup]: its shape and fill. Built by [SegmentedGroup], or by [segmentedItem] row by row. */ +/** One item of a [SegmentedGroup]: its shape and fill. */ class SegmentedItemScope internal constructor(val index: Int, val count: Int, val shape: Shape, val fill: Color) -/** - * The scope of item [index] of [count] of a segmented group, for building the group one row at a time where - * [SegmentedGroup] cannot hold the rows, such as one `LazyColumn` item per row (S-12): the item gets the §3.5 group - * shape (outer corners 24 on the ends, inner 8) and the [fill]; the caller spaces the items with - * `KvittTheme.spacing.groupGap`. Unlike [SegmentedGroup] it casts no shared group shadow (one per item would show - * between the rows), so lazily built groups are flat in light theme too. - */ -@Composable -fun segmentedItem(index: Int, count: Int, fill: GroupFill = GroupFill.Card): SegmentedItemScope { - val color = if (fill == GroupFill.Card) KvittTheme.colors.card else MaterialTheme.colorScheme.surfaceContainerLow - return SegmentedItemScope(index, count, KvittTheme.shapes.groupItem(index, count), color) -} - /** * A vertical group of items 3 dp apart with outer corners 24 and inner corners 8 (design-spec §3.5). Each item draws * its own background with `scope.shape` and `scope.fill` (so a row can tint itself, as the settlement row does). @@ -517,9 +503,6 @@ fun KvittSnackbar(message: String, modifier: Modifier = Modifier, action: String } } -/** How long a snackbar stays: 4 s without an action, 10 s with one (design-spec §3.11). */ -fun snackbarMillis(hasAction: Boolean): Long = if (hasAction) 10_000L else 4_000L - /** Loading placeholder blocks (`surface-container-highest`, radius 12); first sync and online fetches only. */ @Composable fun Skeleton(width: Dp, height: Dp, modifier: Modifier = Modifier, pill: Boolean = false) { diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Settle.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Settle.kt index a769cf3..898dac2 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Settle.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Settle.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.IconButton -import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Timeline.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Timeline.kt index 67e2553..6b01d3a 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Timeline.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/component/Timeline.kt @@ -32,7 +32,6 @@ import se.hagstedt.kvitt.design.KvittTheme import se.hagstedt.kvitt.design.format.DateFormatter import se.hagstedt.kvitt.design.format.KvittLanguage import se.hagstedt.kvitt.design.format.MoneyFormatter -import se.hagstedt.kvitt.design.icon.KvittIcon import se.hagstedt.kvitt.design.theme.KvittDimens import se.hagstedt.kvitt.model.AuditAction import se.hagstedt.kvitt.model.AuditSource diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/icon/KvittIcons.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/icon/KvittIcons.kt index 5b7174f..f49186a 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/icon/KvittIcons.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/icon/KvittIcons.kt @@ -33,7 +33,6 @@ enum class KvittIcon(@param:DrawableRes val outline: Int, @param:DrawableRes val ContentPaste(R.drawable.ic_content_paste, R.drawable.ic_content_paste_filled), DateRange(R.drawable.ic_date_range, R.drawable.ic_date_range_filled), Delete(R.drawable.ic_delete, R.drawable.ic_delete_filled), - Description(R.drawable.ic_description, R.drawable.ic_description_filled), Devices(R.drawable.ic_devices, R.drawable.ic_devices_filled), Dns(R.drawable.ic_dns, R.drawable.ic_dns_filled), Download(R.drawable.ic_download, R.drawable.ic_download_filled), diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittDimens.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittDimens.kt index bda7feb..fba3215 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittDimens.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittDimens.kt @@ -7,10 +7,9 @@ import androidx.compose.ui.unit.dp * is written down anywhere else; the spacing scale is [KvittSpacing]. */ object KvittDimens { - // Icons (§2.12): 24 default, 18 in chips, 15–16 in row meta, 20 in buttons. + // Icons (§2.12): 24 default, 18 in chips, 16 in hints, 20 in buttons. val icon = 24.dp val iconChip = 18.dp - val iconMeta = 15.dp val iconHint = 16.dp val iconButton = 20.dp val iconBadge = 14.dp @@ -72,7 +71,6 @@ object KvittDimens { val heroSide = 20.dp val heroBottom = 20.dp val heroSettledTop = 28.dp - val seesawWidth = 250.dp val seesawHeight = 92.dp val plankLength = 220.dp val plankThickness = 8.dp @@ -108,7 +106,6 @@ object KvittDimens { val keypadKey = 52.dp val keypadKeyCompact = 46.dp val keypadDeleteIcon = 26.dp - const val KEYPAD_COLUMNS = 3 val keypadPadding = 12.dp val keypadBottom = 8.dp val fieldFocusOutline = 2.dp @@ -143,7 +140,6 @@ object KvittDimens { val knobHeight = 44.dp val previewBar = 72.dp val exactFieldBorder = 1.dp - val presetMinHeight = 40.dp val fullPickerMinHeight = 52.dp val avatarFullPicker = 28.dp const val NOTES_MIN_LINES = 3 @@ -196,8 +192,6 @@ object KvittDimens { // Scaffolding (§3.11). val wordmarkMark = 22.dp val wordmarkIcon = 15.dp - val navIndicatorWidth = 56.dp - val navIndicatorHeight = 32.dp val fabHeight = 56.dp val buttonSmall = 40.dp val buttonMedium = 56.dp diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittMotion.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittMotion.kt index 1459adf..6d417d7 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittMotion.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittMotion.kt @@ -1,60 +1,21 @@ package se.hagstedt.kvitt.design.theme -import androidx.compose.animation.core.CubicBezierEasing import androidx.compose.animation.core.FiniteAnimationSpec -import androidx.compose.animation.core.Spring import androidx.compose.animation.core.spring -import androidx.compose.ui.unit.dp // Motion of docs/ux/design-spec.md §2.11. // // Expressive status against the pinned Material 3 1.4.0 (design-spec §3.1, §6 open point 5): `MotionScheme`, // `MotionScheme.expressive()` and the `MaterialTheme(motionScheme = …)` overload are internal in 1.4.0, so neither the // Expressive scheme nor a custom one can be installed. Fallback: Material components keep 1.4.0's own (standard) -// motion, and Kvitt's components animate with the springs below, which carry the Expressive values of §2.11. +// motion, and Kvitt's own animations use the springs below, which carry the Expressive values of §2.11. Only the +// motions a component uses are defined; add the next one from §2.11 when a component needs it. -/** Spring parameters and the named motions of design-spec §2.11. */ +/** The named motions of design-spec §2.11 that Kvitt's components use. */ object KvittMotion { - const val SPATIAL_FAST_DAMPING = 0.6f - const val SPATIAL_FAST_STIFFNESS = 800f - const val SPATIAL_DEFAULT_DAMPING = 0.8f - const val SPATIAL_DEFAULT_STIFFNESS = 380f - const val SPATIAL_SLOW_DAMPING = 0.8f - const val SPATIAL_SLOW_STIFFNESS = 200f - const val EFFECTS_FAST_STIFFNESS = 3800f - const val EFFECTS_DEFAULT_STIFFNESS = 1600f - const val EFFECTS_SLOW_STIFFNESS = 800f - /** Seesaw re-tilt when the global balance changes. */ const val SEESAW_DAMPING = 0.55f const val SEESAW_STIFFNESS = 300f - /** The hero amount counts from the old to the new value over this many milliseconds, emphasized decelerate. */ - const val HERO_COUNT_MILLIS = 400 - val EmphasizedDecelerate = CubicBezierEasing(0.05f, 0.7f, 0.1f, 1f) - - /** Settling to zero: the bunting drops one pennant at a time with this stagger. */ - const val BUNTING_STAGGER_MILLIS = 40 - - /** Pushed screens: horizontal shared axis, slide distance. S-7 and S-9 enter from the bottom by this fraction. */ - val SharedAxisSlide = 30.dp - const val SHEET_ENTER_FRACTION = 0.10f - - /** Keypad swap for the system keyboard (design-spec §5.2). */ - const val KEYPAD_SWAP_MILLIS = 150 - - fun fastSpatial(): FiniteAnimationSpec = spring(SPATIAL_FAST_DAMPING, SPATIAL_FAST_STIFFNESS) - fun defaultSpatial(): FiniteAnimationSpec = spring(SPATIAL_DEFAULT_DAMPING, SPATIAL_DEFAULT_STIFFNESS) - fun slowSpatial(): FiniteAnimationSpec = spring(SPATIAL_SLOW_DAMPING, SPATIAL_SLOW_STIFFNESS) - fun fastEffects(): FiniteAnimationSpec = spring(Spring.DampingRatioNoBouncy, EFFECTS_FAST_STIFFNESS) - fun defaultEffects(): FiniteAnimationSpec = spring(Spring.DampingRatioNoBouncy, EFFECTS_DEFAULT_STIFFNESS) - fun slowEffects(): FiniteAnimationSpec = spring(Spring.DampingRatioNoBouncy, EFFECTS_SLOW_STIFFNESS) - fun seesaw(): FiniteAnimationSpec = spring(SEESAW_DAMPING, SEESAW_STIFFNESS) - - /** - * Reduced motion (system "remove animations", animator duration scale 0): every spring becomes critically damped - * and immediate (design-spec §2.11). - */ - fun reduced(): FiniteAnimationSpec = spring(Spring.DampingRatioNoBouncy, Spring.StiffnessHigh) } diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittShapes.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittShapes.kt index 6e11f15..83cf381 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittShapes.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittShapes.kt @@ -14,7 +14,8 @@ import androidx.compose.ui.unit.dp // Expressive status against the pinned Material 3 1.4.0 (design-spec §3.1, §6 open point 5): `MaterialShapes` // (Cookie4Sided, Clover4Leaf, Sunny, Cookie9Sided) is not part of the 1.4.0 release, and `Shapes.largeIncreased`, // `extraLargeIncreased` and `extraExtraLarge` are internal there. Every shape below therefore uses the stable -// fallback the spec names; the swap to MaterialShapes happens here and nowhere else. +// fallback the spec names (the FAB's largeIncreased 20 is [KvittShapes.fab]); the swap to MaterialShapes happens here +// and nowhere else. /** Material 3 shape scale: extraSmall 4, small 8, medium 12, large 16, extraLarge 28. */ internal val KvittMaterialShapes = Shapes( @@ -28,12 +29,6 @@ internal val KvittMaterialShapes = Shapes( /** Kvitt's named shapes (design-spec §2.9, §2.14). */ @Immutable data class KvittShapes( - /** largeIncreased 20: the FAB. */ - val largeIncreased: CornerBasedShape = RoundedCornerShape(20.dp), - /** extraLargeIncreased 32. */ - val extraLargeIncreased: CornerBasedShape = RoundedCornerShape(32.dp), - /** extraExtraLarge 48. */ - val extraExtraLarge: CornerBasedShape = RoundedCornerShape(48.dp), /** Category tile: MaterialShapes.Cookie4Sided, fallback 30 % rounded. */ val categoryTile: Shape = RoundedCornerShape(30), /** Account tile: MaterialShapes.Clover4Leaf, fallback 16 dp rounded. */ diff --git a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittSpacing.kt b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittSpacing.kt index 793e468..219cb4b 100644 --- a/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittSpacing.kt +++ b/android/core/design/src/main/kotlin/se/hagstedt/kvitt/design/theme/KvittSpacing.kt @@ -36,9 +36,8 @@ data class KvittSpacing( val ledgerRowMin: Dp = 72.dp, /** Bottom padding of a scrolling column under a FAB. */ val fabClearance: Dp = 120.dp, - /** Top app bar height; bottom navigation height (plus the system inset). */ + /** Top app bar height. */ val topAppBarHeight: Dp = 64.dp, - val navigationBarHeight: Dp = 64.dp, /** Minimum touch target. */ val touchTarget: Dp = 48.dp, ) diff --git a/android/core/design/src/main/res/drawable/ic_description.xml b/android/core/design/src/main/res/drawable/ic_description.xml deleted file mode 100644 index 03ad85e..0000000 --- a/android/core/design/src/main/res/drawable/ic_description.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/android/core/design/src/main/res/drawable/ic_description_filled.xml b/android/core/design/src/main/res/drawable/ic_description_filled.xml deleted file mode 100644 index 09e35ff..0000000 --- a/android/core/design/src/main/res/drawable/ic_description_filled.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/analytics/AnalyticsScenarios.kt b/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/analytics/AnalyticsScenarios.kt index 00589a6..bbc8981 100644 --- a/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/analytics/AnalyticsScenarios.kt +++ b/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/analytics/AnalyticsScenarios.kt @@ -17,7 +17,6 @@ import se.hagstedt.kvitt.model.Measure import se.hagstedt.kvitt.model.RangePreset import se.hagstedt.kvitt.model.Share import se.hagstedt.kvitt.model.SplitMode -import se.hagstedt.kvitt.model.UserId /** * Scenarios of S-11 (analytics) and S-12 (drill-down), M7e. All share FakeScenarios.empty's household and clock diff --git a/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/settle/SettleScenarios.kt b/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/settle/SettleScenarios.kt index 36e0e3c..d681223 100644 --- a/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/settle/SettleScenarios.kt +++ b/android/core/fakes/src/main/kotlin/se/hagstedt/kvitt/fakes/settle/SettleScenarios.kt @@ -66,15 +66,6 @@ object SettleScenarios { expenses = proposal.expenses + listOf(expense(0xe4, vardag, jacob, 650_000, "2026-10-12")), ) - /** S-9 with the partner owing globally: the direction defaults to "Anna betalar dig". */ - val partnerOwes: FakeScenario = proposal.copy( - expenses = listOf( - expense(0xe1, huset, jacob, 616_900, "2026-10-02"), - expense(0xe2, japan, jacob, 270_000, "2026-10-05"), - expense(0xe3, vardag, anna, 236_900, "2026-10-09"), - ), - ) - /** S-9 offline with pending changes: settling up works unchanged (AC-11.6). */ val offline: FakeScenario = proposal.copy( online = false, @@ -162,9 +153,6 @@ object SettleScenarios { ), ) - /** The long scenario's accounts in created order. */ - val longAccountIds: List = longAccounts.map { it.id } - private fun id(suffix: Int): String = "01920000-0000-7000-8000-" + suffix.toString(16).padStart(12, '0') private fun account(suffix: Int, name: String, createdAt: String, archived: Boolean = false): Account = diff --git a/android/data/src/main/kotlin/se/hagstedt/kvitt/data/util/Clock.kt b/android/data/src/main/kotlin/se/hagstedt/kvitt/data/util/Clock.kt index e01f6b0..4552723 100644 --- a/android/data/src/main/kotlin/se/hagstedt/kvitt/data/util/Clock.kt +++ b/android/data/src/main/kotlin/se/hagstedt/kvitt/data/util/Clock.kt @@ -1,7 +1,6 @@ package se.hagstedt.kvitt.data.util import java.time.Instant -import java.time.LocalDate import java.time.ZoneId import java.time.ZoneOffset import java.time.format.DateTimeFormatter @@ -34,5 +33,3 @@ fun Clock.nowTimestamp(): String = Timestamps.format(nowMillis()) /** Today's date in the phone's zone, `YYYY-MM-DD`. */ fun Clock.today(): String = Instant.ofEpochMilli(nowMillis()).atZone(zone()).toLocalDate().toString() - -fun Clock.todayDate(): LocalDate = LocalDate.parse(today())