-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Appearance.setColorScheme support #35989
Conversation
@jacdebug has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Base commit: 62fa6d9 |
@jacdebug has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java
Outdated
Show resolved
Hide resolved
ReactAndroid/src/main/java/com/facebook/react/modules/appearance/AppearanceModule.java
Outdated
Show resolved
Hide resolved
Overall question I wanted to check, are we able to call the API early enough on the JS side to avoid fluttering between the settings when starting the app? |
Thanks for the feedback, especially on the flow front. I didn’t want to add
I have been doing this in multiple apps with my own native module, persisted with AsyncStorage, and haven’t had any issues with timing or fluttering. I’ve persisted with UserDefaults in a native swift app, but this doesn’t bring any noticeable timing benefit. Splash screen is always displayed in the system selected theme anyway. |
I don't think we should add "unspecified" to |
Agree, I updated the PR to reflect this. PS. I think the failing test is false positive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly LGTM. Still a little bit around nullability that isn't quite annotated correctly.
It matters less since it is an internal implementation details, but you would also be able to forward null to the native component, vs "unspecified".
Co-authored-by: Nick Gerleman <nick@nickgerleman.com>
Co-authored-by: Nick Gerleman <nick@nickgerleman.com>
Co-authored-by: Nick Gerleman <nick@nickgerleman.com>
Thanks @NickGerleman 👍🏻 |
@jacdebug has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
React/CoreModules/RCTAppearance.mm
Outdated
@@ -92,6 +106,17 @@ - (dispatch_queue_t)methodQueue | |||
return std::make_shared<NativeAppearanceSpecJSI>(params); | |||
} | |||
|
|||
RCT_EXPORT_METHOD(setColorScheme : (NSString *)style) { | |||
UIUserInterfaceStyle userInterfaceStyle = [RCTConvert UIUserInterfaceStyle:style]; | |||
NSArray<__kindof UIWindow*>* windows = [[UIApplication sharedApplication] windows]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am trying to import this and hit this error in our internal CI, can you investigate it please?
xplat/js/react-native-github/React/CoreModules/RCTAppearance.mm:112:59: error: 'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.
NSArray<__kindof UIWindow *> *windows = [[UIApplication sharedApplication] windows];
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see the error got while importing.
Fixed. Wasn't aware of this change - see #34787 Using RCTSharedApplication now that I believe is fail-safe. |
@jacdebug has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@@ -66,6 +67,17 @@ private String colorSchemeForCurrentConfiguration(Context context) { | |||
return "light"; | |||
} | |||
|
|||
@Override | |||
public void setColorScheme(String style) { | |||
if (style == "dark") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@birkir I missed that birkir@e633876 changed this from .equals()
to ==
.
==
against two Java strings does a reference comparison, instead of a value comparison. So it is not safe for using to compare string value.
Would you be willing to make a followup change to move this back to .equals()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot and @birkir can you follow up with a test case to cover this please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there @birkir @jacdebug. Because I think this change may not work, and we don't have any RNTester page or automated tests to verify a fix, I'm going to revert this change.
Do feel free to resubmit this change, with a fix, and test collateral. I do think this API makes sense as part of Appearance
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing, added RNTester and fixed the bug in a new PR #36122
In retrospect, I think the strict equals bug came about because of coding style change (yoda) and the fact Kotlin uses ==
the same as Java equals
.
Summary: See #35989 (comment) Changelog: [General][Fixed] - Back out "Add Appearance.setColorScheme support" Reviewed By: jacdebug Differential Revision: D43148056 fbshipit-source-id: 823ab8276207f243b788ce7757839a3e95bdbe07
Summary: Both Android and iOS allow you to set application specific user interface style, which is useful for applications that support both light and dark mode. With the newly added `Appearance.setColorScheme`, you can natively manage the application's user interface style rather than keeping that preference in JavaScript. The benefit is that native dialogs like alert, keyboard, action sheets and more will also be affected by this change. Implemented using Android X [AppCompatDelegate.setDefaultNightMode](https://developer.android.com/reference/androidx/appcompat/app/AppCompatDelegate#setDefaultNightMode(int)) and iOS 13+ [overrideUserInterfaceStyle](https://developer.apple.com/documentation/uikit/uiview/3238086-overrideuserinterfacestyle?language=objc) ## Changelog [GENERAL] [ADDED] - Added `setColorScheme` to `Appearance` module Pull Request resolved: facebook#35989 Test Plan: This is a void function so testing is rather limited. ```tsx // Lets assume a given device is set to **dark** mode. Appearance.getColorScheme(); // `dark` // Set the app's user interface to `light` Appearance.setColorScheme('light'); Appearance.getColorScheme(); // `light` // Set the app's user interface to `unspecified` Appearance.setColorScheme(null); Appearance.getColorScheme() // `dark` ``` Reviewed By: NickGerleman Differential Revision: D42801094 Pulled By: jacdebug fbshipit-source-id: ede810fe9ee98f313fd3fbbb16b60c84ef8c7204
Summary: See facebook#35989 (comment) Changelog: [General][Fixed] - Back out "Add Appearance.setColorScheme support" Reviewed By: jacdebug Differential Revision: D43148056 fbshipit-source-id: 823ab8276207f243b788ce7757839a3e95bdbe07
Summary
Both Android and iOS allow you to set application specific user interface style, which is useful for applications that support both light and dark mode.
With the newly added
Appearance.setColorScheme
, you can natively manage the application's user interface style rather than keeping that preference in JavaScript. The benefit is that native dialogs like alert, keyboard, action sheets and more will also be affected by this change.Implemented using Android X AppCompatDelegate.setDefaultNightMode and iOS 13+ overrideUserInterfaceStyle
Changelog
[GENERAL] [ADDED] - Added
setColorScheme
toAppearance
moduleTest Plan
This is a void function so testing is rather limited.