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,7 +15,6 @@ 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.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -27,6 +26,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.LiveRegionMode
@@ -46,6 +46,7 @@ import se.hagstedt.kvitt.design.component.InviteCodeField
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.showKvittSnackbar
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
@@ -113,14 +114,15 @@ fun PairingContent(
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
) {
val snackbarText = when (state.error) {
PairingError.AppTooOld -> stringResource(DesignR.string.error_app_too_old)
PairingError.Server -> stringResource(DesignR.string.error_server)
PairingError.Validation -> stringResource(DesignR.string.error_validation)
PairingError.AppTooOld -> DesignR.string.error_app_too_old
PairingError.Server -> DesignR.string.error_server
PairingError.Validation -> DesignR.string.error_validation
else -> null
}
val resources = LocalResources.current
LaunchedEffect(snackbarText) {
if (snackbarText != null) {
snackbarHostState.showSnackbar(snackbarText, duration = SnackbarDuration.Short)
snackbarHostState.showKvittSnackbar(resources, snackbarText)
actions.onErrorShown()
}
}
@@ -22,7 +22,6 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -33,6 +32,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
@@ -60,6 +60,7 @@ import se.hagstedt.kvitt.design.component.NeedsConnectionHint
import se.hagstedt.kvitt.design.component.PersonAvatar
import se.hagstedt.kvitt.design.component.ProvideHousehold
import se.hagstedt.kvitt.design.component.kvittLanguage
import se.hagstedt.kvitt.design.component.showKvittSnackbar
import se.hagstedt.kvitt.design.format.KvittLanguage
import se.hagstedt.kvitt.design.icon.KvittIcon
import se.hagstedt.kvitt.design.theme.KvittDimens
@@ -130,10 +131,11 @@ fun ProfileStepContent(
modifier: Modifier = Modifier,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
) {
val message = state.message?.let { stringResource(it.text) }
val message = state.message?.text
val resources = LocalResources.current
LaunchedEffect(message) {
if (message != null) {
snackbarHostState.showSnackbar(message, duration = SnackbarDuration.Short)
snackbarHostState.showKvittSnackbar(resources, message)
actions.onMessageShown()
}
}
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text
@@ -22,6 +21,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@@ -43,6 +43,7 @@ import se.hagstedt.kvitt.design.component.NeedsConnectionHint
import se.hagstedt.kvitt.design.component.ProvideHousehold
import se.hagstedt.kvitt.design.component.SegmentedGroup
import se.hagstedt.kvitt.design.component.kvittLanguage
import se.hagstedt.kvitt.design.component.showKvittSnackbar
import se.hagstedt.kvitt.design.format.DateFormatter
import se.hagstedt.kvitt.design.icon.KvittIcon
import kotlin.time.Instant
@@ -83,12 +84,12 @@ fun WaitingContent(
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
) {
val error = state.loadError?.let {
stringResource(if (it == "network") DesignR.string.common_could_not_reach_server else DesignR.string.error_server)
if (it == "network") DesignR.string.common_could_not_reach_server else DesignR.string.error_server
}
val retry = stringResource(DesignR.string.common_retry)
val resources = LocalResources.current
LaunchedEffect(error) {
if (error != null) {
val result = snackbarHostState.showSnackbar(error, actionLabel = retry, duration = SnackbarDuration.Long)
val result = snackbarHostState.showKvittSnackbar(resources, error, action = DesignR.string.common_retry)
actions.onErrorShown()
if (result == SnackbarResult.ActionPerformed) actions.onRetry()
}