-
Notifications
You must be signed in to change notification settings - Fork 24.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
//xplat/js/react-native-github/packages/react-native/ReactAndroid/src…
…/main/java/com/facebook/react/modules/appearance:appearanceAndroid (#44006) Summary: Pull Request resolved: #44006 Changelog: [Internal] Reviewed By: cortinico Differential Revision: D55725334 fbshipit-source-id: 4d7ad2bb6395674d47fd5e3cd01a8515627f6cd4
- Loading branch information
1 parent
b9a2249
commit c8d5f0f
Showing
3 changed files
with
109 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 0 additions & 125 deletions
125
...ve/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java
This file was deleted.
Oops, something went wrong.
100 changes: 100 additions & 0 deletions
100
...tive/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
package com.facebook.react.modules.appearance | ||
|
||
import android.content.Context | ||
import android.content.res.Configuration | ||
import androidx.appcompat.app.AppCompatDelegate | ||
import com.facebook.fbreact.specs.NativeAppearanceSpec | ||
import com.facebook.react.bridge.Arguments | ||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.module.annotations.ReactModule | ||
|
||
/** Module that exposes the user's preferred color scheme. */ | ||
@ReactModule(name = NativeAppearanceSpec.NAME) | ||
public class AppearanceModule | ||
@JvmOverloads | ||
constructor( | ||
reactContext: ReactApplicationContext, | ||
private val overrideColorScheme: OverrideColorScheme? = null | ||
) : NativeAppearanceSpec(reactContext) { | ||
|
||
private var colorScheme = colorSchemeForCurrentConfiguration(reactContext) | ||
|
||
/** Optional override to the current color scheme */ | ||
public interface OverrideColorScheme { | ||
/** | ||
* Color scheme will use the return value instead of the current system configuration. Available | ||
* scheme: {light, dark} | ||
*/ | ||
public fun getScheme(): String | ||
} | ||
|
||
private fun colorSchemeForCurrentConfiguration(context: Context): String { | ||
if (overrideColorScheme != null) { | ||
return overrideColorScheme.getScheme() | ||
} | ||
|
||
val currentNightMode = | ||
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK | ||
when (currentNightMode) { | ||
Configuration.UI_MODE_NIGHT_NO -> return "light" | ||
Configuration.UI_MODE_NIGHT_YES -> return "dark" | ||
else -> return "light" | ||
} | ||
} | ||
|
||
public override fun getColorScheme(): String { | ||
// Attempt to use the Activity context first in order to get the most up to date | ||
// scheme. This covers the scenario when AppCompatDelegate.setDefaultNightMode() | ||
// is called directly (which can occur in Brownfield apps for example). | ||
val activity = getCurrentActivity() | ||
colorScheme = colorSchemeForCurrentConfiguration(activity ?: getReactApplicationContext()) | ||
return colorScheme | ||
} | ||
|
||
public override fun setColorScheme(style: String) { | ||
when { | ||
style == "dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) | ||
style == "light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) | ||
style == "unspecified" -> | ||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) | ||
} | ||
} | ||
|
||
/** Stub */ | ||
public override fun addListener(eventName: String): Unit = Unit | ||
|
||
/** Stub */ | ||
public override fun removeListeners(count: Double): Unit = Unit | ||
|
||
/* | ||
* Call this from your root activity whenever configuration changes. If the | ||
* color scheme has changed, an event will emitted. | ||
*/ | ||
public fun onConfigurationChanged(currentContext: Context) { | ||
val newColorScheme = colorSchemeForCurrentConfiguration(currentContext) | ||
if (colorScheme != newColorScheme) { | ||
colorScheme = newColorScheme | ||
emitAppearanceChanged(colorScheme) | ||
} | ||
} | ||
|
||
/** Sends an event to the JS instance that the preferred color scheme has changed. */ | ||
public fun emitAppearanceChanged(colorScheme: String) { | ||
val appearancePreferences = Arguments.createMap() | ||
appearancePreferences.putString("colorScheme", colorScheme) | ||
val reactApplicationContext = getReactApplicationContextIfActiveOrWarn() | ||
reactApplicationContext?.emitDeviceEvent(APPEARANCE_CHANGED_EVENT_NAME, appearancePreferences) | ||
} | ||
|
||
public companion object { | ||
public const val NAME: String = NativeAppearanceSpec.NAME | ||
private const val APPEARANCE_CHANGED_EVENT_NAME = "appearanceChanged" | ||
} | ||
} |