feat(shift): undoable reset-to-default via Snackbar

恢复默认改为 Snackbar 撤销模式:
- 点恢复默认立即生效 + 显示 5 秒"撤销"Snackbar
- 点撤销恢复之前的 pattern
- 删除 AlertDialog 确认框(更现代,防误操作)
- 首次在项目引入 SnackbarHost
This commit is contained in:
xfy 2026-07-09 16:38:57 +08:00
parent 4b098442c4
commit c68944bd55

View File

@ -13,7 +13,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronLeft import androidx.compose.material.icons.filled.ChevronLeft
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DatePicker import androidx.compose.material3.DatePicker
@ -25,6 +24,10 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
@ -34,6 +37,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -42,6 +46,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone import kotlinx.datetime.TimeZone
import kotlinx.coroutines.launch
import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.atStartOfDayIn
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
import plus.rua.project.CalendarViewModel import plus.rua.project.CalendarViewModel
@ -73,7 +78,8 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
LaunchedEffect(pattern) { storage.save(pattern) } LaunchedEffect(pattern) { storage.save(pattern) }
var showAnchorPicker by remember { mutableStateOf(false) } var showAnchorPicker by remember { mutableStateOf(false) }
var showResetDialog by remember { mutableStateOf(false) } val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold( Scaffold(
topBar = { topBar = {
@ -85,7 +91,8 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
} }
} }
) )
} },
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
) { padding -> ) { padding ->
Column( Column(
modifier = Modifier modifier = Modifier
@ -167,7 +174,20 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
) )
OutlinedButton( OutlinedButton(
onClick = { showResetDialog = true }, onClick = {
val previous = pattern
pattern = CalendarViewModel.DEFAULT_PATTERN
scope.launch {
val result = snackbarHostState.showSnackbar(
message = "已恢复默认设置",
actionLabel = "撤销",
duration = SnackbarDuration.Short
)
if (result == SnackbarResult.ActionPerformed) {
pattern = previous
}
}
},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text("恢复默认") Text("恢复默认")
@ -194,23 +214,6 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
DatePicker(state = state) DatePicker(state = state)
} }
} }
if (showResetDialog) {
AlertDialog(
onDismissRequest = { showResetDialog = false },
title = { Text("恢复默认") },
text = { Text("将清空所有调班与断点设置,恢复为 2 班 2 休。确认?") },
confirmButton = {
TextButton(onClick = {
pattern = CalendarViewModel.DEFAULT_PATTERN
showResetDialog = false
}) { Text("确定") }
},
dismissButton = {
TextButton(onClick = { showResetDialog = false }) { Text("取消") }
}
)
}
} }
private fun LocalDate.toEpochMillis(): Long = private fun LocalDate.toEpochMillis(): Long =