Просмотр исходного кода

fix: 阅读菜单新增了一个精简按钮

HapeLee 3 месяцев назад
Родитель
Сommit
89ab5bee82

+ 1 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -342,6 +342,7 @@ object PreferKey {
     const val titleBarIconPosition = "titleBarIconPosition"
     const val showTitleBarIcons = "showTitleBarIcons"
     const val showMenuIcon = "showMenuIcon"
+    const val titleBarCompact = "titleBarCompact"
     const val disableReturnKey = "disableReturnKey"
     const val selectText = "selectText"
     //我在干什么

+ 5 - 0
app/src/main/java/io/legado/app/data/repository/ReadSettingsRepository.kt

@@ -335,6 +335,9 @@ class ReadSettingsRepository(
     suspend fun setShowMenuIcon(value: Boolean) =
         settingsRepository.putBoolean(PreferKey.showMenuIcon, value)
 
+    suspend fun setTitleBarCompact(value: Boolean) =
+        settingsRepository.putBoolean(PreferKey.titleBarCompact, value)
+
     suspend fun setChineseConverterType(value: Int) =
         settingsRepository.putInt(PreferKey.chineseConverterType, value)
 
@@ -448,6 +451,7 @@ class ReadSettingsRepository(
             showTitleBarIcons = compatDsValue(Keys.ShowTitleBarIcons, false),
             chineseConverterType = compatDsValue(Keys.ChineseConverterType, 0),
             showMenuIcon = compatDsValue(Keys.ShowMenuIcon, false),
+            titleBarCompact = compatDsValue(Keys.TitleBarCompact, false),
         )
     }
 
@@ -551,5 +555,6 @@ class ReadSettingsRepository(
         val ShowTitleBarIcons = booleanPreferencesKey(PreferKey.showTitleBarIcons)
         val ChineseConverterType = intPreferencesKey(PreferKey.chineseConverterType)
         val ShowMenuIcon = booleanPreferencesKey(PreferKey.showMenuIcon)
+        val TitleBarCompact = booleanPreferencesKey(PreferKey.titleBarCompact)
     }
 }

+ 1 - 0
app/src/main/java/io/legado/app/domain/model/settings/ReadSettings.kt

@@ -100,5 +100,6 @@ data class ReadSettings(
     val showTitleBarIcons: Boolean = true,
     val chineseConverterType: Int = 0,
     val showMenuIcon: Boolean = false,
+    val titleBarCompact: Boolean = false,
 )
 

+ 1 - 0
app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt

