1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | #import "RCTAppearance.h"
|
9 |
|
10 | #import <FBReactNativeSpec/FBReactNativeSpec.h>
|
11 | #import <React/RCTConstants.h>
|
12 | #import <React/RCTEventEmitter.h>
|
13 |
|
14 | #import "CoreModulesPlugins.h"
|
15 |
|
16 | using namespace facebook::react;
|
17 |
|
18 | NSString *const RCTAppearanceColorSchemeLight = @"light";
|
19 | NSString *const RCTAppearanceColorSchemeDark = @"dark";
|
20 |
|
21 | static BOOL sAppearancePreferenceEnabled = YES;
|
22 | void RCTEnableAppearancePreference(BOOL enabled) {
|
23 | sAppearancePreferenceEnabled = enabled;
|
24 | }
|
25 |
|
26 | static NSString *RCTColorSchemePreference(UITraitCollection *traitCollection)
|
27 | {
|
28 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
29 | if (@available(iOS 13.0, *)) {
|
30 | static NSDictionary *appearances;
|
31 | static dispatch_once_t onceToken;
|
32 |
|
33 | dispatch_once(&onceToken, ^{
|
34 | appearances = @{
|
35 | @(UIUserInterfaceStyleLight): RCTAppearanceColorSchemeLight,
|
36 | @(UIUserInterfaceStyleDark): RCTAppearanceColorSchemeDark
|
37 | };
|
38 | });
|
39 |
|
40 | if (!sAppearancePreferenceEnabled) {
|
41 |
|
42 | return RCTAppearanceColorSchemeLight;
|
43 | }
|
44 |
|
45 | traitCollection = traitCollection ?: [UITraitCollection currentTraitCollection];
|
46 | return appearances[@(traitCollection.userInterfaceStyle)] ?: RCTAppearanceColorSchemeLight;
|
47 | }
|
48 | #endif
|
49 |
|
50 |
|
51 | return RCTAppearanceColorSchemeLight;
|
52 | }
|
53 |
|
54 | @interface RCTAppearance () <NativeAppearanceSpec>
|
55 | @end
|
56 |
|
57 | @implementation RCTAppearance
|
58 | {
|
59 | NSString *_currentColorScheme;
|
60 | }
|
61 |
|
62 | RCT_EXPORT_MODULE(Appearance)
|
63 |
|
64 | + (BOOL)requiresMainQueueSetup
|
65 | {
|
66 | return YES;
|
67 | }
|
68 |
|
69 | - (dispatch_queue_t)methodQueue
|
70 | {
|
71 | return dispatch_get_main_queue();
|
72 | }
|
73 |
|
74 | - (std::shared_ptr<TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
|
75 | {
|
76 | return std::make_shared<NativeAppearanceSpecJSI>(self, jsInvoker);
|
77 | }
|
78 |
|
79 | RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getColorScheme)
|
80 | {
|
81 | _currentColorScheme = RCTColorSchemePreference(nil);
|
82 | return _currentColorScheme;
|
83 | }
|
84 |
|
85 | - (void)appearanceChanged:(NSNotification *)notification
|
86 | {
|
87 | NSDictionary *userInfo = [notification userInfo];
|
88 | UITraitCollection *traitCollection = nil;
|
89 | if (userInfo) {
|
90 | traitCollection = userInfo[RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey];
|
91 | }
|
92 | NSString *newColorScheme = RCTColorSchemePreference(traitCollection);
|
93 | if (![_currentColorScheme isEqualToString:newColorScheme]) {
|
94 | _currentColorScheme = newColorScheme;
|
95 | [self sendEventWithName:@"appearanceChanged" body:@{@"colorScheme": newColorScheme}];
|
96 | }
|
97 | }
|
98 |
|
99 | #pragma mark - RCTEventEmitter
|
100 |
|
101 | - (NSArray<NSString *> *)supportedEvents
|
102 | {
|
103 | return @[@"appearanceChanged"];
|
104 | }
|
105 |
|
106 | - (void)startObserving
|
107 | {
|
108 | if (@available(iOS 13.0, *)) {
|
109 | [[NSNotificationCenter defaultCenter] addObserver:self
|
110 | selector:@selector(appearanceChanged:)
|
111 | name:RCTUserInterfaceStyleDidChangeNotification
|
112 | object:nil];
|
113 | }
|
114 | }
|
115 |
|
116 | - (void)stopObserving
|
117 | {
|
118 | if (@available(iOS 13.0, *)) {
|
119 | [[NSNotificationCenter defaultCenter] removeObserver:self];
|
120 | }
|
121 | }
|
122 |
|
123 | @end
|
124 |
|
125 | Class RCTAppearanceCls(void) {
|
126 | return RCTAppearance.class;
|
127 | }
|