[优化] 优化代码

This commit is contained in:
HapeLee committed 2026-04-28 12:46:20 +08:00
1 parent 166c3a8deb
commit 29505aa4ef
39 files changed
+731 -841

No files matched your search

@@ -31,7 +31,7 @@ import io.legado.app.constant.AppConst.appInfo
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.settingItem.SettingItem import io.legado.app.ui.widget.components.settingItem.SettingItem
import io.legado.app.ui.widget.components.text.AppText import io.legado.app.ui.widget.components.text.AppText
@@ -56,8 +56,8 @@ import io.legado.app.ui.widget.components.EmptyMessage
import io.legado.app.ui.widget.components.SearchBar import io.legado.app.ui.widget.components.SearchBar
import io.legado.app.ui.widget.components.bookmark.BookmarkEditSheet import io.legado.app.ui.widget.components.bookmark.BookmarkEditSheet
import io.legado.app.ui.widget.components.bookmark.BookmarkItem import io.legado.app.ui.widget.components.bookmark.BookmarkItem
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
@@ -308,8 +308,6 @@ fun AllBookmarkScreen(
TextCard( TextCard(
text = group.bookName, text = group.bookName,
textStyle = LegadoTheme.typography.labelLarge, textStyle = LegadoTheme.typography.labelLarge,
backgroundColor = LegadoTheme.colorScheme.cardContainer,
contentColor = LegadoTheme.colorScheme.onCardContainer,
cornerRadius = 8.dp, cornerRadius = 8.dp,
horizontalPadding = 8.dp, horizontalPadding = 8.dp,
verticalPadding = 6.dp, verticalPadding = 6.dp,
@@ -50,8 +50,8 @@ import io.legado.app.ui.widget.components.AppLinearProgressIndicator
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.SmallTonalIconButton import io.legado.app.ui.widget.components.button.SmallTonalIconButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.NormalCard import io.legado.app.ui.widget.components.card.NormalCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.icon.AppIcon import io.legado.app.ui.widget.components.icon.AppIcon
@@ -70,8 +70,8 @@ import io.legado.app.ui.theme.responsiveHazeSource
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.SearchBar import io.legado.app.ui.widget.components.SearchBar
import io.legado.app.ui.widget.components.button.AnimatedTextButton import io.legado.app.ui.widget.components.button.AnimatedTextButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.explore.calculateExploreKindRows import io.legado.app.ui.widget.components.explore.calculateExploreKindRows
import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem
@@ -64,7 +64,7 @@ import io.legado.app.ui.widget.components.SelectionActions
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.SmallIconButton import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.button.SmallTonalIconButton import io.legado.app.ui.widget.components.button.SmallTonalIconButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
@@ -80,7 +80,7 @@ import io.legado.app.ui.widget.components.button.ConfirmDismissButtonsRow
import io.legado.app.ui.widget.components.button.MediumIconButton import io.legado.app.ui.widget.components.button.MediumIconButton
import io.legado.app.ui.widget.components.button.SmallIconButton import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.button.SmallTonalIconButton import io.legado.app.ui.widget.components.button.SmallTonalIconButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.card.SelectionItemCard import io.legado.app.ui.widget.components.card.SelectionItemCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
@@ -259,7 +259,8 @@ fun RemoteBookScreen(
topBarActions = { topBarActions = {
TopBarActionButton( TopBarActionButton(
onClick = { showSheet = RemoteBookSheet.Servers }, onClick = { showSheet = RemoteBookSheet.Servers },
imageVector = Icons.Default.Storage imageVector = Icons.Default.Storage,
contentDescription = "服务器"
) )
}, },
dropDownMenuContent = { dismiss -> dropDownMenuContent = { dismiss ->
@@ -83,8 +83,8 @@ import io.legado.app.ui.theme.responsiveHazeEffectFixedStyle
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.cover.CoilBookCover import io.legado.app.ui.widget.components.cover.CoilBookCover
@@ -417,15 +417,18 @@ private fun BookInfoTopBarActions(
TopBarActionButton( TopBarActionButton(
onClick = { onMenuAction(BookInfoMenuAction.Edit) }, onClick = { onMenuAction(BookInfoMenuAction.Edit) },
imageVector = Icons.Default.Edit, imageVector = Icons.Default.Edit,
contentDescription = "编辑"
) )
} }
TopBarActionButton( TopBarActionButton(
onClick = { onMenuAction(BookInfoMenuAction.Share) }, onClick = { onMenuAction(BookInfoMenuAction.Share) },
imageVector = Icons.Default.Share, imageVector = Icons.Default.Share,
contentDescription = "分享"
) )
TopBarActionButton( TopBarActionButton(
onClick = { onShowMenuChange(true) }, onClick = { onShowMenuChange(true) },
imageVector = Icons.Default.MoreVert, imageVector = Icons.Default.MoreVert,
contentDescription = "更多"
) )
BookInfoOverflowMenu( BookInfoOverflowMenu(
expanded = showMenu, expanded = showMenu,
@@ -45,8 +45,7 @@ import io.legado.app.ui.book.changecover.ChangeCoverDialog
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.button.MediumOutlinedIconButton import io.legado.app.ui.widget.components.button.MediumOutlinedIconButton
import io.legado.app.ui.widget.components.button.TopBarButtonVariant import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton
import io.legado.app.ui.widget.components.cover.CoilBookCover import io.legado.app.ui.widget.components.cover.CoilBookCover
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
@@ -74,8 +73,7 @@ fun BookInfoEditScreen(
title = stringResource(id = R.string.book_info_edit), title = stringResource(id = R.string.book_info_edit),
navigationIcon = { navigationIcon = {
TopBarNavigationButton( TopBarNavigationButton(
onClick = onBack, onClick = onBack
style = TopBarButtonVariant.Outlined
) )
}, },
actions = { actions = {
@@ -91,7 +91,7 @@ import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.SmallTonalIconButton import io.legado.app.ui.widget.components.button.SmallTonalIconButton
import io.legado.app.ui.widget.components.button.SmallTonalTextButton import io.legado.app.ui.widget.components.button.SmallTonalTextButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.card.NormalCard import io.legado.app.ui.widget.components.card.NormalCard
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
import io.legado.app.ui.widget.components.card.SelectionItemCard import io.legado.app.ui.widget.components.card.SelectionItemCard
@@ -77,7 +77,7 @@ import io.legado.app.ui.widget.components.EmptyMessage
import io.legado.app.ui.widget.components.SearchBar import io.legado.app.ui.widget.components.SearchBar
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.AppIconButton import io.legado.app.ui.widget.components.button.AppIconButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.checkBox.CheckboxItem import io.legado.app.ui.widget.components.checkBox.CheckboxItem
@@ -81,9 +81,9 @@ import io.legado.app.ui.widget.components.button.SmallTextButton
import io.legado.app.ui.widget.components.card.NormalCard import io.legado.app.ui.widget.components.card.NormalCard
import io.legado.app.ui.widget.components.card.SelectionItemCard import io.legado.app.ui.widget.components.card.SelectionItemCard
import io.legado.app.ui.widget.components.button.ToggleChip import io.legado.app.ui.widget.components.button.ToggleChip
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarAnimatedActionButton import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.icon.AppIcon import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.icon.AppIcons import io.legado.app.ui.widget.components.icon.AppIcons
@@ -219,13 +219,15 @@ fun SearchScreen(
onClick = { onClick = {
viewModel.onIntent(SearchIntent.SetScopeSheetVisible(true)) viewModel.onIntent(SearchIntent.SetScopeSheetVisible(true))
}, },
imageVector = AppIcons.Filter imageVector = AppIcons.Filter,
contentDescription = "筛选"
) )
TopBarActionButton( TopBarActionButton(
onClick = { onClick = {
viewModel.onIntent(SearchIntent.OpenSourceManage) viewModel.onIntent(SearchIntent.OpenSourceManage)
}, },
imageVector = AppIcons.Settings, imageVector = AppIcons.Settings,
contentDescription = "书源管理"
) )
}, },
scrollBehavior = scrollBehavior scrollBehavior = scrollBehavior
@@ -63,8 +63,8 @@ import io.legado.app.ui.widget.components.SearchBar
import io.legado.app.ui.widget.components.button.MediumOutlinedButton import io.legado.app.ui.widget.components.button.MediumOutlinedButton
import io.legado.app.ui.widget.components.button.SmallAnimatedActionButton import io.legado.app.ui.widget.components.button.SmallAnimatedActionButton
import io.legado.app.ui.widget.components.button.SmallIconButton import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.button.TopBarAnimatedActionButton import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.icon.AppIcon import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
@@ -12,7 +12,7 @@ import io.legado.app.R
import io.legado.app.ui.theme.adaptiveContentPadding import io.legado.app.ui.theme.adaptiveContentPadding
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar import io.legado.app.ui.widget.components.topbar.GlassMediumFlexibleTopAppBar
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
@@ -49,7 +49,7 @@ import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.SelectionItemCard import io.legado.app.ui.widget.components.card.SelectionItemCard
import io.legado.app.ui.widget.components.checkBox.CheckboxItem import io.legado.app.ui.widget.components.checkBox.CheckboxItem
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
@@ -25,7 +25,7 @@ import io.legado.app.constant.PreferKey
import io.legado.app.ui.theme.adaptiveContentPadding import io.legado.app.ui.theme.adaptiveContentPadding
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem
@@ -28,7 +28,7 @@ import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem
@@ -18,7 +18,7 @@ import io.legado.app.R
import io.legado.app.ui.theme.adaptiveContentPadding import io.legado.app.ui.theme.adaptiveContentPadding
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem
import io.legado.app.ui.widget.components.settingItem.SliderSettingItem import io.legado.app.ui.widget.components.settingItem.SliderSettingItem
@@ -82,7 +82,7 @@ import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.SplicedColumnGroup import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem
@@ -87,7 +87,7 @@ import io.legado.app.ui.theme.adaptiveHorizontalPadding
import io.legado.app.ui.theme.adaptiveHorizontalPaddingTab import io.legado.app.ui.theme.adaptiveHorizontalPaddingTab
import io.legado.app.ui.widget.components.EmptyMessage import io.legado.app.ui.widget.components.EmptyMessage
import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.card.NormalCard import io.legado.app.ui.widget.components.card.NormalCard
import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.card.TextCard
@@ -272,8 +272,6 @@ fun ExploreScreen(
TextCard( TextCard(
text = item.bookSourceName, text = item.bookSourceName,
textStyle = LegadoTheme.typography.labelMediumEmphasized, textStyle = LegadoTheme.typography.labelMediumEmphasized,
backgroundColor = LegadoTheme.colorScheme.cardContainer,
contentColor = LegadoTheme.colorScheme.onCardContainer,
cornerRadius = 12.dp, cornerRadius = 12.dp,
horizontalPadding = 12.dp, horizontalPadding = 12.dp,
verticalPadding = 8.dp, verticalPadding = 8.dp,
@@ -56,7 +56,7 @@ import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.adaptiveContentPadding import io.legado.app.ui.theme.adaptiveContentPadding
import io.legado.app.ui.widget.components.SourceIcon import io.legado.app.ui.widget.components.SourceIcon
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.divider.PillDivider import io.legado.app.ui.widget.components.divider.PillDivider
import io.legado.app.ui.widget.components.divider.PillHeaderDivider import io.legado.app.ui.widget.components.divider.PillHeaderDivider
import io.legado.app.ui.widget.components.list.ListScaffold import io.legado.app.ui.widget.components.list.ListScaffold
@@ -1,4 +1,4 @@
package io.legado.app.ui.replace.edit package io.legado.app.ui.replace.edit
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
@@ -71,11 +71,10 @@ import androidx.compose.ui.zIndex
import io.legado.app.ui.widget.components.AppScaffold import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.AppTextField import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.AlertButton
import io.legado.app.ui.widget.components.button.MediumIconButton import io.legado.app.ui.widget.components.button.MediumIconButton
import io.legado.app.ui.widget.components.button.ToggleChip import io.legado.app.ui.widget.components.button.ToggleChip
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.checkBox.CheckboxItem import io.legado.app.ui.widget.components.checkBox.CheckboxItem
import io.legado.app.ui.widget.components.icon.AppIcon import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
@@ -53,8 +53,8 @@ import io.legado.app.ui.widget.components.AppScaffold
import io.legado.app.ui.widget.components.EmptyMessage import io.legado.app.ui.widget.components.EmptyMessage
import io.legado.app.ui.widget.components.button.SmallIconButton import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.icon.AppIcons import io.legado.app.ui.widget.components.icon.AppIcons
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
@@ -72,8 +72,8 @@ import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.button.MediumIconButton import io.legado.app.ui.widget.components.button.MediumIconButton
import io.legado.app.ui.widget.components.card.GlassCard import io.legado.app.ui.widget.components.card.GlassCard
import io.legado.app.ui.widget.components.button.SmallIconButton import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
@@ -7,11 +7,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AlertDialogDefaults import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@@ -23,8 +20,8 @@ import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver import io.legado.app.ui.theme.ThemeResolver
import io.legado.app.ui.widget.components.button.MiuixPrimaryButton import io.legado.app.ui.widget.components.button.PrimaryButton
import io.legado.app.ui.widget.components.button.MiuixSecondaryButton import io.legado.app.ui.widget.components.button.SecondaryButton
import top.yukonga.miuix.kmp.window.WindowDialog import top.yukonga.miuix.kmp.window.WindowDialog
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@@ -67,7 +64,7 @@ fun AppAlertDialog(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
if (onDismiss != null) { if (onDismiss != null) {
MiuixSecondaryButton( SecondaryButton(
text = dismissText, text = dismissText,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onClick = {
@@ -78,7 +75,7 @@ fun AppAlertDialog(
} }
if (onConfirm != null) { if (onConfirm != null) {
MiuixPrimaryButton( PrimaryButton(
text = confirmText, text = confirmText,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
onClick = { onClick = {
@@ -115,29 +112,21 @@ fun AppAlertDialog(
}, },
confirmButton = { confirmButton = {
if (onConfirm != null) { if (onConfirm != null) {
OutlinedButton( PrimaryButton(
onClick = onConfirm, onClick = onConfirm,
colors = ButtonDefaults.outlinedButtonColors( text = confirmText
contentColor = LegadoTheme.colorScheme.primary
) )
) {
Text(text = confirmText)
}
} }
}, },
dismissButton = { dismissButton = {
if (onDismiss != null) { if (onDismiss != null) {
TextButton( SecondaryButton(
onClick = { onClick = {
onDismiss() onDismiss()
onDismissRequest() onDismissRequest()
}, },
colors = ButtonDefaults.textButtonColors( text = dismissText
contentColor = LegadoTheme.colorScheme.primary
) )
) {
Text(text = dismissText)
}
} }
} }
) )
@@ -1,30 +0,0 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import io.legado.app.ui.widget.components.text.AppText
@Composable
fun AlertButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: String = "删除",
enabled: Boolean = true
) {
OutlinedButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = ButtonDefaults.outlinedButtonColors(
contentColor = MaterialTheme.colorScheme.error,
containerColor = Color.Transparent,
)
) {
AppText(text = text)
}
}
@@ -0,0 +1,74 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
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.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import kotlinx.coroutines.delay
@Composable
internal fun AnimatedActionButtonCore(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
iconChecked: ImageVector,
iconUnchecked: ImageVector,
activeText: String,
inactiveText: String,
modifier: Modifier = Modifier,
iconSize: Dp,
textStyle: TextStyle,
textStartPadding: Dp,
contentColor: Color? = null,
button: @Composable (
modifier: Modifier,
onToggle: (Boolean) -> Unit,
content: @Composable RowScope.() -> Unit
) -> Unit,
icon: @Composable (imageVector: ImageVector, modifier: Modifier, tint: Color?) -> Unit,
text: @Composable (text: String, modifier: Modifier, style: TextStyle, color: Color?) -> Unit
) {
var showText by remember { mutableStateOf(false) }
var lastCheckedState by remember { mutableStateOf(checked) }
LaunchedEffect(showText) {
if (showText) {
delay(1000)
showText = false
}
}
button(
modifier,
{ nextChecked ->
lastCheckedState = nextChecked
onCheckedChange(nextChecked)
showText = true
}
) {
icon(
if (checked) iconChecked else iconUnchecked,
Modifier.size(iconSize),
contentColor
)
AnimatedVisibility(visible = showText) {
text(
if (lastCheckedState) activeText else inactiveText,
Modifier.padding(start = textStartPadding),
textStyle,
contentColor
)
}
}
}
@@ -0,0 +1,33 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.togetherWith
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@Composable
fun AnimatedIcon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier
) {
AnimatedContent(
targetState = imageVector,
transitionSpec = {
(fadeIn() + scaleIn(initialScale = 0.8f))
.togetherWith(fadeOut())
},
label = "IconTransition"
) { targetIcon ->
Icon(
imageVector = targetIcon,
contentDescription = contentDescription,
modifier = modifier
)
}
}
@@ -0,0 +1,66 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver
import top.yukonga.miuix.kmp.basic.Button as MiuixButton
import top.yukonga.miuix.kmp.basic.ButtonDefaults as MiuixButtonDefaults
import top.yukonga.miuix.kmp.basic.Text as MiuixText
@Composable
fun PrimaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColorsPrimary()
) {
MiuixText(text = text)
}
} else {
Button(
onClick = onClick,
modifier = modifier,
enabled = enabled,
) {
Text(text = text)
}
}
}
@Composable
fun SecondaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColors()
) {
MiuixText(text = text)
}
} else {
OutlinedButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
) {
Text(text = text)
}
}
}
@@ -42,9 +42,9 @@ fun AppIconButton(
enabled = enabled, enabled = enabled,
holdDownState = holdDownState, holdDownState = holdDownState,
backgroundColor = miuixBackgroundColor, backgroundColor = miuixBackgroundColor,
cornerRadius = MiuixIconButtonDefaults.CornerRadius, cornerRadius = miuixCornerRadius ?: MiuixIconButtonDefaults.CornerRadius,
minHeight = MiuixIconButtonDefaults.MinHeight, minHeight = miuixMinHeight ?: MiuixIconButtonDefaults.MinHeight,
minWidth = MiuixIconButtonDefaults.MinWidth, minWidth = miuixMinWidth ?: MiuixIconButtonDefaults.MinWidth,
content = content content = content
) )
} else { } else {
@@ -4,80 +4,12 @@ import androidx.compose.foundation.layout.Arrangement
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.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver import io.legado.app.ui.theme.ThemeResolver
import top.yukonga.miuix.kmp.basic.Button as MiuixButton
import top.yukonga.miuix.kmp.basic.ButtonDefaults as MiuixButtonDefaults
import top.yukonga.miuix.kmp.basic.Text as MiuixText
@Composable
fun PrimaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColorsPrimary()
) {
MiuixText(
text = text
)
}
} else {
Button(
onClick = onClick,
modifier = modifier,
enabled = enabled,
) {
Text(
text = text,
)
}
}
}
@Composable
fun SecondaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColors()
) {
MiuixText(
text = text
)
}
} else {
OutlinedButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
) {
Text(
text = text
)
}
}
}
@Composable @Composable
fun ConfirmDismissButtonsRow( fun ConfirmDismissButtonsRow(
@@ -1,29 +1,20 @@
package io.legado.app.ui.widget.components.button package io.legado.app.ui.widget.components.button
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.OutlinedIconButton import androidx.compose.material3.OutlinedIconButton
import androidx.compose.material3.OutlinedIconToggleButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TonalToggleButton import androidx.compose.material3.TonalToggleButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@@ -32,25 +23,25 @@ import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver import io.legado.app.ui.theme.ThemeResolver
import kotlinx.coroutines.delay
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
import top.yukonga.miuix.kmp.basic.Text as MiuixText import top.yukonga.miuix.kmp.basic.Text as MiuixText
@Composable @Composable
fun MediumIconButton( fun MediumIconButton(
onClick: () -> Unit, onClick: () -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
tint: Color = LegadoTheme.colorScheme.onSurface, tint: Color = LegadoTheme.colorScheme.onSurface,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
if (ThemeResolver.isMiuixEngine(composeEngine)) { if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixIconButton( MiuixIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier modifier = modifier,
enabled = enabled
) { ) {
MiuixIcon( MiuixIcon(
imageVector = imageVector, imageVector = imageVector,
@@ -61,7 +52,8 @@ fun MediumIconButton(
} else { } else {
IconButton( IconButton(
onClick = onClick, onClick = onClick,
modifier = modifier modifier = modifier,
enabled = enabled
) { ) {
Icon( Icon(
imageVector = imageVector, imageVector = imageVector,
@@ -77,13 +69,14 @@ fun MediumOutlinedIconButton(
onClick: () -> Unit, onClick: () -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine) if (ThemeResolver.isMiuixEngine(composeEngine)) {
if (isMiuix) {
MiuixIconButton( MiuixIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier, modifier = modifier,
enabled = enabled,
backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh
) { ) {
MiuixIcon( MiuixIcon(
@@ -94,6 +87,8 @@ fun MediumOutlinedIconButton(
} else { } else {
OutlinedIconButton( OutlinedIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier,
enabled = enabled,
border = ButtonDefaults.outlinedButtonBorder() border = ButtonDefaults.outlinedButtonBorder()
) { ) {
Icon( Icon(
@@ -104,133 +99,6 @@ fun MediumOutlinedIconButton(
} }
} }
@Composable
fun MediumOutlinedButton(
onClick: () -> Unit,
imageVector: ImageVector,
text: String,
modifier: Modifier = Modifier,
contentDescription: String? = null
) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
MiuixIconButton(
onClick = onClick,
modifier = modifier,
backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription
)
MiuixText(text = text)
}
}
} else {
OutlinedIconButton(
onClick = onClick,
border = ButtonDefaults.outlinedButtonBorder()
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
Text(text = text)
}
}
}
}
@Composable
fun MediumTonalIconButton(
onClick: () -> Unit,
imageVector: ImageVector,
modifier: Modifier = Modifier,
contentDescription: String? = null
) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
MiuixIconButton(
onClick = onClick,
modifier = modifier,
backgroundColor = LegadoTheme.colorScheme.surfaceContainer
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
} else {
FilledTonalIconButton(
onClick = onClick,
modifier = modifier.size(40.dp),
colors = IconButtonDefaults.filledTonalIconButtonColors()
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
}
@Composable
fun MediumOutlinedIconToggleButton(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
imageVector: ImageVector,
modifier: Modifier = Modifier,
contentDescription: String? = null
) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
val containerColor by animateColorAsState(
targetValue = if (checked) LegadoTheme.colorScheme.primaryContainer else LegadoTheme.colorScheme.surfaceContainer,
animationSpec = tween(150),
label = "MiuixToggleContainerColor"
)
val iconTint by animateColorAsState(
targetValue = if (checked) LegadoTheme.colorScheme.onPrimaryContainer else LegadoTheme.colorScheme.onSurfaceVariant,
animationSpec = tween(150),
label = "MiuixToggleIconTint"
)
MiuixIconButton(
onClick = { onCheckedChange(!checked) },
modifier = modifier,
backgroundColor = containerColor
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription,
tint = iconTint
)
}
} else {
OutlinedIconToggleButton(
checked = checked,
onCheckedChange = onCheckedChange,
modifier = modifier
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun MediumAnimatedActionButton( fun MediumAnimatedActionButton(
@@ -242,20 +110,7 @@ fun MediumAnimatedActionButton(
inactiveText: String, inactiveText: String,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
var showText by remember { mutableStateOf(false) } if (ThemeResolver.isMiuixEngine(composeEngine)) {
var lastCheckedState by remember { mutableStateOf(checked) }
LaunchedEffect(showText) {
if (showText) {
delay(1000)
showText = false
}
}
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
val containerColor by animateColorAsState( val containerColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainerHigh, targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainerHigh,
animationSpec = tween(150), animationSpec = tween(150),
@@ -265,72 +120,97 @@ fun MediumAnimatedActionButton(
val contentColor by animateColorAsState( val contentColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.onPrimaryContainer else MiuixTheme.colorScheme.onSurface, targetValue = if (checked) MiuixTheme.colorScheme.onPrimaryContainer else MiuixTheme.colorScheme.onSurface,
animationSpec = tween(150), animationSpec = tween(150),
label = "MiuixActionButtonContainer" label = "MiuixActionButtonContent"
) )
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier,
iconSize = 24.dp,
textStyle = LegadoTheme.typography.labelMedium,
textStartPadding = 8.dp,
contentColor = contentColor,
button = { buttonModifier, onToggle, content ->
MiuixIconButton( MiuixIconButton(
onClick = { onClick = { onToggle(!checked) },
lastCheckedState = !checked modifier = buttonModifier,
onCheckedChange(!checked)
showText = true
},
backgroundColor = containerColor backgroundColor = containerColor
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
modifier = Modifier.padding(horizontal = 8.dp) modifier = Modifier.padding(horizontal = 8.dp),
) { content = content
MiuixIcon(
tint = contentColor,
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = null
) )
}
AnimatedVisibility( },
visible = showText icon = { imageVector, iconModifier, tint ->
) { MiuixIcon(
imageVector = imageVector,
contentDescription = null,
modifier = iconModifier,
tint = tint ?: Color.Unspecified
)
},
text = { label, textModifier, style, color ->
MiuixText( MiuixText(
text = if (lastCheckedState) activeText else inactiveText, text = label,
color = contentColor, color = color ?: Color.Unspecified,
style = LegadoTheme.typography.labelMedium, style = style,
modifier = Modifier.padding(start = 8.dp), modifier = textModifier,
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
} }
} )
}
} else { } else {
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier,
iconSize = 24.dp,
textStyle = LegadoTheme.typography.labelMedium,
textStartPadding = 8.dp,
button = { buttonModifier, onToggle, content ->
TonalToggleButton( TonalToggleButton(
checked = checked, checked = checked,
onCheckedChange = { onCheckedChange = onToggle,
lastCheckedState = it modifier = buttonModifier,
onCheckedChange(it)
showText = true
},
contentPadding = PaddingValues(horizontal = 8.dp) contentPadding = PaddingValues(horizontal = 8.dp)
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center,
) { content = content
AnimatedIcon(
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = null
) )
}
AnimatedVisibility( },
visible = showText icon = { imageVector, iconModifier, _ ->
) { AnimatedIcon(
imageVector = imageVector,
contentDescription = null,
modifier = iconModifier
)
},
text = { label, textModifier, style, color ->
Text( Text(
text = if (lastCheckedState) activeText else inactiveText, text = label,
modifier = Modifier.padding(start = 8.dp), modifier = textModifier,
style = style,
color = color ?: Color.Unspecified,
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
} }
} )
}
} }
} }
@@ -0,0 +1,66 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
import top.yukonga.miuix.kmp.basic.Text as MiuixText
@Composable
fun MediumOutlinedButton(
onClick: () -> Unit,
imageVector: ImageVector,
text: String,
modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null
) {
if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixIconButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription
)
MiuixText(text = text)
}
}
} else {
OutlinedButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
border = ButtonDefaults.outlinedButtonBorder()
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
Text(
text = text,
modifier = Modifier.padding(start = 8.dp)
)
}
}
}
@@ -1,98 +0,0 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import io.legado.app.R
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.extended.Back
import top.yukonga.miuix.kmp.theme.LocalContentColor
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.basic.Button as MiuixButton
import top.yukonga.miuix.kmp.basic.ButtonDefaults as MiuixButtonDefaults
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
import top.yukonga.miuix.kmp.basic.Text as MiuixText
@Composable
fun MiuixIconButton(
modifier: Modifier = Modifier,
imageVector: ImageVector = MiuixIcons.Regular.Back,
tint: Color = LocalContentColor.current,
contentDescription: String? = stringResource(id = R.string.back),
onClick: () -> Unit,
) {
MiuixIconButton(
onClick = onClick,
modifier = modifier
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription,
tint = tint
)
}
}
@Composable
fun MiuixToggleButton(
modifier: Modifier = Modifier,
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
iconChecked: ImageVector,
iconUnchecked: ImageVector = iconChecked,
checkedTint: Color = MiuixTheme.colorScheme.primary,
uncheckedTint: Color = LocalContentColor.current,
contentDescription: String? = null,
) {
MiuixIconButton(
onClick = { onCheckedChange(!checked) },
modifier = modifier
) {
Icon(
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = contentDescription,
tint = if (checked) checkedTint else uncheckedTint
)
}
}
@Composable
fun MiuixPrimaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColorsPrimary()
) {
MiuixText(
text = text
)
}
}
@Composable
fun MiuixSecondaryButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
text: String
) {
MiuixButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = MiuixButtonDefaults.buttonColors()
) {
MiuixText(
text = text
)
}
}
@@ -1,6 +1,5 @@
package io.legado.app.ui.widget.components.button package io.legado.app.ui.widget.components.button
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -23,19 +22,16 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TonalToggleButton import androidx.compose.material3.TonalToggleButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
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
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
import io.legado.app.ui.theme.ThemeResolver import io.legado.app.ui.theme.ThemeResolver
import kotlinx.coroutines.delay
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
import top.yukonga.miuix.kmp.basic.Text as MiuixText import top.yukonga.miuix.kmp.basic.Text as MiuixText
@@ -65,11 +61,15 @@ private fun SmallNoMinTouchTarget(content: @Composable () -> Unit) {
fun SmallIconButton( fun SmallIconButton(
onClick: () -> Unit, onClick: () -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
if (ThemeResolver.isMiuixEngine(composeEngine)) { if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixIconButton( MiuixIconButton(
onClick = onClick onClick = onClick,
modifier = modifier,
enabled = enabled
) { ) {
MiuixIcon( MiuixIcon(
imageVector = imageVector, imageVector = imageVector,
@@ -81,7 +81,8 @@ fun SmallIconButton(
SmallNoMinTouchTarget { SmallNoMinTouchTarget {
IconButton( IconButton(
onClick = onClick, onClick = onClick,
modifier = Modifier.size(smallContainerSize()), modifier = modifier.size(smallContainerSize()),
enabled = enabled,
shape = IconButtonDefaults.extraSmallRoundShape, shape = IconButtonDefaults.extraSmallRoundShape,
) { ) {
Icon( Icon(
@@ -100,13 +101,14 @@ fun SmallOutlinedIconButton(
onClick: () -> Unit, onClick: () -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine) if (ThemeResolver.isMiuixEngine(composeEngine)) {
if (isMiuix) {
MiuixIconButton( MiuixIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier.size(SmallMiuixButtonSize), modifier = modifier.size(SmallMiuixButtonSize),
enabled = enabled,
backgroundColor = LegadoTheme.colorScheme.surfaceContainer backgroundColor = LegadoTheme.colorScheme.surfaceContainer
) { ) {
MiuixIcon( MiuixIcon(
@@ -119,7 +121,8 @@ fun SmallOutlinedIconButton(
SmallNoMinTouchTarget { SmallNoMinTouchTarget {
OutlinedIconButton( OutlinedIconButton(
onClick = onClick, onClick = onClick,
modifier = Modifier.size(smallContainerSize()), modifier = modifier.size(smallContainerSize()),
enabled = enabled,
shapes = IconButtonDefaults.shapes(), shapes = IconButtonDefaults.shapes(),
border = ButtonDefaults.outlinedButtonBorder() border = ButtonDefaults.outlinedButtonBorder()
) { ) {
@@ -139,14 +142,14 @@ fun SmallTonalIconButton(
onClick: () -> Unit, onClick: () -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine) if (ThemeResolver.isMiuixEngine(composeEngine)) {
if (isMiuix) {
MiuixIconButton( MiuixIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier.size(SmallMiuixButtonSize), modifier = modifier.size(SmallMiuixButtonSize),
enabled = enabled,
backgroundColor = LegadoTheme.colorScheme.surfaceContainer backgroundColor = LegadoTheme.colorScheme.surfaceContainer
) { ) {
MiuixIcon( MiuixIcon(
@@ -160,6 +163,7 @@ fun SmallTonalIconButton(
FilledTonalIconButton( FilledTonalIconButton(
onClick = onClick, onClick = onClick,
modifier = modifier.size(smallContainerSize()), modifier = modifier.size(smallContainerSize()),
enabled = enabled,
shapes = IconButtonDefaults.shapes(), shapes = IconButtonDefaults.shapes(),
colors = IconButtonDefaults.filledTonalIconButtonColors() colors = IconButtonDefaults.filledTonalIconButtonColors()
) { ) {
@@ -180,12 +184,10 @@ fun SmallOutlinedIconToggleButton(
onCheckedChange: (Boolean) -> Unit, onCheckedChange: (Boolean) -> Unit,
imageVector: ImageVector, imageVector: ImageVector,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
enabled: Boolean = true,
contentDescription: String? = null contentDescription: String? = null
) { ) {
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine) if (ThemeResolver.isMiuixEngine(composeEngine)) {
if (isMiuix) {
val containerColor by animateColorAsState( val containerColor by animateColorAsState(
targetValue = if (checked) LegadoTheme.colorScheme.primaryContainer else LegadoTheme.colorScheme.surfaceContainer, targetValue = if (checked) LegadoTheme.colorScheme.primaryContainer else LegadoTheme.colorScheme.surfaceContainer,
animationSpec = tween(150), animationSpec = tween(150),
@@ -200,8 +202,8 @@ fun SmallOutlinedIconToggleButton(
MiuixIconButton( MiuixIconButton(
onClick = { onCheckedChange(!checked) }, onClick = { onCheckedChange(!checked) },
modifier = modifier modifier = modifier.size(SmallMiuixButtonSize),
.size(SmallMiuixButtonSize), enabled = enabled,
backgroundColor = containerColor backgroundColor = containerColor
) { ) {
MiuixIcon( MiuixIcon(
@@ -211,7 +213,6 @@ fun SmallOutlinedIconToggleButton(
modifier = Modifier.size(SmallMiuixIconSize) modifier = Modifier.size(SmallMiuixIconSize)
) )
} }
} else { } else {
val defaultShape = IconButtonDefaults.extraSmallRoundShape val defaultShape = IconButtonDefaults.extraSmallRoundShape
val pressedShape = IconButtonDefaults.extraSmallPressedShape val pressedShape = IconButtonDefaults.extraSmallPressedShape
@@ -225,11 +226,12 @@ fun SmallOutlinedIconToggleButton(
) )
} }
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) { SmallNoMinTouchTarget {
OutlinedIconToggleButton( OutlinedIconToggleButton(
checked = checked, checked = checked,
onCheckedChange = onCheckedChange, onCheckedChange = onCheckedChange,
modifier = modifier.size(smallContainerSize()), modifier = modifier.size(smallContainerSize()),
enabled = enabled,
shapes = toggleShapes shapes = toggleShapes
) { ) {
Icon( Icon(
@@ -253,91 +255,102 @@ fun SmallAnimatedActionButton(
inactiveText: String, inactiveText: String,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
var showText by remember { mutableStateOf(false) } if (ThemeResolver.isMiuixEngine(composeEngine)) {
var lastCheckedState by remember { mutableStateOf(checked) }
LaunchedEffect(showText) {
if (showText) {
delay(1000)
showText = false
}
}
val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
if (isMiuix) {
val containerColor by animateColorAsState( val containerColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainer, targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainer,
animationSpec = tween(150), animationSpec = tween(150),
label = "MiuixActionButtonContainer" label = "MiuixActionButtonContainer"
) )
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier,
iconSize = 18.dp,
textStyle = LegadoTheme.typography.labelSmall,
textStartPadding = 6.dp,
button = { buttonModifier, onToggle, content ->
MiuixIconButton( MiuixIconButton(
onClick = { onClick = { onToggle(!checked) },
lastCheckedState = !checked modifier = buttonModifier,
onCheckedChange(!checked)
showText = true
},
backgroundColor = containerColor backgroundColor = containerColor
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp) modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp),
) { content = content
MiuixIcon(
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = null
) )
}
AnimatedVisibility( },
visible = showText icon = { imageVector, iconModifier, tint ->
) { MiuixIcon(
imageVector = imageVector,
contentDescription = null,
modifier = iconModifier,
tint = tint ?: Color.Unspecified
)
},
text = { label, textModifier, style, color ->
MiuixText( MiuixText(
text = if (lastCheckedState) activeText else inactiveText, text = label,
style = LegadoTheme.typography.labelSmall, style = style,
modifier = Modifier.padding(start = 6.dp), color = color ?: Color.Unspecified,
modifier = textModifier,
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
} }
} )
}
} else { } else {
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) { SmallNoMinTouchTarget {
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier.height(36.dp),
iconSize = 16.dp,
textStyle = LegadoTheme.typography.labelSmall,
textStartPadding = 6.dp,
button = { buttonModifier, onToggle, content ->
TonalToggleButton( TonalToggleButton(
checked = checked, checked = checked,
onCheckedChange = { onCheckedChange = onToggle,
lastCheckedState = it modifier = buttonModifier,
onCheckedChange(it)
showText = true
},
modifier = modifier.height(36.dp),
contentPadding = PaddingValues(horizontal = 8.dp) contentPadding = PaddingValues(horizontal = 8.dp)
) { ) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center horizontalArrangement = Arrangement.Center,
) { content = content
AnimatedIcon(
modifier = Modifier.size(16.dp),
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = null
) )
}
AnimatedVisibility( },
visible = showText icon = { imageVector, iconModifier, _ ->
) { AnimatedIcon(
imageVector = imageVector,
contentDescription = null,
modifier = iconModifier
)
},
text = { label, textModifier, style, color ->
Text( Text(
text = if (lastCheckedState) activeText else inactiveText, text = label,
style = LegadoTheme.typography.labelSmall, style = style,
modifier = Modifier.padding(start = 6.dp), color = color ?: Color.Unspecified,
modifier = textModifier,
maxLines = 1, maxLines = 1,
softWrap = false softWrap = false
) )
} }
} )
}
} }
} }
} }
@@ -16,6 +16,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.semantics.toggleableState
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.legado.app.ui.theme.LegadoTheme import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.LegadoTheme.composeEngine import io.legado.app.ui.theme.LegadoTheme.composeEngine
@@ -31,12 +37,26 @@ fun ToggleChip(
selected: Boolean, selected: Boolean,
onToggle: () -> Unit, onToggle: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
checkedContentDescription: String = "已选择" checkedContentDescription: String = "已选择",
uncheckedContentDescription: String = "未选择"
) { ) {
val isSelected = selected
if (ThemeResolver.isMiuixEngine(composeEngine)) { if (ThemeResolver.isMiuixEngine(composeEngine)) {
MiuixIconButton( MiuixIconButton(
onClick = onToggle, onClick = onToggle,
modifier = modifier, modifier = modifier.semantics {
role = Role.Checkbox
toggleableState = if (isSelected) {
ToggleableState.On
} else {
ToggleableState.Off
}
stateDescription = if (isSelected) {
checkedContentDescription
} else {
uncheckedContentDescription
}
},
backgroundColor = if (selected) { backgroundColor = if (selected) {
MiuixTheme.colorScheme.primaryContainer MiuixTheme.colorScheme.primaryContainer
} else { } else {
@@ -1,304 +0,0 @@
package io.legado.app.ui.widget.components.button
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.OutlinedIconButton
import androidx.compose.material3.Text
import androidx.compose.material3.ToggleButton
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.setValue
import androidx.compose.ui.Alignment
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 io.legado.app.R
import io.legado.app.ui.config.themeConfig.ThemeConfig
import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.ThemeResolver
import io.legado.app.ui.widget.components.icon.AppIcons
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
import kotlinx.coroutines.delay
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.basic.Text as MiuixText
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
enum class TopBarButtonVariant {
Filled, Outlined, Icon
}
@Composable
fun TopBarButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
imageVector: ImageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription: String? = null,
style: TopBarButtonVariant = TopBarButtonVariant.Filled
) {
val commonModifier = modifier
.size(36.dp)
when (style) {
TopBarButtonVariant.Filled -> {
FilledTonalIconButton(
onClick = onClick,
modifier = commonModifier,
colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = GlassTopAppBarDefaults.controlContainerColor(),
contentColor = LegadoTheme.colorScheme.onSurface
)
) {
AnimatedIcon(
modifier = Modifier.size(20.dp),
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
TopBarButtonVariant.Outlined -> {
OutlinedIconButton(
onClick = onClick,
modifier = commonModifier,
border = ButtonDefaults.outlinedButtonBorder()
) {
AnimatedIcon(
modifier = Modifier.size(20.dp),
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
TopBarButtonVariant.Icon -> {
IconButton(
onClick = onClick,
modifier = commonModifier
) {
AnimatedIcon(
modifier = Modifier.size(20.dp),
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
}
}
@Composable
fun TopBarNavigationButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
imageVector: ImageVector = AppIcons.Back,
contentDescription: String? = stringResource(id = R.string.back),
style: TopBarButtonVariant = TopBarButtonVariant.Filled
) {
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
MiuixIconButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription
)
} else {
TopBarButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier.padding(horizontal = 12.dp),
style = style
)
}
}
@Composable
fun TopBarActionButton(
onClick: () -> Unit,
imageVector: ImageVector,
contentDescription: String? = "",
modifier: Modifier = Modifier
) {
val enableProgressive = ThemeConfig.enableProgressiveBlur
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
MiuixIconButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier,
)
} else {
if (enableProgressive) {
TopBarButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier.padding(end = 12.dp),
style = TopBarButtonVariant.Filled
)
} else {
IconButton(onClick = onClick) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
}
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun TopBarAnimatedActionButton(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
iconChecked: ImageVector,
iconUnchecked: ImageVector,
activeText: String,
inactiveText: String,
modifier: Modifier = Modifier
) {
var showText by remember { mutableStateOf(false) }
var lastCheckedState by remember { mutableStateOf(checked) }
LaunchedEffect(showText) {
if (showText) {
delay(1000)
showText = false
}
}
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
val containerColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainerHigh,
animationSpec = tween(150),
label = "MiuixActionButtonContainer"
)
val contentColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.onPrimaryContainer else MiuixTheme.colorScheme.onSurface,
animationSpec = tween(150),
label = "MiuixActionButtonContainer"
)
MiuixIconButton(
onClick = {
lastCheckedState = !checked
onCheckedChange(!checked)
showText = true
},
backgroundColor = containerColor
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.padding(horizontal = 8.dp)
) {
MiuixIcon(
tint = contentColor,
imageVector = if (checked) iconChecked else iconUnchecked,
contentDescription = null
)
AnimatedVisibility(
visible = showText
) {
MiuixText(
text = if (lastCheckedState) activeText else inactiveText,
color = contentColor,
style = LegadoTheme.typography.labelMedium,
modifier = Modifier.padding(start = 8.dp),
maxLines = 1,
softWrap = false
)
}
}
}
} else {
ToggleButton(
modifier = modifier.height(36.dp),
contentPadding = PaddingValues(horizontal = 8.dp),
checked = checked,
onCheckedChange = {
lastCheckedState = it
onCheckedChange(it)
showText = true
}
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
AnimatedContent(
targetState = checked,
label = "IconAnimation"
) { targetChecked ->
AnimatedIcon(
modifier = Modifier.size(20.dp),
imageVector = if (targetChecked) iconChecked else iconUnchecked,
contentDescription = null
)
}
AnimatedVisibility(
visible = showText
) {
Text(
text = if (lastCheckedState) activeText else inactiveText,
style = LegadoTheme.typography.labelMedium,
modifier = Modifier.padding(start = 8.dp),
maxLines = 1,
softWrap = false
)
}
}
}
}
}
@Composable
fun AnimatedIcon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier
) {
AnimatedContent(
targetState = imageVector,
transitionSpec = {
(fadeIn() + scaleIn(initialScale = 0.8f))
.togetherWith(fadeOut())
},
label = "IconTransition"
) { targetIcon ->
Icon(
imageVector = targetIcon,
contentDescription = contentDescription,
modifier = modifier
)
}
}
@@ -23,8 +23,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import io.legado.app.ui.theme.adaptiveHorizontalPadding import io.legado.app.ui.theme.adaptiveHorizontalPadding
import io.legado.app.ui.widget.components.SearchBar import io.legado.app.ui.widget.components.SearchBar
import io.legado.app.ui.widget.components.icon.AppIcon import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.button.TopBarActionButton import io.legado.app.ui.widget.components.topbar.TopBarActionButton
import io.legado.app.ui.widget.components.button.TopBarNavigationButton import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
import io.legado.app.ui.widget.components.icon.AppIcons import io.legado.app.ui.widget.components.icon.AppIcons
import io.legado.app.ui.widget.components.list.ListUiState import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
@@ -0,0 +1,250 @@
package io.legado.app.ui.widget.components.topbar
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.ToggleButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import io.legado.app.R
import io.legado.app.ui.config.themeConfig.ThemeConfig
import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.theme.ThemeResolver
import io.legado.app.ui.widget.components.button.AnimatedActionButtonCore
import io.legado.app.ui.widget.components.button.AnimatedIcon
import io.legado.app.ui.widget.components.icon.AppIcons
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.basic.Text as MiuixText
import top.yukonga.miuix.kmp.basic.Icon as MiuixIcon
import top.yukonga.miuix.kmp.basic.IconButton as MiuixIconButton
@Composable
private fun TopBarButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
imageVector: ImageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription: String? = null
) {
FilledTonalIconButton(
onClick = onClick,
modifier = modifier.size(36.dp),
colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = GlassTopAppBarDefaults.controlContainerColor(),
contentColor = LegadoTheme.colorScheme.onSurface
)
) {
AnimatedIcon(
modifier = Modifier.size(20.dp),
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
@Composable
fun TopBarNavigationButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
imageVector: ImageVector = AppIcons.Back,
contentDescription: String? = stringResource(id = R.string.back)
) {
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
MiuixIconButton(
onClick = onClick,
modifier = modifier
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
} else {
TopBarButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier.padding(horizontal = 12.dp)
)
}
}
@Composable
fun TopBarActionButton(
onClick: () -> Unit,
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier
) {
val enableProgressive = ThemeConfig.enableProgressiveBlur
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
MiuixIconButton(
onClick = onClick,
modifier = modifier,
) {
MiuixIcon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
} else {
if (enableProgressive) {
TopBarButton(
onClick = onClick,
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier.padding(end = 12.dp)
)
} else {
IconButton(
onClick = onClick,
modifier = modifier
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription
)
}
}
}
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun TopBarAnimatedActionButton(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
iconChecked: ImageVector,
iconUnchecked: ImageVector,
activeText: String,
inactiveText: String,
modifier: Modifier = Modifier
) {
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) {
val containerColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainerHigh,
animationSpec = tween(150),
label = "MiuixActionButtonContainer"
)
val contentColor by animateColorAsState(
targetValue = if (checked) MiuixTheme.colorScheme.onPrimaryContainer else MiuixTheme.colorScheme.onSurface,
animationSpec = tween(150),
label = "MiuixActionButtonContainer"
)
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier,
iconSize = 24.dp,
textStyle = LegadoTheme.typography.labelMedium,
textStartPadding = 8.dp,
contentColor = contentColor,
button = { buttonModifier, onToggle, content ->
MiuixIconButton(
onClick = { onToggle(!checked) },
modifier = buttonModifier,
backgroundColor = containerColor
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.padding(horizontal = 8.dp),
content = content
)
}
},
icon = { imageVector, iconModifier, tint ->
MiuixIcon(
tint = tint ?: Color.Unspecified,
imageVector = imageVector,
contentDescription = null,
modifier = iconModifier
)
},
text = { label, textModifier, style, color ->
MiuixText(
text = label,
color = color ?: Color.Unspecified,
style = style,
modifier = textModifier,
maxLines = 1,
softWrap = false
)
}
)
} else {
AnimatedActionButtonCore(
checked = checked,
onCheckedChange = onCheckedChange,
iconChecked = iconChecked,
iconUnchecked = iconUnchecked,
activeText = activeText,
inactiveText = inactiveText,
modifier = modifier.height(36.dp),
iconSize = 20.dp,
textStyle = LegadoTheme.typography.labelMedium,
textStartPadding = 8.dp,
button = { buttonModifier, onToggle, content ->
ToggleButton(
modifier = buttonModifier,
contentPadding = PaddingValues(horizontal = 8.dp),
checked = checked,
onCheckedChange = onToggle
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
content = content
)
}
},
icon = { imageVector, iconModifier, _ ->
AnimatedContent(
targetState = imageVector,
label = "IconAnimation"
) { targetIcon ->
AnimatedIcon(
modifier = iconModifier,
imageVector = targetIcon,
contentDescription = null
)
}
},
text = { label, textModifier, style, color ->
Text(
text = label,
style = style,
color = color ?: Color.Unspecified,
modifier = textModifier,
maxLines = 1,
softWrap = false
)
}
)
}
}