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.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronLeft
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DatePicker
@ -25,6 +24,10 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
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.TextButton
import androidx.compose.material3.TopAppBar
@ -34,6 +37,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -42,6 +46,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.coroutines.launch
import kotlinx.datetime.atStartOfDayIn
import kotlinx.datetime.toLocalDateTime
import plus.rua.project.CalendarViewModel
@ -73,7 +78,8 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
LaunchedEffect(pattern) { storage.save(pattern) }
var showAnchorPicker by remember { mutableStateOf(false) }
var showResetDialog by remember { mutableStateOf(false) }
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
topBar = {
@ -85,7 +91,8 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
}
}
)
}
},
snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
) { padding ->
Column(
modifier = Modifier
@ -167,7 +174,20 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
)
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()
) {
Text("恢复默认")
@ -194,23 +214,6 @@ fun ShiftPatternScreen(onBack: () -> Unit) {
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 =