-
-
Notifications
You must be signed in to change notification settings - Fork 261
/
Copy pathRNBootSplash.m
executable file
·135 lines (104 loc) · 3.92 KB
/
RNBootSplash.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#import "RNBootSplash.h"
#import <React/RCTBridge.h>
#import <React/RCTUtils.h>
static NSMutableArray<RCTPromiseResolveBlock> *_resolverQueue = nil;
static RCTRootView *_rootView = nil;
static bool _isTransitioning = false;
@implementation RNBootSplash
RCT_EXPORT_MODULE();
+ (BOOL)requiresMainQueueSetup {
return NO;
}
- (dispatch_queue_t)methodQueue {
return dispatch_get_main_queue();
}
+ (void)initWithStoryboard:(NSString * _Nonnull)storyboardName
rootView:(UIView * _Nullable)rootView {
if (rootView == nil ||
![rootView isKindOfClass:[RCTRootView class]] ||
_rootView != nil ||
RCTRunningInAppExtension())
return;
_rootView = (RCTRootView *)rootView;
[[NSNotificationCenter defaultCenter] removeObserver:rootView
name:RCTContentDidAppearNotification
object:rootView];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
UIView *loadingView = [[storyboard instantiateInitialViewController] view];
if (_resolverQueue != nil)
return; // hide has already been called, abort init
[_rootView setLoadingView:loadingView];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onJavaScriptDidLoad)
name:RCTJavaScriptDidLoadNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onJavaScriptDidFailToLoad)
name:RCTJavaScriptDidFailToLoadNotification
object:nil];
}
+ (void)onJavaScriptDidLoad {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
+ (void)onJavaScriptDidFailToLoad {
[self removeLoadingView];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
+ (bool)isHidden {
return _rootView == nil || _rootView.loadingView == nil || [_rootView.loadingView isHidden];
}
+ (void)removeLoadingView {
if (![self isHidden]) {
_rootView.loadingView.hidden = YES;
[_rootView.loadingView removeFromSuperview];
_rootView.loadingView = nil;
}
}
- (void)clearResolverQueue {
while ([_resolverQueue count] > 0) {
RCTPromiseResolveBlock resolve = [_resolverQueue objectAtIndex:0];
[_resolverQueue removeObjectAtIndex:0];
resolve(@(true));
}
}
RCT_REMAP_METHOD(hide,
hideWithFade:(BOOL)fade
duration:(NSInteger)duration
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (_resolverQueue == nil)
_resolverQueue = [[NSMutableArray alloc] init];
[_resolverQueue addObject:resolve];
if ([RNBootSplash isHidden] || RCTRunningInAppExtension())
return [self clearResolverQueue];
if (!fade) {
[RNBootSplash removeLoadingView];
return [self clearResolverQueue];
}
dispatch_async(dispatch_get_main_queue(), ^{
_isTransitioning = true;
[UIView transitionWithView:_rootView
duration:duration / 1000.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
_rootView.loadingView.hidden = YES;
}
completion:^(__unused BOOL finished) {
[_rootView.loadingView removeFromSuperview];
_rootView.loadingView = nil;
_isTransitioning = false;
return [self clearResolverQueue];
}];
});
}
RCT_REMAP_METHOD(getVisibilityStatus,
getVisibilityStatusWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if ([RNBootSplash isHidden])
return resolve(@"hidden");
else if (_isTransitioning)
return resolve(@"transitioning");
else
return resolve(@"visible");
}
@end