Skip to content

Commit 7041ed2

Browse files
vonovakfacebook-github-bot
authored andcommitted
fix(android): ensure Appearance change listener does not skip events (facebook#46017)
Summary: I'm able to reproduce a case when Appearance module methods are called in the following order: starting point: dark mode enabled 1. call `setColorScheme` light 2. call `getColorScheme`, which sets `colorScheme` to light [here](https://github.com/facebook/react-native/blob/7bb7a6037bd78bbfa6d9e8499973ea921e9c70e1/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt#L57) 3. [onConfigurationChanged](https://github.com/facebook/react-native/blob/7bb7a6037bd78bbfa6d9e8499973ea921e9c70e1/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt#L82) is called but `if (colorScheme != newColorScheme)` does not evaluate to true, so no event is dispatched to JS. That means JS is not in sync with the native state. The issue was the `getColorScheme` had a side-effect of setting `colorScheme` private member (not sure what its use was). The fix remembers the last emitted color scheme value and emits event if new value is different. ## Changelog: [ANDROID] [FIXED] - ensure Appearance change listener does not skip events Pull Request resolved: facebook#46017 Test Plan: tested locally with RN tester Reviewed By: NickGerleman Differential Revision: D62016949 Pulled By: cipolleschi fbshipit-source-id: b7b5755d38becda655cf376749d9a996daff7e07
1 parent 148066e commit 7041ed2

File tree

1 file changed

+14
-14
lines changed
  • packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance

1 file changed

+14
-14
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ constructor(
2424
private val overrideColorScheme: OverrideColorScheme? = null
2525
) : NativeAppearanceSpec(reactContext) {
2626

27-
private var colorScheme = colorSchemeForCurrentConfiguration(reactContext)
27+
private var lastEmittedColorScheme: String? = null
2828

2929
/** Optional override to the current color scheme */
3030
public fun interface OverrideColorScheme {
@@ -42,10 +42,10 @@ constructor(
4242

4343
val currentNightMode =
4444
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
45-
when (currentNightMode) {
46-
Configuration.UI_MODE_NIGHT_NO -> return "light"
47-
Configuration.UI_MODE_NIGHT_YES -> return "dark"
48-
else -> return "light"
45+
return when (currentNightMode) {
46+
Configuration.UI_MODE_NIGHT_NO -> "light"
47+
Configuration.UI_MODE_NIGHT_YES -> "dark"
48+
else -> "light"
4949
}
5050
}
5151

@@ -54,16 +54,16 @@ constructor(
5454
// scheme. This covers the scenario when AppCompatDelegate.setDefaultNightMode()
5555
// is called directly (which can occur in Brownfield apps for example).
5656
val activity = getCurrentActivity()
57-
colorScheme = colorSchemeForCurrentConfiguration(activity ?: getReactApplicationContext())
58-
return colorScheme
57+
return colorSchemeForCurrentConfiguration(activity ?: getReactApplicationContext())
5958
}
6059

6160
public override fun setColorScheme(style: String) {
62-
when {
63-
style == "dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
64-
style == "light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
65-
style == "unspecified" ->
61+
when (style) {
62+
"dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
63+
"light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
64+
"unspecified" ->
6665
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
66+
6767
}
6868
}
6969

@@ -79,9 +79,9 @@ constructor(
7979
*/
8080
public fun onConfigurationChanged(currentContext: Context) {
8181
val newColorScheme = colorSchemeForCurrentConfiguration(currentContext)
82-
if (colorScheme != newColorScheme) {
83-
colorScheme = newColorScheme
84-
emitAppearanceChanged(colorScheme)
82+
if (lastEmittedColorScheme != newColorScheme) {
83+
lastEmittedColorScheme = newColorScheme
84+
emitAppearanceChanged(newColorScheme)
8585
}
8686
}
8787

0 commit comments

Comments
 (0)