feat: 将按钮和进度条进行 MD3E 改造

This commit is contained in:
Super12138 2025-11-08 08:21:59 +08:00
parent 96fdb86e91
commit e7b75aadce
12 changed files with 195 additions and 163 deletions

View file

@ -113,7 +113,9 @@ dependencies {
implementation(libs.aboutlibraries.core)
implementation(libs.aboutlibraries.compose)
// M3 Color
implementation(libs.com.kyant0.m3color)
implementation(libs.kyant0.m3color)
// Capsule
implementation(libs.kyant0.capsule)
// Konfetti
implementation(libs.nl.dionsegijn.konfetti.compose)
// Lazy Column Scrollbar

View file

@ -17,9 +17,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalView
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.utils.VibrationUtils
import com.kyant.capsule.ContinuousRoundedRectangle
@Composable
fun ConfirmDialog(
@ -87,7 +89,10 @@ fun BasicDialog(
VibrationUtils.performHapticFeedback(view)
onConfirm()
},
shapes = ButtonDefaults.shapes()
shapes = ButtonDefaults.shapes(
/*shape = ContinuousRoundedRectangle(50.dp),
pressedShape = ContinuousRoundedRectangle(12.dp)*/
)
) {
Text(confirmButton)
}

View file

@ -1,14 +1,9 @@
package cn.super12138.todo.ui.pages.main
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
@ -24,6 +19,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.animateFloatingActionButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
@ -32,12 +28,12 @@ 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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.window.core.layout.WindowWidthSizeClass
import androidx.window.core.layout.WindowSizeClass
import cn.super12138.todo.R
import cn.super12138.todo.constants.Constants
import cn.super12138.todo.logic.database.TodoEntity
import cn.super12138.todo.logic.datastore.DataStoreManager
import cn.super12138.todo.ui.components.ConfirmDialog
import cn.super12138.todo.ui.pages.main.components.TodoTopAppBar
@ -46,17 +42,17 @@ import cn.super12138.todo.ui.viewmodels.MainViewModel
@OptIn(ExperimentalSharedTransitionApi::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun MainPage(
modifier: Modifier = Modifier,
viewModel: MainViewModel,
toTodoEditPage: () -> Unit,
toSettingsPage: () -> Unit,
sharedTransitionScope: SharedTransitionScope,
animatedVisibilityScope: AnimatedVisibilityScope,
modifier: Modifier = Modifier
windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,
) {
val toDos = viewModel.sortedTodos.collectAsState(initial = emptyList())
val selectedTodos = viewModel.selectedTodoIds.collectAsState()
val showCompleted by DataStoreManager.showCompletedFlow.collectAsState(initial = Constants.PREF_SHOW_COMPLETED_DEFAULT)
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val listState = rememberLazyListState()
var showDeleteConfirmDialog by rememberSaveable { mutableStateOf(false) }
@ -86,99 +82,37 @@ fun MainPage(
},
floatingActionButton = {
with(sharedTransitionScope) {
AnimatedVisibility(
visible = !inSelectedMode,
enter = fadeIn() + expandIn(),
exit = shrinkOut() + fadeOut()
) {
// TODO: 修复在滑动列表时FAB位移导致的动画不连贯临时方案为底部加padding
/*AnimatedExtendedFloatingActionButton(
icon = Icons.Outlined.Add,
text = stringResource(R.string.action_add_task),
expanded = true,
onClick = {
viewModel.setEditTodoItem(null) // 每次添加待办前清除上一次已选待办
toTodoEditPage()
},
modifier = Modifier.sharedElement(
SmallExtendedFloatingActionButton(
text = { Text(stringResource(R.string.action_add_task)) },
icon = {
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = null
)
},
expanded = expandedFab,
onClick = {
viewModel.setEditTodoItem(null) // 每次添加待办前清除上一次已选待办
toTodoEditPage()
},
modifier = Modifier
.sharedElement(
sharedContentState = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
animatedVisibilityScope = animatedVisibilityScope
)
)*/
SmallExtendedFloatingActionButton(
text = { Text(stringResource(R.string.action_add_task)) },
icon = {
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = null
)
},
expanded = expandedFab,
onClick = {
viewModel.setEditTodoItem(null) // 每次添加待办前清除上一次已选待办
toTodoEditPage()
},
modifier = Modifier.sharedElement(
sharedContentState = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
animatedVisibilityScope = animatedVisibilityScope
.animateFloatingActionButton(
visible = !inSelectedMode,
alignment = Alignment.BottomEnd,
)
)
}
)
}
},
contentWindowInsets = WindowInsets(0, 0, 0, 0),
modifier = modifier
) { innerPadding ->
if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.COMPACT) {
Column(
modifier = Modifier.padding(
top = innerPadding.calculateTopPadding(),
bottom = innerPadding.calculateBottomPadding()
)
) {
ProgressFragment(
totalTasks = totalTasks,
completedTasks = completedTasks,
modifier = Modifier
.weight(2f)
.fillMaxSize()
)
ManagerFragment(
state = listState,
list = filteredTodoList,
onItemClick = { item ->
if (inSelectedMode) {
viewModel.toggleTodoSelection(item)
} else {
viewModel.setEditTodoItem(item)
toTodoEditPage()
}
},
onItemLongClick = { viewModel.toggleTodoSelection(it) },
onItemChecked = { item ->
item.apply {
viewModel.updateTodo(
TodoEntity(
content = content,
category = category,
isCompleted = true,
priority = priority,
id = id
)
)
viewModel.playConfetti()
}
},
selectedTodoIds = selectedTodoIds,
// sharedTransitionScope = sharedTransitionScope,
// animatedVisibilityScope = animatedVisibilityScope,
modifier = Modifier
.weight(3f)
.fillMaxSize()
)
}
} else {
val isMediumScreen =
windowSizeClass.isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND)
if (isMediumScreen) {
Row(
modifier = Modifier.padding(
top = innerPadding.calculateTopPadding(),
@ -204,20 +138,48 @@ fun MainPage(
}
},
onItemLongClick = { viewModel.toggleTodoSelection(it) },
onItemChecked = { item ->
item.apply {
viewModel.updateTodo(
TodoEntity(
content = content,
category = category,
isCompleted = true,
priority = priority,
id = id
)
)
viewModel.playConfetti()
onItemChecked = {
viewModel.updateTodo(it.copy(isCompleted = true))
viewModel.playConfetti()
},
selectedTodoIds = selectedTodoIds,
// sharedTransitionScope = sharedTransitionScope,
// animatedVisibilityScope = animatedVisibilityScope,
modifier = Modifier
.weight(3f)
.fillMaxSize()
)
}
} else {
Column(
modifier = Modifier.padding(
top = innerPadding.calculateTopPadding(),
bottom = innerPadding.calculateBottomPadding()
)
) {
ProgressFragment(
totalTasks = totalTasks,
completedTasks = completedTasks,
modifier = Modifier
.weight(2f)
.fillMaxSize()
)
ManagerFragment(
state = listState,
list = filteredTodoList,
onItemClick = { item ->
if (inSelectedMode) {
viewModel.toggleTodoSelection(item)
} else {
viewModel.setEditTodoItem(item)
toTodoEditPage()
}
},
onItemLongClick = { viewModel.toggleTodoSelection(it) },
onItemChecked = {
viewModel.updateTodo(it.copy(isCompleted = true))
viewModel.playConfetti()
},
selectedTodoIds = selectedTodoIds,
// sharedTransitionScope = sharedTransitionScope,
// animatedVisibilityScope = animatedVisibilityScope,

View file

@ -45,6 +45,14 @@ fun ManagerFragment(
bottom = TodoDefaults.toDoCardHeight / 2,
end = TodoDefaults.screenPadding
),
/*modifier = Modifier
.clip(
MaterialTheme.shapes.extraLarge.copy(
bottomEnd = CornerSize(0.dp),
bottomStart = CornerSize(0.dp)
)
)
.background(MaterialTheme.colorScheme.surfaceContainerHighest)*/
// verticalArrangement = Arrangement.spacedBy(10.dp)
) {
if (list.isEmpty()) {

View file

@ -1,7 +1,9 @@
package cn.super12138.todo.ui.pages.settings
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
@ -10,6 +12,8 @@ import androidx.compose.material.icons.outlined.DeveloperMode
import androidx.compose.material.icons.outlined.Numbers
import androidx.compose.material.icons.outlined.Person4
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@ -19,19 +23,22 @@ import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import cn.super12138.todo.R
import cn.super12138.todo.constants.Constants
import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.icons.GitHubIcon
import cn.super12138.todo.ui.pages.settings.components.SettingsItem
import cn.super12138.todo.utils.SystemUtils
import kotlinx.coroutines.delay
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SettingsAbout(
//toSpecialPage: () -> Unit,
@ -51,9 +58,12 @@ fun SettingsAbout(
val uriHandler = LocalUriHandler.current
LazyColumn(
verticalArrangement = Arrangement.spacedBy(2.dp),
modifier = Modifier
.fillMaxSize()
.fillMaxWidth()
.padding(innerPadding)
.padding(horizontal = TodoDefaults.screenPadding)
.clip(MaterialTheme.shapes.extraExtraLarge)
) {
item {
var clickCount by remember { mutableIntStateOf(0) }

View file

@ -4,15 +4,18 @@ import android.content.Context
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Category
import androidx.compose.material.icons.outlined.FileDownload
import androidx.compose.material.icons.outlined.FileUpload
import androidx.compose.material.icons.outlined.RestartAlt
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.TopAppBarDefaults
@ -29,9 +32,11 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.DialogProperties
import cn.super12138.todo.R
import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.ui.activities.MainActivity
import cn.super12138.todo.ui.components.ConfirmDialog
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.Settings
import cn.super12138.todo.ui.pages.settings.components.SettingsCategory
import cn.super12138.todo.ui.pages.settings.components.SettingsItem
import cn.super12138.todo.ui.viewmodels.MainViewModel
@ -39,7 +44,7 @@ import cn.super12138.todo.utils.SystemUtils
import kotlinx.coroutines.launch
import kotlin.system.exitProcess
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SettingsData(
viewModel: MainViewModel,
@ -111,13 +116,15 @@ fun SettingsData(
snackbarHost = { SnackbarHost(snackbarHostState) },
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { innerPadding ->
LazyColumn(
modifier = Modifier
Column(
Modifier
.fillMaxSize()
.padding(innerPadding)
.padding(horizontal = TodoDefaults.screenPadding)
.verticalScroll(rememberScrollState())
) {
item {
SettingsCategory(stringResource(R.string.pref_category_data_management))
SettingsCategory(stringResource(R.string.pref_category_data_management))
Settings {
SettingsItem(
leadingIcon = Icons.Outlined.FileDownload,
title = stringResource(R.string.pref_backup),
@ -126,8 +133,6 @@ fun SettingsData(
backupLauncher.launch("Todo-backup-${SystemUtils.getTime()}.zip")
}
)
}
item {
SettingsItem(
leadingIcon = Icons.Outlined.FileUpload,
title = stringResource(R.string.pref_restore),
@ -137,8 +142,8 @@ fun SettingsData(
}
)
}
item {
SettingsCategory(stringResource(R.string.pref_category_category_management))
SettingsCategory(stringResource(R.string.pref_category_category_management))
Settings {
SettingsItem(
leadingIcon = Icons.Outlined.Category,
title = stringResource(R.string.pref_category_category_management),
@ -147,17 +152,17 @@ fun SettingsData(
)
}
}
ConfirmDialog(
visible = showRestoreDialog,
icon = Icons.Outlined.RestartAlt,
title = stringResource(R.string.tip_tips),
text = stringResource(R.string.tip_restore_success),
showDismissButton = false,
onConfirm = { restartApp(context) },
onDismiss = { showRestoreDialog = false },
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false)
)
}
ConfirmDialog(
visible = showRestoreDialog,
icon = Icons.Outlined.RestartAlt,
title = stringResource(R.string.tip_tips),
text = stringResource(R.string.tip_restore_success),
showDismissButton = false,
onConfirm = { restartApp(context) },
onDismiss = { showRestoreDialog = false },
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false)
)
}
/**

View file

@ -1,14 +1,17 @@
package cn.super12138.todo.ui.pages.settings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Sort
import androidx.compose.material.icons.outlined.Checklist
import androidx.compose.material.icons.outlined.Shield
import androidx.compose.material.icons.outlined.Vibration
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@ -26,7 +29,9 @@ import cn.super12138.todo.R
import cn.super12138.todo.constants.Constants
import cn.super12138.todo.logic.datastore.DataStoreManager
import cn.super12138.todo.logic.model.SortingMethod
import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.Settings
import cn.super12138.todo.ui.pages.settings.components.SettingsCategory
import cn.super12138.todo.ui.pages.settings.components.SettingsItem
import cn.super12138.todo.ui.pages.settings.components.SettingsPlainBox
@ -35,7 +40,7 @@ import cn.super12138.todo.ui.pages.settings.components.SettingsRadioOptions
import cn.super12138.todo.ui.pages.settings.components.SwitchSettingsItem
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SettingsInterface(
onNavigateUp: () -> Unit,
@ -56,16 +61,15 @@ fun SettingsInterface(
scrollBehavior = scrollBehavior,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
) { innerPadding ->
LazyColumn(
modifier = Modifier
Column(
Modifier
.fillMaxSize()
.padding(innerPadding)
.padding(horizontal = TodoDefaults.screenPadding)
.verticalScroll(rememberScrollState())
) {
item {
SettingsCategory(stringResource(R.string.pref_category_todo_list))
}
item {
SettingsCategory(stringResource(R.string.pref_category_todo_list))
Settings {
SwitchSettingsItem(
checked = showCompleted,
leadingIcon = Icons.Outlined.Checklist,
@ -73,8 +77,6 @@ fun SettingsInterface(
description = stringResource(R.string.pref_show_completed_desc),
onCheckedChange = { scope.launch { DataStoreManager.setShowCompleted(it) } },
)
}
item {
SettingsItem(
leadingIcon = Icons.AutoMirrored.Outlined.Sort,
title = stringResource(R.string.pref_sorting_method),
@ -82,11 +84,8 @@ fun SettingsInterface(
onClick = { showSortingMethodDialog = true }
)
}
item {
SettingsCategory(stringResource(R.string.pref_category_global))
}
item {
SettingsCategory(stringResource(R.string.pref_category_global))
Settings {
SwitchSettingsItem(
checked = secureMode,
leadingIcon = Icons.Outlined.Shield,
@ -94,8 +93,6 @@ fun SettingsInterface(
description = stringResource(R.string.pref_secure_mode_desc),
onCheckedChange = { scope.launch { DataStoreManager.setSecureMode(it) } }
)
}
item {
SwitchSettingsItem(
checked = hapticFeedback,
leadingIcon = Icons.Outlined.Vibration,
@ -103,9 +100,10 @@ fun SettingsInterface(
description = stringResource(R.string.pref_haptic_feedback_desc),
onCheckedChange = { scope.launch { DataStoreManager.setHapticFeedback(it) } }
)
SettingsPlainBox(stringResource(R.string.pref_haptic_feedback_more_info))
}
SettingsPlainBox(stringResource(R.string.pref_haptic_feedback_more_info))
}
}
val sortingList = remember {

View file

@ -1,24 +1,29 @@
package cn.super12138.todo.ui.pages.settings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ColorLens
import androidx.compose.material.icons.outlined.Dns
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.ViewComfy
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import cn.super12138.todo.R
import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
import cn.super12138.todo.ui.pages.settings.components.Settings
import cn.super12138.todo.ui.pages.settings.components.SettingsItem
@OptIn(ExperimentalMaterial3Api::class)
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SettingsMain(
toAppearancePage: () -> Unit,
@ -35,42 +40,39 @@ fun SettingsMain(
onBack = onNavigateUp,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
) { innerPadding ->
LazyColumn(
modifier = Modifier
Column(
Modifier
.fillMaxSize()
.padding(innerPadding)
.padding(horizontal = TodoDefaults.screenPadding)
.verticalScroll(rememberScrollState())
) {
item {
Settings {
SettingsItem(
leadingIcon = Icons.Outlined.ColorLens,
title = stringResource(R.string.pref_appearance),
description = stringResource(R.string.pref_appearance_desc),
onClick = toAppearancePage
)
}
item {
SettingsItem(
leadingIcon = Icons.Outlined.ViewComfy,
title = stringResource(R.string.pref_interface_interaction),
description = stringResource(R.string.pref_interface_interaction_desc),
onClick = toInterfacePage
)
}
item {
SettingsItem(
leadingIcon = Icons.Outlined.Dns,
title = stringResource(R.string.pref_data),
description = stringResource(R.string.pref_data_desc),
onClick = toDataPage
)
}
item {
SettingsItem(
leadingIcon = Icons.Outlined.Info,
title = stringResource(R.string.pref_about),
description = stringResource(R.string.pref_about_desc),
onClick = toAboutPage
)
}
}
}

View file

@ -0,0 +1,24 @@
package cn.super12138.todo.ui.pages.settings.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun Settings(
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit,
) {
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
modifier = modifier.clip(MaterialTheme.shapes.extraExtraLarge),
content = content
)
}

View file

@ -1,11 +1,13 @@
package cn.super12138.todo.ui.pages.settings.components
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
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.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@ -13,6 +15,7 @@ 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.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalView
@ -48,6 +51,7 @@ fun SettingsItem(
title: String,
description: String? = null,
trailingContent: (@Composable () -> Unit)? = null,
background: Color = MaterialTheme.colorScheme.surfaceContainerHighest,
enableClick: Boolean = true,
onClick: () -> Unit = {}
) {
@ -65,12 +69,14 @@ fun SettingsItem(
title = title,
description = description,
trailingContent = trailingContent,
background = background,
enableClick = enableClick,
onClick = onClick,
modifier = modifier
)
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SettingsItem(
modifier: Modifier = Modifier,
@ -78,9 +84,10 @@ fun SettingsItem(
title: String,
description: String? = null,
trailingContent: (@Composable () -> Unit)? = null,
shape: Shape = MaterialTheme.shapes.large,
shape: Shape = MaterialTheme.shapes.small,
background: Color = MaterialTheme.colorScheme.surfaceContainerHighest,
enableClick: Boolean = true,
onClick: () -> Unit = {}
onClick: () -> Unit = {},
) {
val view = LocalView.current
Row(
@ -95,6 +102,7 @@ fun SettingsItem(
onClick()
}
)
.background(background)
.padding(
horizontal = TodoDefaults.settingsItemHorizontalPadding,
vertical = TodoDefaults.settingsItemVerticalPadding

View file

@ -8,6 +8,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -26,6 +28,7 @@ import cn.super12138.todo.utils.VibrationUtils
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun LicenceList(
modifier: Modifier = Modifier,
@ -80,7 +83,8 @@ fun LicenceList(
onClick = {
openDialog = false
VibrationUtils.performHapticFeedback(view)
}
},
shapes = ButtonDefaults.shapes()
) { Text(stringResource(R.string.action_confirm)) }
},
onDismissRequest = { openDialog = false }

View file

@ -18,6 +18,8 @@ aboutLibsRelease = "13.1.0"
aboutLibsReleasePlugin = "13.1.0"
# M3 Color
m3color = "2025.4"
# Capsule
capsule = "2.1.1"
# Konfetti
konfetti = "2.0.5"
# Lazy Column Scrollbar
@ -70,7 +72,9 @@ aboutlibraries-core = { group = "com.mikepenz", name = "aboutlibraries-core", ve
aboutlibraries-compose = { group = "com.mikepenz", name = "aboutlibraries-compose-m3", version.ref = "aboutLibsRelease" }
# M3 Color
com-kyant0-m3color = { group = "com.github.Kyant0", name = "m3color", version.ref = "m3color" }
kyant0-m3color = { group = "com.github.Kyant0", name = "m3color", version.ref = "m3color" }
# Capsule
kyant0-capsule = { group = "io.github.kyant0", name = "capsule", version.ref = "capsule" }
# Konfetti
nl-dionsegijn-konfetti-compose = { group = "nl.dionsegijn", name = "konfetti-compose", version.ref = "konfetti" }