HapeLee 6 месяцев назад
Родитель
Сommit
29505aa4ef
39 измененных файлов с 762 добавлено и 872 удалено
  1. 1 1
      app/src/main/java/io/legado/app/ui/about/AboutScreen.kt
  2. 2 4
      app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt
  3. 2 2
      app/src/main/java/io/legado/app/ui/book/cache/manage/BookCacheManageScreen.kt
  4. 2 2
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt
  5. 1 1
      app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt
  6. 3 2
      app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt
  7. 5 2
      app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt
  8. 2 4
      app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt
  9. 1 1
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageScreen.kt
  10. 1 1
      app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt
  11. 6 4
      app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt
  12. 2 2
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt
  13. 1 1
      app/src/main/java/io/legado/app/ui/config/ConfigNavScreen.kt
  14. 1 1
      app/src/main/java/io/legado/app/ui/config/backupConfig/BackupConfigScreen.kt
  15. 1 1
      app/src/main/java/io/legado/app/ui/config/coverConfig/CoverConfigScreen.kt
  16. 1 1
      app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt
  17. 1 1
      app/src/main/java/io/legado/app/ui/config/readConfig/ReadConfigScreen.kt
  18. 1 1
      app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfigScreen.kt
  19. 1 1
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt
  20. 0 2
      app/src/main/java/io/legado/app/ui/main/explore/ExploreScreen.kt
  21. 1 1
      app/src/main/java/io/legado/app/ui/main/rss/RssScreen.kt
  22. 3 4
      app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt
  23. 2 2
      app/src/main/java/io/legado/app/ui/rss/article/RssSortScreen.kt
  24. 2 2
      app/src/main/java/io/legado/app/ui/rss/read/RssReadRouteScreen.kt
  25. 10 21
      app/src/main/java/io/legado/app/ui/widget/components/alert/AppAlertDialog.kt
  26. 0 30
      app/src/main/java/io/legado/app/ui/widget/components/button/AlertButton.kt
  27. 74 0
      app/src/main/java/io/legado/app/ui/widget/components/button/AnimatedActionButtonCore.kt
  28. 33 0
      app/src/main/java/io/legado/app/ui/widget/components/button/AnimatedIcon.kt
  29. 66 0
      app/src/main/java/io/legado/app/ui/widget/components/button/AppButton.kt
  30. 4 4
      app/src/main/java/io/legado/app/ui/widget/components/button/AppIconButton.kt
  31. 0 68
      app/src/main/java/io/legado/app/ui/widget/components/button/ConfirmDismissButtonsRow.kt
  32. 90 210
      app/src/main/java/io/legado/app/ui/widget/components/button/MediumIconButton.kt
  33. 66 0
      app/src/main/java/io/legado/app/ui/widget/components/button/MediumTextButton.kt
  34. 0 98
      app/src/main/java/io/legado/app/ui/widget/components/button/MiuixButton.kt
  35. 102 89
      app/src/main/java/io/legado/app/ui/widget/components/button/SmallIconButton.kt
  36. 22 2
      app/src/main/java/io/legado/app/ui/widget/components/button/ToggleChip.kt
  37. 0 304
      app/src/main/java/io/legado/app/ui/widget/components/button/TopBarButton.kt
  38. 2 2
      app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt
  39. 250 0
      app/src/main/java/io/legado/app/ui/widget/components/topbar/TopBarButton.kt

+ 1 - 1
app/src/main/java/io/legado/app/ui/about/AboutScreen.kt

@@ -31,7 +31,7 @@ import io.legado.app.constant.AppConst.appInfo
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.widget.components.AppScaffold
 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.settingItem.SettingItem
 import io.legado.app.ui.widget.components.text.AppText

+ 2 - 4
app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt

@@ -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.bookmark.BookmarkEditSheet
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.TextCard
 import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
