Add Display size customization page

Consolidates UI sizing into three percentage sliders surfaced through a
new Settings -> Interface -> Display size page: UI scale (50-150%),
Card size (50-150%), Spacing (25-175%). Each persists immediately via
DataStore; the rest of the app reflects them through
LocalInterfaceCustomization and a root-level LocalDensity override in
MainContent.

The page mirrors HomeSettingsPage's two-column shell: a fixed-width
settings panel on the left, HomePageContent rendering live preview rows
on the right. The page snapshots its own density on entry so the slider
rail stays fixed while UI scale changes the rest of the app.

Includes a one-shot AppUpgradeHandler migration block for installs at or
before 0.6.4-31-g0 that resets the three new percent fields to their
defaults.
This commit is contained in:
Justin Visser 2026-05-26 10:48:16 +02:00
parent 81e5f31401
commit 8fb301c2bb
12 changed files with 551 additions and 11 deletions

View file

@ -18,6 +18,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
@ -60,7 +62,19 @@ fun MainContent(
// setupNavigationManager.backStack = backStack
val interfaceCustomization =
remember(appPreferences) { InterfaceCustomization(appPreferences) }
CompositionLocalProvider(LocalInterfaceCustomization provides interfaceCustomization) {
val baseDensity = LocalDensity.current
val scaledDensity =
remember(baseDensity, interfaceCustomization.uiScalePercent) {
val factor = interfaceCustomization.uiScalePercent / 100f
Density(
density = baseDensity.density * factor,
fontScale = baseDensity.fontScale * factor,
)
}
CompositionLocalProvider(
LocalInterfaceCustomization provides interfaceCustomization,
LocalDensity provides scaledDensity,
) {
NavDisplay(
backStack = backStack,
onBack = { backStack.removeLastOrNull() },