1#import <ExpoModulesCore/EXDefines.h>
2
3#import "Expo_Go-Swift.h"
4#import "EXAppLoadingProgressWindowController.h"
5#import "EXUtil.h"
6
7@interface EXAppLoadingProgressWindowController ()
8
9@property (nonatomic, assign) BOOL enabled;
10@property (nonatomic, strong) UIWindow *window;
11@property (nonatomic, strong) UILabel *textLabel;
12
13@end
14
15@implementation EXAppLoadingProgressWindowController
16
17- (instancetype)initWithEnabled:(BOOL)enabled
18{
19  if (self = [super init]) {
20    _enabled = enabled;
21  }
22  return self;
23}
24
25- (void)show
26{
27  if (!_enabled) {
28    return;
29  }
30
31  EX_WEAKIFY(self);
32  dispatch_async(dispatch_get_main_queue(), ^{
33    EX_ENSURE_STRONGIFY(self);
34    if (!self.window) {
35      CGSize screenSize = [UIScreen mainScreen].bounds.size;
36
37      int bottomInsets = EXSharedApplication().keyWindow.safeAreaInsets.bottom;
38      self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0,
39                                                               screenSize.height - 36 - bottomInsets,
40                                                               screenSize.width,
41                                                               36 + bottomInsets)];
42      self.window.windowLevel = UIWindowLevelStatusBar + 1;
43      self.window.rootViewController = [EXAppLoadingProgressWindowViewController new];
44      self.window.backgroundColor = [EXUtil colorWithRGB:0xfafafa];
45
46      UIView *containerView = [UIView new];
47      [self.window addSubview:containerView];
48
49      CALayer *topBorderLayer = [CALayer layer];
50      topBorderLayer.frame = CGRectMake(0, 0, screenSize.width, 1);
51      topBorderLayer.backgroundColor = [EXUtil colorWithRGB:0xe3e3e3].CGColor;
52      [containerView.layer addSublayer:topBorderLayer];
53
54      self.textLabel = [UILabel new];
55      self.textLabel.frame = CGRectMake(10, 0, screenSize.width - 20, 36);
56      self.textLabel.font = [UIFont systemFontOfSize:12];
57      self.textLabel.textAlignment = NSTextAlignmentLeft;
58      self.textLabel.textColor = [EXUtil colorWithRGB:0xa7a7a7];
59      [containerView addSubview:self.textLabel];
60    }
61    self.textLabel.text =  @"Waiting for server ...";
62    self.window.hidden = NO;
63  });
64}
65
66- (void)hide
67{
68  if (!_enabled) {
69    return;
70  }
71
72  EX_WEAKIFY(self);
73  dispatch_async(dispatch_get_main_queue(), ^{
74    EX_ENSURE_STRONGIFY(self);
75    if (self.window) {
76      self.window.hidden = YES;
77      // remove this window altogther to hand over the command over StatusBar rotation
78      self.window = nil;
79    }
80  });
81}
82
83- (void)updateStatusWithProgress:(EXLoadingProgress *)progress
84{
85  if (!_enabled) {
86    return;
87  }
88
89  [self show];
90
91  EX_WEAKIFY(self);
92  dispatch_async(dispatch_get_main_queue(), ^{
93    EX_ENSURE_STRONGIFY(self);
94    float progressPercent = ([progress.done floatValue] / [progress.total floatValue]);
95    self.textLabel.text = [NSString stringWithFormat:@"%@ %.2f%%", progress.status, progressPercent * 100];
96    [self.textLabel setNeedsDisplay];
97
98    // TODO: (@bbarthec) maybe it's better to show/hide this based on other thing than progress status reported by the fetcher?
99    self.window.hidden = !(progress.total.floatValue > 0);
100  });
101}
102
103- (void)updateStatus:(EXAppLoaderRemoteUpdateStatus)status
104{
105  if (!_enabled) {
106    return;
107  }
108
109  NSString *statusText = [[self class] _loadingViewTextForStatus:status];
110  if (!statusText) {
111    return;
112  }
113
114  [self show];
115
116  EX_WEAKIFY(self);
117  dispatch_async(dispatch_get_main_queue(), ^{
118    EX_ENSURE_STRONGIFY(self);
119    self.textLabel.text = statusText;
120    [self.textLabel setNeedsDisplay];
121  });
122}
123
124+ (nullable NSString *)_loadingViewTextForStatus:(EXAppLoaderRemoteUpdateStatus)status
125{
126  if (status == kEXAppLoaderRemoteUpdateStatusChecking) {
127    return @"Checking for new update...";
128  } else if (status == kEXAppLoaderRemoteUpdateStatusDownloading) {
129    return @"New update available, downloading...";
130  } else {
131    return nil;
132  }
133}
134
135@end
136