@@ -212,6 +212,7 @@ object ReadBookConfig {
     var useZhLayout by prefDelegate(PreferKey.useZhLayout, false)
     var readMenuIconShowText by prefDelegate(PreferKey.readMenuIconShowText, false)
     var showMenuIcon by prefDelegate(PreferKey.showMenuIcon, false)
+    var titleBarCompact by prefDelegate(PreferKey.titleBarCompact, false)
     var readMenuFloatingBottomBar by prefDelegate(PreferKey.readMenuFloatingBottomBar, true)
     var readMenuTopBarLiquidGlassButtons by prefDelegate(PreferKey.readMenuTopBarLiquidGlassButtons, false)
     var readMenuTopBarTitleCapsule by prefDelegate(PreferKey.readMenuTopBarTitleCapsule, false)

+ 5 - 0
app/src/main/java/io/legado/app/ui/book/read/ReadBookContract.kt

@@ -399,6 +399,7 @@ data class ReadMenuConfig(
     val readBrightness: Int = 100,
     val brightnessAuto: Boolean = false,
     val showMenuIcon: Boolean = false,
+    val titleBarCompact: Boolean = false,
 )
 
 @Immutable
@@ -1416,6 +1417,10 @@ sealed interface ConfigUpdate {
         override val actions = emptySet<ConfigUpdateAction>()
     }
 
+    data class TitleBarCompact(val value: Boolean) : ConfigUpdate {
+        override val actions = emptySet<ConfigUpdateAction>()
+    }
+
     // --- System UI (also updates AppConfig) ---
     data class HideStatusBar(val value: Boolean) : ConfigUpdate {
         override val actions = setOf(ConfigUpdateAction.UpdateSystemUi, ConfigUpdateAction.UpdateStyle)

+ 100 - 41
app/src/main/java/io/legado/app/ui/book/read/ReadBookMenuBar.kt

@@ -61,11 +61,11 @@ import androidx.compose.material.icons.filled.Block
 import androidx.compose.material.icons.filled.Bookmark
 import androidx.compose.material.icons.filled.BrightnessAuto
 import androidx.compose.material.icons.filled.BugReport
-import androidx.compose.material.icons.filled.Build
 import androidx.compose.material.icons.filled.CleanHands
 import androidx.compose.material.icons.filled.Close
 import androidx.compose.material.icons.filled.CloudDownload
 import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material.icons.filled.Extension
 import androidx.compose.material.icons.filled.FindReplace
 import androidx.compose.material.icons.filled.Image
 import androidx.compose.material.icons.filled.Menu
@@ -1000,7 +1000,6 @@ private fun MenuTitleBar(
             )
     ) {
         val useTitleCapsule = readMenuTopBarTitleCapsuleEnabled(backdrop, state.menuConfig)
-                && topBarVisualState.isProgressiveBlur
         val capsuleIconColor = LegadoTheme.colorScheme.onSurfaceVariant
 
         // Title row: left group (back + capsule/title) + right group (actions)
@@ -1025,7 +1024,7 @@ private fun MenuTitleBar(
                     backdrop = backdrop,
                 )
 
-                if (useTitleCapsule) {
+                if (useTitleCapsule && titleBarMode != "1" && titleBarMode != "3") {
                     TitleCapsuleGlassLayout(
                         state = state,
                         colors = colors,
@@ -1063,12 +1062,13 @@ private fun MenuTitleBar(
                     backdrop = backdrop,
                 )
             } else {
+                val compact = state.menuConfig.titleBarCompact
                 Row(
                     horizontalArrangement = Arrangement.spacedBy(6.dp),
                     verticalAlignment = Alignment.CenterVertically,
                 ) {
                     if (!state.isLocalBook) {
-                        if (state.bookSource?.customButton == true) {
+                        if (!compact && state.bookSource?.customButton == true) {
                             SourceCustomActionButton(
                                 state = state,
                                 colors = colors,
@@ -1076,25 +1076,27 @@ private fun MenuTitleBar(
                                 backdrop = backdrop,
                             )
                         }
-                        SourceActionButton(
-                            state = state,
-                            colors = colors,
-                            onIntent = onIntent,
-                            backdrop = backdrop,
-                        )
-                        RefreshActionButton(
-                            state = state,
-                            colors = colors,
-                            onIntent = onIntent,
-                            backdrop = backdrop,
-                        )
-                        DownloadActionButton(
-                            state = state,
-                            colors = colors,
-                            onIntent = onIntent,
-                            backdrop = backdrop,
-                        )
-                    } else {
+                        if (!compact) {
+                            SourceActionButton(
+                                state = state,
+                                colors = colors,
+                                onIntent = onIntent,
+                                backdrop = backdrop,
+                            )
+                            RefreshActionButton(
+                                state = state,
+                                colors = colors,
+                                onIntent = onIntent,
+                                backdrop = backdrop,
+                            )
+                            DownloadActionButton(
+                                state = state,
+                                colors = colors,
+                                onIntent = onIntent,
+                                backdrop = backdrop,
+                            )
+                        }
+                    } else if (state.isLocalBook && !compact) {
                         if (state.isLocalTxt) {
                             TxtTocRuleActionButton(
                                 state = state,
@@ -1400,20 +1402,44 @@ private fun RowScope.TitleCapsuleGlassLayout(
     titleTextColor: Color,
 ) {
     val pillShape = RoundedCornerShape(50)
+    val glassEnabled = readerMenuLiquidGlassAvailable(backdrop)
+            && state.menuConfig.readMenuTopBarLiquidGlassButtons
+    val iconStyle = state.menuConfig.titleBarIconStyle
 
     Row(
         modifier = Modifier
             .weight(1f)
             .padding(start = 12.dp)
             .height(40.dp)
-            .readMenuLiquidGlass(
-                backdrop = backdrop,
-                colors = colors,
-                shape = pillShape,
-                useTopBarStyle = true,
-                useLens = false,
-                blurRadius = 32.dp,
-                menuConfig = state.menuConfig,
+            .then(
+                if (glassEnabled) {
+                    Modifier.readMenuLiquidGlass(
+                        backdrop = backdrop,
+                        colors = colors,
+                        shape = pillShape,
+                        useTopBarStyle = true,
+                        useLens = false,
+                        blurRadius = 32.dp,
+                        menuConfig = state.menuConfig,
+                    )
+                } else {
+                    val containerColor = when (iconStyle) {
+                        1 -> LegadoTheme.colorScheme.surfaceContainerLow
+                        else -> Color.Transparent
+                    }
+                    val border = when (iconStyle) {
+                        2 -> BorderStroke(
+                            1.dp,
+                            LegadoTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.45f)
+                        )
+
+                        else -> null
+                    }
+                    Modifier
+                        .clip(pillShape)
+                        .background(containerColor, pillShape)
+                        .then(if (border != null) Modifier.border(border, pillShape) else Modifier)
+                }
             )
             .then(
                 if (!state.isLocalBook) {
@@ -1470,6 +1496,7 @@ private fun MenuTitleBarMergedGlassButton(
 
     val pillShape = RoundedCornerShape(50)
     val tint = LegadoTheme.colorScheme.onSurfaceVariant
+    val compact = state.menuConfig.titleBarCompact
 
     Box {
         Row(
@@ -1484,12 +1511,11 @@ private fun MenuTitleBarMergedGlassButton(
                     blurRadius = 32.dp,
                     interactive = true,
                     menuConfig = state.menuConfig,
-                )
-                .padding(horizontal = 4.dp),
+                ),
                 verticalAlignment = Alignment.CenterVertically,
             ) {
             // SwapHoriz - change source
-            if (!state.isLocalBook) {
+            if (!state.isLocalBook && !compact) {
                 if (state.bookSource?.customButton == true) {
                     val customButtonDescription = stringResource(R.string.custom_button)
                     Box(
@@ -1509,7 +1535,7 @@ private fun MenuTitleBarMergedGlassButton(
                             },
                     ) {
                         Icon(
-                            imageVector = Icons.Default.Build,
+                            imageVector = Icons.Default.Extension,
                             contentDescription = null,
                             tint = tint,
                             modifier = Modifier.size(20.dp),
@@ -1624,7 +1650,7 @@ private fun MenuTitleBarMergedGlassButton(
                         .background(tint.copy(alpha = 0.15f))
                         .clearAndSetSemantics { }
                 )
-            } else {
+            } else if (state.isLocalBook && !compact) {
                 // TXT directory rule
                 if (state.isLocalTxt) {
                     val tocRuleDescription = stringResource(R.string.txt_toc_rule)
@@ -1770,7 +1796,7 @@ private fun SourceCustomActionButton(
     MenuTitleGlassButton(
         onClick = { onIntent(ReadBookIntent.SourceCustomButton(false)) },
         onLongClick = { onIntent(ReadBookIntent.SourceCustomButton(true)) },
-        icon = Icons.Default.Build,
+        icon = Icons.Default.Extension,
         contentDescription = stringResource(R.string.custom_button),
         state = state,
         colors = colors,
@@ -1998,6 +2024,41 @@ private fun OverflowDropdownMenu(
     ) { dismiss ->
         var imageStyleExpanded by remember { mutableStateOf(false) }
 
+        // Compact mode: moved from top bar buttons
+        if (state.menuConfig.titleBarCompact) {
+            if (!state.isLocalBook) {
+                RoundDropdownMenuItem(
+                    text = stringResource(R.string.change_origin),
+                    leadingIcon = menuIcon(Icons.Default.SwapHoriz),
+                    onClick = { dismiss(); onIntent(ReadBookIntent.MenuChangeSource) },
+                )
+                RoundDropdownMenuItem(
+                    text = stringResource(R.string.menu_refresh_after),
+                    leadingIcon = menuIcon(Icons.Default.Refresh),
+                    onClick = { dismiss(); onIntent(ReadBookIntent.MenuRefreshAfter) },
+                )
+                RoundDropdownMenuItem(
+                    text = stringResource(R.string.offline_cache),
+                    leadingIcon = menuIcon(Icons.Default.CloudDownload),
+                    onClick = { dismiss(); onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Download)) },
+                )
+            } else {
+                if (state.isLocalTxt) {
+                    RoundDropdownMenuItem(
+                        text = stringResource(R.string.txt_toc_rule),
+                        leadingIcon = menuIcon(Icons.Default.Toc),
+                        onClick = { dismiss(); onIntent(ReadBookIntent.MenuTocRegex) },
+                    )
+                }
+                RoundDropdownMenuItem(
+                    text = stringResource(R.string.set_charset),
+                    leadingIcon = menuIcon(Icons.Default.Translate),
+                    onClick = { dismiss(); onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Charset)) },
+                )
+            }
+            PillDivider()
+        }
+
         // Source actions
         if (!state.isLocalBook) {
             RoundDropdownMenuItem(
@@ -2154,7 +2215,7 @@ private fun OverflowDropdownMenu(
         )
         RoundDropdownMenuItem(
             text = stringResource(R.string.config_btn),
-            leadingIcon = menuIcon(Icons.Default.Build),
+            leadingIcon = menuIcon(Icons.Default.Extension),
             onClick = {
                 dismiss()
                 onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.ToolButtonConfig))
@@ -3094,9 +3155,7 @@ private fun readMenuTopBarTitleCapsuleEnabled(
     backdrop: Backdrop?,
     menuConfig: ReadMenuConfig,
 ): Boolean {
-    return menuConfig.readMenuTopBarBlurMode != ReadMenuBlurMode.None &&
-            menuConfig.readMenuTopBarTitleCapsule &&
-            readerMenuLiquidGlassAvailable(backdrop)
+    return menuConfig.readMenuTopBarTitleCapsule
 }
 
 private fun readMenuBottomBarButtonLiquidGlassEnabled(

+ 8 - 0
app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt

@@ -2340,6 +2340,7 @@ class ReadBookViewModel(
                 readBrightness = ReadBookConfig.readBrightness,
                 brightnessAuto = ReadBookConfig.brightnessAuto,
                 showMenuIcon = ReadBookConfig.showMenuIcon,
+                titleBarCompact = ReadBookConfig.titleBarCompact,
             ),
         )
     }
@@ -5161,6 +5162,13 @@ class ReadBookViewModel(
                 }
                 _uiState.update { it.copy(menuConfig = it.menuConfig.copy(showTitleBarIcons = update.value)) }
             }
+            is ConfigUpdate.TitleBarCompact -> {
+                ReadBookConfig.titleBarCompact = update.value
+                viewModelScope.launch {
+                    readSettingsRepository.setTitleBarCompact(update.value)
+                }
+                _uiState.update { it.copy(menuConfig = it.menuConfig.copy(titleBarCompact = update.value)) }
+            }
 
             // --- System UI (also persists to DataStore) ---
             is ConfigUpdate.HideStatusBar -> {

+ 80 - 48
app/src/main/java/io/legado/app/ui/book/read/sheet/SystemMenuPage.kt

@@ -381,31 +381,6 @@ private fun GlobalMenuTab(
             }
         }
 
-        TinyDropdownSettingItem(
-            title = stringResource(R.string.title_bar_icon_position),
-            selectedValue = preferences.titleBarIconPosition.toString(),
-            displayEntries = arrayOf(
-                stringResource(R.string.position_top_start),
-                stringResource(R.string.position_top_end),
-                stringResource(R.string.position_bottom_start),
-                stringResource(R.string.position_bottom_end),
-            ),
-            entryValues = arrayOf("0", "1", "2", "3"),
-            onValueChange = {
-                onIntent(
-                    ReadBookIntent.UpdateConfig(
-                        ConfigUpdate.TitleBarIconPosition(it.toInt())
-                    )
-                )
-            },
-        )
-        TinySwitchSettingItem(
-            title = stringResource(R.string.show_title_bar_icons),
-            checked = preferences.showTitleBarIcons,
-            onCheckedChange = {
-                onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ShowTitleBarIcons(it)))
-            },
-        )
 
         SectionTitle(stringResource(R.string.show_brightness_view))
 
@@ -522,6 +497,52 @@ private fun GlobalMenuTab(
                 }
             },
         )
+
+        // --- Floating icon settings (at bottom) ---
+        SectionTitle(stringResource(R.string.show_title_bar_icons))
+
+        TinySwitchSettingItem(
+            title = stringResource(R.string.show_title_bar_icons),
+            checked = preferences.showTitleBarIcons,
+            onCheckedChange = {
+                onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.ShowTitleBarIcons(it)))
+            },
+        )
+        AnimatedVisibility(visible = preferences.showTitleBarIcons) {
+            Column {
+                TinyDropdownSettingItem(
+                    title = stringResource(R.string.title_bar_icon_position),
+                    selectedValue = preferences.titleBarIconPosition.toString(),
+                    displayEntries = arrayOf(
+                        stringResource(R.string.position_top_start),
+                        stringResource(R.string.position_top_end),
+                        stringResource(R.string.position_bottom_start),
+                        stringResource(R.string.position_bottom_end),
+                    ),
+                    entryValues = arrayOf("0", "1", "2", "3"),
+                    onValueChange = {
+                        onIntent(
+                            ReadBookIntent.UpdateConfig(
+                                ConfigUpdate.TitleBarIconPosition(it.toInt())
+                            )
+                        )
+                    },
+                )
+                TinyDropdownSettingItem(
+                    title = stringResource(R.string.read_menu_icon_container_style),
+                    selectedValue = preferences.titleBarIconStyle.toString(),
+                    displayEntries = arrayOf(
+                        stringResource(R.string.read_menu_icon_style_plain),
+                        stringResource(R.string.read_menu_icon_style_tonal),
+                        stringResource(R.string.read_menu_icon_style_outlined),
+                    ),
+                    entryValues = arrayOf("0", "1", "2"),
+                    onValueChange = {
+                        onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleBarIconStyle(it.toInt())))
+                    },
+                )
+            }
+        }
     }
 }
 
@@ -732,13 +753,35 @@ private fun TopBarTab(
             .padding(horizontal = 16.dp)
             .verticalScroll(rememberScrollState()),
     ) {
-        TinyDropdownSettingItem(
-            title = stringResource(R.string.title_bar_mode),
-            selectedValue = preferences.titleBarMode,
-            displayEntries = titleBarModeEntries,
-            entryValues = titleBarModeValues,
-            onValueChange = { value ->
-                onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleBarMode(value)))
+        TinySwitchSettingItem(
+            title = stringResource(R.string.read_menu_top_bar_title_capsule),
+            checked = preferences.readMenuTopBarTitleCapsule,
+            onCheckedChange = {
+                onIntent(
+                    ReadBookIntent.UpdateConfig(
+                        ConfigUpdate.MenuTopBarTitleCapsule(
+                            it
+                        )
+                    )
+                )
+            },
+        )
+        AnimatedVisibility(visible = !preferences.readMenuTopBarTitleCapsule) {
+            TinyDropdownSettingItem(
+                title = stringResource(R.string.title_bar_mode),
+                selectedValue = preferences.titleBarMode,
+                displayEntries = titleBarModeEntries,
+                entryValues = titleBarModeValues,
+                onValueChange = { value ->
+                    onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleBarMode(value)))
+                },
+            )
+        }
+        TinySwitchSettingItem(
+            title = stringResource(R.string.title_bar_compact),
+            checked = preferences.titleBarCompact,
+            onCheckedChange = {
+                onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.TitleBarCompact(it)))
             },
         )
         TinyClickableSettingItem(
@@ -818,21 +861,6 @@ private fun TopBarTab(
                 },
             )
         }
-        AnimatedVisibility(visible = topBarBlurEnabled) {
-            TinySwitchSettingItem(
-                title = stringResource(R.string.read_menu_top_bar_title_capsule),
-                checked = preferences.readMenuTopBarTitleCapsule,
-                onCheckedChange = {
-                    onIntent(
-                        ReadBookIntent.UpdateConfig(
-                            ConfigUpdate.MenuTopBarTitleCapsule(
-                                it
-                            )
-                        )
-                    )
-                },
-            )
-        }
     }
 }
 
@@ -863,7 +891,11 @@ internal fun readMenuButtonInfos(context: Context): List<ReadMenuButtonInfo> = l
     ReadMenuButtonInfo("prev_chapter", Icons.Default.SkipPrevious, context.getString(R.string.previous_chapter)),
     ReadMenuButtonInfo("next_chapter", Icons.Default.SkipNext, context.getString(R.string.next_chapter)),
     ReadMenuButtonInfo("replace", Icons.Default.FindReplace, context.getString(R.string.replace_purify)),
-    ReadMenuButtonInfo("replace_badge", Icons.Default.AutoAwesome, context.getString(R.string.replace_purify_badge)),
+    ReadMenuButtonInfo(
+        "replace_badge",
+        Icons.Default.FindReplace,
+        context.getString(R.string.replace_purify_badge)
+    ),
     ReadMenuButtonInfo("translate", Icons.Default.Translate, context.getString(R.string.translate)),
     ReadMenuButtonInfo(
         "ai_summary",

+ 3 - 2
app/src/main/res/values-zh-rCN/strings.xml

@@ -2155,10 +2155,11 @@
     <string name="read_menu_custom_icons">自定义图标</string>
     <string name="read_menu_custom_icons_none">使用默认图标</string>
     <string name="read_menu_custom_icons_count">已自定义 %1$d 个图标</string>
-    <string name="title_bar_icons">顶栏图标</string>
+    <string name="title_bar_icons">浮动图标</string>
     <string name="title_bar_layout">顶栏布局</string>
     <string name="show_title_bar_icons">显示浮动图标</string>
-    <string name="title_bar_icon_position">顶栏图标位置</string>
+    <string name="title_bar_compact">精简顶部按钮</string>
+    <string name="title_bar_icon_position">浮动图标位置</string>
     <string name="position_top_start">左上</string>
     <string name="position_top_end">右上</string>
     <string name="position_bottom_start">左下</string>

+ 3 - 2
app/src/main/res/values/strings.xml

@@ -2176,10 +2176,11 @@
     <string name="read_menu_custom_icons">Custom icons</string>
     <string name="read_menu_custom_icons_none">Use default icons</string>
     <string name="read_menu_custom_icons_count">%1$d custom icons</string>
-    <string name="title_bar_icons">Title Bar Icons</string>
+    <string name="title_bar_icons">Floating icons</string>
     <string name="title_bar_layout">Title Bar Layout</string>
     <string name="show_title_bar_icons">Show floating icons</string>
-    <string name="title_bar_icon_position">Title bar icon position</string>
+    <string name="title_bar_compact">Compact top bar buttons</string>
+    <string name="title_bar_icon_position">Floating icon position</string>
     <string name="position_top_start">Top left</string>
     <string name="position_top_end">Top right</string>
     <string name="position_bottom_start">Bottom left</string>