feat: 支持在分类管理页面修改已有分类
This commit is contained in:
parent
839b2a02e1
commit
b92a62e57f
3 changed files with 59 additions and 34 deletions
|
|
@ -47,13 +47,14 @@ fun SettingsDataCategory(
|
|||
modifier: Modifier = Modifier
|
||||
) {
|
||||
// TODO: 本页及其相关组件重组性能检查优化
|
||||
// TODO: 优化内部项目样式
|
||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
var initialCategory by rememberSaveable { mutableStateOf("") }
|
||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
val categories by DataStoreManager.categoriesFlow.collectAsState(initial = emptyList())
|
||||
|
||||
val isExpanded by remember { derivedStateOf { listState.firstVisibleItemIndex == 0 } }
|
||||
|
|
@ -68,7 +69,10 @@ fun SettingsDataCategory(
|
|||
icon = Icons.Outlined.Add,
|
||||
text = stringResource(R.string.action_add_category),
|
||||
expanded = isExpanded,
|
||||
onClick = { showDialog = true }
|
||||
onClick = {
|
||||
initialCategory = ""
|
||||
showDialog = true
|
||||
}
|
||||
)
|
||||
},
|
||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
|
|
@ -92,8 +96,12 @@ fun SettingsDataCategory(
|
|||
items(items = categories, key = { it }) {
|
||||
CategoryItem(
|
||||
name = it,
|
||||
onDelete = { it ->
|
||||
scope.launch { DataStoreManager.setCategories(categories - it) }
|
||||
onClick = { category ->
|
||||
initialCategory = category
|
||||
showDialog = true
|
||||
},
|
||||
onDelete = { category ->
|
||||
scope.launch { DataStoreManager.setCategories(categories - category) }
|
||||
},
|
||||
modifier = Modifier.animateItem(
|
||||
fadeInSpec = tween(100),
|
||||
|
|
@ -110,20 +118,29 @@ fun SettingsDataCategory(
|
|||
|
||||
CategoryPromptDialog(
|
||||
visible = showDialog,
|
||||
text = stringResource(R.string.tip_enter_category),
|
||||
onSave = {
|
||||
if (!categories.contains(it)) {
|
||||
scope.launch {
|
||||
DataStoreManager.setCategories(categories + it)
|
||||
}
|
||||
} else {
|
||||
scope.launch {
|
||||
/*snackbarHostState.showSnackbar(
|
||||
initialCategory = initialCategory,
|
||||
onSave = { oldCategory, newCategory ->
|
||||
if (oldCategory.isEmpty()) {
|
||||
if (!categories.contains(newCategory)) {
|
||||
scope.launch {
|
||||
DataStoreManager.setCategories(categories + newCategory)
|
||||
}
|
||||
} else {
|
||||
scope.launch {
|
||||
/*snackbarHostState.showSnackbar(
|
||||
message = context.getString(R.string.error_category_duplicate)
|
||||
)*/
|
||||
// 调换分类位置
|
||||
val tempList = categories - it
|
||||
DataStoreManager.setCategories(tempList + it)
|
||||
// 调换分类位置
|
||||
val tempList = categories - newCategory
|
||||
DataStoreManager.setCategories(tempList + newCategory)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (oldCategory != newCategory) {
|
||||
scope.launch {
|
||||
val tempList = categories - oldCategory
|
||||
DataStoreManager.setCategories(tempList + newCategory)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,18 +6,19 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.text.input.TextFieldLineLimits
|
||||
import androidx.compose.foundation.text.input.clearText
|
||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
|
|
@ -28,19 +29,20 @@ import cn.super12138.todo.ui.components.BasicDialog
|
|||
fun CategoryPromptDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
visible: Boolean,
|
||||
icon: ImageVector = Icons.Outlined.Info,
|
||||
title: String = stringResource(R.string.tip_tips),
|
||||
text: String,
|
||||
confirmButtonText: String = stringResource(R.string.action_save),
|
||||
showDismissButton: Boolean = true,
|
||||
dismissButtonText: String = stringResource(R.string.action_cancel),
|
||||
properties: DialogProperties = DialogProperties(),
|
||||
onSave: (String) -> Unit,
|
||||
initialCategory: String = "",
|
||||
onSave: (oldValue: String, newValue: String) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val textFieldState = rememberTextFieldState()
|
||||
val textFieldState = rememberTextFieldState(initialText = initialCategory)
|
||||
var isError by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(visible) {
|
||||
if (visible) {
|
||||
textFieldState.setTextAndPlaceCursorAtEnd(initialCategory)
|
||||
isError = false
|
||||
}
|
||||
}
|
||||
|
||||
val supportingText = listOf(
|
||||
stringResource(R.string.tip_max_length_5),
|
||||
stringResource(R.string.error_no_content_entered),
|
||||
|
|
@ -51,11 +53,11 @@ fun CategoryPromptDialog(
|
|||
|
||||
BasicDialog(
|
||||
visible = visible,
|
||||
icon = icon,
|
||||
title = title,
|
||||
icon = Icons.Outlined.Info,
|
||||
title = stringResource(R.string.tip_tips),
|
||||
text = {
|
||||
// 已经是实现好滚动的Column布局
|
||||
Text(text)
|
||||
Text(stringResource(R.string.tip_enter_category))
|
||||
Spacer(Modifier.size(3.dp))
|
||||
OutlinedTextField(
|
||||
state = textFieldState,
|
||||
|
|
@ -65,8 +67,8 @@ fun CategoryPromptDialog(
|
|||
isError = isError
|
||||
)
|
||||
},
|
||||
confirmButton = confirmButtonText,
|
||||
dismissButton = if (showDismissButton) dismissButtonText else null,
|
||||
confirmButton = stringResource(R.string.action_save),
|
||||
dismissButton = stringResource(R.string.action_cancel),
|
||||
onConfirm = {
|
||||
val trimmedText = textFieldState.text.trim()
|
||||
when {
|
||||
|
|
@ -83,7 +85,7 @@ fun CategoryPromptDialog(
|
|||
}
|
||||
|
||||
else -> {
|
||||
onSave(trimmedText.toString())
|
||||
onSave(initialCategory, trimmedText.toString())
|
||||
isError = false
|
||||
currentSupportingText = supportingText[0]
|
||||
textFieldState.clearText()
|
||||
|
|
@ -92,7 +94,7 @@ fun CategoryPromptDialog(
|
|||
}
|
||||
},
|
||||
onDismiss = onDismiss,
|
||||
properties = properties,
|
||||
properties = DialogProperties(),
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.sp
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.ui.TodoDefaults
|
||||
import cn.super12138.todo.utils.VibrationUtils
|
||||
|
|
@ -27,6 +26,7 @@ import cn.super12138.todo.utils.VibrationUtils
|
|||
fun CategoryItem(
|
||||
modifier: Modifier = Modifier,
|
||||
name: String,
|
||||
onClick: (String) -> Unit = {},
|
||||
onDelete: (String) -> Unit = {}
|
||||
) {
|
||||
val view = LocalView.current
|
||||
|
|
@ -35,6 +35,12 @@ fun CategoryItem(
|
|||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.clip(MaterialTheme.shapes.large)
|
||||
.clickable(
|
||||
onClick = {
|
||||
VibrationUtils.performHapticFeedback(view)
|
||||
onClick(name)
|
||||
}
|
||||
)
|
||||
.padding(
|
||||
horizontal = TodoDefaults.settingsItemHorizontalPadding,
|
||||
vertical = TodoDefaults.settingsItemVerticalPadding / 2
|
||||
|
|
|
|||
Loading…
Reference in a new issue