diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index 015393830..010803100 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -10,7 +10,6 @@ import android.content.res.Configuration import android.graphics.BitmapFactory import android.os.Build import androidx.core.graphics.scale -import coil.ImageLoader import com.github.liuyueyi.quick.transfer.constants.TransType import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColorsOptions @@ -44,9 +43,9 @@ import io.legado.app.help.LifecycleHelp import io.legado.app.help.RuleBigDataHelp import io.legado.app.help.book.BookHelp import io.legado.app.help.config.AppConfig +import io.legado.app.help.config.OldThemeConfig +import io.legado.app.help.config.OldThemeConfig.applyDayNightInit import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig -import io.legado.app.help.config.ThemeConfig.applyDayNightInit import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.http.Cronet import io.legado.app.help.http.ObsoleteUrlFactory @@ -155,7 +154,7 @@ class App : Application() { BookHelp.clearInvalidCache() Backup.clearCache() ReadBookConfig.clearBgAndCache() - ThemeConfig.clearBg() + OldThemeConfig.clearBg() //初始化简繁转换引擎 when (AppConfig.chineseConverterType) { 1 -> { diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 452fea8f9..bc03e5d5d 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -27,9 +27,8 @@ import io.legado.app.constant.EventBus import io.legado.app.constant.PreferKey import io.legado.app.constant.Theme import io.legado.app.help.config.AppConfig -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.theme.ThemeSyncer import io.legado.app.utils.applyOpenTint import io.legado.app.utils.applyTint import io.legado.app.utils.disableAutoFill @@ -232,7 +231,7 @@ abstract class BaseActivity( open fun upBackgroundImage() { if (imageBg) { try { - ThemeConfig.getBgImage(this, windowManager.windowSize)?.let { + OldThemeConfig.getBgImage(this, windowManager.windowSize)?.let { window.decorView.background = it.toDrawable(resources) } } catch (e: OutOfMemoryError) { @@ -245,7 +244,6 @@ abstract class BaseActivity( open fun observeLiveBus() { observeEvent(EventBus.RECREATE) { - ThemeSyncer.syncAll() recreate() } } diff --git a/app/src/main/java/io/legado/app/base/BaseComposeActivity.kt b/app/src/main/java/io/legado/app/base/BaseComposeActivity.kt index 261cf87ee..1ecddb6c7 100644 --- a/app/src/main/java/io/legado/app/base/BaseComposeActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseComposeActivity.kt @@ -9,9 +9,8 @@ import androidx.core.graphics.drawable.toDrawable import androidx.core.view.WindowCompat import io.legado.app.constant.EventBus import io.legado.app.constant.Theme -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.ui.theme.AppTheme -import io.legado.app.ui.theme.ThemeSyncer import io.legado.app.utils.disableAutoFill import io.legado.app.utils.fullScreen import io.legado.app.utils.observeEvent @@ -66,7 +65,7 @@ abstract class BaseComposeActivity( open fun upBackgroundImage() { try { - ThemeConfig.getBgImage(this, windowManager.windowSize)?.let { + OldThemeConfig.getBgImage(this, windowManager.windowSize)?.let { window.setBackgroundDrawable(it.toDrawable(resources)) } } catch (_: Exception) {} @@ -74,7 +73,6 @@ abstract class BaseComposeActivity( open fun observeLiveBus() { observeEvent(EventBus.RECREATE) { - ThemeSyncer.syncAll() recreate() } } diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index c2e7a4b37..3d147b820 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -181,6 +181,7 @@ object PreferKey { const val composeEngine = "composeEngine" const val containerOpacity = "containerOpacity" const val enableBlur = "enableBlur" + const val enableProgressiveBlur = "enableProgressiveBlur" const val cBackground = "colorBackground" const val cBBackground = "colorBottomBackground" const val bgImage = "backgroundImage" diff --git a/app/src/main/java/io/legado/app/help/DefaultData.kt b/app/src/main/java/io/legado/app/help/DefaultData.kt index b99f7953b..0d70c5993 100644 --- a/app/src/main/java/io/legado/app/help/DefaultData.kt +++ b/app/src/main/java/io/legado/app/help/DefaultData.kt @@ -8,8 +8,8 @@ import io.legado.app.data.entities.KeyboardAssist import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.TxtTocRule import io.legado.app.help.config.LocalConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.BookCover import io.legado.app.utils.GSON @@ -70,12 +70,12 @@ object DefaultData { GSON.fromJsonArray(json).getOrNull() ?: emptyList() } - val themeConfigs: List by lazy { + val themeConfigs: List by lazy { val json = String( - appCtx.assets.open("defaultData${File.separator}${ThemeConfig.configFileName}") + appCtx.assets.open("defaultData${File.separator}${OldThemeConfig.configFileName}") .readBytes() ) - GSON.fromJsonArray(json).getOrNull() ?: emptyList() + GSON.fromJsonArray(json).getOrNull() ?: emptyList() } val rssSources: List by lazy { diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 52ce1b079..de6f2eea0 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -15,8 +15,8 @@ import io.legado.app.constant.AppPattern import io.legado.app.data.entities.BaseSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.config.AppConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.help.http.BackstageWebView import io.legado.app.help.http.CookieManager.cookieJarHeader import io.legado.app.help.http.CookieStore @@ -1203,12 +1203,12 @@ interface JsExtensions : JsEncodeUtils { */ @JavascriptInterface fun getThemeConfig(): String { - val themeConfig = ThemeConfig.getDurConfig(appCtx) + val themeConfig = OldThemeConfig.getDurConfig(appCtx) return GSON.toJson(themeConfig) } fun getThemeConfigMap(): Map { - return ThemeConfig.getDurConfig(appCtx).toMap() + return OldThemeConfig.getDurConfig(appCtx).toMap() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/config/ThemeConfig.kt b/app/src/main/java/io/legado/app/help/config/OldThemeConfig.kt similarity index 99% rename from app/src/main/java/io/legado/app/help/config/ThemeConfig.kt rename to app/src/main/java/io/legado/app/help/config/OldThemeConfig.kt index e4725866c..42a54eef2 100644 --- a/app/src/main/java/io/legado/app/help/config/ThemeConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/OldThemeConfig.kt @@ -32,7 +32,7 @@ import splitties.init.appCtx import java.io.File @Keep -object ThemeConfig { +object OldThemeConfig { const val configFileName = "themeConfig.json" val configFilePath = FileUtils.getPath(appCtx.filesDir, configFileName) diff --git a/app/src/main/java/io/legado/app/help/storage/Backup.kt b/app/src/main/java/io/legado/app/help/storage/Backup.kt index 291701084..4b58081f3 100644 --- a/app/src/main/java/io/legado/app/help/storage/Backup.kt +++ b/app/src/main/java/io/legado/app/help/storage/Backup.kt @@ -13,8 +13,8 @@ import io.legado.app.help.AppWebDav import io.legado.app.help.DirectLinkUpload import io.legado.app.help.config.AppConfig import io.legado.app.help.config.LocalConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.BookCover import io.legado.app.utils.FileUtils @@ -82,7 +82,7 @@ object Backup { DirectLinkUpload.ruleFileName, ReadBookConfig.configFileName, ReadBookConfig.shareConfigFileName, - ThemeConfig.configFileName, + OldThemeConfig.configFileName, BookCover.configFileName, "config.xml" ) @@ -169,8 +169,8 @@ object Backup { FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.shareConfigFileName) .writeText(it) } - GSON.toJson(ThemeConfig.configList).let { - FileUtils.createFileIfNotExist(backupPath + File.separator + ThemeConfig.configFileName) + GSON.toJson(OldThemeConfig.configList).let { + FileUtils.createFileIfNotExist(backupPath + File.separator + OldThemeConfig.configFileName) .writeText(it) } DirectLinkUpload.getConfig()?.let { diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index 3cc79fe4c..4d7793532 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -33,8 +33,8 @@ import io.legado.app.help.LauncherIconHelp import io.legado.app.help.book.isLocal import io.legado.app.help.book.upType import io.legado.app.help.config.LocalConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.model.BookCover import io.legado.app.model.localBook.LocalBook import io.legado.app.utils.ACache @@ -216,12 +216,12 @@ object Restore { AppLog.put("恢复直链上传出错\n${it.localizedMessage}", it) } //恢复主题配置 - File(path, ThemeConfig.configFileName).takeIf { + File(path, OldThemeConfig.configFileName).takeIf { it.exists() }?.runCatching { - FileUtils.delete(ThemeConfig.configFilePath) - copyTo(File(ThemeConfig.configFilePath)) - ThemeConfig.upConfig() + FileUtils.delete(OldThemeConfig.configFilePath) + copyTo(File(OldThemeConfig.configFilePath)) + OldThemeConfig.upConfig() }?.onFailure { AppLog.put("恢复主题出错\n${it.localizedMessage}", it) } @@ -301,7 +301,7 @@ object Restore { if (!BuildConfig.DEBUG) { LauncherIconHelp.changeIcon(appCtx.getPrefString(PreferKey.launcherIcon)) } - ThemeConfig.applyDayNight(appCtx) + OldThemeConfig.applyDayNight(appCtx) } } diff --git a/app/src/main/java/io/legado/app/lib/prefs/ThemeCardPreference.kt b/app/src/main/java/io/legado/app/lib/prefs/ThemeCardPreference.kt index 72a90ddb4..ee2a0becc 100644 --- a/app/src/main/java/io/legado/app/lib/prefs/ThemeCardPreference.kt +++ b/app/src/main/java/io/legado/app/lib/prefs/ThemeCardPreference.kt @@ -21,7 +21,7 @@ import io.legado.app.constant.EventBus import io.legado.app.constant.PreferKey import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.alert -import io.legado.app.ui.theme.ThemeSyncer +import io.legado.app.ui.config.themeConfig.ThemeConfig import io.legado.app.utils.getPrefString import io.legado.app.utils.postEvent import io.legado.app.utils.restart @@ -91,13 +91,13 @@ class ThemeCardPreference(context: Context, attrs: AttributeSet) : Preference(co return@setOnClickListener } else { AppConfig.containerOpacity = 0 - ThemeSyncer.syncContainerOpacity() } } val oldValue = currentValue currentValue = value persistString(value) callChangeListener(value) + ThemeConfig.appTheme = value notifyDataSetChanged() val isDynamicSwitch = (oldValue == "12" || value == "12") Handler(Looper.getMainLooper()).postDelayed({ diff --git a/app/src/main/java/io/legado/app/lib/prefs/ThemeModePreference.kt b/app/src/main/java/io/legado/app/lib/prefs/ThemeModePreference.kt index 404fd08b3..d6fd9777b 100644 --- a/app/src/main/java/io/legado/app/lib/prefs/ThemeModePreference.kt +++ b/app/src/main/java/io/legado/app/lib/prefs/ThemeModePreference.kt @@ -7,7 +7,7 @@ import android.util.AttributeSet import androidx.preference.PreferenceViewHolder import com.google.android.material.button.MaterialButtonToggleGroup import io.legado.app.R -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { @@ -59,7 +59,7 @@ class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(co persistString(newValue) callChangeListener(newValue) Handler(Looper.getMainLooper()).postDelayed({ - ThemeConfig.applyDayNight(context) + OldThemeConfig.applyDayNight(context) }, 300) } } diff --git a/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt b/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt index 01697e969..aae01fb9b 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutScreen.kt @@ -35,7 +35,7 @@ import io.legado.app.R import io.legado.app.constant.AppConst.appInfo import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar import io.legado.app.ui.widget.components.SplicedColumnGroup -import io.legado.app.ui.widget.components.button.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.settingItem.SettingItem @@ -61,7 +61,7 @@ fun AboutScreen( GlassMediumFlexibleTopAppBar( title = { Text(stringResource(R.string.about)) }, navigationIcon = { - SmallTopBarButton(onClick = onBack) + TopbarNavigationButton(onClick = onBack) }, scrollBehavior = scrollBehavior ) diff --git a/app/src/main/java/io/legado/app/ui/association/ImportThemeDialog.kt b/app/src/main/java/io/legado/app/ui/association/ImportThemeDialog.kt index 60babbeca..d98eae3b9 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportThemeDialog.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportThemeDialog.kt @@ -14,7 +14,7 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.ItemSourceImportBinding -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig //import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.dialog.CodeDialog import io.legado.app.ui.widget.dialog.WaitDialog @@ -126,7 +126,7 @@ class ImportThemeDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_recycl } inner class SourcesAdapter(context: Context) : - RecyclerAdapter(context) { + RecyclerAdapter(context) { override fun getViewBinding(parent: ViewGroup): ItemSourceImportBinding { return ItemSourceImportBinding.inflate(inflater, parent, false) @@ -135,7 +135,7 @@ class ImportThemeDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_recycl override fun convert( holder: ItemViewHolder, binding: ItemSourceImportBinding, - item: ThemeConfig.Config, + item: OldThemeConfig.Config, payloads: MutableList ) { binding.apply { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt index e6bd927e3..83f9aa612 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt @@ -8,12 +8,19 @@ import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppConst import io.legado.app.constant.AppLog import io.legado.app.exception.NoStackTraceException -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text -import io.legado.app.utils.* +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.isAbsUrl +import io.legado.app.utils.isJsonArray +import io.legado.app.utils.isJsonObject +import io.legado.app.utils.isUri +import io.legado.app.utils.readText import splitties.init.appCtx class ImportThemeViewModel(app: Application) : BaseViewModel(app) { @@ -21,8 +28,8 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { val errorLiveData = MutableLiveData() val successLiveData = MutableLiveData() - val allSources = arrayListOf() - val checkSources = arrayListOf() + val allSources = arrayListOf() + val checkSources = arrayListOf() val selectStatus = arrayListOf() val isSelectAll: Boolean @@ -50,7 +57,7 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { execute { selectStatus.forEachIndexed { index, b -> if (b) { - ThemeConfig.addConfig(allSources[index]) + OldThemeConfig.addConfig(allSources[index]) } } }.onFinally { @@ -72,11 +79,12 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { private suspend fun importSourceAwait(text: String) { when { text.isJsonObject() -> { - GSON.fromJsonObject(text).getOrThrow().let { + GSON.fromJsonObject(text).getOrThrow().let { allSources.add(it) } } - text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow() + + text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow() .let { items -> allSources.addAll(items) } @@ -106,7 +114,7 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { private fun comparisonSource() { execute { allSources.forEach { config -> - val source = ThemeConfig.configList.find { + val source = OldThemeConfig.configList.find { it.themeName == config.themeName } checkSources.add(source) diff --git a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt index 9edd64367..6ce30df5f 100644 --- a/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/bookmark/AllBookmarkScreen.kt @@ -22,8 +22,6 @@ import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.UnfoldLess import androidx.compose.material.icons.filled.UnfoldMore -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.Icon @@ -48,9 +46,11 @@ import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar import io.legado.app.ui.widget.components.SearchBarSection 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.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn import io.legado.app.ui.widget.components.lazylist.Scroller +import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu +import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import org.koin.androidx.compose.koinViewModel @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class, @@ -105,7 +105,7 @@ fun AllBookmarkScreen( }, scrollBehavior = scrollBehavior, navigationIcon = { - SmallTopBarButton(onClick = onBack) + TopbarNavigationButton(onClick = onBack) }, actions = { if (bookmarksGrouped.isNotEmpty()) { @@ -127,11 +127,11 @@ fun AllBookmarkScreen( IconButton(onClick = { showMenu = true }) { Icon(Icons.Default.MoreVert, contentDescription = "Menu") } - DropdownMenu( + RoundDropdownMenu( expanded = showMenu, onDismissRequest = { showMenu = false } ) { - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("导出 JSON") }, onClick = { showMenu = false @@ -139,7 +139,7 @@ fun AllBookmarkScreen( exportLauncher.launch(null) } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("导出 Markdown") }, onClick = { showMenu = false diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt index 2ed649187..f9b566099 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt @@ -53,6 +53,7 @@ class ExploreShowViewModel( private val _rawBooks = MutableStateFlow>(emptyList()) private val _filterState = MutableStateFlow(BookFilterState.fromId(AppConfig.exploreFilterState)) private val _isLoading = MutableStateFlow(false) + private val _isRefreshing = MutableStateFlow(false) private val _errorMsg = MutableStateFlow(null) private var bookSource: BookSource? = null private var exploreUrl: String? = null @@ -68,10 +69,14 @@ class ExploreShowViewModel( private val _gridCount = MutableStateFlow(appCtx.exploreLayoutGrid) val gridCount = _gridCount.asStateFlow() val isEnd: StateFlow = _isEndStateFlow.asStateFlow() + + val isRefreshing = _isRefreshing.asStateFlow() + fun saveGridCount(value: Int) { appCtx.exploreLayoutGrid = value _gridCount.value = value } + val uiBooks = combine( _rawBooks, _filterState, diff --git a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt index 8d81be832..1edb86582 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditScreen.kt @@ -50,8 +50,8 @@ 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.SmallTopBarButton import io.legado.app.ui.widget.components.button.TopBarButtonVariant +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import io.legado.app.utils.SelectImageContract import io.legado.app.utils.launch import io.legado.app.utils.showDialogFragment @@ -72,13 +72,13 @@ fun BookInfoEditScreen( GlassMediumFlexibleTopAppBar( title = { Text(text = stringResource(id = R.string.book_info_edit)) }, navigationIcon = { - SmallTopBarButton( + TopbarNavigationButton( onClick = onBack, style = TopBarButtonVariant.Outlined ) }, actions = { - SmallTopBarButton( + TopbarNavigationButton( onClick = { viewModel.save(onSave) }, imageVector = Icons.Default.Save ) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt index 92d3369b2..cec12e392 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt @@ -33,8 +33,8 @@ import io.legado.app.constant.PreferKey import io.legado.app.databinding.ViewReadMenuBinding import io.legado.app.help.config.AppConfig import io.legado.app.help.config.LocalConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.source.getSourceType import io.legado.app.lib.dialogs.alert @@ -693,7 +693,7 @@ class ReadMenu @JvmOverloads constructor( description = context.getString(R.string.day_night_switch), onClick = { AppConfig.isNightTheme = !AppConfig.isNightTheme - ThemeConfig.applyDayNight(context) + OldThemeConfig.applyDayNight(context) buttonMap["theme"]?.setIconResource( if (AppConfig.isNightTheme) R.drawable.ic_daytime else R.drawable.ic_brightness ) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index 456218c45..bb30a09bc 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -15,8 +15,8 @@ import io.legado.app.constant.EventBus import io.legado.app.databinding.DialogReadBookStyleBinding import io.legado.app.databinding.ItemReadStyleBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.config.ThemeConfig import io.legado.app.lib.dialogs.alert import io.legado.app.model.ReadBook import io.legado.app.ui.book.read.ReadBookActivity @@ -121,7 +121,7 @@ class ReadStyleDialog : BaseBottomSheetDialogFragment(R.layout.dialog_read_book_ } tvDayNight.setOnClickListener { AppConfig.isNightTheme = !AppConfig.isNightTheme - ThemeConfig.applyDayNight(requireContext()) + OldThemeConfig.applyDayNight(requireContext()) } // rgPageAnim.setOnCheckedChangeListener { _, checkedId -> // ReadBook.book?.setPageAnim(-1) diff --git a/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt b/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt index f390256f7..9ea526af7 100644 --- a/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/readRecord/ReadRecordScreen.kt @@ -47,6 +47,7 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -87,7 +88,7 @@ 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.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton 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 @@ -98,6 +99,7 @@ import io.legado.app.ui.widget.components.heatmap.WeekdayLabelsColumn import io.legado.app.ui.widget.components.heatmap.rememberDateRange import io.legado.app.ui.widget.components.heatmap.rememberDaysInRange import io.legado.app.ui.widget.components.heatmap.rememberWeeks +import io.legado.app.ui.widget.components.modalBottomSheet.GlassModalBottomSheet import io.legado.app.ui.widget.components.swipe.SwipeAction import io.legado.app.ui.widget.components.swipe.SwipeActionContainer import io.legado.app.utils.StringUtils.formatFriendlyDate @@ -163,7 +165,7 @@ fun ReadRecordScreen( ) }, navigationIcon = { - SmallTopBarButton(onClick = onBackClick) + TopbarNavigationButton(onClick = onBackClick) }, actions = { IconButton(onClick = { @@ -318,8 +320,8 @@ fun ReadRecordScreen( if (showCalendar) { val sheetState = - androidx.compose.material3.rememberModalBottomSheetState(skipPartiallyExpanded = true) - androidx.compose.material3.ModalBottomSheet( + rememberModalBottomSheetState(skipPartiallyExpanded = true) + GlassModalBottomSheet( onDismissRequest = { showCalendar = false }, sheetState = sheetState ) { diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt index 4860b4d8f..79f15221f 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentScreen.kt @@ -58,7 +58,7 @@ 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.button.AnimatedActionButton -import io.legado.app.ui.widget.components.button.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import io.legado.app.ui.widget.components.card.TextCard import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn import org.koin.androidx.compose.koinViewModel @@ -141,7 +141,7 @@ fun SearchContentScreen( ) }, navigationIcon = { - SmallTopBarButton(onClick = onBack) + TopbarNavigationButton(onClick = onBack) }, actions = { Row( diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocScreen.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocScreen.kt index c025b9ce6..18f06a54e 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocScreen.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocScreen.kt @@ -294,33 +294,33 @@ fun TocScreen( when (pagerState.currentPage) { 0 -> { RoundDropdownMenuItem( - text = "使用替换规则", + text = { Text("使用替换规则") }, trailingIcon = { Checkbox(checked = useReplace, onCheckedChange = null) }, onClick = { viewModel.toggleUseReplace() } ) RoundDropdownMenuItem( - text = "显示字数", + text = { Text("显示字数") }, trailingIcon = { Checkbox(checked = showWordCount, onCheckedChange = null) }, onClick = { viewModel.toggleShowWordCount() } ) RoundDropdownMenuItem( - text = "反转目录", + text = { Text("反转目录") }, onClick = { viewModel.reverseToc() } ) PillDivider() RoundDropdownMenuItem( - text = "替换规则", + text = { Text("替换规则") }, onClick = { onOpenReplaceRule(null) dismiss() } ) RoundDropdownMenuItem( - text = "新建替换规则", + text = { Text("新建替换规则") }, onClick = { val scopes = mutableListOf() book?.name?.let { scopes.add(it) } @@ -340,7 +340,7 @@ fun TocScreen( if (book?.isLocal == true) { PillHeaderDivider(title = "本地书籍选项") RoundDropdownMenuItem( - text = "本地书籍目录规则", + text = { Text("本地书籍目录规则") }, onClick = { val intent = Intent(context, TxtTocRuleActivity::class.java).apply { @@ -351,7 +351,7 @@ fun TocScreen( } ) RoundDropdownMenuItem( - text = "拆分超长章节", + text = { Text("拆分超长章节") }, trailingIcon = { Checkbox( checked = viewModel.isSplitLongChapter, @@ -368,7 +368,7 @@ fun TocScreen( else -> { RoundDropdownMenuItem( - text = "导出书签为JSON", + text = { Text("导出书签为JSON") }, onClick = { val dateFormat = SimpleDateFormat( "yyyyMMdd_HHmm", @@ -380,7 +380,7 @@ fun TocScreen( } ) RoundDropdownMenuItem( - text = "导出书签为MarkDown", + text = { Text("导出书签为MarkDown") }, onClick = { val dateFormat = SimpleDateFormat( "yyyyMMdd_HHmm", @@ -445,13 +445,13 @@ fun TocScreen( onDismissRequest = { showVolumeMenu = false } ) { RoundDropdownMenuItem( - text = "展开所有卷", + text = { Text("展开所有卷") }, onClick = { viewModel.expandAllVolumes(); showVolumeMenu = false } ) RoundDropdownMenuItem( - text = "收起所有卷", + text = { Text("收起所有卷") }, onClick = { viewModel.collapseAllVolumes(); showVolumeMenu = false } @@ -463,7 +463,7 @@ fun TocScreen( PillHeaderDivider(title = "快速跳转") volumeItems.forEach { uiItem -> RoundDropdownMenuItem( - text = uiItem.title, + text = { Text(uiItem.title) }, onClick = { scope.launch { val targetIndex = diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt index 8ee66e2a8..93b164981 100644 --- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt @@ -22,7 +22,7 @@ import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogImageBlurringBinding import io.legado.app.help.LauncherIconHelp import io.legado.app.help.config.AppConfig -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector import io.legado.app.lib.prefs.ColorPreference @@ -32,7 +32,7 @@ import io.legado.app.lib.prefs.ThemeCardPreference import io.legado.app.lib.prefs.ThemeModePreference import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.theme.ThemeSyncer +import io.legado.app.ui.config.themeConfig.ThemeConfig import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.utils.ColorUtils @@ -181,13 +181,20 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), } - PreferKey.paletteStyle, PreferKey.pureBlack, PreferKey.enableBlur, PreferKey.swipeAnimation -> { - ThemeSyncer.syncAll() + PreferKey.paletteStyle, PreferKey.pureBlack, PreferKey.swipeAnimation -> { Handler(Looper.getMainLooper()).postDelayed({ recreateActivities() }, 100) } + PreferKey.enableBlur -> { + ThemeConfig.enableBlur = PreferKey.enableBlur.toBoolean() + } + + PreferKey.enableProgressiveBlur -> { + ThemeConfig.enableProgressiveBlur = PreferKey.enableProgressiveBlur.toBoolean() + } + PreferKey.customMode -> handleRestartRequired() PreferKey.isPredictiveBackEnabled -> { @@ -263,17 +270,15 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), .setTitle(getString(R.string.container_opacity)) .setMaxValue(100) .setMinValue(0) - .setValue(AppConfig.containerOpacity) + .setValue(ThemeConfig.containerOpacity) .setCustomButton((R.string.btn_default_s)) { - AppConfig.containerOpacity = 100 - ThemeSyncer.syncContainerOpacity() + ThemeConfig.containerOpacity = 100 Handler(Looper.getMainLooper()).postDelayed({ upPreferenceSummary(PreferKey.containerOpacity) }, 100) } .show { - AppConfig.containerOpacity = it - ThemeSyncer.syncContainerOpacity() + ThemeConfig.containerOpacity = it Handler(Looper.getMainLooper()).postDelayed({ upPreferenceSummary(PreferKey.containerOpacity) }, 100) @@ -305,11 +310,11 @@ class ThemeConfigFragment : PreferenceFragmentCompat(), alertBinding.editView.text?.toString()?.let { themeName -> when (key) { "saveDayTheme" -> { - ThemeConfig.saveDayTheme(requireContext(), themeName) + OldThemeConfig.saveDayTheme(requireContext(), themeName) } "saveNightTheme" -> { - ThemeConfig.saveNightTheme(requireContext(), themeName) + OldThemeConfig.saveNightTheme(requireContext(), themeName) } } } diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt b/app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt index bab1a338e..804eab7ac 100644 --- a/app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt +++ b/app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt @@ -2,7 +2,6 @@ package io.legado.app.ui.config import android.content.Context import android.os.Bundle -import android.util.Log import android.view.MenuItem import android.view.View import android.view.ViewGroup @@ -15,11 +14,10 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.ItemThemeConfigBinding -import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.config.OldThemeConfig import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.primaryColor //import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -54,14 +52,14 @@ class ThemeListDialog : BaseBottomSheetDialogFragment(R.layout.dialog_recycler_v } fun initData() { - adapter.setItems(ThemeConfig.configList) + adapter.setItems(OldThemeConfig.configList) } override fun onMenuItemClick(item: MenuItem?): Boolean { when (item?.itemId) { R.id.menu_import -> { requireContext().getClipText()?.let { - if (ThemeConfig.addConfig(it)) { + if (OldThemeConfig.addConfig(it)) { initData() } else { toastOnUi("格式不对,添加失败") @@ -75,7 +73,7 @@ class ThemeListDialog : BaseBottomSheetDialogFragment(R.layout.dialog_recycler_v fun delete(index: Int) { alert(R.string.delete, R.string.sure_del) { yesButton { - ThemeConfig.delConfig(index) + OldThemeConfig.delConfig(index) initData() } noButton() @@ -83,12 +81,12 @@ class ThemeListDialog : BaseBottomSheetDialogFragment(R.layout.dialog_recycler_v } fun share(index: Int) { - val json = GSON.toJson(ThemeConfig.configList[index]) + val json = GSON.toJson(OldThemeConfig.configList[index]) requireContext().share(json, "主题分享") } inner class Adapter(context: Context) : - RecyclerAdapter(context) { + RecyclerAdapter(context) { override fun getViewBinding(parent: ViewGroup): ItemThemeConfigBinding { return ItemThemeConfigBinding.inflate(inflater, parent, false) @@ -97,7 +95,7 @@ class ThemeListDialog : BaseBottomSheetDialogFragment(R.layout.dialog_recycler_v override fun convert( holder: ItemViewHolder, binding: ItemThemeConfigBinding, - item: ThemeConfig.Config, + item: OldThemeConfig.Config, payloads: MutableList ) { binding.apply { @@ -113,7 +111,10 @@ class ThemeListDialog : BaseBottomSheetDialogFragment(R.layout.dialog_recycler_v override fun registerListener(holder: ItemViewHolder, binding: ItemThemeConfigBinding) { binding.apply { root.setOnClickListener { - ThemeConfig.applyConfig(context, ThemeConfig.configList[holder.layoutPosition]) + OldThemeConfig.applyConfig( + context, + OldThemeConfig.configList[holder.layoutPosition] + ) } ivShare.setOnClickListener { share(holder.layoutPosition) diff --git a/app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt b/app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt index 3746d3c3a..29c19b312 100644 --- a/app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt +++ b/app/src/main/java/io/legado/app/ui/config/otherConfig/OtherConfigScreen.kt @@ -34,7 +34,7 @@ import io.legado.app.R 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.SmallTopBarButton +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.settingItem.ClickableSettingItem import io.legado.app.ui.widget.components.settingItem.DropdownListSettingItem @@ -89,7 +89,7 @@ fun OtherConfigScreen( }, scrollBehavior = scrollBehavior, navigationIcon = { - SmallTopBarButton(onClick = onBackClick) + TopbarNavigationButton(onClick = onBackClick) } ) } diff --git a/app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfig.kt b/app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfig.kt new file mode 100644 index 000000000..e554753d2 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfig.kt @@ -0,0 +1,31 @@ +package io.legado.app.ui.config.themeConfig + +import io.legado.app.constant.PreferKey +import io.legado.app.ui.config.prefDelegate + +object ThemeConfig { + + var containerOpacity by prefDelegate(PreferKey.containerOpacity, 100) + + var enableBlur by prefDelegate(PreferKey.enableBlur, false) + + var enableProgressiveBlur by prefDelegate(PreferKey.enableProgressiveBlur, true) + + var paletteStyle by prefDelegate(PreferKey.paletteStyle, "tonalSpot") + + var appTheme by prefDelegate(PreferKey.appTheme, "0") + + var isPureBlack by prefDelegate(PreferKey.pureBlack, false) + + var bgImageLight by prefDelegate(PreferKey.bgImage, null) + + var bgImageDark by prefDelegate(PreferKey.bgImageN, null) + + fun hasImageBg(isDark: Boolean): Boolean { + return if (isDark) { + !bgImageDark.isNullOrEmpty() + } else { + !bgImageLight.isNullOrEmpty() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleScreen.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleScreen.kt index 13335ba26..83cd0c65a 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleScreen.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleScreen.kt @@ -73,6 +73,7 @@ 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 import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn +import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.rules.RuleListScaffold import kotlinx.coroutines.launch import org.koin.androidx.compose.koinViewModel @@ -387,35 +388,35 @@ fun ReplaceRuleScreen( }, snackbarHostState = snackbarHostState, dropDownMenuContent = { dismiss -> - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("在线导入") }, onClick = { dismiss() showUrlInput = true // 触发输入框 } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("本地导入") }, onClick = { importDoc.launch(arrayOf("text/plain", "application/json")); dismiss() } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("分组管理") }, onClick = { showGroupManageSheet = true; dismiss() } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("帮助") }, onClick = { /*TODO*/ dismiss() } ) HorizontalDivider() - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("旧的在前") }, onClick = { viewModel.setSortMode("asc"); dismiss() } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("新的在前") }, onClick = { viewModel.setSortMode("desc"); dismiss() } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("名称升序") }, onClick = { viewModel.setSortMode("name_asc") @@ -425,7 +426,7 @@ fun ReplaceRuleScreen( } } ) - DropdownMenuItem( + RoundDropdownMenuItem( text = { Text("名称降序") }, onClick = { viewModel.setSortMode("name_desc") diff --git a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt index 586db348e..e39a7f26e 100644 --- a/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt +++ b/app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditScreen.kt @@ -81,7 +81,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar import io.legado.app.ui.widget.components.button.AlertButton -import io.legado.app.ui.widget.components.button.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import org.koin.androidx.compose.koinViewModel @Composable @@ -121,7 +121,7 @@ fun ReplaceEditScreen( GlassMediumFlexibleTopAppBar( title = { Text(if (state.id > 0) "编辑替换规则" else "新增替换规则") }, navigationIcon = { - SmallTopBarButton(onClick = onBack) + TopbarNavigationButton(onClick = onBack) }, actions = { AnimatedVisibility( diff --git a/app/src/main/java/io/legado/app/ui/theme/AppTheme.kt b/app/src/main/java/io/legado/app/ui/theme/AppTheme.kt index e38b19296..cf706fedc 100644 --- a/app/src/main/java/io/legado/app/ui/theme/AppTheme.kt +++ b/app/src/main/java/io/legado/app/ui/theme/AppTheme.kt @@ -7,8 +7,9 @@ import androidx.compose.material3.MotionScheme import androidx.compose.material3.Shapes import androidx.compose.material3.Typography import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import io.legado.app.ui.config.themeConfig.ThemeConfig @OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable @@ -16,18 +17,23 @@ fun AppTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { - val appThemeMode by ThemeState.themeMode.collectAsState() - val isPureBlack by ThemeState.isPureBlack.collectAsState() - val hasImageBg by ThemeState.hasImageBg.collectAsState() - val paletteStyle by ThemeState.paletteStyle.collectAsState() + val context = LocalContext.current + val appThemeMode = ThemeResolver.resolveThemeMode(ThemeConfig.appTheme) + val isPureBlack = ThemeConfig.isPureBlack + val hasImageBg = ThemeConfig.hasImageBg(darkTheme) + val paletteStyle = ThemeConfig.paletteStyle - val colorScheme = ThemeManager.getColorScheme( - mode = appThemeMode, - darkTheme = darkTheme, - isAmoled = isPureBlack, - isImageBg = hasImageBg, - paletteStyle = paletteStyle - ) + val colorScheme = + remember(context, appThemeMode, darkTheme, isPureBlack, hasImageBg, paletteStyle) { + ThemeManager.getColorScheme( + context = context, + mode = appThemeMode, + darkTheme = darkTheme, + isAmoled = isPureBlack, + isImageBg = hasImageBg, + paletteStyle = paletteStyle + ) + } MaterialExpressiveTheme( colorScheme = colorScheme, @@ -36,5 +42,4 @@ fun AppTheme( shapes = Shapes(), content = content ) - } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/theme/BaseColorScheme.kt b/app/src/main/java/io/legado/app/ui/theme/BaseColorScheme.kt index 9f64ac4a7..0146ae1bd 100644 --- a/app/src/main/java/io/legado/app/ui/theme/BaseColorScheme.kt +++ b/app/src/main/java/io/legado/app/ui/theme/BaseColorScheme.kt @@ -1,15 +1,11 @@ package io.legado.app.ui.theme import androidx.compose.material3.ColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ReadOnlyComposable abstract class BaseColorScheme { abstract val lightScheme: ColorScheme abstract val darkScheme: ColorScheme - @Composable - @ReadOnlyComposable fun getColorScheme(darkTheme: Boolean): ColorScheme { return if (darkTheme) darkScheme else lightScheme } diff --git a/app/src/main/java/io/legado/app/ui/theme/OpaqueColorScheme.kt b/app/src/main/java/io/legado/app/ui/theme/OpaqueColorScheme.kt new file mode 100644 index 000000000..7b48561a5 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/theme/OpaqueColorScheme.kt @@ -0,0 +1,31 @@ +package io.legado.app.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.ColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import io.legado.app.ui.config.themeConfig.ThemeConfig +import io.legado.app.ui.theme.ThemeManager.getColorScheme + +@Composable +fun rememberOpaqueColorScheme(): ColorScheme { + val context = LocalContext.current + val isDark = isSystemInDarkTheme() + val appThemeMode = ThemeResolver.resolveThemeMode(ThemeConfig.appTheme) + val isPureBlack = ThemeConfig.isPureBlack + val hasImageBg = ThemeConfig.hasImageBg(isDark) + val paletteStyle = ThemeConfig.paletteStyle + + return remember(context, appThemeMode, isDark, isPureBlack, hasImageBg, paletteStyle) { + getColorScheme( + context = context, + mode = appThemeMode, + darkTheme = isDark, + isAmoled = isPureBlack, + isImageBg = hasImageBg, + paletteStyle = paletteStyle, + forceOpaque = true + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/theme/ThemeManager.kt b/app/src/main/java/io/legado/app/ui/theme/ThemeManager.kt index 8f7d87d5f..ebc798374 100644 --- a/app/src/main/java/io/legado/app/ui/theme/ThemeManager.kt +++ b/app/src/main/java/io/legado/app/ui/theme/ThemeManager.kt @@ -1,13 +1,11 @@ package io.legado.app.ui.theme +import android.content.Context import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.ColorScheme import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.theme.ThemeResolver.resolvePaletteStyle import io.legado.app.ui.theme.colorScheme.AugustColorScheme @@ -40,16 +38,17 @@ object ThemeManager { AppThemeMode.Transparent to TransparentColorScheme, ) - @Composable + fun getColorScheme( + context: Context, mode: AppThemeMode, - darkTheme: Boolean = isSystemInDarkTheme(), + darkTheme: Boolean, isAmoled: Boolean, isImageBg: Boolean, paletteStyle: String?, forceOpaque: Boolean = false ): ColorScheme { - val context = LocalContext.current + val style = resolvePaletteStyle(paletteStyle) val actualMode = if (forceOpaque && mode == AppThemeMode.Transparent) { AppThemeMode.WH diff --git a/app/src/main/java/io/legado/app/ui/theme/ThemeState.kt b/app/src/main/java/io/legado/app/ui/theme/ThemeState.kt deleted file mode 100644 index ca2371b19..000000000 --- a/app/src/main/java/io/legado/app/ui/theme/ThemeState.kt +++ /dev/null @@ -1,73 +0,0 @@ -package io.legado.app.ui.theme - -import io.legado.app.constant.PreferKey -import io.legado.app.help.config.AppConfig -import io.legado.app.utils.getPrefBoolean -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import splitties.init.appCtx - -object ThemeState { - - private val _themeMode = - MutableStateFlow(ThemeResolver.resolveThemeMode(AppConfig.AppTheme.toString())) - val themeMode: StateFlow = _themeMode.asStateFlow() - - private val _isPureBlack = - MutableStateFlow(appCtx.getPrefBoolean(PreferKey.pureBlack, false)) - val isPureBlack: StateFlow = _isPureBlack.asStateFlow() - - private val _hasImageBg = - MutableStateFlow(AppConfig.hasImageBg) - val hasImageBg: StateFlow = _hasImageBg.asStateFlow() - - private val _paletteStyle = - MutableStateFlow(AppConfig.paletteStyle) - val paletteStyle: StateFlow = _paletteStyle.asStateFlow() - - private val _enableBlur = - MutableStateFlow(AppConfig.enableBlur) - val enableBlur: StateFlow = _enableBlur.asStateFlow() - - private val _containerOpacity = - MutableStateFlow(AppConfig.containerOpacity) - val containerOpacity: StateFlow = _containerOpacity - - fun updateThemeMode(newMode: AppThemeMode) { - if (_themeMode.value != newMode) { - _themeMode.value = newMode - } - } - - fun updatePureBlack(enabled: Boolean) { - if (_isPureBlack.value != enabled) { - _isPureBlack.value = enabled - } - } - - fun updateImageBg(enabled: Boolean) { - if (_hasImageBg.value != enabled) { - _hasImageBg.value = enabled - } - } - - fun updatePaletteStyle(style: String?) { - if (_paletteStyle.value != style) { - _paletteStyle.value = style - } - } - - fun updateEnableBlur(enabled: Boolean) { - if (_enableBlur.value != enabled) { - _enableBlur.value = enabled - } - } - - fun updateContainerOpacity(opacity: Int) { - if (_containerOpacity.value != opacity) { - _containerOpacity.value = opacity - } - } - -} diff --git a/app/src/main/java/io/legado/app/ui/theme/ThemeSyncer.kt b/app/src/main/java/io/legado/app/ui/theme/ThemeSyncer.kt deleted file mode 100644 index 666847c45..000000000 --- a/app/src/main/java/io/legado/app/ui/theme/ThemeSyncer.kt +++ /dev/null @@ -1,45 +0,0 @@ -package io.legado.app.ui.theme - -import io.legado.app.constant.PreferKey -import io.legado.app.help.config.AppConfig -import io.legado.app.utils.getPrefBoolean -import splitties.init.appCtx - -object ThemeSyncer { - - fun syncAll() { - syncThemeMode() - syncPureBlack() - syncImageBg() - syncPaletteStyle() - syncEnableBlur() - syncContainerOpacity() - } - - fun syncThemeMode() { - ThemeState.updateThemeMode( - ThemeResolver.resolveThemeMode(AppConfig.AppTheme.toString()) - ) - } - - fun syncPureBlack() { - ThemeState.updatePureBlack(appCtx.getPrefBoolean(PreferKey.pureBlack, false)) - } - - fun syncImageBg() { - ThemeState.updateImageBg(AppConfig.hasImageBg) - } - - fun syncPaletteStyle() { - ThemeState.updatePaletteStyle(AppConfig.paletteStyle) - } - - fun syncEnableBlur() { - ThemeState.updateEnableBlur(AppConfig.enableBlur) - } - - fun syncContainerOpacity() { - ThemeState.updateContainerOpacity(AppConfig.containerOpacity) - } - -} diff --git a/app/src/main/java/io/legado/app/ui/widget/components/GlassMediumFlexibleTopAppBar.kt b/app/src/main/java/io/legado/app/ui/widget/components/GlassMediumFlexibleTopAppBar.kt index 71a88d821..7dc5b72a6 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/GlassMediumFlexibleTopAppBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/GlassMediumFlexibleTopAppBar.kt @@ -5,14 +5,13 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MediumFlexibleTopAppBar +import androidx.compose.material3.TopAppBarColors import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import io.legado.app.ui.theme.ThemeState +import io.legado.app.ui.config.themeConfig.ThemeConfig @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable @@ -22,30 +21,9 @@ fun GlassMediumFlexibleTopAppBar( subtitle: (@Composable () -> Unit)? = null, scrollBehavior: TopAppBarScrollBehavior? = null, navigationIcon: @Composable () -> Unit = {}, - actions: @Composable RowScope.() -> Unit = {} + actions: @Composable RowScope.() -> Unit = {}, + colors: TopAppBarColors = GlassTopAppBarDefaults.glassColors() ) { - val opacityValue by ThemeState.containerOpacity.collectAsState() - val enableBlur by ThemeState.enableBlur.collectAsState() - - val alpha = opacityValue / 100f - - val containerColor = if (enableBlur) { - Color.Transparent - } else { - MaterialTheme.colorScheme.surface.copy(alpha = alpha) - } - - val scrolledContainerColor = if (enableBlur) { - Color.Transparent - } else { - MaterialTheme.colorScheme.surfaceContainer.copy(alpha = alpha) - } - - val appBarColors = TopAppBarDefaults.topAppBarColors( - containerColor = containerColor, - scrolledContainerColor = scrolledContainerColor - ) - MediumFlexibleTopAppBar( modifier = modifier, title = title, @@ -53,7 +31,46 @@ fun GlassMediumFlexibleTopAppBar( navigationIcon = navigationIcon, actions = actions, scrollBehavior = scrollBehavior, - colors = appBarColors + colors = colors ) +} + +object GlassTopAppBarDefaults { + + @Composable + fun glassColors(): TopAppBarColors { + val alpha = ThemeConfig.containerOpacity / 100f + val enableBlur = ThemeConfig.enableBlur + + val containerColor = if (enableBlur) { + MaterialTheme.colorScheme.surface + } else { + MaterialTheme.colorScheme.surface.copy(alpha = alpha) + } + + val scrolledContainerColor = if (enableBlur) { + MaterialTheme.colorScheme.surface.copy(alpha = 0f) + } else { + MaterialTheme.colorScheme.surfaceContainer + } + + return TopAppBarDefaults.topAppBarColors( + containerColor = containerColor, + scrolledContainerColor = scrolledContainerColor + ) + } + + @Composable + fun controlContainerColor(): Color { + val enableBlur = ThemeConfig.enableBlur + val baseColor = MaterialTheme.colorScheme.surfaceContainerHigh + + return if (enableBlur) { + val alpha = 0.6f + baseColor.copy(alpha = alpha) + } else { + baseColor.copy(alpha = ThemeConfig.containerOpacity / 100f) + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/components/button/SmallTopBarButton.kt b/app/src/main/java/io/legado/app/ui/widget/components/button/TopBarButton.kt similarity index 66% rename from app/src/main/java/io/legado/app/ui/widget/components/button/SmallTopBarButton.kt rename to app/src/main/java/io/legado/app/ui/widget/components/button/TopBarButton.kt index b1bddcf99..90d99eade 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/button/SmallTopBarButton.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/button/TopBarButton.kt @@ -17,31 +17,26 @@ import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedIconButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp -import io.legado.app.ui.theme.ThemeState +import io.legado.app.ui.config.themeConfig.ThemeConfig +import io.legado.app.ui.widget.components.GlassTopAppBarDefaults enum class TopBarButtonVariant { Filled, Outlined, Icon } @Composable -fun SmallTopBarButton( +fun TopBarButton( onClick: () -> Unit, modifier: Modifier = Modifier, imageVector: ImageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription: String? = null, style: TopBarButtonVariant = TopBarButtonVariant.Filled ) { - val themeOpacity by ThemeState.containerOpacity.collectAsState() - val baseColor = MaterialTheme.colorScheme.surfaceContainerHigh - val glassColor = baseColor.copy(alpha = (themeOpacity / 100f).coerceAtLeast(0.6f)) val commonModifier = modifier - .padding(horizontal = 12.dp) .size(36.dp) when (style) { @@ -50,7 +45,7 @@ fun SmallTopBarButton( onClick = onClick, modifier = commonModifier, colors = IconButtonDefaults.filledTonalIconButtonColors( - containerColor = glassColor, + containerColor = GlassTopAppBarDefaults.controlContainerColor(), contentColor = MaterialTheme.colorScheme.onSurface ) ) { @@ -79,6 +74,50 @@ fun SmallTopBarButton( } } +@Composable +fun TopbarNavigationButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + imageVector: ImageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription: String? = "返回", + style: TopBarButtonVariant = TopBarButtonVariant.Filled +) { + TopBarButton( + onClick = onClick, + imageVector = imageVector, + contentDescription = contentDescription, + modifier = modifier.padding(start = 12.dp, end = 4.dp), + style = style + ) +} + +@Composable +fun TopBarActionButton( + onClick: () -> Unit, + imageVector: ImageVector, + contentDescription: String?, + modifier: Modifier = Modifier +) { + val enableProgressive = ThemeConfig.enableProgressiveBlur + + 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 + ) + } + } +} + @Composable private fun SmallIcon(imageVector: ImageVector, contentDescription: String?) { AnimatedContent( diff --git a/app/src/main/java/io/legado/app/ui/widget/components/card/GlassCard.kt b/app/src/main/java/io/legado/app/ui/widget/components/card/GlassCard.kt index 201ec3d34..01add0890 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/card/GlassCard.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/card/GlassCard.kt @@ -7,12 +7,10 @@ import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardElevation import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape -import io.legado.app.ui.theme.ThemeState +import io.legado.app.ui.config.themeConfig.ThemeConfig @Composable fun GlassCard( @@ -24,7 +22,7 @@ fun GlassCard( border: BorderStroke? = null, content: @Composable ColumnScope.() -> Unit ) { - val opacity by ThemeState.containerOpacity.collectAsState() + val opacity = ThemeConfig.containerOpacity val cardColors = CardDefaults.cardColors( containerColor = color.copy(alpha = opacity / 100f) ) diff --git a/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenu.kt b/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenu.kt index b4a4b478f..033191122 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenu.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenu.kt @@ -4,13 +4,21 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.MaterialExpressiveTheme import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MotionScheme +import androidx.compose.material3.Shapes +import androidx.compose.material3.Typography import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import io.legado.app.ui.theme.rememberOpaqueColorScheme + +@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun RoundDropdownMenu( expanded: Boolean, @@ -21,17 +29,27 @@ fun RoundDropdownMenu( verticalSpacing: Dp = 8.dp, content: @Composable ColumnScope.(dismiss: () -> Unit) -> Unit ) { + val colorScheme = rememberOpaqueColorScheme() + DropdownMenu( expanded = expanded, onDismissRequest = onDismissRequest, modifier = modifier, shape = shape, - shadowElevation = shadowElevation + shadowElevation = shadowElevation, + containerColor = colorScheme.surfaceContainerLow ) { - Column( - verticalArrangement = Arrangement.spacedBy(verticalSpacing) + MaterialExpressiveTheme( + colorScheme = colorScheme, + typography = Typography(), + motionScheme = MotionScheme.expressive(), + shapes = Shapes() ) { - content(onDismissRequest) + Column( + verticalArrangement = Arrangement.spacedBy(verticalSpacing) + ) { + content(onDismissRequest) + } } } } diff --git a/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenuItem.kt b/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenuItem.kt index d37c966b8..fe61216a0 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenuItem.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/menuItem/RoundDropdownMenuItem.kt @@ -4,26 +4,28 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.padding import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp +import io.legado.app.ui.theme.rememberOpaqueColorScheme @Composable fun RoundDropdownMenuItem( modifier: Modifier = Modifier, - text: String, + text: @Composable () -> Unit, onClick: () -> Unit, trailingIcon: @Composable (() -> Unit)? = null, ) { + val colorScheme = rememberOpaqueColorScheme() + DropdownMenuItem( modifier = modifier .padding(horizontal = 8.dp) .clip(MaterialTheme.shapes.small) - .background(MaterialTheme.colorScheme.surface), - text = { Text(text) }, + .background(colorScheme.surface), + text = text, trailingIcon = trailingIcon, - onClick = onClick, + onClick = onClick ) } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/components/modalBottomSheet/GlassModalBottomSheet.kt b/app/src/main/java/io/legado/app/ui/widget/components/modalBottomSheet/GlassModalBottomSheet.kt index a7ea6f37e..826fdfb0e 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/modalBottomSheet/GlassModalBottomSheet.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/modalBottomSheet/GlassModalBottomSheet.kt @@ -15,12 +15,9 @@ import androidx.compose.material3.SheetState import androidx.compose.material3.Typography import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import io.legado.app.ui.theme.ThemeManager -import io.legado.app.ui.theme.ThemeState +import io.legado.app.ui.theme.rememberOpaqueColorScheme @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable @@ -31,18 +28,7 @@ fun GlassModalBottomSheet( containerColor: (ColorScheme) -> Color = { it.surfaceContainerLow }, content: @Composable ColumnScope.() -> Unit ) { - val themeMode by ThemeState.themeMode.collectAsState() - val isPureBlack by ThemeState.isPureBlack.collectAsState() - val hasImageBg by ThemeState.hasImageBg.collectAsState() - val paletteStyle by ThemeState.paletteStyle.collectAsState() - - val colorScheme = ThemeManager.getColorScheme( - mode = themeMode, - isAmoled = isPureBlack, - isImageBg = hasImageBg, - forceOpaque = true, - paletteStyle = paletteStyle - ) + val colorScheme = rememberOpaqueColorScheme() ModalBottomSheet( onDismissRequest = onDismissRequest, diff --git a/app/src/main/java/io/legado/app/ui/widget/components/swipe/SwipeActionContainer.kt b/app/src/main/java/io/legado/app/ui/widget/components/swipe/SwipeActionContainer.kt index 5d76bffa2..30e7ea11d 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/swipe/SwipeActionContainer.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/swipe/SwipeActionContainer.kt @@ -12,6 +12,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.SwipeToDismissBox +import androidx.compose.material3.SwipeToDismissBoxState import androidx.compose.material3.SwipeToDismissBoxValue import androidx.compose.material3.contentColorFor import androidx.compose.material3.rememberSwipeToDismissBoxState @@ -79,8 +80,8 @@ fun SwipeActionContainer( SwipeToDismissBoxValue.StartToEnd -> { startAction?.let { action -> SwipeBackground( + dismissState = dismissState, action = action, - progress = progress, alignStart = true ) } @@ -89,8 +90,8 @@ fun SwipeActionContainer( SwipeToDismissBoxValue.EndToStart -> { endAction?.let { action -> SwipeBackground( + dismissState = dismissState, action = action, - progress = progress, alignStart = false ) } @@ -114,10 +115,13 @@ fun SwipeActionContainer( @Composable private fun SwipeBackground( action: SwipeAction, - progress: Float, + dismissState: SwipeToDismissBoxState, alignStart: Boolean ) { - val isThresholdReached = progress > 0.6f + val isThresholdReached = dismissState.targetValue == if (alignStart) + SwipeToDismissBoxValue.StartToEnd + else + SwipeToDismissBoxValue.EndToStart val backgroundColor by animateColorAsState( targetValue = if (isThresholdReached) @@ -128,8 +132,8 @@ private fun SwipeBackground( ) val iconScale by animateFloatAsState( - targetValue = if (isThresholdReached) 1.3f - else progress.coerceIn(0.5f, 1f), + targetValue = if (isThresholdReached) 1.2f + else 1f, label = "iconScale" ) diff --git a/app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt b/app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt index 30d527f03..7c2c49095 100644 --- a/app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/components/topbar/DynamicTopAppBar.kt @@ -29,7 +29,7 @@ import io.legado.app.ui.widget.components.AdaptiveAnimatedText import io.legado.app.ui.widget.components.AnimatedTextLine import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar import io.legado.app.ui.widget.components.SearchBarSection -import io.legado.app.ui.widget.components.button.SmallTopBarButton +import io.legado.app.ui.widget.components.button.TopbarNavigationButton import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.rules.RuleActionState @@ -75,7 +75,7 @@ fun DynamicTopAppBar( { AnimatedTextLine(text = it) } }, navigationIcon = { - SmallTopBarButton( + TopbarNavigationButton( onClick = { if (isSelecting) onClearSelection() else onBackClick() }, imageVector = if (isSelecting) Icons.Default.Close else Icons.AutoMirrored.Filled.ArrowBack, contentDescription = if (isSelecting) "取消选择" else "返回" diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 431fe481e..dd01fe5f2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1386,4 +1386,5 @@ 启用滑动时动画 点击图片行为 输出日志 + 启用渐变模糊 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eebd1ae68..e44da0849 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1390,4 +1390,5 @@ 启用滑动时动画 点击图片行为 输出日志 + 启用渐变模糊 diff --git a/app/src/main/res/xml/pref_config_theme.xml b/app/src/main/res/xml/pref_config_theme.xml index aee0e10f3..897b1eccf 100644 --- a/app/src/main/res/xml/pref_config_theme.xml +++ b/app/src/main/res/xml/pref_config_theme.xml @@ -116,6 +116,12 @@ android:title="@string/is_blur_enable" app:iconSpaceReserved="false" /> + +