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:
+9
-5
@@ -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
|
||||
|
||||
+9
-5
@@ -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(
|
||||
|
||||
+8
-5
@@ -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()
|
||||
|
||||
+18
-51
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -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
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
+9
-6
@@ -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
|
||||
|
||||
+9
-6
@@ -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
|
||||
|
||||
+8
-6
@@ -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) {
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user