@@ -308,8 +308,6 @@ fun AllBookmarkScreen(
                                 TextCard(
                                     text = group.bookName,
                                     textStyle = LegadoTheme.typography.labelLarge,
-                                    backgroundColor = LegadoTheme.colorScheme.cardContainer,
-                                    contentColor = LegadoTheme.colorScheme.onCardContainer,
                                     cornerRadius = 8.dp,
                                     horizontalPadding = 8.dp,
                                     verticalPadding = 6.dp,

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/cache/manage/BookCacheManageScreen.kt

@@ -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.alert.AppAlertDialog
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.TextCard
 import io.legado.app.ui.widget.components.icon.AppIcon

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt

@@ -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.SearchBar
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.explore.calculateExploreKindRows
 import io.legado.app.ui.widget.components.explore.ExploreKindMultiTypeItem

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookScreen.kt

@@ -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.button.SmallIconButton
 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.TextCard
 import io.legado.app.ui.widget.components.filePicker.FilePickerSheet

+ 3 - 2
app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookScreen.kt

@@ -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.SmallIconButton
 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.SelectionItemCard
 import io.legado.app.ui.widget.components.card.TextCard
@@ -259,7 +259,8 @@ fun RemoteBookScreen(
         topBarActions = {
             TopBarActionButton(
                 onClick = { showSheet = RemoteBookSheet.Servers },
-                imageVector = Icons.Default.Storage
+                imageVector = Icons.Default.Storage,
+                contentDescription = "服务器"
             )
         },
         dropDownMenuContent = { dismiss ->

+ 5 - 2
app/src/main/java/io/legado/app/ui/book/info/BookInfoScreen.kt

@@ -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.AppTextField
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.TextCard
 import io.legado.app.ui.widget.components.cover.CoilBookCover
@@ -417,15 +417,18 @@ private fun BookInfoTopBarActions(
         TopBarActionButton(
             onClick = { onMenuAction(BookInfoMenuAction.Edit) },
             imageVector = Icons.Default.Edit,
+            contentDescription = "编辑"
         )
     }
     TopBarActionButton(
         onClick = { onMenuAction(BookInfoMenuAction.Share) },
         imageVector = Icons.Default.Share,
+        contentDescription = "分享"
     )
     TopBarActionButton(
         onClick = { onShowMenuChange(true) },
         imageVector = Icons.Default.MoreVert,
+        contentDescription = "更多"
     )
     BookInfoOverflowMenu(
         expanded = showMenu,

+ 2 - 4
app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt

@@ -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.AppTextField
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarNavigationButton
 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.RoundDropdownMenuItem
@@ -74,8 +73,7 @@ fun BookInfoEditScreen(
                 title = stringResource(id = R.string.book_info_edit),
                 navigationIcon = {
                     TopBarNavigationButton(
-                        onClick = onBack,
-                        style = TopBarButtonVariant.Outlined
+                        onClick = onBack
                     )
                 },
                 actions = {

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageScreen.kt

@@ -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.button.SmallTonalIconButton
 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.ReorderableSelectionItem
 import io.legado.app.ui.widget.components.card.SelectionItemCard

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt

@@ -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.alert.AppAlertDialog
 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.TextCard
 import io.legado.app.ui.widget.components.checkBox.CheckboxItem

+ 6 - 4
app/src/main/java/io/legado/app/ui/book/search/SearchScreen.kt

@@ -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.SelectionItemCard
 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.button.TopBarAnimatedActionButton
-import io.legado.app.ui.widget.components.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
+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.icon.AppIcon
 import io.legado.app.ui.widget.components.icon.AppIcons
@@ -219,13 +219,15 @@ fun SearchScreen(
                             onClick = {
                                 viewModel.onIntent(SearchIntent.SetScopeSheetVisible(true))
                             },
-                            imageVector = AppIcons.Filter
+                            imageVector = AppIcons.Filter,
+                            contentDescription = "筛选"
                         )
                         TopBarActionButton(
                             onClick = {
                                 viewModel.onIntent(SearchIntent.OpenSourceManage)
                             },
                             imageVector = AppIcons.Settings,
+                            contentDescription = "书源管理"
                         )
                     },
                     scrollBehavior = scrollBehavior

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt

@@ -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.SmallAnimatedActionButton
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarAnimatedActionButton
+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.icon.AppIcon
 import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/ConfigNavScreen.kt

@@ -12,7 +12,7 @@ import io.legado.app.R
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.AppScaffold
 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.topbar.GlassMediumFlexibleTopAppBar
 import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/backupConfig/BackupConfigScreen.kt

@@ -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.SplicedColumnGroup
 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.checkBox.CheckboxItem
 import io.legado.app.ui.widget.components.filePicker.FilePickerSheet

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/coverConfig/CoverConfigScreen.kt

@@ -25,7 +25,7 @@ import io.legado.app.constant.PreferKey
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.AppScaffold
 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.settingItem.ClickableSettingItem
 import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt

@@ -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.SplicedColumnGroup
 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.settingItem.ClickableSettingItem
 import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/readConfig/ReadConfigScreen.kt

@@ -18,7 +18,7 @@ import io.legado.app.R
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.AppScaffold
 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.DropdownListSettingItem
 import io.legado.app.ui.widget.components.settingItem.SliderSettingItem

+ 1 - 1
app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfigScreen.kt

@@ -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.SplicedColumnGroup
 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.settingItem.ClickableSettingItem
 import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem

+ 1 - 1
app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfScreen.kt

@@ -87,7 +87,7 @@ import io.legado.app.ui.theme.adaptiveHorizontalPadding
 import io.legado.app.ui.theme.adaptiveHorizontalPaddingTab
 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.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.card.NormalCard
 import io.legado.app.ui.widget.components.card.TextCard

+ 0 - 2
app/src/main/java/io/legado/app/ui/main/explore/ExploreScreen.kt

@@ -272,8 +272,6 @@ fun ExploreScreen(
                 TextCard(
                     text = item.bookSourceName,
                     textStyle = LegadoTheme.typography.labelMediumEmphasized,
-                    backgroundColor = LegadoTheme.colorScheme.cardContainer,
-                    contentColor = LegadoTheme.colorScheme.onCardContainer,
                     cornerRadius = 12.dp,
                     horizontalPadding = 12.dp,
                     verticalPadding = 8.dp,

+ 1 - 1
app/src/main/java/io/legado/app/ui/main/rss/RssScreen.kt

@@ -56,7 +56,7 @@ import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.adaptiveContentPadding
 import io.legado.app.ui.widget.components.SourceIcon
 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.PillHeaderDivider
 import io.legado.app.ui.widget.components.list.ListScaffold

+ 3 - 4
app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt

@@ -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.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.AppTextField
 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.ToggleChip
-import io.legado.app.ui.widget.components.button.TopBarActionButton
-import io.legado.app.ui.widget.components.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.icon.AppIcon
 import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu

+ 2 - 2
app/src/main/java/io/legado/app/ui/rss/article/RssSortScreen.kt

@@ -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.button.SmallIconButton
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.icon.AppIcons
 import io.legado.app.ui.widget.components.menuItem.MenuItemIcon

+ 2 - 2
app/src/main/java/io/legado/app/ui/rss/read/RssReadRouteScreen.kt

@@ -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.card.GlassCard
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.RoundDropdownMenu
 import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem

+ 10 - 21
app/src/main/java/io/legado/app/ui/widget/components/alert/AppAlertDialog.kt

@@ -7,11 +7,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.material3.AlertDialog
 import androidx.compose.material3.AlertDialogDefaults
-import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
-import androidx.compose.material3.OutlinedButton
 import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 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.composeEngine
 import io.legado.app.ui.theme.ThemeResolver
-import io.legado.app.ui.widget.components.button.MiuixPrimaryButton
-import io.legado.app.ui.widget.components.button.MiuixSecondaryButton
+import io.legado.app.ui.widget.components.button.PrimaryButton
+import io.legado.app.ui.widget.components.button.SecondaryButton
 import top.yukonga.miuix.kmp.window.WindowDialog
 
 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@@ -67,7 +64,7 @@ fun AppAlertDialog(
                     verticalAlignment = Alignment.CenterVertically
                 ) {
                     if (onDismiss != null) {
-                        MiuixSecondaryButton(
+                        SecondaryButton(
                             text = dismissText,
                             modifier = Modifier.weight(1f),
                             onClick = {
@@ -78,7 +75,7 @@ fun AppAlertDialog(
                     }
 
                     if (onConfirm != null) {
-                        MiuixPrimaryButton(
+                        PrimaryButton(
                             text = confirmText,
                             modifier = Modifier.weight(1f),
                             onClick = {
@@ -115,29 +112,21 @@ fun AppAlertDialog(
                 },
                 confirmButton = {
                     if (onConfirm != null) {
-                        OutlinedButton(
+                        PrimaryButton(
                             onClick = onConfirm,
-                            colors = ButtonDefaults.outlinedButtonColors(
-                                contentColor = LegadoTheme.colorScheme.primary
-                            )
-                        ) {
-                            Text(text = confirmText)
-                        }
+                            text = confirmText
+                        )
                     }
                 },
                 dismissButton = {
                     if (onDismiss != null) {
-                        TextButton(
+                        SecondaryButton(
                             onClick = {
                                 onDismiss()
                                 onDismissRequest()
                             },
-                            colors = ButtonDefaults.textButtonColors(
-                                contentColor = LegadoTheme.colorScheme.primary
-                            )
-                        ) {
-                            Text(text = dismissText)
-                        }
+                            text = dismissText
+                        )
                     }
                 }
             )

+ 0 - 30
app/src/main/java/io/legado/app/ui/widget/components/button/AlertButton.kt

@@ -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)
-    }
-}
-

+ 74 - 0
app/src/main/java/io/legado/app/ui/widget/components/button/AnimatedActionButtonCore.kt

@@ -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
+            )
+        }
+    }
+}

+ 33 - 0
app/src/main/java/io/legado/app/ui/widget/components/button/AnimatedIcon.kt

@@ -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
+        )
+    }
+}

+ 66 - 0
app/src/main/java/io/legado/app/ui/widget/components/button/AppButton.kt

@@ -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)
+        }
+    }
+}

+ 4 - 4
app/src/main/java/io/legado/app/ui/widget/components/button/AppIconButton.kt

@@ -42,9 +42,9 @@ fun AppIconButton(
             enabled = enabled,
             holdDownState = holdDownState,
             backgroundColor = miuixBackgroundColor,
-            cornerRadius = MiuixIconButtonDefaults.CornerRadius,
-            minHeight = MiuixIconButtonDefaults.MinHeight,
-            minWidth = MiuixIconButtonDefaults.MinWidth,
+            cornerRadius = miuixCornerRadius ?: MiuixIconButtonDefaults.CornerRadius,
+            minHeight = miuixMinHeight ?: MiuixIconButtonDefaults.MinHeight,
+            minWidth = miuixMinWidth ?: MiuixIconButtonDefaults.MinWidth,
             content = content
         )
     } else {
@@ -58,4 +58,4 @@ fun AppIconButton(
             content = content
         )
     }
-}
+}

