M7g: feature cleanups after the design-system fix pass

Resource-backed snackbars (showKvittSnackbar) in account, onboarding and
settings; SettingsScaffold replaced by KvittScaffold + SettingsMessageEffect.
KvittButton(loading) for S-6 saving and S-16 Synka nu. S-10 missing state
disables Synka nu offline (connectivity in the ViewModel, new
detail_missing_offline goldens). S-6 system back asks to discard unsaved
changes.

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:44:07 +02:00
parent f4dc10c7ae
commit 3dda414ec2
22 changed files with 177 additions and 160 deletions
@@ -15,9 +15,11 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -35,6 +37,7 @@ import se.hagstedt.kvitt.design.component.ButtonSize
import se.hagstedt.kvitt.design.component.FactRow
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.NeedsConnectionHint
import se.hagstedt.kvitt.design.component.SegmentedGroup
@@ -44,7 +47,7 @@ import se.hagstedt.kvitt.design.component.UpdateBanner
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.UpdateState
import se.hagstedt.kvitt.core.design.R as DesignR
@@ -76,13 +79,14 @@ class AboutActions(
/** Stateless S-22. */
@Composable
fun AboutContent(state: AboutScreenState?, actions: AboutActions, updateCheckAvailable: Boolean, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown)
KvittScaffold(
modifier.fillMaxSize(),
topBar = { KvittTopAppBar(stringResource(R.string.settings_about_title), navigation = TopBarNavigation.Back, onNavigation = actions.onBack) },
message = state?.message,
onMessageShown = actions.onMessageShown,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
val about = state.about
Column(
Modifier
@@ -11,10 +11,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
@@ -30,6 +32,7 @@ import se.hagstedt.kvitt.design.component.ConfirmDialog
import se.hagstedt.kvitt.design.component.KvittBadge
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTextField
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.NeedsConnectionHint
@@ -39,8 +42,8 @@ import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.HintText
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.SaveAction
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.ColorToken
import se.hagstedt.kvitt.core.design.R as DesignR
@@ -100,7 +103,9 @@ class CategoryEditorActions(
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun CategoryEditorContent(state: CategoryEditorState?, actions: CategoryEditorActions, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown)
KvittScaffold(
modifier.fillMaxSize(),
topBar = {
val title = if (state?.isNew != false) R.string.settings_category_editor_new else R.string.settings_category_editor_edit
@@ -108,10 +113,9 @@ fun CategoryEditorContent(state: CategoryEditorState?, actions: CategoryEditorAc
SaveAction(enabled = state?.canSave == true, onClick = actions.onSave)
}
},
message = state?.message,
onMessageShown = actions.onMessageShown,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
val defaultName = state.defaultKey?.let { stringResource(defaultCategoryName(it)) }
val shownName = state.name.trim().ifEmpty { defaultName ?: "" }
Column(
@@ -19,6 +19,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -52,6 +53,7 @@ import se.hagstedt.kvitt.design.KvittTheme
import se.hagstedt.kvitt.design.component.CategoryTile
import se.hagstedt.kvitt.design.component.CollapsibleRow
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.NeedsConnectionHint
import se.hagstedt.kvitt.design.component.SegmentedGroup
@@ -61,7 +63,7 @@ import se.hagstedt.kvitt.design.component.categoryName
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.Category
import se.hagstedt.kvitt.model.CategoryId
@@ -118,7 +120,9 @@ class CategoryListActions(
/** Stateless S-15 list. */
@Composable
fun CategoryListContent(state: CategoryListState?, actions: CategoryListActions, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown)
KvittScaffold(
modifier.fillMaxSize(),
topBar = {
KvittTopAppBar(stringResource(R.string.settings_categories_title), navigation = TopBarNavigation.Back, onNavigation = actions.onBack) {
@@ -127,10 +131,9 @@ fun CategoryListContent(state: CategoryListState?, actions: CategoryListActions,
}
}
},
message = state?.message,
onMessageShown = actions.onMessageShown,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
Column(
Modifier
.fillMaxSize()
@@ -1,24 +1,14 @@
package se.hagstedt.kvitt.feature.settings.common
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import kotlinx.coroutines.delay
import se.hagstedt.kvitt.design.KvittTheme
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittSnackbar
import se.hagstedt.kvitt.design.component.snackbarMillis
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.platform.LocalResources
import se.hagstedt.kvitt.design.component.showKvittSnackbar
import se.hagstedt.kvitt.model.OnlineResult
import se.hagstedt.kvitt.core.design.R as DesignR
import se.hagstedt.kvitt.feature.settings.R
@@ -77,42 +67,19 @@ fun failureText(code: String): Int = when (code) {
fun failureMessage(code: String, canRetry: Boolean = true): UiMessage = UiMessage(failureText(code), retry = canRetry && code == NETWORK)
/**
* The settings screens' scaffold: [KvittScaffold] plus the one-shot snackbar of [message] (design-spec §3.11:
* `inverse-surface`, 4 s, 10 s with "Försök igen"), drawn at the bottom above the bars. The text is resolved while
* shown, so it follows the app language. [onMessageShown] when it times out or its action is used.
* Shows [message] once in [host] (design-spec §3.11: 4 s, 10 s with "Försök igen") through [showKvittSnackbar], so its
* text follows the app language while it shows. [onMessageShown] when it times out or its action is used; the action
* then runs [onRetry].
*/
@Composable
fun SettingsScaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
message: UiMessage? = null,
onMessageShown: () -> Unit = {},
onRetry: () -> Unit = {},
content: @Composable (PaddingValues) -> Unit,
) {
Box(modifier.fillMaxSize()) {
KvittScaffold(Modifier.fillMaxSize(), topBar = topBar, bottomBar = bottomBar, floatingActionButton = floatingActionButton, content = content)
if (message != null) {
LaunchedEffect(message.id) {
delay(snackbarMillis(message.retry))
onMessageShown()
}
val text = stringResource(message.text, *message.args.toTypedArray())
KvittSnackbar(
text,
Modifier
.align(Alignment.BottomCenter)
.navigationBarsPadding()
.padding(KvittTheme.spacing.s4)
.semantics { liveRegion = LiveRegionMode.Polite },
action = if (message.retry) stringResource(DesignR.string.common_retry) else null,
onAction = {
onMessageShown()
onRetry()
},
)
}
fun SettingsMessageEffect(message: UiMessage?, host: SnackbarHostState, onMessageShown: () -> Unit, onRetry: () -> Unit = {}) {
val resources = LocalResources.current
val shown by rememberUpdatedState(onMessageShown)
val retry by rememberUpdatedState(onRetry)
LaunchedEffect(message?.id) {
if (message == null) return@LaunchedEffect
val result = host.showKvittSnackbar(resources, message.text, message.args, if (message.retry) DesignR.string.common_retry else null)
shown()
if (result == SnackbarResult.ActionPerformed) retry()
}
}
@@ -15,9 +15,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -33,6 +35,7 @@ import se.hagstedt.kvitt.design.component.ConfirmDialog
import se.hagstedt.kvitt.design.component.KvittBadge
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.PersonAvatar
import se.hagstedt.kvitt.design.component.ProvideHousehold
@@ -48,7 +51,7 @@ import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.CentredStatus
import se.hagstedt.kvitt.feature.settings.common.HintText
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.ColorToken
import se.hagstedt.kvitt.model.Device
import se.hagstedt.kvitt.model.User
@@ -73,13 +76,14 @@ class DevicesActions(
/** Stateless S-20. */
@Composable
fun DevicesContent(state: DevicesState?, actions: DevicesActions, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown)
KvittScaffold(
modifier.fillMaxSize(),
topBar = { KvittTopAppBar(stringResource(R.string.settings_devices_title), navigation = TopBarNavigation.Back, onNavigation = actions.onBack) },
message = state?.message,
onMessageShown = actions.onMessageShown,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.me, state.partner) {
Column(
Modifier
@@ -29,6 +29,7 @@ import se.hagstedt.kvitt.design.component.KvittCard
import se.hagstedt.kvitt.design.component.KvittDestination
import se.hagstedt.kvitt.design.component.KvittDivider
import se.hagstedt.kvitt.design.component.KvittNavigationBar
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.PersonAvatar
import se.hagstedt.kvitt.design.component.ProvideHousehold
@@ -38,7 +39,6 @@ import se.hagstedt.kvitt.design.component.syncLineText
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.model.ColorToken
import se.hagstedt.kvitt.model.Role
import se.hagstedt.kvitt.model.User
@@ -77,12 +77,12 @@ class SettingsHubActions(
/** Stateless S-13; [state] null while the session loads (nothing but the bars). */
@Composable
fun SettingsHubContent(state: SettingsHubState?, actions: SettingsHubActions, modifier: Modifier = Modifier) {
SettingsScaffold(
KvittScaffold(
modifier.fillMaxSize(),
topBar = { KvittTopAppBar(stringResource(R.string.settings_title)) },
bottomBar = { KvittNavigationBar(KvittDestination.Settings, actions.onNavigate) },
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.me, state.partner) {
Column(
Modifier
@@ -18,9 +18,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -44,6 +46,7 @@ import se.hagstedt.kvitt.design.component.InviteCodeDisplay
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittCard
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.LocalKvittClock
import se.hagstedt.kvitt.design.component.ProvideHousehold
@@ -58,8 +61,8 @@ import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.HintText
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.OfflineBanner
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.ColorToken
import se.hagstedt.kvitt.model.Invite
import se.hagstedt.kvitt.model.InviteKind
@@ -121,17 +124,17 @@ class InvitesActions(
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun InvitesContent(state: InvitesState?, actions: InvitesActions, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown, actions.onRetry)
KvittScaffold(
modifier.fillMaxSize(),
topBar = {
val title = if (state != null && state.partner == null) stringResource(DesignR.string.common_invite_partner) else stringResource(R.string.settings_invites_title_device)
KvittTopAppBar(title, navigation = TopBarNavigation.Back, onNavigation = actions.onBack)
},
message = state?.message,
onMessageShown = actions.onMessageShown,
onRetry = actions.onRetry,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.me, state.partner) {
Column(
Modifier
@@ -13,9 +13,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -33,6 +35,7 @@ import se.hagstedt.kvitt.design.component.AvatarShape
import se.hagstedt.kvitt.design.component.AvatarState
import se.hagstedt.kvitt.design.component.ButtonKind
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTextField
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.PersonAvatar
@@ -41,11 +44,11 @@ import se.hagstedt.kvitt.design.component.TopBarNavigation
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.OfflineBanner
import se.hagstedt.kvitt.feature.settings.common.SaveAction
import java.io.IOException
import se.hagstedt.kvitt.core.design.R as DesignR
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
/** S-14 Profile. [onBack] after a saved name and on the back arrow. */
@Composable
@@ -105,18 +108,18 @@ class ProfileActions(
/** Stateless S-14. */
@Composable
fun ProfileContent(state: ProfileState?, actions: ProfileActions, modifier: Modifier = Modifier) {
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown, actions.onRetry)
KvittScaffold(
modifier.fillMaxSize(),
topBar = {
KvittTopAppBar(stringResource(R.string.settings_profile), navigation = TopBarNavigation.Back, onNavigation = actions.onBack) {
SaveAction(enabled = state?.canSave == true, onClick = actions.onSave)
}
},
message = state?.message,
onMessageShown = actions.onMessageShown,
onRetry = actions.onRetry,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.me, state.partner) {
Column(
Modifier
@@ -19,6 +19,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
@@ -57,6 +58,7 @@ import se.hagstedt.kvitt.design.component.ExactSplitEditor
import se.hagstedt.kvitt.design.component.FullSplitPicker
import se.hagstedt.kvitt.design.component.KvittButton
import se.hagstedt.kvitt.design.component.KvittIconImage
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTextField
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.NotesField
@@ -79,9 +81,9 @@ import se.hagstedt.kvitt.design.format.KvittLanguage
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.HintText
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.OfflineBanner
import se.hagstedt.kvitt.feature.settings.common.SaveAction
import se.hagstedt.kvitt.feature.settings.common.SettingsMessageEffect
import se.hagstedt.kvitt.model.AccountId
import se.hagstedt.kvitt.model.CategoryId
import se.hagstedt.kvitt.model.SplitMode
@@ -165,7 +167,9 @@ class RecurringEditorActions(
@Composable
fun RecurringEditorContent(state: RecurringEditorState?, actions: RecurringEditorActions, modifier: Modifier = Modifier) {
val keypad = state != null && state.form.focus != EditorFocus.None
SettingsScaffold(
val snackbar = remember { SnackbarHostState() }
SettingsMessageEffect(state?.message, snackbar, actions.onMessageShown, actions.onRetry)
KvittScaffold(
modifier.fillMaxSize(),
topBar = {
val title = if (state?.isNew != false) R.string.settings_recurring_editor_new else R.string.settings_recurring_editor_edit
@@ -176,11 +180,9 @@ fun RecurringEditorContent(state: RecurringEditorState?, actions: RecurringEdito
bottomBar = {
if (keypad) AmountKeypad(actions.onKey, Modifier.navigationBarsPadding(), compact = state.form.splitOpen)
},
message = state?.message,
onMessageShown = actions.onMessageShown,
onRetry = actions.onRetry,
snackbarHostState = snackbar,
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.options.me, state.options.partner) {
EditorBody(state, actions, Modifier.padding(padding))
when (state.sheet) {
@@ -38,6 +38,7 @@ import se.hagstedt.kvitt.design.component.BadgeKind
import se.hagstedt.kvitt.design.component.CategoryTile
import se.hagstedt.kvitt.design.component.EmptyState
import se.hagstedt.kvitt.design.component.KvittBadge
import se.hagstedt.kvitt.design.component.KvittScaffold
import se.hagstedt.kvitt.design.component.KvittTopAppBar
import se.hagstedt.kvitt.design.component.LocalKvittClock
import se.hagstedt.kvitt.design.component.LocalKvittHousehold
@@ -53,7 +54,6 @@ import se.hagstedt.kvitt.design.format.DateFormatter
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
import se.hagstedt.kvitt.feature.settings.R
import se.hagstedt.kvitt.feature.settings.common.SettingsScaffold
import se.hagstedt.kvitt.feature.settings.common.OfflineBanner
import se.hagstedt.kvitt.model.TemplateId
import se.hagstedt.kvitt.core.design.R as DesignR
@@ -77,14 +77,14 @@ class RecurringListActions(val onBack: () -> Unit = {}, val onOpen: (TemplateId)
@Composable
fun RecurringListContent(state: RecurringListState?, actions: RecurringListActions, modifier: Modifier = Modifier) {
val empty = state != null && state.rows.isEmpty()
SettingsScaffold(
KvittScaffold(
modifier.fillMaxSize(),
topBar = { KvittTopAppBar(stringResource(R.string.settings_recurring_title), navigation = TopBarNavigation.Back, onNavigation = actions.onBack) },
floatingActionButton = {
if (state != null && !empty) AddExpenseFab(actions.onNew, text = stringResource(R.string.settings_recurring_new), enabled = state.online)
},
) { padding ->
if (state == null) return@SettingsScaffold
if (state == null) return@KvittScaffold
ProvideHousehold(state.me, state.partner) {
Column(
Modifier