From ec60ad95805fce6a04cc08c9158094b217f51d40 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 16 May 2020 11:45:56 +0200 Subject: [PATCH] Fix some dark/light theme switch handling --- .../configuration/VectorConfiguration.kt | 57 ++++++++++++++----- .../VectorSettingsPreferencesFragment.kt | 4 +- .../riotx/features/themes/ThemeUtils.kt | 53 ++++++++++++++--- 3 files changed, 91 insertions(+), 23 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt index 2fcf970e04..58f0a1056b 100644 --- a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt @@ -35,16 +35,27 @@ class VectorConfiguration @Inject constructor(private val context: Context) { // TODO Import mLanguageReceiver From Riot? fun onConfigurationChanged() { + var needsSettingsUpdate = false if (Locale.getDefault().toString() != VectorLocale.applicationLocale.toString()) { Timber.v("## onConfigurationChanged(): the locale has been updated to ${Locale.getDefault()}") Timber.v("## onConfigurationChanged(): restore the expected value ${VectorLocale.applicationLocale}") + ThemeUtils.invalidateNightMode() + needsSettingsUpdate = true + } + if (ThemeUtils.useDarkTheme(context) != ThemeUtils.shouldUseDarkTheme(context)) { + Timber.v("## onConfigurationChanged(): night mode has changed") + ThemeUtils.invalidateNightMode() + needsSettingsUpdate = true + } + if (needsSettingsUpdate) { updateApplicationSettings(Locale.getDefault(), - FontScale.getFontScalePrefValue(context), - ThemeUtils.getApplicationTheme(context)) + FontScale.getFontScalePrefValue(context), + ThemeUtils.getApplicationLightTheme(context), + ThemeUtils.getApplicationDarkTheme(context)) } } - private fun updateApplicationSettings(locale: Locale, textSize: String, theme: String) { + private fun updateApplicationSettings(locale: Locale, textSize: String, lightTheme: String, darkTheme: String) { VectorLocale.saveApplicationLocale(context, locale) FontScale.saveFontScale(context, textSize) Locale.setDefault(locale) @@ -56,23 +67,37 @@ class VectorConfiguration @Inject constructor(private val context: Context) { @Suppress("DEPRECATION") context.resources.updateConfiguration(config, context.resources.displayMetrics) - ThemeUtils.setApplicationTheme(context, theme) + ThemeUtils.setApplicationTheme(context, lightTheme, darkTheme) // TODO PhoneNumberUtils.onLocaleUpdate() } /** - * Update the application theme + * Update the light application theme * * @param theme the new theme */ - /* - fun updateApplicationTheme(theme: String) { - ThemeUtils.setApplicationTheme(context, theme) + fun updateApplicationLightTheme(lightTheme: String) { + val darkTheme = ThemeUtils.getApplicationDarkTheme(context) + ThemeUtils.setApplicationTheme(context, lightTheme, darkTheme) updateApplicationSettings(VectorLocale.applicationLocale, FontScale.getFontScalePrefValue(context), - theme) + lightTheme, + darkTheme) + } + + /** + * Update the dark application theme + * + * @param theme the new theme + */ + fun updateApplicationDarkTheme(darkTheme: String) { + val lightTheme = ThemeUtils.getApplicationLightTheme(context) + ThemeUtils.setApplicationTheme(context, lightTheme, darkTheme) + updateApplicationSettings(VectorLocale.applicationLocale, + FontScale.getFontScalePrefValue(context), + lightTheme, + darkTheme) } - */ /** * Init the configuration from the saved one @@ -81,7 +106,8 @@ class VectorConfiguration @Inject constructor(private val context: Context) { VectorLocale.init(context) val locale = VectorLocale.applicationLocale val fontScale = FontScale.getFontScale(context) - val theme = ThemeUtils.getApplicationTheme(context) + val lightTheme = ThemeUtils.getApplicationLightTheme(context) + val darkTheme = ThemeUtils.getApplicationDarkTheme(context) Locale.setDefault(locale) val config = Configuration(context.resources.configuration) @@ -92,7 +118,7 @@ class VectorConfiguration @Inject constructor(private val context: Context) { context.resources.updateConfiguration(config, context.resources.displayMetrics) // init the theme - ThemeUtils.setApplicationTheme(context, theme) + ThemeUtils.setApplicationTheme(context, lightTheme, darkTheme) } /** @@ -102,7 +128,8 @@ class VectorConfiguration @Inject constructor(private val context: Context) { */ // TODO Call from LanguagePickerActivity fun updateApplicationLocale(locale: Locale) { - updateApplicationSettings(locale, FontScale.getFontScalePrefValue(context), ThemeUtils.getApplicationTheme(context)) + updateApplicationSettings(locale, FontScale.getFontScalePrefValue(context), ThemeUtils.getApplicationLightTheme(context), + ThemeUtils.getApplicationDarkTheme(context)) } /** @@ -148,6 +175,8 @@ class VectorConfiguration @Inject constructor(private val context: Context) { fun getHash(): String { return (VectorLocale.applicationLocale.toString() + "_" + FontScale.getFontScalePrefValue(context) - + "_" + ThemeUtils.getApplicationTheme(context)) + + "_" + ThemeUtils.getApplicationLightTheme(context) + + "_" + ThemeUtils.getApplicationDarkTheme(context) + + "_" + ThemeUtils.useDarkTheme(context).toString()) } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt index 5185794478..68a60e139d 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt @@ -55,7 +55,7 @@ class VectorSettingsPreferencesFragment @Inject constructor( findPreference(ThemeUtils.APPLICATION_THEME_KEY)!! .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> if (newValue is String) { - //vectorConfiguration.updateApplicationTheme(newValue) + vectorConfiguration.updateApplicationLightTheme(newValue) // Restart the Activity activity?.let { // Note: recreate does not apply the color correctly @@ -70,7 +70,7 @@ class VectorSettingsPreferencesFragment @Inject constructor( findPreference(ThemeUtils.APPLICATION_DARK_THEME_KEY)!! .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> if (newValue is String) { - //vectorConfiguration.updateApplicationTheme(newValue) + vectorConfiguration.updateApplicationDarkTheme(newValue) // Restart the Activity activity?.let { // Note: recreate does not apply the color correctly diff --git a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt index 2198ba2f71..925cf4e425 100644 --- a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt @@ -28,6 +28,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.preference.PreferenceManager import im.vector.riotx.R +import im.vector.riotx.features.configuration.VectorConfiguration import timber.log.Timber /** @@ -50,7 +51,26 @@ object ThemeUtils { private val mColorByAttr = HashMap() - private var mIsScTheme = false; + private var mIsScTheme = false + private var mUseDarkTheme = false + private var mThemeInitialized = false + + fun shouldUseDarkTheme(context: Context): Boolean { + val currentNightMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + return currentNightMode == Configuration.UI_MODE_NIGHT_YES + } + + fun useDarkTheme(context: Context): Boolean { + if (!mThemeInitialized) { + mThemeInitialized = true + mUseDarkTheme = shouldUseDarkTheme(context) + } + return mUseDarkTheme + } + + fun invalidateNightMode() { + mThemeInitialized = false; + } /** * Provides the selected application theme @@ -59,11 +79,29 @@ object ThemeUtils { * @return the selected application theme */ fun getApplicationTheme(context: Context): String { - val currentNightMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK - return when (currentNightMode) { - Configuration.UI_MODE_NIGHT_YES -> PreferenceManager.getDefaultSharedPreferences(context).getString(APPLICATION_DARK_THEME_KEY, THEME_SC_DARK_COLORED_VALUE)!! - else -> PreferenceManager.getDefaultSharedPreferences(context).getString(APPLICATION_THEME_KEY, THEME_SC_DARK_COLORED_VALUE)!! - } + return if (useDarkTheme(context)) getApplicationDarkTheme(context) else getApplicationLightTheme(context) + } + + + /** + * Provides the selected application theme for light system design + * + * @param context the context + * @return the selected application theme for light system design + */ + fun getApplicationLightTheme(context: Context): String { + return PreferenceManager.getDefaultSharedPreferences(context).getString(APPLICATION_THEME_KEY, THEME_SC_DARK_COLORED_VALUE)!! + } + + + /** + * Provides the selected application theme for night system design + * + * @param context the context + * @return the selected application theme for night system design + */ + fun getApplicationDarkTheme(context: Context): String { + return PreferenceManager.getDefaultSharedPreferences(context).getString(APPLICATION_DARK_THEME_KEY, THEME_SC_DARK_COLORED_VALUE)!! } /** @@ -87,7 +125,8 @@ object ThemeUtils { * * @param aTheme the new theme */ - fun setApplicationTheme(context: Context, aTheme: String) { + fun setApplicationTheme(context: Context, aLightTheme: String, aDarkTheme: String) { + val aTheme = if (useDarkTheme(context)) aDarkTheme else aLightTheme when (aTheme) { THEME_DARK_VALUE -> context.setTheme(R.style.AppTheme_Dark) THEME_BLACK_VALUE -> context.setTheme(R.style.AppTheme_Black)