+ 0 - 68
app/src/main/java/io/legado/app/ui/widget/components/button/ConfirmDismissButtonsRow.kt

@@ -4,80 +4,12 @@ import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
 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.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 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
-            )
-        }
-    }
-}
 
 @Composable
 fun ConfirmDismissButtonsRow(

+ 90 - 210
app/src/main/java/io/legado/app/ui/widget/components/button/MediumIconButton.kt

@@ -1,29 +1,20 @@
 package io.legado.app.ui.widget.components.button
 
-import androidx.compose.animation.AnimatedVisibility
 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.padding
-import androidx.compose.foundation.layout.size
 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.OutlinedIconToggleButton
 import androidx.compose.material3.Text
 import androidx.compose.material3.TonalToggleButton
 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.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.composeEngine
 import io.legado.app.ui.theme.ThemeResolver
-import kotlinx.coroutines.delay
 import top.yukonga.miuix.kmp.theme.MiuixTheme
 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 MediumIconButton(
     onClick: () -> Unit,
     imageVector: ImageVector,
     tint: Color = LegadoTheme.colorScheme.onSurface,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
             onClick = onClick,
-            modifier = modifier
+            modifier = modifier,
+            enabled = enabled
         ) {
             MiuixIcon(
                 imageVector = imageVector,
@@ -61,7 +52,8 @@ fun MediumIconButton(
     } else {
         IconButton(
             onClick = onClick,
-            modifier = modifier
+            modifier = modifier,
+            enabled = enabled
         ) {
             Icon(
                 imageVector = imageVector,
@@ -77,13 +69,14 @@ fun MediumOutlinedIconButton(
     onClick: () -> Unit,
     imageVector: ImageVector,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-    if (isMiuix) {
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
             onClick = onClick,
             modifier = modifier,
+            enabled = enabled,
             backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh
         ) {
             MiuixIcon(
@@ -93,135 +86,10 @@ fun MediumOutlinedIconButton(
         }
     } else {
         OutlinedIconButton(
-            onClick = onClick,
-            border = ButtonDefaults.outlinedButtonBorder()
-        ) {
-            Icon(
-                imageVector = imageVector,
-                contentDescription = contentDescription
-            )
-        }
-    }
-}
-
-@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,
+            enabled = enabled,
             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,
@@ -242,20 +110,7 @@ fun MediumAnimatedActionButton(
     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
-        }
-    }
-
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-
-    if (isMiuix) {
-
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         val containerColor by animateColorAsState(
             targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainerHigh,
             animationSpec = tween(150),
@@ -265,72 +120,97 @@ fun MediumAnimatedActionButton(
         val contentColor by animateColorAsState(
             targetValue = if (checked) MiuixTheme.colorScheme.onPrimaryContainer else MiuixTheme.colorScheme.onSurface,
             animationSpec = tween(150),
-            label = "MiuixActionButtonContainer"
+            label = "MiuixActionButtonContent"
         )
 
-        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
+        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
                 ) {
-                    MiuixText(
-                        text = if (lastCheckedState) activeText else inactiveText,
-                        color = contentColor,
-                        style = LegadoTheme.typography.labelMedium,
-                        modifier = Modifier.padding(start = 8.dp),
-                        maxLines = 1,
-                        softWrap = false
+                    Row(
+                        verticalAlignment = Alignment.CenterVertically,
+                        horizontalArrangement = Arrangement.Center,
+                        modifier = Modifier.padding(horizontal = 8.dp),
+                        content = content
                     )
                 }
+            },
+            icon = { imageVector, iconModifier, tint ->
+                MiuixIcon(
+                    imageVector = imageVector,
+                    contentDescription = null,
+                    modifier = iconModifier,
+                    tint = tint ?: Color.Unspecified
+                )
+            },
+            text = { label, textModifier, style, color ->
+                MiuixText(
+                    text = label,
+                    color = color ?: Color.Unspecified,
+                    style = style,
+                    modifier = textModifier,
+                    maxLines = 1,
+                    softWrap = false
+                )
             }
-        }
+        )
     } else {
-        TonalToggleButton(
+        AnimatedActionButtonCore(
             checked = checked,
-            onCheckedChange = {
-                lastCheckedState = it
-                onCheckedChange(it)
-                showText = true
-            },
-            contentPadding = PaddingValues(horizontal = 8.dp)
-        ) {
-            Row(
-                verticalAlignment = Alignment.CenterVertically,
-                horizontalArrangement = Arrangement.Center
-            ) {
-                AnimatedIcon(
-                    imageVector = if (checked) iconChecked else iconUnchecked,
-                    contentDescription = null
-                )
-
-                AnimatedVisibility(
-                    visible = showText
+            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(
+                    checked = checked,
+                    onCheckedChange = onToggle,
+                    modifier = buttonModifier,
+                    contentPadding = PaddingValues(horizontal = 8.dp)
                 ) {
-                    Text(
-                        text = if (lastCheckedState) activeText else inactiveText,
-                        modifier = Modifier.padding(start = 8.dp),
-                        maxLines = 1,
-                        softWrap = false
+                    Row(
+                        verticalAlignment = Alignment.CenterVertically,
+                        horizontalArrangement = Arrangement.Center,
+                        content = content
                     )
                 }
+            },
+            icon = { imageVector, iconModifier, _ ->
+                AnimatedIcon(
+                    imageVector = imageVector,
+                    contentDescription = null,
+                    modifier = iconModifier
+                )
+            },
+            text = { label, textModifier, style, color ->
+                Text(
+                    text = label,
+                    modifier = textModifier,
+                    style = style,
+                    color = color ?: Color.Unspecified,
+                    maxLines = 1,
+                    softWrap = false
+                )
             }
-        }
+        )
     }
 }

+ 66 - 0
app/src/main/java/io/legado/app/ui/widget/components/button/MediumTextButton.kt

@@ -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)
+            )
+        }
+    }
+}

+ 0 - 98
app/src/main/java/io/legado/app/ui/widget/components/button/MiuixButton.kt

@@ -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
-        )
-    }
-}

