Explorar o código

fix: AppCompat 夜间模式跟随设置网关,不再只由外观页触发

设置网关迁移后,themeMode 有多个写入口:外观设置页、阅读页快捷日夜按钮、
主题包应用、恢复备份。但 AppCompatDelegate.setDefaultNightMode 这个副作用
只留在外观页的 ApplyDayNight effect 里,其余入口只写 DataStore。

后果是进程级 sDefaultNightMode 停在旧值,Activity 资源的 uiMode 不变:
- Compose 界面靠网关流换色,看着一切正常;
- 旧 View 界面按资源限定符取色,切换后新打开的书源编辑页、登录页
  仍按旧的深浅色 inflate;
- WebView 的 android:isLightTheme 不变,prefers-color-scheme 传的是旧值。

改为在 App 启动时订阅 AppShellSettingsGateway 的 themeMode,变化时统一调用
ThemeConfigStore.initNightMode(),让 AppCompat 跟随网关而不是跟随某个页面。
initNightMode 相应放开可见性。

实机 A/B(调试探针 toggleReaderDayNight,走的是阅读页快捷按钮同一条网关路径):
改动前该次切换产生 0 次 onConfigurationChanged,改动后为 1 次。
5151561 hai 3 meses
pai
achega
d9f2a75789

+ 15 - 1
app/src/main/java/io/legado/app/App.kt

@@ -35,8 +35,9 @@ import io.legado.app.data.entities.rule.ExploreRule
 import io.legado.app.data.entities.rule.SearchRule
 import io.legado.app.data.entities.rule.SearchRule
 import io.legado.app.di.appDatabaseModule
 import io.legado.app.di.appDatabaseModule
 import io.legado.app.di.appModule
 import io.legado.app.di.appModule
-import io.legado.app.domain.gateway.BackupSettingsGateway
 import io.legado.app.domain.gateway.AppLocaleGateway
 import io.legado.app.domain.gateway.AppLocaleGateway
+import io.legado.app.domain.gateway.AppShellSettingsGateway
+import io.legado.app.domain.gateway.BackupSettingsGateway
 import io.legado.app.help.AppFreezeMonitor
 import io.legado.app.help.AppFreezeMonitor
 import io.legado.app.help.AppWebDav
 import io.legado.app.help.AppWebDav
 import io.legado.app.help.CrashHandler
 import io.legado.app.help.CrashHandler
@@ -67,7 +68,9 @@ import io.legado.app.utils.LogUtils
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.getPrefString
 import io.legado.app.utils.getPrefString
 import io.legado.app.utils.isDebuggable
 import io.legado.app.utils.isDebuggable
+import kotlinx.coroutines.Dispatchers.Main
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.map
 import org.chromium.base.ThreadUtils
 import org.chromium.base.ThreadUtils
@@ -172,6 +175,17 @@ class App : Application(), ImageLoaderFactory {
                 .distinctUntilChanged()
                 .distinctUntilChanged()
                 .collect { AppWebDav.upConfig() }
                 .collect { AppWebDav.upConfig() }
         }
         }
+        // themeMode 是日夜的唯一来源,除外观设置外(阅读页快捷按钮、主题包、恢复备份)
+        // 也会直接写网关。AppCompat 的夜间模式统一跟随网关,否则资源配置不变,
+        // WebView、旧 View 界面拿到的仍是切换前的深浅色。
+        Coroutine.async {
+            get<AppShellSettingsGateway>().settings
+                .map { it.themeMode }
+                .distinctUntilChanged()
+                .collect {
+                    withContext(Main) { ThemeConfigStore.initNightMode() }
+                }
+        }
         Coroutine.async {
         Coroutine.async {
             LogUtils.init(this@App)
             LogUtils.init(this@App)
             LogUtils.d("App", "onCreate")
             LogUtils.d("App", "onCreate")

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

@@ -61,7 +61,7 @@ object ThemeConfigStore {
         initNightMode()
         initNightMode()
     }
     }
 
 
-    private fun initNightMode() {
+    fun initNightMode() {
         ThemeConfig.initNightMode()
         ThemeConfig.initNightMode()
     }
     }