Skip to content

Commit

Permalink
Delay loading banner inital message by 200ms to prevent flashing
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rickhanlonii authored and facebook-github-bot committed Apr 29, 2020
1 parent 131c497 commit 2b771b0
Showing 1 changed file with 47 additions and 3 deletions.
50 changes: 47 additions & 3 deletions React/CoreModules/RCTDevLoadingView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ @implementation RCTDevLoadingView {
UILabel *_host;
NSDate *_showDate;
BOOL _hiding;
dispatch_block_t _initialMessageBlock;
}

@synthesize bridge = _bridge;
Expand Down Expand Up @@ -66,6 +67,27 @@ - (void)setBridge:(RCTBridge *)bridge
}
}

- (void)clearInitialMessageDelay
{
if (self->_initialMessageBlock != nil) {
dispatch_block_cancel(self->_initialMessageBlock);
self->_initialMessageBlock = nil;
}
}

- (void)showInitialMessageDelayed:(void (^)())initialMessage
{
self->_initialMessageBlock = dispatch_block_create(static_cast<dispatch_block_flags_t>(0), initialMessage);

// We delay the initial loading message to prevent flashing it
// when loading progress starts quickly. To do that, we
// schedule the message to be shown in a block, and cancel
// the block later when the progress starts coming in.
// If the progress beats this timer, this message is not shown.
dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), self->_initialMessageBlock);
}

- (UIColor *)dimColor:(UIColor *)c
{
// Given a color, return a slightly lighter or darker color for dim effect.
Expand Down Expand Up @@ -159,6 +181,9 @@ - (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(
return;
}

// Cancel the initial message block so it doesn't display later and get stuck.
[self clearInitialMessageDelay];

dispatch_async(dispatch_get_main_queue(), ^{
self->_hiding = true;
const NSTimeInterval MIN_PRESENTED_TIME = 0.6;
Expand Down Expand Up @@ -186,28 +211,47 @@ - (void)showWithURL:(NSURL *)URL
UIColor *backgroundColor;
NSString *message;
if (URL.fileURL) {
// If dev mode is not enabled, we don't want to show this kind of notification
// If dev mode is not enabled, we don't want to show this kind of notification.
#if !RCT_DEV
return;
#endif
color = [UIColor whiteColor];
backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
message = [NSString stringWithFormat:@"Connect to %@ to develop JavaScript.", RCT_PACKAGER_NAME];
[self showMessage:message color:color backgroundColor:backgroundColor];
} else {
color = [UIColor whiteColor];
backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
message = [NSString stringWithFormat:@"Loading from %@\u2026", RCT_PACKAGER_NAME];

[self showInitialMessageDelayed:^{
[self showMessage:message color:color backgroundColor:backgroundColor];
}];
}
[self showMessage:message color:color backgroundColor:backgroundColor];
}

- (void)updateProgress:(RCTLoadingProgress *)progress
{
if (!progress) {
return;
}

// Cancel the initial message block so it's not flashed before progress.
[self clearInitialMessageDelay];

dispatch_async(dispatch_get_main_queue(), ^{
self->_label.text = [progress description];
if (self->_window == nil) {
// If we didn't show the initial message, then there's no banner window.
// We need to create it here so that the progress is actually displayed.
UIColor *color = [UIColor whiteColor];
UIColor *backgroundColor = [UIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1];
[self showMessage:[progress description] color:color backgroundColor:backgroundColor];
} else {
// This is an optimization. Since the progress can come in quickly,
// we want to do the minimum amount of work to update the UI,
// which is to only update the label text.
self->_label.text = [progress description];
}
});
}

Expand Down

0 comments on commit 2b771b0

Please sign in to comment.