+ 102 - 89
app/src/main/java/io/legado/app/ui/widget/components/button/SmallIconButton.kt

@@ -1,6 +1,5 @@
 package io.legado.app.ui.widget.components.button
 
-import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.animateColorAsState
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.layout.Arrangement
@@ -23,19 +22,16 @@ import androidx.compose.material3.Text
 import androidx.compose.material3.TonalToggleButton
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
-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.Color
 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 kotlinx.coroutines.delay
 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
@@ -65,11 +61,15 @@ private fun SmallNoMinTouchTarget(content: @Composable () -> Unit) {
 fun SmallIconButton(
     onClick: () -> Unit,
     imageVector: ImageVector,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
-            onClick = onClick
+            onClick = onClick,
+            modifier = modifier,
+            enabled = enabled
         ) {
             MiuixIcon(
                 imageVector = imageVector,
@@ -81,7 +81,8 @@ fun SmallIconButton(
         SmallNoMinTouchTarget {
             IconButton(
                 onClick = onClick,
-                modifier = Modifier.size(smallContainerSize()),
+                modifier = modifier.size(smallContainerSize()),
+                enabled = enabled,
                 shape = IconButtonDefaults.extraSmallRoundShape,
             ) {
                 Icon(
@@ -100,13 +101,14 @@ fun SmallOutlinedIconButton(
     onClick: () -> Unit,
     imageVector: ImageVector,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-    if (isMiuix) {
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
             onClick = onClick,
             modifier = modifier.size(SmallMiuixButtonSize),
+            enabled = enabled,
             backgroundColor = LegadoTheme.colorScheme.surfaceContainer
         ) {
             MiuixIcon(
@@ -119,7 +121,8 @@ fun SmallOutlinedIconButton(
         SmallNoMinTouchTarget {
             OutlinedIconButton(
                 onClick = onClick,
-                modifier = Modifier.size(smallContainerSize()),
+                modifier = modifier.size(smallContainerSize()),
+                enabled = enabled,
                 shapes = IconButtonDefaults.shapes(),
                 border = ButtonDefaults.outlinedButtonBorder()
             ) {
@@ -139,14 +142,14 @@ fun SmallTonalIconButton(
     onClick: () -> Unit,
     imageVector: ImageVector,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-
-    if (isMiuix) {
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
             onClick = onClick,
             modifier = modifier.size(SmallMiuixButtonSize),
+            enabled = enabled,
             backgroundColor = LegadoTheme.colorScheme.surfaceContainer
         ) {
             MiuixIcon(
@@ -160,6 +163,7 @@ fun SmallTonalIconButton(
             FilledTonalIconButton(
                 onClick = onClick,
                 modifier = modifier.size(smallContainerSize()),
+                enabled = enabled,
                 shapes = IconButtonDefaults.shapes(),
                 colors = IconButtonDefaults.filledTonalIconButtonColors()
             ) {
@@ -180,12 +184,10 @@ fun SmallOutlinedIconToggleButton(
     onCheckedChange: (Boolean) -> Unit,
     imageVector: ImageVector,
     modifier: Modifier = Modifier,
+    enabled: Boolean = true,
     contentDescription: String? = null
 ) {
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-
-    if (isMiuix) {
-
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         val containerColor by animateColorAsState(
             targetValue = if (checked) LegadoTheme.colorScheme.primaryContainer else LegadoTheme.colorScheme.surfaceContainer,
             animationSpec = tween(150),
@@ -200,8 +202,8 @@ fun SmallOutlinedIconToggleButton(
 
         MiuixIconButton(
             onClick = { onCheckedChange(!checked) },
-            modifier = modifier
-                .size(SmallMiuixButtonSize),
+            modifier = modifier.size(SmallMiuixButtonSize),
+            enabled = enabled,
             backgroundColor = containerColor
         ) {
             MiuixIcon(
@@ -211,7 +213,6 @@ fun SmallOutlinedIconToggleButton(
                 modifier = Modifier.size(SmallMiuixIconSize)
             )
         }
-
     } else {
         val defaultShape = IconButtonDefaults.extraSmallRoundShape
         val pressedShape = IconButtonDefaults.extraSmallPressedShape
@@ -225,11 +226,12 @@ fun SmallOutlinedIconToggleButton(
             )
         }
 
-        CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
+        SmallNoMinTouchTarget {
             OutlinedIconToggleButton(
                 checked = checked,
                 onCheckedChange = onCheckedChange,
                 modifier = modifier.size(smallContainerSize()),
+                enabled = enabled,
                 shapes = toggleShapes
             ) {
                 Icon(
@@ -253,91 +255,102 @@ fun SmallAnimatedActionButton(
     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
-        }
-    }
-
-    val isMiuix = ThemeResolver.isMiuixEngine(composeEngine)
-
-    if (isMiuix) {
+    if (ThemeResolver.isMiuixEngine(composeEngine)) {
         val containerColor by animateColorAsState(
             targetValue = if (checked) MiuixTheme.colorScheme.primaryContainer else MiuixTheme.colorScheme.surfaceContainer,
             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, vertical = 6.dp)
-            ) {
-                MiuixIcon(
-                    imageVector = if (checked) iconChecked else iconUnchecked,
-                    contentDescription = null
-                )
-
-                AnimatedVisibility(
-                    visible = showText
+        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(
+                    onClick = { onToggle(!checked) },
+                    modifier = buttonModifier,
+                    backgroundColor = containerColor
                 ) {
-                    MiuixText(
-                        text = if (lastCheckedState) activeText else inactiveText,
-                        style = LegadoTheme.typography.labelSmall,
-                        modifier = Modifier.padding(start = 6.dp),
-                        maxLines = 1,
-                        softWrap = false
+                    Row(
+                        verticalAlignment = Alignment.CenterVertically,
+                        horizontalArrangement = Arrangement.Center,
+                        modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp),
+                        content = content
                     )
                 }
+            },
+            icon = { imageVector, iconModifier, tint ->
+                MiuixIcon(
+                    imageVector = imageVector,
+                    contentDescription = null,
+                    modifier = iconModifier,
+                    tint = tint ?: Color.Unspecified
+                )
+            },
+            text = { label, textModifier, style, color ->
+                MiuixText(
+                    text = label,
+                    style = style,
+                    color = color ?: Color.Unspecified,
+                    modifier = textModifier,
+                    maxLines = 1,
+                    softWrap = false
+                )
             }
-        }
+        )
     } else {
-        CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
-            TonalToggleButton(
+        SmallNoMinTouchTarget {
+            AnimatedActionButtonCore(
                 checked = checked,
-                onCheckedChange = {
-                    lastCheckedState = it
-                    onCheckedChange(it)
-                    showText = true
-                },
+                onCheckedChange = onCheckedChange,
+                iconChecked = iconChecked,
+                iconUnchecked = iconUnchecked,
+                activeText = activeText,
+                inactiveText = inactiveText,
                 modifier = modifier.height(36.dp),
-                contentPadding = PaddingValues(horizontal = 8.dp)
-            ) {
-                Row(
-                    verticalAlignment = Alignment.CenterVertically,
-                    horizontalArrangement = Arrangement.Center
-                ) {
-                    AnimatedIcon(
-                        modifier = Modifier.size(16.dp),
-                        imageVector = if (checked) iconChecked else iconUnchecked,
-                        contentDescription = null
-                    )
-
-                    AnimatedVisibility(
-                        visible = showText
+                iconSize = 16.dp,
+                textStyle = LegadoTheme.typography.labelSmall,
+                textStartPadding = 6.dp,
+                button = { buttonModifier, onToggle, content ->
+                    TonalToggleButton(
+                        checked = checked,
+                        onCheckedChange = onToggle,
+                        modifier = buttonModifier,
+                        contentPadding = PaddingValues(horizontal = 8.dp)
                     ) {
-                        Text(
-                            text = if (lastCheckedState) activeText else inactiveText,
-                            style = LegadoTheme.typography.labelSmall,
-                            modifier = Modifier.padding(start = 6.dp),
-                            maxLines = 1,
-                            softWrap = false
+                        Row(
+                            verticalAlignment = Alignment.CenterVertically,
+                            horizontalArrangement = Arrangement.Center,
+                            content = content
                         )
                     }
+                },
+                icon = { imageVector, iconModifier, _ ->
+                    AnimatedIcon(
+                        imageVector = imageVector,
+                        contentDescription = null,
+                        modifier = iconModifier
+                    )
+                },
+                text = { label, textModifier, style, color ->
+                    Text(
+                        text = label,
+                        style = style,
+                        color = color ?: Color.Unspecified,
+                        modifier = textModifier,
+                        maxLines = 1,
+                        softWrap = false
+                    )
                 }
-            }
+            )
         }
     }
 }

+ 22 - 2
app/src/main/java/io/legado/app/ui/widget/components/button/ToggleChip.kt

@@ -16,6 +16,12 @@ import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 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 io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme.composeEngine
@@ -31,12 +37,26 @@ fun ToggleChip(
     selected: Boolean,
     onToggle: () -> Unit,
     modifier: Modifier = Modifier,
-    checkedContentDescription: String = "已选择"
+    checkedContentDescription: String = "已选择",
+    uncheckedContentDescription: String = "未选择"
 ) {
+    val isSelected = selected
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
         MiuixIconButton(
             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) {
                 MiuixTheme.colorScheme.primaryContainer
             } else {

+ 0 - 304
app/src/main/java/io/legado/app/ui/widget/components/button/TopBarButton.kt

@@ -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
-        )
-    }
-}

+ 2 - 2
app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt

@@ -23,8 +23,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
 import io.legado.app.ui.theme.adaptiveHorizontalPadding
 import io.legado.app.ui.widget.components.SearchBar
 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.button.TopBarNavigationButton
+import io.legado.app.ui.widget.components.topbar.TopBarActionButton
+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.list.ListUiState
 import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu

+ 250 - 0
app/src/main/java/io/legado/app/ui/widget/components/topbar/TopBarButton.kt

@@ -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
+                )
+            }
+        )
+    }
+}