// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "SAEScreenLockViewController.h" #import "UIColor+OWS.h" #import #import NS_ASSUME_NONNULL_BEGIN @interface SAEScreenLockViewController () @property (nonatomic, readonly, weak) id shareViewDelegate; @property (nonatomic) BOOL hasShownAuthUIOnce; @property (nonatomic) BOOL isShowingAuthUI; @end #pragma mark - @implementation SAEScreenLockViewController - (instancetype)initWithShareViewDelegate:(id)shareViewDelegate { self = [super init]; if (!self) { return self; } _shareViewDelegate = shareViewDelegate; self.delegate = self; return self; } - (void)loadView { [super loadView]; UIView.appearance.tintColor = LKColors.text; // Gradient background self.view.backgroundColor = UIColor.clearColor; CAGradientLayer *layer = [CAGradientLayer new]; layer.frame = UIScreen.mainScreen.bounds; UIColor *gradientStartColor = LKAppModeUtilities.isLightMode ? [UIColor colorWithRGBHex:0xFCFCFC] : [UIColor colorWithRGBHex:0x171717]; UIColor *gradientEndColor = LKAppModeUtilities.isLightMode ? [UIColor colorWithRGBHex:0xFFFFFF] : [UIColor colorWithRGBHex:0x121212]; layer.colors = @[ (id)gradientStartColor.CGColor, (id)gradientEndColor.CGColor ]; [self.view.layer insertSublayer:layer atIndex:0]; // Navigation bar background color UINavigationBar *navigationBar = self.navigationController.navigationBar; [navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; navigationBar.shadowImage = [UIImage new]; [navigationBar setTranslucent:NO]; navigationBar.barTintColor = LKColors.navigationBarBackground; // Title UILabel *titleLabel = [UILabel new]; titleLabel.text = NSLocalizedString(@"vc_share_title", @""); titleLabel.textColor = LKColors.text; titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.veryLargeFontSize]; self.navigationItem.titleView = titleLabel; // Close button UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"X"] style:UIBarButtonItemStylePlain target:self action:@selector(dismissPressed:)]; closeButton.tintColor = LKColors.text; self.navigationItem.leftBarButtonItem = closeButton; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self ensureUI]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self ensureUI]; // Auto-show the auth UI f if (!self.hasShownAuthUIOnce) { self.hasShownAuthUIOnce = YES; [self tryToPresentAuthUIToUnlockScreenLock]; } } - (void)dealloc { // Surface memory leaks by logging the deallocation of view controllers. OWSLogVerbose(@"Dealloc: %@", self.class); } - (void)tryToPresentAuthUIToUnlockScreenLock { OWSAssertIsOnMainThread(); if (self.isShowingAuthUI) { // We're already showing the auth UI; abort. return; } OWSLogInfo(@"try to unlock screen lock"); self.isShowingAuthUI = YES; [OWSScreenLock.sharedManager tryToUnlockScreenLockWithSuccess:^{ OWSAssertIsOnMainThread(); OWSLogInfo(@"unlock screen lock succeeded."); self.isShowingAuthUI = NO; [self.shareViewDelegate shareViewWasUnlocked]; } failure:^(NSError *error) { OWSAssertIsOnMainThread(); OWSLogInfo(@"unlock screen lock failed."); self.isShowingAuthUI = NO; [self ensureUI]; [self showScreenLockFailureAlertWithMessage:error.localizedDescription]; } unexpectedFailure:^(NSError *error) { OWSAssertIsOnMainThread(); OWSLogInfo(@"unlock screen lock unexpectedly failed."); self.isShowingAuthUI = NO; // Local Authentication isn't working properly. // This isn't covered by the docs or the forums but in practice // it appears to be effective to retry again after waiting a bit. dispatch_async(dispatch_get_main_queue(), ^{ [self ensureUI]; }); } cancel:^{ OWSAssertIsOnMainThread(); OWSLogInfo(@"unlock screen lock cancelled."); self.isShowingAuthUI = NO; [self ensureUI]; }]; [self ensureUI]; } - (void)ensureUI { [self updateUIWithState:ScreenLockUIStateScreenLock isLogoAtTop:NO animated:NO]; } - (void)showScreenLockFailureAlertWithMessage:(NSString *)message { OWSAssertIsOnMainThread(); [OWSAlerts showAlertWithTitle:NSLocalizedString(@"SCREEN_LOCK_UNLOCK_FAILED", @"Title for alert indicating that screen lock could not be unlocked.") message:message buttonTitle:nil buttonAction:^(UIAlertAction *action) { // After the alert, update the UI. [self ensureUI]; } fromViewController:self]; } - (void)dismissPressed:(id)sender { OWSLogDebug(@"tapped dismiss share button"); [self cancelShareExperience]; } - (void)cancelShareExperience { [self.shareViewDelegate shareViewWasCancelled]; } #pragma mark - ScreenLockViewDelegate - (void)unlockButtonWasTapped { OWSAssertIsOnMainThread(); OWSLogInfo(@"unlockButtonWasTapped"); [self tryToPresentAuthUIToUnlockScreenLock]; } @end NS_ASSUME_NONNULL_END