1/* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8#import "ABI47_0_0RCTStatusBarManager.h" 9#import "ABI47_0_0CoreModulesPlugins.h" 10 11#import <ABI47_0_0React/ABI47_0_0RCTEventDispatcherProtocol.h> 12#import <ABI47_0_0React/ABI47_0_0RCTLog.h> 13#import <ABI47_0_0React/ABI47_0_0RCTUtils.h> 14 15#import <ABI47_0_0FBReactNativeSpec/ABI47_0_0FBReactNativeSpec.h> 16 17@implementation ABI47_0_0RCTConvert (UIStatusBar) 18 19+ (UIStatusBarStyle)UIStatusBarStyle:(id)json ABI47_0_0RCT_DYNAMIC 20{ 21 static NSDictionary *mapping; 22 static dispatch_once_t onceToken; 23 dispatch_once(&onceToken, ^{ 24 if (@available(iOS 13.0, *)) { 25 mapping = @{ 26 @"default" : @(UIStatusBarStyleDefault), 27 @"light-content" : @(UIStatusBarStyleLightContent), 28#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ 29 __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 30 @"dark-content" : @(UIStatusBarStyleDarkContent) 31#else 32 @"dark-content": @(UIStatusBarStyleDefault) 33#endif 34 }; 35 36 } else { 37 mapping = @{ 38 @"default" : @(UIStatusBarStyleDefault), 39 @"light-content" : @(UIStatusBarStyleLightContent), 40 @"dark-content" : @(UIStatusBarStyleDefault) 41 }; 42 } 43 }); 44 return _ABI47_0_0RCT_CAST( 45 UIStatusBarStyle, 46 [ABI47_0_0RCTConvertEnumValue("UIStatusBarStyle", mapping, @(UIStatusBarStyleDefault), json) integerValue]); 47} 48 49ABI47_0_0RCT_ENUM_CONVERTER( 50 UIStatusBarAnimation, 51 (@{ 52 @"none" : @(UIStatusBarAnimationNone), 53 @"fade" : @(UIStatusBarAnimationFade), 54 @"slide" : @(UIStatusBarAnimationSlide), 55 }), 56 UIStatusBarAnimationNone, 57 integerValue); 58 59@end 60 61@interface ABI47_0_0RCTStatusBarManager () <ABI47_0_0NativeStatusBarManagerIOSSpec> 62@end 63 64@implementation ABI47_0_0RCTStatusBarManager 65 66static BOOL ABI47_0_0RCTViewControllerBasedStatusBarAppearance() 67{ 68 static BOOL value; 69 static dispatch_once_t onceToken; 70 dispatch_once(&onceToken, ^{ 71 value = 72 [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"] 73 ?: @YES boolValue]; 74 }); 75 76 return value; 77} 78 79ABI47_0_0RCT_EXPORT_MODULE() 80 81+ (BOOL)requiresMainQueueSetup 82{ 83 return YES; 84} 85 86- (NSArray<NSString *> *)supportedEvents 87{ 88 return @[ @"statusBarFrameDidChange", @"statusBarFrameWillChange" ]; 89} 90 91- (void)startObserving 92{ 93 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 94 [nc addObserver:self 95 selector:@selector(applicationDidChangeStatusBarFrame:) 96 name:UIApplicationDidChangeStatusBarFrameNotification 97 object:nil]; 98 [nc addObserver:self 99 selector:@selector(applicationWillChangeStatusBarFrame:) 100 name:UIApplicationWillChangeStatusBarFrameNotification 101 object:nil]; 102} 103 104- (void)stopObserving 105{ 106 [[NSNotificationCenter defaultCenter] removeObserver:self]; 107} 108 109- (dispatch_queue_t)methodQueue 110{ 111 return dispatch_get_main_queue(); 112} 113 114- (void)emitEvent:(NSString *)eventName forNotification:(NSNotification *)notification 115{ 116 CGRect frame = [notification.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue]; 117 NSDictionary *event = @{ 118 @"frame" : @{ 119 @"x" : @(frame.origin.x), 120 @"y" : @(frame.origin.y), 121 @"width" : @(frame.size.width), 122 @"height" : @(frame.size.height), 123 }, 124 }; 125 [self sendEventWithName:eventName body:event]; 126} 127 128- (void)applicationDidChangeStatusBarFrame:(NSNotification *)notification 129{ 130 [self emitEvent:@"statusBarFrameDidChange" forNotification:notification]; 131} 132 133- (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification 134{ 135 [self emitEvent:@"statusBarFrameWillChange" forNotification:notification]; 136} 137 138ABI47_0_0RCT_EXPORT_METHOD(getHeight : (ABI47_0_0RCTResponseSenderBlock)callback) 139{ 140 callback(@[ @{ 141 @"height" : @(ABI47_0_0RCTSharedApplication().statusBarFrame.size.height), 142 } ]); 143} 144 145ABI47_0_0RCT_EXPORT_METHOD(setStyle : (NSString *)style animated : (BOOL)animated) 146{ 147 UIStatusBarStyle statusBarStyle = [ABI47_0_0RCTConvert UIStatusBarStyle:style]; 148 if (ABI47_0_0RCTViewControllerBasedStatusBarAppearance()) { 149 ABI47_0_0RCTLogError(@"ABI47_0_0RCTStatusBarManager module requires that the \ 150 UIViewControllerBasedStatusBarAppearance key in the Info.plist is set to NO"); 151 } else { 152#pragma clang diagnostic push 153#pragma clang diagnostic ignored "-Wdeprecated-declarations" 154 [ABI47_0_0RCTSharedApplication() setStatusBarStyle:statusBarStyle animated:animated]; 155 } 156#pragma clang diagnostic pop 157} 158 159ABI47_0_0RCT_EXPORT_METHOD(setHidden : (BOOL)hidden withAnimation : (NSString *)withAnimation) 160{ 161 UIStatusBarAnimation animation = [ABI47_0_0RCTConvert UIStatusBarAnimation:withAnimation]; 162 if (ABI47_0_0RCTViewControllerBasedStatusBarAppearance()) { 163 ABI47_0_0RCTLogError(@"ABI47_0_0RCTStatusBarManager module requires that the \ 164 UIViewControllerBasedStatusBarAppearance key in the Info.plist is set to NO"); 165 } else { 166#pragma clang diagnostic push 167#pragma clang diagnostic ignored "-Wdeprecated-declarations" 168 [ABI47_0_0RCTSharedApplication() setStatusBarHidden:hidden withAnimation:animation]; 169#pragma clang diagnostic pop 170 } 171} 172 173ABI47_0_0RCT_EXPORT_METHOD(setNetworkActivityIndicatorVisible : (BOOL)visible) 174{ 175 ABI47_0_0RCTSharedApplication().networkActivityIndicatorVisible = visible; 176} 177 178- (ABI47_0_0facebook::ABI47_0_0React::ModuleConstants<ABI47_0_0JS::NativeStatusBarManagerIOS::Constants>)getConstants 179{ 180 __block ABI47_0_0facebook::ABI47_0_0React::ModuleConstants<ABI47_0_0JS::NativeStatusBarManagerIOS::Constants> constants; 181 ABI47_0_0RCTUnsafeExecuteOnMainQueueSync(^{ 182 constants = ABI47_0_0facebook::ABI47_0_0React::typedConstants<ABI47_0_0JS::NativeStatusBarManagerIOS::Constants>({ 183 .HEIGHT = ABI47_0_0RCTSharedApplication().statusBarFrame.size.height, 184 .DEFAULT_BACKGROUND_COLOR = std::nullopt, 185 }); 186 }); 187 188 return constants; 189} 190 191- (ABI47_0_0facebook::ABI47_0_0React::ModuleConstants<ABI47_0_0JS::NativeStatusBarManagerIOS::Constants>)constantsToExport 192{ 193 return (ABI47_0_0facebook::ABI47_0_0React::ModuleConstants<ABI47_0_0JS::NativeStatusBarManagerIOS::Constants>)[self getConstants]; 194} 195 196- (std::shared_ptr<ABI47_0_0facebook::ABI47_0_0React::TurboModule>)getTurboModule: 197 (const ABI47_0_0facebook::ABI47_0_0React::ObjCTurboModule::InitParams &)params 198{ 199 return std::make_shared<ABI47_0_0facebook::ABI47_0_0React::NativeStatusBarManagerIOSSpecJSI>(params); 200} 201 202@end 203 204Class ABI47_0_0RCTStatusBarManagerCls(void) 205{ 206 return ABI47_0_0RCTStatusBarManager.class; 207} 208