Skip to content

Commit

Permalink
refactor: fully manage Theme instance in ThemeManager
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck committed Feb 2, 2024
1 parent 5d5319d commit ed4a77b
Show file tree
Hide file tree
Showing 20 changed files with 134 additions and 177 deletions.
52 changes: 17 additions & 35 deletions app/src/main/java/com/osfans/trime/data/theme/Theme.kt
Expand Up @@ -36,7 +36,7 @@ import java.util.Objects
import kotlin.system.measureTimeMillis

/** 主题和样式配置 */
class Theme private constructor(isDarkMode: Boolean) {
class Theme(private val isDarkMode: Boolean) {
private var currentColorSchemeId: String? = null
private var generalStyle: Map<String, Any?>? = null
private var fallbackColors: Map<String, String>? = null
Expand All @@ -61,38 +61,24 @@ class Theme private constructor(isDarkMode: Boolean) {

companion object {
private const val VERSION_KEY = "config_version"
private var self: Theme? = null
private val appPrefs = AppPrefs.defaultInstance()

@JvmStatic
fun get(): Theme {
if (self == null) self = Theme(false)
return self as Theme
}

@JvmStatic
fun get(isDarkMode: Boolean): Theme {
if (self == null) self = Theme(isDarkMode)
return self as Theme
}

private val defaultThemeName = "trime"
private const val DEFAULT_THEME_NAME = "trime"

fun isFileString(str: String?): Boolean {
return str?.contains(Regex("""\.[a-z]{3,4}$""")) == true
}
}

init {
self = this
init(isDarkMode)
init()
Timber.d("Setting sound from color ...")
SoundThemeManager.switchSound(colors.getString("sound"))
Timber.d("Initialization finished")
}

fun init(isDarkMode: Boolean) {
val active = ThemeManager.getActiveTheme()
fun init() {
val active = appPrefs.themeAndColor.selectedTheme
Timber.i("Initializing theme, currentThemeName=%s ...", active)
runCatching {
val themeFileName = "$active.yaml"
Expand All @@ -104,7 +90,7 @@ class Theme private constructor(isDarkMode: Boolean) {
measureTimeMillis {
var fullThemeConfigMap: Map<String, Any>?
if (Rime.getRimeConfigMap(active, "").also { fullThemeConfigMap = it } == null) {
fullThemeConfigMap = Rime.getRimeConfigMap(defaultThemeName, "")
fullThemeConfigMap = Rime.getRimeConfigMap(DEFAULT_THEME_NAME, "")
}
Objects.requireNonNull(fullThemeConfigMap, "The theme file cannot be empty!")
Timber.d("Fetching done")
Expand All @@ -116,14 +102,14 @@ class Theme private constructor(isDarkMode: Boolean) {
liquidKeyboard = fullThemeConfigMap!!["liquid_keyboard"] as Map<String, Any?>?
}.also { Timber.d("Setting up all theme config map takes $it ms") }
measureTimeMillis {
initCurrentColors(isDarkMode)
refreshColorCaches(isDarkMode)
}.also { Timber.d("Initializing cache takes $it ms") }
Timber.i("The theme is initialized")
}.getOrElse {
Timber.e("Failed to parse the theme: ${it.message}")
if (ThemeManager.getActiveTheme() != defaultThemeName) {
ThemeManager.switchTheme(defaultThemeName)
init(isDarkMode)
if (appPrefs.themeAndColor.selectedTheme != DEFAULT_THEME_NAME) {
ThemeManager.switchTheme(DEFAULT_THEME_NAME)
init()
}
}
}
Expand Down Expand Up @@ -297,10 +283,6 @@ class Theme private constructor(isDarkMode: Boolean) {
}
}

fun destroy() {
self = null
}

lateinit var keyboardPadding: IntArray
private set

Expand Down Expand Up @@ -361,16 +343,16 @@ class Theme private constructor(isDarkMode: Boolean) {
/**
* 获取暗黑模式/明亮模式下配色方案的名称
*
* @param darkMode 是否暗黑模式
* @param isDarkMode 是否暗黑模式
* @return 配色方案名称
*/
private fun getColorSchemeName(darkMode: Boolean): String? {
private fun getColorSchemeName(isDarkMode: Boolean): String? {
var scheme = appPrefs.themeAndColor.selectedColor
if (!presetColorSchemes!!.containsKey(scheme)) scheme = style.getString("color_scheme") // 主題中指定的配色
if (!presetColorSchemes!!.containsKey(scheme)) scheme = "default" // 主題中的default配色
val colorMap = presetColorSchemes!![scheme] as Map<String, Any>
if (colorMap.containsKey("dark_scheme") || colorMap.containsKey("light_scheme")) hasDarkLight = true
if (darkMode) {
if (isDarkMode) {
if (colorMap.containsKey("dark_scheme")) {
return colorMap["dark_scheme"] as String?
}
Expand Down Expand Up @@ -402,12 +384,12 @@ class Theme private constructor(isDarkMode: Boolean) {
}

// 当切换暗黑模式时,刷新键盘配色方案
fun initCurrentColors(darkMode: Boolean) {
currentColorSchemeId = getColorSchemeName(darkMode)
Timber.i(
fun refreshColorCaches(isDarkMode: Boolean) {
currentColorSchemeId = getColorSchemeName(isDarkMode)
Timber.d(
"Caching color values (currentColorSchemeId=%s, isDarkMode=%s) ...",
currentColorSchemeId,
darkMode,
isDarkMode,
)
refreshColorValues()
}
Expand Down
56 changes: 51 additions & 5 deletions app/src/main/java/com/osfans/trime/data/theme/ThemeManager.kt
@@ -1,8 +1,10 @@
package com.osfans.trime.data.theme

import android.content.res.Configuration
import androidx.annotation.Keep
import com.osfans.trime.data.AppPrefs
import com.osfans.trime.data.DataManager
import com.osfans.trime.util.isNightMode
import java.io.File

object ThemeManager {
Expand All @@ -12,10 +14,7 @@ object ThemeManager {
@Keep
private val onDataDirChange =
DataManager.OnDataDirChangeListener {
sharedThemes.clear()
userThemes.clear()
sharedThemes.addAll(listThemes(DataManager.sharedDataDir))
userThemes.addAll(listThemes(DataManager.userDataDir))
refreshThemes()
}

init {
Expand Down Expand Up @@ -46,6 +45,53 @@ object ThemeManager {
return sharedThemes + userThemes
}

fun refreshThemes() {
sharedThemes.clear()
userThemes.clear()
sharedThemes.addAll(listThemes(DataManager.sharedDataDir))
userThemes.addAll(listThemes(DataManager.userDataDir))
}

private lateinit var _activeTheme: Theme

@JvmStatic
var activeTheme: Theme
get() = _activeTheme
private set(value) {
if (_activeTheme == value) return
_activeTheme = value
}

private var isNightMode = false

val prefs = AppPrefs.defaultInstance().themeAndColor

fun setNormalTheme(name: String) {
AppPrefs.defaultInstance().themeAndColor.selectedTheme = name
_activeTheme = evalActiveTheme()
}

private fun evalActiveTheme(): Theme {
return if (prefs.autoDark) {
Theme(isNightMode)
} else {
Theme(false)
}
}

@JvmStatic
fun getActiveTheme() = AppPrefs.defaultInstance().themeAndColor.selectedTheme
fun init(configuration: Configuration) {
isNightMode = configuration.isNightMode()
_activeTheme = evalActiveTheme()
}

@JvmStatic
fun onSystemNightModeChange(isNight: Boolean) {
isNightMode = isNight
if (::_activeTheme.isInitialized) {
activeTheme.refreshColorCaches(isNightMode)
} else {
activeTheme = evalActiveTheme()
}
}
}
2 changes: 0 additions & 2 deletions app/src/main/java/com/osfans/trime/ime/core/RimeWrapper.kt
Expand Up @@ -4,7 +4,6 @@ import android.os.Looper
import androidx.core.os.HandlerCompat
import com.osfans.trime.core.Rime
import com.osfans.trime.data.DataManager
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.util.appContext
import com.osfans.trime.util.isStorageAvailable
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -41,7 +40,6 @@ object RimeWrapper {
scope.launch {
measureTimeMillis {
Rime.getInstance(false)
Theme.get()
}.also {
Timber.d("Startup completed. It takes ${it / 1000} seconds")
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/osfans/trime/ime/core/Speech.kt
Expand Up @@ -27,7 +27,7 @@ import androidx.annotation.StringRes
import com.blankj.utilcode.util.ToastUtils
import com.osfans.trime.R
import com.osfans.trime.data.opencc.OpenCCDictManager
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.data.theme.ThemeManager
import timber.log.Timber
import java.util.Arrays

Expand Down Expand Up @@ -97,7 +97,7 @@ class Speech(context: Context) : RecognitionListener {
val trime = Trime.getServiceOrNull()
if (trime != null) {
val matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
val openccConfig = Theme.get().style.getString("speech_opencc_config")
val openccConfig = ThemeManager.activeTheme.style.getString("speech_opencc_config")
for (result in matches!!) trime.commitText(OpenCCDictManager.convertLine(result!!, openccConfig))
}
}
Expand Down

0 comments on commit ed4a77b

Please sign in to comment.