19ef743bcSBartłomiej Bukowski#import <UMCore/UMDefines.h>
29ef743bcSBartłomiej Bukowski
39ef743bcSBartłomiej Bukowski#import "EXAppLoadingProgressWindowController.h"
49ef743bcSBartłomiej Bukowski#import "EXUtil.h"
59ef743bcSBartłomiej Bukowski
69ef743bcSBartłomiej Bukowski@interface EXAppLoadingProgressWindowController ()
79ef743bcSBartłomiej Bukowski
89ef743bcSBartłomiej Bukowski@property (nonatomic, assign) BOOL enabled;
99ef743bcSBartłomiej Bukowski@property (nonatomic, strong) UIWindow *window;
109ef743bcSBartłomiej Bukowski@property (nonatomic, strong) UILabel *textLabel;
119ef743bcSBartłomiej Bukowski
129ef743bcSBartłomiej Bukowski@end
139ef743bcSBartłomiej Bukowski
149ef743bcSBartłomiej Bukowski@implementation EXAppLoadingProgressWindowController
159ef743bcSBartłomiej Bukowski
169ef743bcSBartłomiej Bukowski- (instancetype)initWithEnabled:(BOOL)enabled
179ef743bcSBartłomiej Bukowski{
189ef743bcSBartłomiej Bukowski  if (self = [super init]) {
199ef743bcSBartłomiej Bukowski    _enabled = enabled;
209ef743bcSBartłomiej Bukowski  }
219ef743bcSBartłomiej Bukowski  return self;
229ef743bcSBartłomiej Bukowski}
239ef743bcSBartłomiej Bukowski
249ef743bcSBartłomiej Bukowski- (void)show
259ef743bcSBartłomiej Bukowski{
269ef743bcSBartłomiej Bukowski  if (!_enabled) {
279ef743bcSBartłomiej Bukowski    return;
289ef743bcSBartłomiej Bukowski  }
299ef743bcSBartłomiej Bukowski
309ef743bcSBartłomiej Bukowski  UM_WEAKIFY(self);
319ef743bcSBartłomiej Bukowski  dispatch_async(dispatch_get_main_queue(), ^{
329ef743bcSBartłomiej Bukowski    UM_ENSURE_STRONGIFY(self);
339ef743bcSBartłomiej Bukowski    if (!self.window) {
349ef743bcSBartłomiej Bukowski      CGSize screenSize = [UIScreen mainScreen].bounds.size;
359ef743bcSBartłomiej Bukowski
3676b4fe7aSBartłomiej Bukowski      int bottomInsets = 0;
379ef743bcSBartłomiej Bukowski      if (@available(iOS 11.0, *)) {
3876b4fe7aSBartłomiej Bukowski        bottomInsets = UMSharedApplication().keyWindow.safeAreaInsets.bottom;
399ef743bcSBartłomiej Bukowski      }
4076b4fe7aSBartłomiej Bukowski      self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0,
4176b4fe7aSBartłomiej Bukowski                                                               screenSize.height - 36 - bottomInsets,
4276b4fe7aSBartłomiej Bukowski                                                               screenSize.width,
4376b4fe7aSBartłomiej Bukowski                                                               36)];
449ef743bcSBartłomiej Bukowski      self.window.windowLevel = UIWindowLevelStatusBar + 1;
459ef743bcSBartłomiej Bukowski      // set a root VC so rotation is supported
469ef743bcSBartłomiej Bukowski      self.window.rootViewController = [UIViewController new];
479ef743bcSBartłomiej Bukowski
489ef743bcSBartłomiej Bukowski      UIView *containerView = [UIView new];
499ef743bcSBartłomiej Bukowski      containerView.backgroundColor = [EXUtil colorWithRGB:0xfafafa];
509ef743bcSBartłomiej Bukowski
519ef743bcSBartłomiej Bukowski      [self.window addSubview:containerView];
529ef743bcSBartłomiej Bukowski
539ef743bcSBartłomiej Bukowski      CALayer *topBorderLayer = [CALayer layer];
549ef743bcSBartłomiej Bukowski      topBorderLayer.frame = CGRectMake(0, 0, screenSize.width, 1);
559ef743bcSBartłomiej Bukowski      topBorderLayer.backgroundColor = [EXUtil colorWithRGB:0xe3e3e3].CGColor;
569ef743bcSBartłomiej Bukowski      [containerView.layer addSublayer:topBorderLayer];
579ef743bcSBartłomiej Bukowski
589ef743bcSBartłomiej Bukowski      self.textLabel = [UILabel new];
599ef743bcSBartłomiej Bukowski      self.textLabel.frame = CGRectMake(10, 0, screenSize.width - 20, 36);
609ef743bcSBartłomiej Bukowski      self.textLabel.font = [UIFont systemFontOfSize:12];
619ef743bcSBartłomiej Bukowski      self.textLabel.textAlignment = NSTextAlignmentLeft;
629ef743bcSBartłomiej Bukowski      self.textLabel.textColor = [EXUtil colorWithRGB:0xa7a7a7];
639ef743bcSBartłomiej Bukowski      [containerView addSubview:self.textLabel];
649ef743bcSBartłomiej Bukowski    }
659ef743bcSBartłomiej Bukowski    self.textLabel.text =  @"Waiting for server ...";
669ef743bcSBartłomiej Bukowski    self.window.hidden = NO;
679ef743bcSBartłomiej Bukowski  });
689ef743bcSBartłomiej Bukowski}
699ef743bcSBartłomiej Bukowski
709ef743bcSBartłomiej Bukowski- (void)hide
719ef743bcSBartłomiej Bukowski{
729ef743bcSBartłomiej Bukowski  if (!_enabled) {
739ef743bcSBartłomiej Bukowski    return;
749ef743bcSBartłomiej Bukowski  }
759ef743bcSBartłomiej Bukowski
7664c37d52SBartłomiej Bukowski  if (self.window) {
779ef743bcSBartłomiej Bukowski    self.window.hidden = YES;
789ef743bcSBartłomiej Bukowski  }
7964c37d52SBartłomiej Bukowski}
809ef743bcSBartłomiej Bukowski
819ef743bcSBartłomiej Bukowski- (void)updateStatusWithProgress:(EXLoadingProgress *)progress
829ef743bcSBartłomiej Bukowski{
839ef743bcSBartłomiej Bukowski  if (!_enabled) {
849ef743bcSBartłomiej Bukowski    return;
859ef743bcSBartłomiej Bukowski  }
869ef743bcSBartłomiej Bukowski
8764c37d52SBartłomiej Bukowski  [self show];
8864c37d52SBartłomiej Bukowski
899ef743bcSBartłomiej Bukowski  UM_WEAKIFY(self);
909ef743bcSBartłomiej Bukowski  dispatch_async(dispatch_get_main_queue(), ^{
919ef743bcSBartłomiej Bukowski    UM_ENSURE_STRONGIFY(self);
929ef743bcSBartłomiej Bukowski    float progressPercent = ([progress.done floatValue] / [progress.total floatValue]);
939ef743bcSBartłomiej Bukowski    self.textLabel.text = [NSString stringWithFormat:@"%@ %.2f%%", progress.status, progressPercent * 100];
949ef743bcSBartłomiej Bukowski    [self.textLabel setNeedsDisplay];
959ef743bcSBartłomiej Bukowski
969ef743bcSBartłomiej Bukowski    // TODO: (@bbarthec) maybe it's better to show/hide this based on other thing than progress status reported by the fetcher?
979ef743bcSBartłomiej Bukowski    self.window.hidden = !(progress.total.floatValue > 0);
989ef743bcSBartłomiej Bukowski  });
999ef743bcSBartłomiej Bukowski}
1009ef743bcSBartłomiej Bukowski
101*57bba33fSEric Samelson- (void)updateStatus:(EXAppLoaderRemoteUpdateStatus)status
102*57bba33fSEric Samelson{
103*57bba33fSEric Samelson  if (!_enabled) {
104*57bba33fSEric Samelson    return;
105*57bba33fSEric Samelson  }
106*57bba33fSEric Samelson
107*57bba33fSEric Samelson  NSString *statusText = [[self class] _loadingViewTextForStatus:status];
108*57bba33fSEric Samelson  if (!statusText) {
109*57bba33fSEric Samelson    return;
110*57bba33fSEric Samelson  }
111*57bba33fSEric Samelson
112*57bba33fSEric Samelson  [self show];
113*57bba33fSEric Samelson
114*57bba33fSEric Samelson  UM_WEAKIFY(self);
115*57bba33fSEric Samelson  dispatch_async(dispatch_get_main_queue(), ^{
116*57bba33fSEric Samelson    UM_ENSURE_STRONGIFY(self);
117*57bba33fSEric Samelson    self.textLabel.text = statusText;
118*57bba33fSEric Samelson    [self.textLabel setNeedsDisplay];
119*57bba33fSEric Samelson  });
120*57bba33fSEric Samelson}
121*57bba33fSEric Samelson
122*57bba33fSEric Samelson+ (nullable NSString *)_loadingViewTextForStatus:(EXAppLoaderRemoteUpdateStatus)status
123*57bba33fSEric Samelson{
124*57bba33fSEric Samelson  if (status == kEXAppLoaderRemoteUpdateStatusChecking) {
125*57bba33fSEric Samelson    return @"Checking for new update...";
126*57bba33fSEric Samelson  } else if (status == kEXAppLoaderRemoteUpdateStatusDownloading) {
127*57bba33fSEric Samelson    return @"New update available, downloading...";
128*57bba33fSEric Samelson  } else {
129*57bba33fSEric Samelson    return nil;
130*57bba33fSEric Samelson  }
131*57bba33fSEric Samelson}
1329ef743bcSBartłomiej Bukowski
1339ef743bcSBartłomiej Bukowski@end
134