Skip to content

Commit 2b771b0

Browse files
rickhanloniifacebook-github-bot
authored andcommitted
Delay loading banner inital message by 200ms to prevent flashing
Summary: This diff fixes an issue where the initial "Loading from Metro..." message is flashed for a few milliseconds before the download progress kicks in. It's just jarring enough to be noticed and is ~600ms too fast to be read. This diff adds a delay so that if the loading progress starts within 200ms we go straight to the progress. Changelog: [Fixed] [iOS] Delay loading banner message to prevent flashing messages Reviewed By: PeteTheHeat Differential Revision: D21281870 fbshipit-source-id: d28c1eae01c2ac9d79f356f1870f17dbb22a9d84
1 parent 131c497 commit 2b771b0

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

React/CoreModules/RCTDevLoadingView.mm

+47-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ @implementation RCTDevLoadingView {
3232
UILabel *_host;
3333
NSDate *_showDate;
3434
BOOL _hiding;
35+
dispatch_block_t _initialMessageBlock;
3536
}
3637

3738
@synthesize bridge = _bridge;
@@ -66,6 +67,27 @@ - (void)setBridge:(RCTBridge *)bridge
6667
}
6768
}
6869

70+
- (void)clearInitialMessageDelay
71+
{
72+
if (self->_initialMessageBlock != nil) {
73+
dispatch_block_cancel(self->_initialMessageBlock);
74+
self->_initialMessageBlock = nil;
75+
}
76+
}
77+
78+
- (void)showInitialMessageDelayed:(void (^)())initialMessage
79+
{
80+
self->_initialMessageBlock = dispatch_block_create(static_cast<dispatch_block_flags_t>(0), initialMessage);
81+
82+
// We delay the initial loading message to prevent flashing it
83+
// when loading progress starts quickly. To do that, we
84+
// schedule the message to be shown in a block, and cancel
85+
// the block later when the progress starts coming in.
86+
// If the progress beats this timer, this message is not shown.
87+
dispatch_after(
88+
dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), self->_initialMessageBlock);
89+
}
90+
6991
- (UIColor *)dimColor:(UIColor *)c
7092
{
7193
// Given a color, return a slightly lighter or darker color for dim effect.
@@ -159,6 +181,9 @@ - (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(
159181
return;
160182
}
161183

184+
// Cancel the initial message block so it doesn't display later and get stuck.
185+
[self clearInitialMessageDelay];
186+
162187
dispatch_async(dispatch_get_main_queue(), ^{
163188
self->_hiding = true;
164189
const NSTimeInterval MIN_PRESENTED_TIME = 0.6;
@@ -186,28 +211,47 @@ - (void)showWithURL:(NSURL *)URL
186211
UIColor *backgroundColor;
187212
NSString *message;
188213
if (URL.fileURL) {
189-
// If dev mode is not enabled, we don't want to show this kind of notification
214+
// If dev mode is not enabled, we don't want to show this kind of notification.
190215
#if !RCT_DEV
191216
return;
192217
#endif
193218
color = [UIColor whiteColor];
194219
backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
195220
message = [NSString stringWithFormat:@"Connect to %@ to develop JavaScript.", RCT_PACKAGER_NAME];
221+
[self showMessage:message color:color backgroundColor:backgroundColor];
196222
} else {
197223
color = [UIColor whiteColor];
198224
backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
199225
message = [NSString stringWithFormat:@"Loading from %@\u2026", RCT_PACKAGER_NAME];
226+
227+
[self showInitialMessageDelayed:^{
228+
[self showMessage:message color:color backgroundColor:backgroundColor];
229+
}];
200230
}
201-
[self showMessage:message color:color backgroundColor:backgroundColor];
202231
}
203232

204233
- (void)updateProgress:(RCTLoadingProgress *)progress
205234
{
206235
if (!progress) {
207236
return;
208237
}
238+
239+
// Cancel the initial message block so it's not flashed before progress.
240+
[self clearInitialMessageDelay];
241+
209242
dispatch_async(dispatch_get_main_queue(), ^{
210-
self->_label.text = [progress description];
243+
if (self->_window == nil) {
244+
// If we didn't show the initial message, then there's no banner window.
245+
// We need to create it here so that the progress is actually displayed.
246+
UIColor *color = [UIColor whiteColor];
247+
UIColor *backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
248+
[self showMessage:[progress description] color:color backgroundColor:backgroundColor];
249+
} else {
250+
// This is an optimization. Since the progress can come in quickly,
251+
// we want to do the minimum amount of work to update the UI,
252+
// which is to only update the label text.
253+
self->_label.text = [progress description];
254+
}
211255
});
212256
}
213257

0 commit comments

Comments
 (0)