feat: 优化编辑器逻辑及代码 & 优化添加类别对话框样式
This commit is contained in:
parent
29d71fc060
commit
75913080ea
7 changed files with 226 additions and 86 deletions
|
|
@ -43,9 +43,6 @@ fun FilterChipGroup(
|
||||||
defaultSelectedItemIndex: Int = 0,
|
defaultSelectedItemIndex: Int = 0,
|
||||||
onSelectedChanged: (Int) -> Unit = {}
|
onSelectedChanged: (Int) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
SideEffect {
|
|
||||||
Log.d("TAG", "来自 FilterChipGroup:重组啦")
|
|
||||||
}
|
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
var selectedItemIndex by rememberSaveable { mutableIntStateOf(defaultSelectedItemIndex) }
|
var selectedItemIndex by rememberSaveable { mutableIntStateOf(defaultSelectedItemIndex) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,15 @@ package cn.super12138.todo.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.input.TextFieldLineLimits
|
|
||||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
|
||||||
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.outlined.ErrorOutline
|
import androidx.compose.material.icons.outlined.ErrorOutline
|
||||||
import androidx.compose.material.icons.outlined.Info
|
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.OutlinedTextField
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
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.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
|
@ -28,66 +19,6 @@ import androidx.compose.ui.window.DialogProperties
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.utils.VibrationUtils
|
import cn.super12138.todo.utils.VibrationUtils
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun FiveCharPromptDialog(
|
|
||||||
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,
|
|
||||||
onDismiss: () -> Unit
|
|
||||||
) {
|
|
||||||
val textFieldState = rememberTextFieldState()
|
|
||||||
var isError by rememberSaveable { mutableStateOf(false) }
|
|
||||||
|
|
||||||
val supportingText = listOf(
|
|
||||||
stringResource(R.string.tip_max_length_5),
|
|
||||||
stringResource(R.string.error_no_content_entered),
|
|
||||||
stringResource(R.string.error_exceeds_5_chars)
|
|
||||||
)
|
|
||||||
|
|
||||||
var currentSupportingText by remember { mutableStateOf(supportingText[0]) }
|
|
||||||
|
|
||||||
BasicDialog(
|
|
||||||
visible = visible,
|
|
||||||
icon = icon,
|
|
||||||
title = title,
|
|
||||||
text = { // 已经是实现好滚动的Column布局
|
|
||||||
Text(text)
|
|
||||||
OutlinedTextField(
|
|
||||||
state = textFieldState,
|
|
||||||
lineLimits = TextFieldLineLimits.SingleLine,
|
|
||||||
label = { Text(stringResource(R.string.label_enter_sth)) },
|
|
||||||
supportingText = { Text(currentSupportingText) },
|
|
||||||
isError = isError
|
|
||||||
)
|
|
||||||
},
|
|
||||||
confirmButton = confirmButtonText,
|
|
||||||
dismissButton = if (showDismissButton) dismissButtonText else null,
|
|
||||||
onConfirm = {
|
|
||||||
if (textFieldState.text.trim().isEmpty()) {
|
|
||||||
isError = true
|
|
||||||
currentSupportingText = supportingText[1]
|
|
||||||
return@BasicDialog
|
|
||||||
} else if (textFieldState.text.trim().length > 5) {
|
|
||||||
isError = true
|
|
||||||
currentSupportingText = supportingText[2]
|
|
||||||
} else {
|
|
||||||
onSave(textFieldState.text.toString())
|
|
||||||
onDismiss()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDismiss = onDismiss,
|
|
||||||
properties = properties,
|
|
||||||
modifier = modifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ConfirmDialog(
|
fun ConfirmDialog(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.super12138.todo.ui.pages.editor
|
package cn.super12138.todo.ui.pages.editor
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.AnimatedVisibilityScope
|
import androidx.compose.animation.AnimatedVisibilityScope
|
||||||
|
|
@ -33,7 +32,6 @@ import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
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
|
||||||
|
|
@ -48,8 +46,8 @@ import cn.super12138.todo.ui.TodoDefaults
|
||||||
import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
||||||
import cn.super12138.todo.ui.components.ChipItem
|
import cn.super12138.todo.ui.components.ChipItem
|
||||||
import cn.super12138.todo.ui.components.ConfirmDialog
|
import cn.super12138.todo.ui.components.ConfirmDialog
|
||||||
import cn.super12138.todo.ui.components.FilterChipGroup
|
|
||||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||||
|
import cn.super12138.todo.ui.pages.editor.components.TodoCategoryChip
|
||||||
import cn.super12138.todo.ui.pages.editor.components.TodoCategoryTextField
|
import cn.super12138.todo.ui.pages.editor.components.TodoCategoryTextField
|
||||||
import cn.super12138.todo.ui.pages.editor.components.TodoContentTextField
|
import cn.super12138.todo.ui.pages.editor.components.TodoContentTextField
|
||||||
import cn.super12138.todo.ui.pages.editor.components.TodoPrioritySlider
|
import cn.super12138.todo.ui.pages.editor.components.TodoPrioritySlider
|
||||||
|
|
@ -67,6 +65,7 @@ fun TodoEditorPage(
|
||||||
sharedTransitionScope: SharedTransitionScope,
|
sharedTransitionScope: SharedTransitionScope,
|
||||||
animatedVisibilityScope: AnimatedVisibilityScope
|
animatedVisibilityScope: AnimatedVisibilityScope
|
||||||
) {
|
) {
|
||||||
|
// TODO: 本页及其相关组件重组性能检查优化
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
|
|
||||||
|
|
@ -83,6 +82,7 @@ fun TodoEditorPage(
|
||||||
|
|
||||||
var defaultIndex by remember { mutableIntStateOf(0) }
|
var defaultIndex by remember { mutableIntStateOf(0) }
|
||||||
LaunchedEffect(originalCategories, toDo) {
|
LaunchedEffect(originalCategories, toDo) {
|
||||||
|
if (originalCategories.isEmpty()) return@LaunchedEffect
|
||||||
if (toDo == null) {
|
if (toDo == null) {
|
||||||
val index = if (categories.size == 1) -1 else 0
|
val index = if (categories.size == 1) -1 else 0
|
||||||
defaultIndex = index
|
defaultIndex = index
|
||||||
|
|
@ -91,9 +91,7 @@ fun TodoEditorPage(
|
||||||
val index = categories.firstOrNull { it.name == toDo.category }?.id ?: -1
|
val index = categories.firstOrNull { it.name == toDo.category }?.id ?: -1
|
||||||
defaultIndex = index
|
defaultIndex = index
|
||||||
uiState.selectedCategoryIndex = index
|
uiState.selectedCategoryIndex = index
|
||||||
if (index == -1) {
|
if (index != -1) uiState.categoryContent = ""
|
||||||
uiState.categoryContent = toDo.category
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,8 +172,7 @@ fun TodoEditorPage(
|
||||||
value = uiState.toDoContent,
|
value = uiState.toDoContent,
|
||||||
onValueChange = { uiState.toDoContent = it },
|
onValueChange = { uiState.toDoContent = it },
|
||||||
isError = uiState.isErrorContent,
|
isError = uiState.isErrorContent,
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxWidth()
|
||||||
.fillMaxWidth()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,10 +183,11 @@ fun TodoEditorPage(
|
||||||
style = MaterialTheme.typography.titleMedium
|
style = MaterialTheme.typography.titleMedium
|
||||||
)
|
)
|
||||||
|
|
||||||
FilterChipGroup(
|
TodoCategoryChip(
|
||||||
items = categories,
|
items = categories,
|
||||||
defaultSelectedItemIndex = defaultIndex,
|
defaultSelectedItemIndex = defaultIndex,
|
||||||
onSelectedChanged = { uiState.selectedCategoryIndex = it },
|
isLoading = originalCategories.isEmpty(),
|
||||||
|
onCategorySelected = { uiState.selectedCategoryIndex = it },
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package cn.super12138.todo.ui.pages.editor.components
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import cn.super12138.todo.ui.components.ChipItem
|
||||||
|
import cn.super12138.todo.ui.components.FilterChipGroup
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TodoCategoryChip(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
items: List<ChipItem>,
|
||||||
|
defaultSelectedItemIndex: Int,
|
||||||
|
isLoading: Boolean = false,
|
||||||
|
onCategorySelected: (Int) -> Unit
|
||||||
|
) {
|
||||||
|
Box(modifier = modifier.fillMaxWidth()) {
|
||||||
|
AnimatedContent(
|
||||||
|
targetState = isLoading,
|
||||||
|
transitionSpec = { fadeIn(tween(100)) togetherWith fadeOut(tween(100)) }
|
||||||
|
) {
|
||||||
|
if (it) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
} else {
|
||||||
|
FilterChipGroup(
|
||||||
|
modifier = Modifier,
|
||||||
|
items = items,
|
||||||
|
defaultSelectedItemIndex = defaultSelectedItemIndex,
|
||||||
|
onSelectedChanged = onCategorySelected
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,9 +28,9 @@ import androidx.compose.ui.res.stringResource
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.logic.datastore.DataStoreManager
|
import cn.super12138.todo.logic.datastore.DataStoreManager
|
||||||
import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
||||||
import cn.super12138.todo.ui.components.FiveCharPromptDialog
|
|
||||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||||
import cn.super12138.todo.ui.pages.settings.components.SettingsCategory
|
import cn.super12138.todo.ui.pages.settings.components.category.CategoryItem
|
||||||
|
import cn.super12138.todo.ui.pages.settings.components.category.CategoryPromptDialog
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|
@ -39,6 +39,7 @@ fun SettingsDataCategory(
|
||||||
onNavigateUp: () -> Unit,
|
onNavigateUp: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
// TODO: 本页及其相关组件重组性能检查优化
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
@ -77,13 +78,21 @@ fun SettingsDataCategory(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
items(items = categories, key = { it }) {
|
items(items = categories, key = { it }) {
|
||||||
SettingsCategory(it)
|
CategoryItem(
|
||||||
|
name = it,
|
||||||
|
onDelete = { it ->
|
||||||
|
scope.launch {
|
||||||
|
DataStoreManager.setCategories(categories - it)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.animateItem()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FiveCharPromptDialog(
|
CategoryPromptDialog(
|
||||||
visible = showDialog,
|
visible = showDialog,
|
||||||
text = stringResource(R.string.tip_enter_category),
|
text = stringResource(R.string.tip_enter_category),
|
||||||
onSave = {
|
onSave = {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
package cn.super12138.todo.ui.pages.settings.components.category
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
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.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.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
|
||||||
|
import cn.super12138.todo.R
|
||||||
|
import cn.super12138.todo.ui.components.BasicDialog
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
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,
|
||||||
|
onDismiss: () -> Unit
|
||||||
|
) {
|
||||||
|
val textFieldState = rememberTextFieldState()
|
||||||
|
var isError by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val supportingText = listOf(
|
||||||
|
stringResource(R.string.tip_max_length_5),
|
||||||
|
stringResource(R.string.error_no_content_entered),
|
||||||
|
stringResource(R.string.error_exceeds_5_chars)
|
||||||
|
)
|
||||||
|
|
||||||
|
var currentSupportingText by remember { mutableStateOf(supportingText[0]) }
|
||||||
|
|
||||||
|
BasicDialog(
|
||||||
|
visible = visible,
|
||||||
|
icon = icon,
|
||||||
|
title = title,
|
||||||
|
text = {
|
||||||
|
// 已经是实现好滚动的Column布局
|
||||||
|
Text(text)
|
||||||
|
Spacer(Modifier.size(3.dp))
|
||||||
|
OutlinedTextField(
|
||||||
|
state = textFieldState,
|
||||||
|
lineLimits = TextFieldLineLimits.SingleLine,
|
||||||
|
label = { Text(stringResource(R.string.label_enter_sth)) },
|
||||||
|
supportingText = { AnimatedContent(targetState = currentSupportingText) { Text(it) } },
|
||||||
|
isError = isError
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = confirmButtonText,
|
||||||
|
dismissButton = if (showDismissButton) dismissButtonText else null,
|
||||||
|
onConfirm = {
|
||||||
|
val trimmedText = textFieldState.text.trim()
|
||||||
|
when {
|
||||||
|
trimmedText.isEmpty() -> {
|
||||||
|
isError = true
|
||||||
|
currentSupportingText = supportingText[1]
|
||||||
|
return@BasicDialog
|
||||||
|
}
|
||||||
|
|
||||||
|
trimmedText.length > 5 -> {
|
||||||
|
isError = true
|
||||||
|
currentSupportingText = supportingText[2]
|
||||||
|
return@BasicDialog
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
onSave(trimmedText.toString())
|
||||||
|
isError = false
|
||||||
|
currentSupportingText = supportingText[0]
|
||||||
|
textFieldState.clearText()
|
||||||
|
onDismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismiss = onDismiss,
|
||||||
|
properties = properties,
|
||||||
|
modifier = modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package cn.super12138.todo.ui.pages.settings.components.category
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
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
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategoryItem(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
name: String,
|
||||||
|
onDelete: (String) -> Unit = {}
|
||||||
|
) {
|
||||||
|
val view = LocalView.current
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.clip(MaterialTheme.shapes.large)
|
||||||
|
.padding(
|
||||||
|
horizontal = TodoDefaults.settingsItemHorizontalPadding,
|
||||||
|
vertical = TodoDefaults.settingsItemVerticalPadding
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = name,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
style = MaterialTheme.typography.titleLarge.copy(
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
fontSize = 20.sp
|
||||||
|
),
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
VibrationUtils.performHapticFeedback(view)
|
||||||
|
onDelete(name)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = stringResource(R.string.action_delete)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue