[优化] 一些优化

This commit is contained in:
HapeLee
2026-03-16 00:31:37 +08:00
parent d6f0ca01b6
commit d2539f80f4
26 changed files with 93 additions and 236 deletions
@@ -13,8 +13,8 @@ import io.legado.app.help.http.text
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.importComponents.ImportItemWrapper
import io.legado.app.ui.widget.components.importComponents.ImportStatus
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isUri
import io.legado.app.utils.readText
@@ -19,9 +19,9 @@ import io.legado.app.model.analyzeRule.CustomUrl
import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.remote.RemoteBook
import io.legado.app.model.remote.RemoteBookWebDav
import io.legado.app.ui.widget.components.rules.InteractionState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.InteractionState
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.AlphanumComparator
import io.legado.app.utils.ConvertUtils
import io.legado.app.utils.toastOnUi
@@ -48,10 +48,10 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import io.legado.app.R
import io.legado.app.ui.book.changecover.ChangeCoverDialog
import io.legado.app.ui.widget.components.Cover
import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
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.cover.Cover
import io.legado.app.utils.SelectImageContract
import io.legado.app.utils.launch
import io.legado.app.utils.showDialogFragment
@@ -81,13 +81,13 @@ import cn.hutool.core.date.DateUtil
import io.legado.app.data.entities.readRecord.ReadRecord
import io.legado.app.data.entities.readRecord.ReadRecordDetail
import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.Cover
import io.legado.app.ui.widget.components.EmptyMessageView
import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
import io.legado.app.ui.widget.components.SearchBarSection
import io.legado.app.ui.widget.components.SectionHeader
import io.legado.app.ui.widget.components.button.AlertButton
import io.legado.app.ui.widget.components.button.TopbarNavigationButton
import io.legado.app.ui.widget.components.cover.Cover
import io.legado.app.ui.widget.components.heatmap.HeatmapCalendarTopBar
import io.legado.app.ui.widget.components.heatmap.HeatmapConfig
import io.legado.app.ui.widget.components.heatmap.HeatmapLegend
@@ -21,8 +21,8 @@ import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook
import io.legado.app.ui.config.readConfig.ReadConfig
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -49,8 +49,8 @@ import io.legado.app.ui.widget.components.ActionItem
import io.legado.app.ui.widget.components.DraggableSelectionHandler
import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheet
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheetMode
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.filePicker.FilePickerSheetMode
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
@@ -8,9 +8,9 @@ import io.legado.app.data.entities.TxtTocRule
import io.legado.app.data.repository.TxtTocRuleRepository
import io.legado.app.data.repository.UploadRepository
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.rules.InteractionState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.InteractionState
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import io.legado.app.utils.fromJsonObject
@@ -34,7 +34,7 @@ import io.legado.app.service.WebService
import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
import io.legado.app.ui.widget.components.SplicedColumnGroup
import io.legado.app.ui.widget.components.button.TopbarNavigationButton
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheet
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.settingItem.ClickableSettingItem
import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem
import io.legado.app.ui.widget.components.settingItem.InputSettingItem
@@ -49,8 +49,8 @@ import io.legado.app.ui.widget.components.ActionItem
import io.legado.app.ui.widget.components.DraggableSelectionHandler
import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheet
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheetMode
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.filePicker.FilePickerSheetMode
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
@@ -8,9 +8,9 @@ import io.legado.app.data.entities.DictRule
import io.legado.app.data.repository.DictRuleRepository
import io.legado.app.data.repository.UploadRepository
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.rules.InteractionState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.InteractionState
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import io.legado.app.utils.fromJsonObject
@@ -1,123 +0,0 @@
package io.legado.app.ui.main.my
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
import androidx.preference.Preference
import io.legado.app.R
import io.legado.app.ui.theme.AppTheme
import io.legado.app.base.BaseFragment
import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey
import io.legado.app.databinding.FragmentMyConfigBinding
import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.prefs.SwitchPreference
import io.legado.app.lib.prefs.fragment.PreferenceFragment
import io.legado.app.service.WebService
import io.legado.app.ui.about.AboutActivity
import io.legado.app.ui.book.bookmark.AllBookmarkActivity
import io.legado.app.ui.book.readRecord.ReadRecordActivity
import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.book.toc.rule.TxtTocRuleActivity
import io.legado.app.ui.config.ConfigActivity
import io.legado.app.ui.config.ConfigTag
import io.legado.app.ui.dict.rule.DictRuleActivity
import io.legado.app.ui.file.FileManageActivity
import io.legado.app.ui.main.MainFragmentInterface
import io.legado.app.ui.main.explore.ExploreFragment
import io.legado.app.ui.replace.ReplaceRuleActivity
import io.legado.app.utils.LogUtils
import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.observeEventSticky
import io.legado.app.utils.openUrl
import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.sendToClip
import io.legado.app.utils.showHelp
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.koin.androidx.compose.koinViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
class MyFragment : Fragment(), MainFragmentInterface {
companion object {
private const val ARG_POSITION = "position"
fun newInstance(position: Int): MyFragment {
return MyFragment().apply {
arguments = Bundle().apply {
putInt(ARG_POSITION, position)
}
}
}
}
override val position: Int by lazy {
arguments?.getInt(ARG_POSITION) ?: 0
}
private val viewModel: MyViewModel by viewModel()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
)
setContent {
AppTheme{
MyScreen(
viewModel = viewModel,
onNavigate = { event ->
handleEvent(event)
}
)
}
}
}
}
private fun handleEvent(event: PrefClickEvent) {
when (event) {
is PrefClickEvent.StartActivity -> {
startActivity(
Intent(requireContext(), event.destination).apply {
event.configTag?.let {
putExtra("configTag", it)
}
}
)
}
is PrefClickEvent.OpenUrl ->
requireContext().openUrl(event.url)
is PrefClickEvent.CopyUrl ->
requireContext().sendToClip(event.url)
is PrefClickEvent.ShowMd ->
showHelp(event.title)
PrefClickEvent.ExitApp ->
requireActivity().finish()
else -> Unit
}
}
}
@@ -1,43 +0,0 @@
package io.legado.app.ui.main.rss
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
import io.legado.app.ui.main.MainFragmentInterface
import io.legado.app.ui.theme.AppTheme
/**
* 订阅界面
*/
class RssFragment() : Fragment(), MainFragmentInterface {
constructor(position: Int) : this() {
arguments = Bundle().apply {
putInt("position", position)
}
}
override val position: Int
get() = arguments?.getInt("position") ?: 0
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
)
setContent {
AppTheme {
RssScreen()
}
}
}
}
}
@@ -1,7 +1,7 @@
package io.legado.app.ui.main.rss
import io.legado.app.data.entities.RssSource
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.list.ListUiState
data class RssUiState(
override val items: List<RssSource> = emptyList(),
@@ -68,8 +68,8 @@ import io.legado.app.ui.widget.components.GlassTopAppBarDefaults
import io.legado.app.ui.widget.components.GroupManageBottomSheet
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
import io.legado.app.ui.widget.components.divider.PillDivider
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheet
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheetMode
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.filePicker.FilePickerSheetMode
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
@@ -13,9 +13,9 @@ import io.legado.app.data.repository.ReplaceRuleRepository
import io.legado.app.data.repository.UploadRepository
import io.legado.app.help.ReplaceAnalyzer
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.rules.InteractionState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.InteractionState
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.GSON
import io.legado.app.utils.getPrefString
import io.legado.app.utils.isJsonArray
@@ -5,7 +5,7 @@ import androidx.lifecycle.viewModelScope
import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb
import io.legado.app.data.entities.RssStar
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.list.ListUiState
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -50,7 +50,7 @@ import io.legado.app.ui.widget.components.button.SmallIconButton
import io.legado.app.ui.widget.components.card.ReorderableSelectionItem
import io.legado.app.ui.widget.components.dialog.TextListInputDialog
import io.legado.app.ui.widget.components.divider.PillDivider
import io.legado.app.ui.widget.components.exportComponents.FilePickerSheet
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
@@ -11,9 +11,9 @@ import io.legado.app.data.repository.UploadRepository
import io.legado.app.help.DefaultData
import io.legado.app.help.source.SourceHelp
import io.legado.app.ui.widget.components.importComponents.BaseImportUiState
import io.legado.app.ui.widget.components.rules.InteractionState
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.rules.SelectableItem
import io.legado.app.ui.widget.components.list.InteractionState
import io.legado.app.ui.widget.components.list.ListUiState
import io.legado.app.ui.widget.components.list.SelectableItem
import io.legado.app.utils.FileUtils
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
@@ -6,7 +6,7 @@ import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb
import io.legado.app.data.entities.RuleSub
import io.legado.app.ui.widget.components.rules.ListUiState
import io.legado.app.ui.widget.components.list.ListUiState
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -39,17 +39,15 @@ object GlassTopAppBarDefaults {
@Composable
fun glassColors(): TopAppBarColors {
val alpha = ThemeConfig.containerOpacity / 100f
val enableBlur = ThemeConfig.enableBlur
val opacity = ThemeConfig.containerOpacity / 100f
val containerColor = if (enableBlur) {
MaterialTheme.colorScheme.surface.copy(alpha = 0f)
} else {
MaterialTheme.colorScheme.surface.copy(alpha = alpha)
}
val containerColor = GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surface.copy(alpha = opacity),
blurAlpha = GlassDefaults.TransparentAlpha
)
val scrolledContainerColor = if (enableBlur) {
MaterialTheme.colorScheme.surface.copy(alpha = 0f)
val scrolledContainerColor = if (ThemeConfig.enableBlur) {
MaterialTheme.colorScheme.surface.copy(alpha = GlassDefaults.TransparentAlpha)
} else {
MaterialTheme.colorScheme.surfaceContainer
}
@@ -62,27 +60,18 @@ object GlassTopAppBarDefaults {
@Composable
fun containerColor(): Color {
val enableBlur = ThemeConfig.enableBlur
val containerColor = if (enableBlur) {
MaterialTheme.colorScheme.surface.copy(alpha = 0f)
} else {
MaterialTheme.colorScheme.surface
}
return containerColor
val opacity = ThemeConfig.containerOpacity / 100f
return GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surface.copy(alpha = opacity),
blurAlpha = GlassDefaults.TransparentAlpha
)
}
@Composable
fun controlContainerColor(): Color {
val enableBlur = ThemeConfig.enableBlur
val baseColor = MaterialTheme.colorScheme.surfaceContainerHighest
return if (enableBlur) {
baseColor.copy(alpha = 0.72f)
} else {
baseColor
}
return GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surfaceContainerHighest,
blurAlpha = GlassDefaults.DefaultBlurAlpha
)
}
}
@@ -7,6 +7,7 @@ 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.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
@@ -15,6 +16,7 @@ import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.IconToggleButtonShapes
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedIconButton
import androidx.compose.material3.OutlinedIconToggleButton
import androidx.compose.material3.OutlinedToggleButton
import androidx.compose.material3.Text
@@ -58,6 +60,35 @@ fun SmallIconButton(
}
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SmallOutlinedIconButton(
onClick: () -> Unit,
icon: ImageVector,
contentDescription: String? = null
) {
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
OutlinedIconButton(
onClick = onClick,
modifier = Modifier.size(
IconButtonDefaults.extraSmallContainerSize(
IconButtonDefaults.IconButtonWidthOption.Uniform
)
),
shapes = IconButtonDefaults.shapes(),
border = ButtonDefaults.outlinedButtonBorder()
) {
Icon(
imageVector = icon,
contentDescription = contentDescription,
modifier = Modifier.size(
IconButtonDefaults.extraSmallIconSize
)
)
}
}
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun SmallTonalIconButton(
@@ -73,7 +104,7 @@ fun SmallTonalIconButton(
IconButtonDefaults.IconButtonWidthOption.Uniform
)
),
shape = IconButtonDefaults.extraSmallRoundShape,
shapes = IconButtonDefaults.shapes(),
colors = IconButtonDefaults.filledTonalIconButtonColors()
) {
Icon(
@@ -16,7 +16,6 @@ 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.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@@ -45,8 +44,7 @@ fun TextCard(
verticalPadding: Dp = 2.dp,
iconSize: Dp = 14.dp,
spacing: Dp = 4.dp,
textStyle: TextStyle = MaterialTheme.typography.labelSmall,
bold: Boolean = true,
textStyle: TextStyle = MaterialTheme.typography.labelSmall
) {
GlassCard(
modifier = modifier,
@@ -75,8 +73,7 @@ fun TextCard(
AnimatedTextLine(
text = text,
style = textStyle,
color = contentColor,
fontWeight = if (bold) FontWeight.Bold else FontWeight.Normal
color = contentColor
)
}
}
@@ -36,6 +36,7 @@ import io.legado.app.R
import io.legado.app.ui.widget.components.ActionItem
import io.legado.app.ui.widget.components.SelectionActions
import io.legado.app.ui.widget.components.list.ListScaffold
import io.legado.app.ui.widget.components.list.ListUiState
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -113,7 +113,7 @@ fun SettingItem(
Text(
it,
style = MaterialTheme.typography.bodySmallEmphasized,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f)
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
)
}
option?.let {
@@ -2,6 +2,7 @@ package io.legado.app.ui.widget.components.settingItem
import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
@Composable
@@ -10,18 +11,22 @@ fun SwitchSettingItem(
description: String? = null,
checked: Boolean,
imageVector: ImageVector? = null,
color: Color? = null,
enabled: Boolean = true,
onCheckedChange: (Boolean) -> Unit
) {
SettingItem(
title = title,
description = description,
imageVector = imageVector,
onClick = { onCheckedChange(!checked) },
color = color,
onClick = { if (enabled) onCheckedChange(!checked) },
trailingContent = {
Switch(
checked = checked,
onCheckedChange = onCheckedChange
onCheckedChange = onCheckedChange,
enabled = enabled
)
}
)
}
}
@@ -30,8 +30,8 @@ import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
import io.legado.app.ui.widget.components.SearchBarSection
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.list.ListUiState
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.rules.ListUiState
@OptIn(ExperimentalMaterial3Api::class)