Skip to content

Commit

Permalink
Addressing various issues with the Appearance API (#28823) (#29106)
Browse files Browse the repository at this point in the history
Summary:
This PR fixes a few issues with the Appearance API (as noted here #28823).

1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN).

2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context.

3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

### Fixed

#28823

* [Android] [Fixed] - Appearance API now works on Android
* [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()`
* [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle`

Pull Request resolved: #29106

Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url)

Reviewed By: hramos

Differential Revision: D31284331

Pulled By: sota000

fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
  • Loading branch information
mrbrentkelly authored and Luna Wei committed Oct 15, 2021
1 parent bd01f16 commit e94f9fa
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 14 deletions.
4 changes: 3 additions & 1 deletion React/CoreModules/RCTAppearance.mm
Expand Up @@ -89,7 +89,9 @@ - (dispatch_queue_t)methodQueue

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getColorScheme)
{
_currentColorScheme = RCTColorSchemePreference(nil);
if (_currentColorScheme == nil) {
_currentColorScheme = RCTColorSchemePreference(nil);
}
return _currentColorScheme;
}

Expand Down
Expand Up @@ -8,6 +8,7 @@
package com.facebook.react;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -121,6 +122,12 @@ public void onWindowFocusChanged(boolean hasFocus) {
mDelegate.onWindowFocusChanged(hasFocus);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDelegate.onConfigurationChanged(newConfig);
}

protected final ReactNativeHost getReactNativeHost() {
return mDelegate.getReactNativeHost();
}
Expand Down
Expand Up @@ -11,6 +11,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
Expand Down Expand Up @@ -154,6 +155,12 @@ public void onWindowFocusChanged(boolean hasFocus) {
}
}

public void onConfigurationChanged(Configuration newConfig) {
if (getReactNativeHost().hasInstance()) {
getReactInstanceManager().onConfigurationChanged(getContext(), newConfig);
}
}

@TargetApi(Build.VERSION_CODES.M)
public void requestPermissions(
String[] permissions, int requestCode, PermissionListener listener) {
Expand Down
Expand Up @@ -7,6 +7,7 @@

package com.facebook.react.modules.appearance;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -74,7 +75,15 @@ public String getName() {

@Override
public String getColorScheme() {
mColorScheme = colorSchemeForCurrentConfiguration(getReactApplicationContext());
// 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).
Activity activity = getCurrentActivity();

mColorScheme =
colorSchemeForCurrentConfiguration(
activity != null ? activity : getReactApplicationContext());

return mColorScheme;
}

Expand Down
Expand Up @@ -7,12 +7,10 @@

package com.facebook.react.uiapp;

import android.content.res.Configuration;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;

public class RNTesterActivity extends ReactActivity {
Expand Down Expand Up @@ -64,14 +62,4 @@ protected ReactActivityDelegate createReactActivityDelegate() {
protected String getMainComponentName() {
return "RNTesterApp";
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ReactInstanceManager instanceManager = getReactInstanceManager();

if (instanceManager != null) {
instanceManager.onConfigurationChanged(this, newConfig);
}
}
}

0 comments on commit e94f9fa

Please sign in to comment.