feat: 优化分类列表项和编辑器页面的显示效果
优化语言表述 优化添加重复分类时的处理方案
This commit is contained in:
parent
75913080ea
commit
88d4132c99
7 changed files with 69 additions and 45 deletions
|
|
@ -80,7 +80,7 @@ fun TodoEditorPage(
|
||||||
)
|
)
|
||||||
} + ChipItem(id = -1, name = "自定义")
|
} + ChipItem(id = -1, name = "自定义")
|
||||||
|
|
||||||
var defaultIndex by remember { mutableIntStateOf(0) }
|
var defaultIndex by remember { mutableIntStateOf(-1) }
|
||||||
LaunchedEffect(originalCategories, toDo) {
|
LaunchedEffect(originalCategories, toDo) {
|
||||||
if (originalCategories.isEmpty()) return@LaunchedEffect
|
if (originalCategories.isEmpty()) return@LaunchedEffect
|
||||||
if (toDo == null) {
|
if (toDo == null) {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
package cn.super12138.todo.ui.pages.editor.components
|
package cn.super12138.todo.ui.pages.editor.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.foundation.layout.Column
|
||||||
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.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.ui.components.ChipItem
|
import cn.super12138.todo.ui.components.ChipItem
|
||||||
import cn.super12138.todo.ui.components.FilterChipGroup
|
import cn.super12138.todo.ui.components.FilterChipGroup
|
||||||
|
|
||||||
|
|
@ -21,21 +20,23 @@ fun TodoCategoryChip(
|
||||||
isLoading: Boolean = false,
|
isLoading: Boolean = false,
|
||||||
onCategorySelected: (Int) -> Unit
|
onCategorySelected: (Int) -> Unit
|
||||||
) {
|
) {
|
||||||
Box(modifier = modifier.fillMaxWidth()) {
|
Column(modifier = modifier.fillMaxWidth()) {
|
||||||
AnimatedContent(
|
if (isLoading) {
|
||||||
targetState = isLoading,
|
Text(
|
||||||
transitionSpec = { fadeIn(tween(100)) togetherWith fadeOut(tween(100)) }
|
text = stringResource(R.string.tip_no_category_chip),
|
||||||
) {
|
style = MaterialTheme.typography.labelLarge.copy(
|
||||||
if (it) {
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
CircularProgressIndicator()
|
),
|
||||||
} else {
|
textAlign = TextAlign.Center,
|
||||||
FilterChipGroup(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
modifier = Modifier,
|
)
|
||||||
items = items,
|
|
||||||
defaultSelectedItemIndex = defaultSelectedItemIndex,
|
|
||||||
onSelectedChanged = onCategorySelected
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilterChipGroup(
|
||||||
|
modifier = Modifier,
|
||||||
|
items = items,
|
||||||
|
defaultSelectedItemIndex = defaultSelectedItemIndex,
|
||||||
|
onSelectedChanged = onCategorySelected
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ import cn.super12138.todo.logic.database.TodoEntity
|
||||||
class EditorState(val initialTodo: TodoEntity? = null) {
|
class EditorState(val initialTodo: TodoEntity? = null) {
|
||||||
var toDoContent by mutableStateOf(initialTodo?.content ?: "")
|
var toDoContent by mutableStateOf(initialTodo?.content ?: "")
|
||||||
var isErrorContent by mutableStateOf(false)
|
var isErrorContent by mutableStateOf(false)
|
||||||
var selectedCategoryIndex by mutableIntStateOf(0)
|
var selectedCategoryIndex by mutableIntStateOf(-1)
|
||||||
var categoryContent by mutableStateOf(initialTodo?.category ?: "")
|
var categoryContent by mutableStateOf(initialTodo?.category ?: "")
|
||||||
var isErrorCategory by mutableStateOf(false)
|
var isErrorCategory by mutableStateOf(false)
|
||||||
var priorityState by mutableFloatStateOf(initialTodo?.priority ?: 0f)
|
var priorityState by mutableFloatStateOf(initialTodo?.priority ?: 0f)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
package cn.super12138.todo.ui.pages.settings
|
package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.Spring
|
||||||
|
import androidx.compose.animation.core.VisibilityThreshold
|
||||||
|
import androidx.compose.animation.core.spring
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
|
@ -8,6 +13,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Add
|
import androidx.compose.material.icons.outlined.Add
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -23,8 +29,9 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.IntOffset
|
||||||
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
|
||||||
|
|
@ -44,7 +51,6 @@ fun SettingsDataCategory(
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
val categories by DataStoreManager.categoriesFlow.collectAsState(initial = emptyList())
|
val categories by DataStoreManager.categoriesFlow.collectAsState(initial = emptyList())
|
||||||
|
|
@ -74,18 +80,28 @@ fun SettingsDataCategory(
|
||||||
) {
|
) {
|
||||||
if (categories.isEmpty()) {
|
if (categories.isEmpty()) {
|
||||||
item {
|
item {
|
||||||
Text("空")
|
Text(
|
||||||
|
text = stringResource(R.string.tip_no_category_page),
|
||||||
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
items(items = categories, key = { it }) {
|
items(items = categories, key = { it }) {
|
||||||
CategoryItem(
|
CategoryItem(
|
||||||
name = it,
|
name = it,
|
||||||
onDelete = { it ->
|
onDelete = { it ->
|
||||||
scope.launch {
|
scope.launch { DataStoreManager.setCategories(categories - it) }
|
||||||
DataStoreManager.setCategories(categories - it)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
modifier = Modifier.animateItem()
|
modifier = Modifier.animateItem(
|
||||||
|
fadeInSpec = tween(100),
|
||||||
|
placementSpec = spring(
|
||||||
|
stiffness = Spring.StiffnessMediumLow,
|
||||||
|
visibilityThreshold = IntOffset.VisibilityThreshold
|
||||||
|
),
|
||||||
|
fadeOutSpec = tween(100)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,9 +118,12 @@ fun SettingsDataCategory(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
snackbarHostState.showSnackbar(
|
/*snackbarHostState.showSnackbar(
|
||||||
message = context.getString(R.string.error_category_duplicate)
|
message = context.getString(R.string.error_category_duplicate)
|
||||||
)
|
)*/
|
||||||
|
// 调换分类位置
|
||||||
|
val tempList = categories - it
|
||||||
|
DataStoreManager.setCategories(tempList + it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.super12138.todo.ui.pages.settings.components.category
|
package cn.super12138.todo.ui.pages.settings.components.category
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -36,7 +37,7 @@ fun CategoryItem(
|
||||||
.clip(MaterialTheme.shapes.large)
|
.clip(MaterialTheme.shapes.large)
|
||||||
.padding(
|
.padding(
|
||||||
horizontal = TodoDefaults.settingsItemHorizontalPadding,
|
horizontal = TodoDefaults.settingsItemHorizontalPadding,
|
||||||
vertical = TodoDefaults.settingsItemVerticalPadding
|
vertical = TodoDefaults.settingsItemVerticalPadding / 2
|
||||||
),
|
),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
|
|
@ -44,9 +45,8 @@ fun CategoryItem(
|
||||||
text = name,
|
text = name,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
style = MaterialTheme.typography.titleLarge.copy(
|
style = MaterialTheme.typography.bodyLarge.copy(
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
fontSize = 20.sp
|
|
||||||
),
|
),
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
<string name="pref_developer">开发者</string>
|
<string name="pref_developer">开发者</string>
|
||||||
<string name="pref_licence">开放源代码许可</string>
|
<string name="pref_licence">开放源代码许可</string>
|
||||||
<string name="pref_licence_desc">查看应用使用的开源库及其许可</string>
|
<string name="pref_licence_desc">查看应用使用的开源库及其许可</string>
|
||||||
<string name="label_category">类别</string>
|
<string name="label_category">分类</string>
|
||||||
<string name="priority_not_urgent">不紧急</string>
|
<string name="priority_not_urgent">不紧急</string>
|
||||||
<string name="priority_not_important">不重要</string>
|
<string name="priority_not_important">不重要</string>
|
||||||
<string name="priority_default">默认</string>
|
<string name="priority_default">默认</string>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
<string name="pref_view_on_github_desc">查看源代码、提交错误报告和改进建议</string>
|
<string name="pref_view_on_github_desc">查看源代码、提交错误报告和改进建议</string>
|
||||||
<string name="tip_discard_changes">退出编辑后将无法找回你修改过的数据。确定退出编辑吗?</string>
|
<string name="tip_discard_changes">退出编辑后将无法找回你修改过的数据。确定退出编辑吗?</string>
|
||||||
<string name="sorting_sequential">添加先后顺序</string>
|
<string name="sorting_sequential">添加先后顺序</string>
|
||||||
<string name="sorting_category">类别</string>
|
<string name="sorting_category">分类</string>
|
||||||
<string name="sorting_priority">优先级</string>
|
<string name="sorting_priority">优先级</string>
|
||||||
<string name="sorting_completion">完成状态</string>
|
<string name="sorting_completion">完成状态</string>
|
||||||
<string name="sorting_alphabetical_ascending">首字母(升序)</string>
|
<string name="sorting_alphabetical_ascending">首字母(升序)</string>
|
||||||
|
|
@ -96,16 +96,18 @@
|
||||||
<string name="pref_secure_mode">安全模式</string>
|
<string name="pref_secure_mode">安全模式</string>
|
||||||
<string name="pref_secure_mode_desc">阻止截屏并保护后台预览图</string>
|
<string name="pref_secure_mode_desc">阻止截屏并保护后台预览图</string>
|
||||||
<string name="label_more">更多</string>
|
<string name="label_more">更多</string>
|
||||||
<string name="label_enter_category_name">输入类别名称</string>
|
<string name="label_enter_category_name">输入分类名称</string>
|
||||||
<string name="accessibility_progress_tasks">当前共有 %1$d 项任务,其中 %2$d 项已完成,%3$d 项未完成</string>
|
<string name="accessibility_progress_tasks">当前共有 %1$d 项任务,其中 %2$d 项已完成,%3$d 项未完成</string>
|
||||||
<string name="accessibility_progress_no_tasks">当前没有任务</string>
|
<string name="accessibility_progress_no_tasks">当前没有任务</string>
|
||||||
<string name="pref_category_category_management">类别管理</string>
|
<string name="pref_category_category_management">分类管理</string>
|
||||||
<string name="pref_category_data_management">数据管理</string>
|
<string name="pref_category_data_management">数据管理</string>
|
||||||
<string name="pref_category_management_desc">管理任务的类别标签</string>
|
<string name="pref_category_management_desc">管理任务的分类标签</string>
|
||||||
<string name="action_add_category">添加类别</string>
|
<string name="action_add_category">添加分类</string>
|
||||||
<string name="label_enter_sth">输入内容</string>
|
<string name="label_enter_sth">输入内容</string>
|
||||||
<string name="tip_max_length_5">不超过 5 个字</string>
|
<string name="tip_max_length_5">不超过 5 个字</string>
|
||||||
<string name="error_exceeds_5_chars">超过 5 个字</string>
|
<string name="error_exceeds_5_chars">超过 5 个字</string>
|
||||||
<string name="tip_enter_category">输入你想添加的类别</string>
|
<string name="tip_enter_category">输入你想添加的分类名称</string>
|
||||||
<string name="error_category_duplicate">该类别已经存在</string>
|
<!--<string name="error_category_duplicate">该分类已经存在</string>-->
|
||||||
|
<string name="tip_no_category_chip">当前暂无自定义分类,你可以在设置中添加分类</string>
|
||||||
|
<string name="tip_no_category_page">当前暂无自定义分类</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -108,5 +108,7 @@
|
||||||
<string name="tip_max_length_5">Up to 5 characters</string>
|
<string name="tip_max_length_5">Up to 5 characters</string>
|
||||||
<string name="error_exceeds_5_chars">Exceeds 5 characters</string>
|
<string name="error_exceeds_5_chars">Exceeds 5 characters</string>
|
||||||
<string name="tip_enter_category">Enter the category you want to add</string>
|
<string name="tip_enter_category">Enter the category you want to add</string>
|
||||||
<string name="error_category_duplicate">The category is duplicate</string>
|
<!--<string name="error_category_duplicate">The category is duplicate</string>-->
|
||||||
|
<string name="tip_no_category_chip">There are currently no custom categories. You can add categories in the settings.</string>
|
||||||
|
<string name="tip_no_category_page">There are no custom categories at the moment.</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in a new issue