diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index df434d4ce..0d3bbe37f 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -110,7 +110,6 @@ 34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B0796B1FCF46B000E248C2 /* MainAppContext.m */; }; 34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */; }; 34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */; }; - 34B3F8741E8DF1700035BE1A /* AttachmentSharing.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */; }; 34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */; }; 34B3F8761E8DF1700035BE1A /* CodeVerificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */; }; 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */; }; @@ -118,7 +117,6 @@ 34B3F8791E8DF1700035BE1A /* CountryCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8411E8DF1700035BE1A /* CountryCodeViewController.m */; }; 34B3F87B1E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8441E8DF1700035BE1A /* ExperienceUpgradesPageViewController.swift */; }; 34B3F87C1E8DF1700035BE1A /* FingerprintViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8461E8DF1700035BE1A /* FingerprintViewController.m */; }; - 34B3F87D1E8DF1700035BE1A /* FullImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8481E8DF1700035BE1A /* FullImageViewController.m */; }; 34B3F87E1E8DF1700035BE1A /* InboxTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F84A1E8DF1700035BE1A /* InboxTableViewCell.m */; }; 34B3F8801E8DF1700035BE1A /* InviteFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F84C1E8DF1700035BE1A /* InviteFlow.swift */; }; 34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */; }; @@ -184,6 +182,10 @@ 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; }; 4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */; }; 450998651FD8A34D00D89EB3 /* DeviceSleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */; }; + 450998661FD8BD9C00D89EB3 /* FullImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8481E8DF1700035BE1A /* FullImageViewController.m */; }; + 450998671FD8BDA600D89EB3 /* FullImageViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B3F8471E8DF1700035BE1A /* FullImageViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 450998681FD8C0FF00D89EB3 /* AttachmentSharing.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */; }; + 450998691FD8C10200D89EB3 /* AttachmentSharing.h in Headers */ = {isa = PBXBuildFile; fileRef = 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4509E79A1DD653700025A59F /* WebRTC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4509E7991DD653700025A59F /* WebRTC.framework */; }; 450D19131F85236600970622 /* RemoteVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 450D19121F85236600970622 /* RemoteVideoView.m */; }; 450DF2051E0D74AC003D14BE /* Platform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450DF2041E0D74AC003D14BE /* Platform.swift */; }; @@ -1248,8 +1250,6 @@ 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */, 34B3F8681E8DF1700035BE1A /* AppSettingsViewController.h */, 34B3F8691E8DF1700035BE1A /* AppSettingsViewController.m */, - 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */, - 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */, 34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */, 34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */, 34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */, @@ -1271,8 +1271,6 @@ 34B3F8461E8DF1700035BE1A /* FingerprintViewController.m */, 34E8BF361EE9E2FD00F5F4CA /* FingerprintViewScanController.h */, 34E8BF371EE9E2FD00F5F4CA /* FingerprintViewScanController.m */, - 34B3F8471E8DF1700035BE1A /* FullImageViewController.h */, - 34B3F8481E8DF1700035BE1A /* FullImageViewController.m */, 34BECE2C1F7ABCE000D7438D /* GifPicker */, 34B3F86F1E8DF1700035BE1A /* HomeViewController.h */, 34B3F8701E8DF1700035BE1A /* HomeViewController.m */, @@ -1533,6 +1531,10 @@ 454A96571FD600B4008D2A0E /* attachments */ = { isa = PBXGroup; children = ( + 34B3F8391E8DF1700035BE1A /* AttachmentSharing.h */, + 34B3F83A1E8DF1700035BE1A /* AttachmentSharing.m */, + 34B3F8471E8DF1700035BE1A /* FullImageViewController.h */, + 34B3F8481E8DF1700035BE1A /* FullImageViewController.m */, 45E5471F1FD755E700DFC09E /* AttachmentApprovalViewController.swift */, 3400C7901EAF89CD008A8584 /* SendExternalFileViewController.h */, 3400C7911EAF89CD008A8584 /* SendExternalFileViewController.m */, @@ -2009,6 +2011,7 @@ 346129CA1FD2072E00532771 /* UIImage+OWS.h in Headers */, 346129711FD1D74C00532771 /* SignalKeyingStorage.h in Headers */, 34612A011FD5F31400532771 /* OWS104CreateRecipientIdentities.h in Headers */, + 450998691FD8C10200D89EB3 /* AttachmentSharing.h in Headers */, 346129C71FD2072E00532771 /* NSString+OWS.h in Headers */, 451F8A3C1FD71392005CB9DA /* UIUtil.h in Headers */, 346129D61FD20ADC00532771 /* UIViewController+OWS.h in Headers */, @@ -2034,6 +2037,7 @@ 451F8A3E1FD713D2005CB9DA /* ThreadViewHelper.h in Headers */, 346129391FD1B47300532771 /* OWSPreferences.h in Headers */, 346129DE1FD5C02A00532771 /* LockInteractionController.h in Headers */, + 450998671FD8BDA600D89EB3 /* FullImageViewController.h in Headers */, 451F8A451FD71570005CB9DA /* BlockListUIUtils.h in Headers */, 451F8A4A1FD715D9005CB9DA /* OWSContactAvatarBuilder.h in Headers */, 34480B5B1FD0A7E300BC14EF /* SignalMessaging-Prefix.pch in Headers */, @@ -2674,6 +2678,7 @@ 45194F951FD7216600333B2C /* TSUnreadIndicatorInteraction.m in Sources */, 346129F71FD5F31400532771 /* OWS105AttachmentFilePaths.m in Sources */, 45194F931FD7215C00333B2C /* OWSContactOffersInteraction.m in Sources */, + 450998681FD8C0FF00D89EB3 /* AttachmentSharing.m in Sources */, 346129761FD1E0B500532771 /* WeakTimer.swift in Sources */, 346129F81FD5F31400532771 /* OWS100RemoveTSRecipientsMigration.m in Sources */, 45E547201FD755E700DFC09E /* AttachmentApprovalViewController.swift in Sources */, @@ -2689,6 +2694,7 @@ 451F8A461FD715BA005CB9DA /* OWSGroupAvatarBuilder.m in Sources */, 346129961FD1E30000532771 /* OWSDatabaseMigration.m in Sources */, 346129CD1FD2072E00532771 /* UIImage+OWS.m in Sources */, + 450998661FD8BD9C00D89EB3 /* FullImageViewController.m in Sources */, 346129FB1FD5F31400532771 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */, 450998651FD8A34D00D89EB3 /* DeviceSleepManager.swift in Sources */, 451F8A3D1FD713CA005CB9DA /* ThreadViewHelper.m in Sources */, @@ -2744,7 +2750,6 @@ 3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */, 34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */, 34D1F0BA1F8800D90066283D /* OWSAudioMessageView.m in Sources */, - 34B3F8741E8DF1700035BE1A /* AttachmentSharing.m in Sources */, 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */, 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */, 34D1F0501F7D45A60066283D /* GifPickerCell.swift in Sources */, @@ -2878,7 +2883,6 @@ 45E5A6991F61E6DE001E4A8A /* MarqueeLabel.swift in Sources */, 34D1F0B01F867BFC0066283D /* OWSSystemMessageCell.m in Sources */, 45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */, - 34B3F87D1E8DF1700035BE1A /* FullImageViewController.m in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, B90418E6183E9DD40038554A /* DateUtil.m in Sources */, 459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */, diff --git a/Signal/src/util/MainAppContext.m b/Signal/src/util/MainAppContext.m index 08d9a8eaa..7bc5b7bbd 100644 --- a/Signal/src/util/MainAppContext.m +++ b/Signal/src/util/MainAppContext.m @@ -76,6 +76,11 @@ NS_ASSUME_NONNULL_BEGIN return UIApplication.sharedApplication.frontmostViewControllerIgnoringAlerts; } +- (UIView *)keyWindow +{ + return UIApplication.sharedApplication.keyWindow; +} + - (void)openSystemSettings { [UIApplication.sharedApplication openSystemSettings]; diff --git a/SignalMessaging/SignalMessaging.h b/SignalMessaging/SignalMessaging.h index b11ed9f42..5c087d642 100644 --- a/SignalMessaging/SignalMessaging.h +++ b/SignalMessaging/SignalMessaging.h @@ -13,6 +13,7 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[]; // The public headers of the framework #import #import +#import #import #import #import diff --git a/Signal/src/ViewControllers/AttachmentSharing.h b/SignalMessaging/attachments/AttachmentSharing.h similarity index 100% rename from Signal/src/ViewControllers/AttachmentSharing.h rename to SignalMessaging/attachments/AttachmentSharing.h diff --git a/Signal/src/ViewControllers/AttachmentSharing.m b/SignalMessaging/attachments/AttachmentSharing.m similarity index 90% rename from Signal/src/ViewControllers/AttachmentSharing.m rename to SignalMessaging/attachments/AttachmentSharing.m index 0ee5f518b..7341e1a4b 100644 --- a/Signal/src/ViewControllers/AttachmentSharing.m +++ b/SignalMessaging/attachments/AttachmentSharing.m @@ -10,13 +10,15 @@ @implementation AttachmentSharing -+ (void)showShareUIForAttachment:(TSAttachmentStream *)stream { ++ (void)showShareUIForAttachment:(TSAttachmentStream *)stream +{ OWSAssert(stream); [self showShareUIForURL:stream.mediaURL]; } -+ (void)showShareUIForURL:(NSURL *)url { ++ (void)showShareUIForURL:(NSURL *)url +{ OWSAssert(url); [AttachmentSharing showShareUIForActivityItems:@[ @@ -27,10 +29,10 @@ + (void)showShareUIForText:(NSString *)text { OWSAssert(text); - + [AttachmentSharing showShareUIForActivityItems:@[ - text, - ]]; + text, + ]]; } + (void)showShareUIForActivityItems:(NSArray *)activityItems diff --git a/Signal/src/ViewControllers/FullImageViewController.h b/SignalMessaging/attachments/FullImageViewController.h similarity index 100% rename from Signal/src/ViewControllers/FullImageViewController.h rename to SignalMessaging/attachments/FullImageViewController.h diff --git a/Signal/src/ViewControllers/FullImageViewController.m b/SignalMessaging/attachments/FullImageViewController.m similarity index 62% rename from Signal/src/ViewControllers/FullImageViewController.m rename to SignalMessaging/attachments/FullImageViewController.m index 49a4c6bcb..fac409e6a 100644 --- a/Signal/src/ViewControllers/FullImageViewController.m +++ b/SignalMessaging/attachments/FullImageViewController.m @@ -5,12 +5,13 @@ #import "FullImageViewController.h" #import "AttachmentSharing.h" #import "ConversationViewItem.h" -#import "Signal-Swift.h" #import "TSAttachmentStream.h" #import "TSInteraction.h" #import "UIColor+OWS.h" #import "UIUtil.h" #import "UIView+OWS.h" +#import +#import #import #import @@ -31,7 +32,8 @@ NS_ASSUME_NONNULL_BEGIN @implementation AttachmentMenuView -- (BOOL)canBecomeFirstResponder { +- (BOOL)canBecomeFirstResponder +{ return YES; } @@ -76,7 +78,7 @@ NS_ASSUME_NONNULL_BEGIN if (self) { self.attachmentStream = attachmentStream; - self.originRect = rect; + self.originRect = rect; self.viewItem = viewItem; } @@ -118,7 +120,8 @@ NS_ASSUME_NONNULL_BEGIN return _fileData; } -- (UIImage *)image { +- (UIImage *)image +{ if (self.attachmentStream) { return self.attachmentStream.image; } else if (self.attachment) { @@ -139,15 +142,17 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)loadView { +- (void)loadView +{ self.view = [AttachmentMenuView new]; self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:kBackgroundAlpha]; self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; } -- (void)viewDidLoad { +- (void)viewDidLoad +{ [super viewDidLoad]; - + [self initializeBackground]; [self initializeContentViewAndFooterBar]; [self initializeScrollView]; @@ -157,64 +162,76 @@ NS_ASSUME_NONNULL_BEGIN [self populateImageView:self.image]; } -- (void)viewWillDisappear:(BOOL)animated { +- (void)viewWillDisappear:(BOOL)animated +{ [super viewWillDisappear:animated]; - + if ([UIMenuController sharedMenuController].isMenuVisible) { - [[UIMenuController sharedMenuController] setMenuVisible:NO - animated:NO]; + [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO]; } } #pragma mark - Initializers -- (void)initializeBackground { - self.imageView.backgroundColor = [UIColor colorWithWhite:0 alpha:kBackgroundAlpha]; - - self.backgroundView = [UIView new]; +- (void)initializeBackground +{ + self.imageView.backgroundColor = [UIColor colorWithWhite:0 alpha:kBackgroundAlpha]; + + self.backgroundView = [UIView new]; self.backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:kBackgroundAlpha]; [self.view addSubview:self.backgroundView]; [self.backgroundView autoPinEdgesToSuperviewEdges]; } -- (void)initializeContentViewAndFooterBar { +- (void)initializeContentViewAndFooterBar +{ self.contentView = [UIView new]; [self.backgroundView addSubview:self.contentView]; [self.contentView autoPinWidthToSuperview]; [self.contentView autoPinToTopLayoutGuideOfViewController:self withInset:0]; - + self.footerBar = [UIToolbar new]; _footerBar.barTintColor = [UIColor ows_signalBrandBlueColor]; - [self.footerBar setItems:@[ - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction - target:self - action:@selector(shareWasPressed:)], - [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], - ] - animated:NO]; + if (CurrentAppContext().isMainApp) { + [self.footerBar setItems:@[ + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil], + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction + target:self + action:@selector(shareWasPressed:)], + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil], + ] + animated:NO]; + } [self.backgroundView addSubview:self.footerBar]; [self.footerBar autoPinWidthToSuperview]; [self.footerBar autoPinToBottomLayoutGuideOfViewController:self withInset:0]; [self.footerBar autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.contentView]; } -- (void)shareWasPressed:(id)sender { +- (void)shareWasPressed:(id)sender +{ DDLogInfo(@"%@: sharing image.", self.logTag); + OWSAssert(CurrentAppContext().isMainApp); [AttachmentSharing showShareUIForURL:self.attachmentUrl]; } -- (void)initializeScrollView { - self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; - self.scrollView.delegate = self; - self.scrollView.zoomScale = 1.0f; +- (void)initializeScrollView +{ + self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; + self.scrollView.delegate = self; + self.scrollView.zoomScale = 1.0f; self.scrollView.maximumZoomScale = kMaxZoomScale; - self.scrollView.scrollEnabled = NO; + self.scrollView.scrollEnabled = NO; [self.contentView addSubview:self.scrollView]; } -- (void)initializeImageView { +- (void)initializeImageView +{ if (self.isAnimated) { if ([self.fileData ows_isValidImage]) { YYImage *animatedGif = [YYImage imageWithData:self.fileData]; @@ -229,10 +246,10 @@ NS_ASSUME_NONNULL_BEGIN } } else { // Present the static image using standard UIImageView - self.imageView = [[UIImageView alloc] initWithFrame:self.originRect]; - self.imageView.contentMode = UIViewContentModeScaleAspectFill; - self.imageView.userInteractionEnabled = YES; - self.imageView.clipsToBounds = YES; + self.imageView = [[UIImageView alloc] initWithFrame:self.originRect]; + self.imageView.contentMode = UIViewContentModeScaleAspectFill; + self.imageView.userInteractionEnabled = YES; + self.imageView.clipsToBounds = YES; self.imageView.layer.allowsEdgeAntialiasing = YES; // Use trilinear filters for better scaling quality at // some performance cost. @@ -243,55 +260,59 @@ NS_ASSUME_NONNULL_BEGIN [self.scrollView addSubview:self.imageView]; } -- (void)populateImageView:(UIImage *)image { +- (void)populateImageView:(UIImage *)image +{ if (image && !self.isAnimated) { self.imageView.image = image; } } -- (void)initializeGestureRecognizers { - UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(imageDismissGesture:)]; +- (void)initializeGestureRecognizers +{ + UITapGestureRecognizer *singleTap = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageDismissGesture:)]; singleTap.delegate = self; [self.view addGestureRecognizer:singleTap]; - - UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(imageDismissGesture:)]; + + UITapGestureRecognizer *doubleTap = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageDismissGesture:)]; doubleTap.numberOfTapsRequired = 2; doubleTap.delegate = self; [self.view addGestureRecognizer:doubleTap]; - + // UISwipeGestureRecognizer supposedly supports multiple directions, // but in practice it works better if you use a separate GR for each // direction. for (NSNumber *direction in @[ - @(UISwipeGestureRecognizerDirectionRight), - @(UISwipeGestureRecognizerDirectionLeft), - @(UISwipeGestureRecognizerDirectionUp), - @(UISwipeGestureRecognizerDirectionDown), - ]) { - UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self - action:@selector(imageDismissGesture:)]; - swipe.direction = (UISwipeGestureRecognizerDirection) direction.integerValue; + @(UISwipeGestureRecognizerDirectionRight), + @(UISwipeGestureRecognizerDirectionLeft), + @(UISwipeGestureRecognizerDirectionUp), + @(UISwipeGestureRecognizerDirectionDown), + ]) { + UISwipeGestureRecognizer *swipe = + [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(imageDismissGesture:)]; + swipe.direction = (UISwipeGestureRecognizerDirection)direction.integerValue; swipe.delegate = self; [self.view addGestureRecognizer:swipe]; } - UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self - action:@selector(longPressGesture:)]; + UILongPressGestureRecognizer *longPress = + [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)]; longPress.delegate = self; [self.view addGestureRecognizer:longPress]; } #pragma mark - Gesture Recognizers -- (void)imageDismissGesture:(UIGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateRecognized) { - [self dismiss]; - } +- (void)imageDismissGesture:(UIGestureRecognizer *)sender +{ + if (sender.state == UIGestureRecognizerStateRecognized) { + [self dismiss]; + } } -- (void)longPressGesture:(UIGestureRecognizer *)sender { +- (void)longPressGesture:(UIGestureRecognizer *)sender +{ // We "eagerly" respond when the long press begins, not when it ends. if (sender.state == UIGestureRecognizerStateBegan) { if (!self.viewItem) { @@ -299,22 +320,17 @@ NS_ASSUME_NONNULL_BEGIN } [self.view becomeFirstResponder]; - + if ([UIMenuController sharedMenuController].isMenuVisible) { - [[UIMenuController sharedMenuController] setMenuVisible:NO - animated:NO]; + [[UIMenuController sharedMenuController] setMenuVisible:NO animated:NO]; } NSArray *menuItems = self.viewItem.menuControllerItems; [UIMenuController sharedMenuController].menuItems = menuItems; CGPoint location = [sender locationInView:self.view]; - CGRect targetRect = CGRectMake(location.x, - location.y, - 1, 1); - [[UIMenuController sharedMenuController] setTargetRect:targetRect - inView:self.view]; - [[UIMenuController sharedMenuController] setMenuVisible:YES - animated:YES]; + CGRect targetRect = CGRectMake(location.x, location.y, 1, 1); + [[UIMenuController sharedMenuController] setTargetRect:targetRect inView:self.view]; + [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES]; } } @@ -355,89 +371,93 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Presentation -- (void)presentFromViewController:(UIViewController *)viewController { - _isPresenting = YES; +- (void)presentFromViewController:(UIViewController *)viewController +{ + _isPresenting = YES; self.view.userInteractionEnabled = NO; [self.view addSubview:self.imageView]; self.modalPresentationStyle = UIModalPresentationOverCurrentContext; - self.view.alpha = 0; + self.view.alpha = 0; [viewController presentViewController:self animated:NO completion:^{ - UIWindow *window = [UIApplication sharedApplication].keyWindow; + UIView *window = CurrentAppContext().keyWindow; // During the presentation animation, we want to seamlessly animate the image // from its location in the conversation view. To do so, we need a // consistent coordinate system, so we pass the `originRect` in the // coordinate system of the window. - self.imageView.frame = [self.view convertRect:self.originRect - fromView:window]; - - [UIView animateWithDuration:0.25f - delay:0 - options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut - animations:^() { - self.view.alpha = 1.0f; - // During the presentation animation, we want to seamlessly animate the image - // to its resting location in this view. We use `resizedFrameForImageView` - // to determine its size "at rest" in the content view, and then convert - // from the content view's coordinate system to the root view coordinate - // system because the image view is temporarily hosted by the root view during - // the presentation animation. - self.imageView.frame = [self resizedFrameForImageView:self.image.size]; - self.imageView.center = [self.contentView convertPoint:self.contentView.center - fromView:self.contentView]; - } - completion:^(BOOL completed) { - self.scrollView.frame = self.contentView.bounds; - [self.scrollView addSubview:self.imageView]; - [self updateLayouts]; - self.view.userInteractionEnabled = YES; - _isPresenting = NO; - }]; - [UIUtil modalCompletionBlock](); + self.imageView.frame = [self.view convertRect:self.originRect fromView:window]; + + [UIView animateWithDuration:0.25f + delay:0 + options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut + animations:^() { + self.view.alpha = 1.0f; + // During the presentation animation, we want to seamlessly animate the image + // to its resting location in this view. We use `resizedFrameForImageView` + // to determine its size "at rest" in the content view, and then convert + // from the content view's coordinate system to the root view coordinate + // system because the image view is temporarily hosted by the root view during + // the presentation animation. + self.imageView.frame = [self resizedFrameForImageView:self.image.size]; + self.imageView.center = + [self.contentView convertPoint:self.contentView.center fromView:self.contentView]; + } + completion:^(BOOL completed) { + self.scrollView.frame = self.contentView.bounds; + [self.scrollView addSubview:self.imageView]; + [self updateLayouts]; + self.view.userInteractionEnabled = YES; + _isPresenting = NO; + }]; + [UIUtil modalCompletionBlock](); }]; } -- (void)dismiss { +- (void)dismiss +{ self.view.userInteractionEnabled = NO; [UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear animations:^() { - self.backgroundView.backgroundColor = [UIColor clearColor]; - self.scrollView.alpha = 0; - self.view.alpha = 0; + self.backgroundView.backgroundColor = [UIColor clearColor]; + self.scrollView.alpha = 0; + self.view.alpha = 0; } completion:^(BOOL completed) { - [self.presentingViewController dismissViewControllerAnimated:NO completion:nil]; + [self.presentingViewController dismissViewControllerAnimated:NO completion:nil]; }]; } #pragma mark - Update Layout -- (void)viewDidLayoutSubviews { +- (void)viewDidLayoutSubviews +{ [self updateLayouts]; } -- (void)updateLayouts { +- (void)updateLayouts +{ if (_isPresenting) { return; } - self.scrollView.frame = self.contentView.bounds; - self.imageView.frame = [self resizedFrameForImageView:self.image.size]; - self.scrollView.contentSize = self.imageView.frame.size; + self.scrollView.frame = self.contentView.bounds; + self.imageView.frame = [self resizedFrameForImageView:self.image.size]; + self.scrollView.contentSize = self.imageView.frame.size; self.scrollView.contentInset = [self contentInsetForScrollView:self.scrollView.zoomScale]; } #pragma mark - Resizing -- (CGRect)resizedFrameForImageView:(CGSize)imageSize { +- (CGRect)resizedFrameForImageView:(CGSize)imageSize +{ CGRect frame = self.contentView.bounds; - CGSize screenSize = - CGSizeMake(frame.size.width * self.scrollView.zoomScale, frame.size.height * self.scrollView.zoomScale); + CGSize screenSize + = CGSizeMake(frame.size.width * self.scrollView.zoomScale, frame.size.height * self.scrollView.zoomScale); CGSize targetSize = screenSize; if ([self isImagePortrait]) { @@ -454,33 +474,34 @@ NS_ASSUME_NONNULL_BEGIN } } - frame.size = targetSize; + frame.size = targetSize; frame.origin = CGPointMake(0, 0); return frame; } -- (UIEdgeInsets)contentInsetForScrollView:(CGFloat)targetZoomScale { +- (UIEdgeInsets)contentInsetForScrollView:(CGFloat)targetZoomScale +{ UIEdgeInsets inset = UIEdgeInsetsZero; - CGSize boundsSize = self.scrollView.bounds.size; + CGSize boundsSize = self.scrollView.bounds.size; CGSize contentSize = self.image.size; CGSize minSize; if ([self isImagePortrait]) { if ([self getAspectRatioForCGSize:boundsSize] < [self getAspectRatioForCGSize:contentSize]) { minSize.height = boundsSize.height; - minSize.width = minSize.height / [self getAspectRatioForCGSize:contentSize]; + minSize.width = minSize.height / [self getAspectRatioForCGSize:contentSize]; } else { - minSize.width = boundsSize.width; + minSize.width = boundsSize.width; minSize.height = minSize.width * [self getAspectRatioForCGSize:contentSize]; } } else { if ([self getAspectRatioForCGSize:boundsSize] > [self getAspectRatioForCGSize:contentSize]) { - minSize.width = boundsSize.width; + minSize.width = boundsSize.width; minSize.height = minSize.width * [self getAspectRatioForCGSize:contentSize]; } else { minSize.height = boundsSize.height; - minSize.width = minSize.height / [self getAspectRatioForCGSize:contentSize]; + minSize.width = minSize.height / [self getAspectRatioForCGSize:contentSize]; } } @@ -498,10 +519,10 @@ NS_ASSUME_NONNULL_BEGIN dy = (dy > 0) ? dy : 0; dx = (dx > 0) ? dx : 0; - inset.top = dy / 2.0f; + inset.top = dy / 2.0f; inset.bottom = dy / 2.0f; - inset.left = dx / 2.0f; - inset.right = dx / 2.0f; + inset.left = dx / 2.0f; + inset.right = dx / 2.0f; } return inset; } @@ -513,7 +534,8 @@ NS_ASSUME_NONNULL_BEGIN return self.imageView; } -- (void)scrollViewDidZoom:(UIScrollView *)scrollView { +- (void)scrollViewDidZoom:(UIScrollView *)scrollView +{ scrollView.contentInset = [self contentInsetForScrollView:scrollView.zoomScale]; if (self.scrollView.scrollEnabled == NO) { @@ -524,27 +546,30 @@ NS_ASSUME_NONNULL_BEGIN - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale { self.scrollView.scrollEnabled = (scale > 1); - self.scrollView.contentInset = [self contentInsetForScrollView:scale]; + self.scrollView.contentInset = [self contentInsetForScrollView:scale]; } #pragma mark - Utility -- (BOOL)isImagePortrait { +- (BOOL)isImagePortrait +{ return ([self getAspectRatioForCGSize:self.image.size] > 1.0f); } -- (CGFloat)getAspectRatioForCGSize:(CGSize)size { +- (CGFloat)getAspectRatioForCGSize:(CGSize)size +{ return size.height / size.width; } #pragma mark - Saving images to Camera Roll -- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { +- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo +{ if (error) { DDLogWarn(@"There was a problem saving <%@> to camera roll from %s ", - error.localizedDescription, - __PRETTY_FUNCTION__); + error.localizedDescription, + __PRETTY_FUNCTION__); } } diff --git a/SignalMessaging/attachments/MediaMessageView.swift b/SignalMessaging/attachments/MediaMessageView.swift index 1845efa71..7399497dc 100644 --- a/SignalMessaging/attachments/MediaMessageView.swift +++ b/SignalMessaging/attachments/MediaMessageView.swift @@ -426,11 +426,10 @@ public class MediaMessageView: UIView, OWSAudioAttachmentPlayerDelegate { return } - // FIXME SHARINGEXTENSION -// let window = UIApplication.shared.keyWindow -// let convertedRect = fromView.convert(fromView.bounds, to:window) -// let viewController = FullImageViewController(attachment:attachment, from:convertedRect) -// viewController.present(from:fromViewController) + let window = CurrentAppContext().keyWindow + let convertedRect = fromView.convert(fromView.bounds, to:window) + let viewController = FullImageViewController(attachment:attachment, from:convertedRect) + viewController.present(from:fromViewController) Logger.error("\(TAG) FIXME. image tapped.") } diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index ded3c3c22..db9fd1889 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -397,7 +397,7 @@ public class SystemContactsFetcher: NSObject { switch authorizationStatus { case .notDetermined: - if CurrentAppContext().isMainApp() { + if CurrentAppContext().isMainApp { if CurrentAppContext().mainApplicationState() == .background { Logger.error("\(self.TAG) do not request contacts permission when app is in background") completion(nil) diff --git a/SignalServiceKit/src/Util/AppContext.h b/SignalServiceKit/src/Util/AppContext.h index ec0d3aa2e..bf3e92061 100755 --- a/SignalServiceKit/src/Util/AppContext.h +++ b/SignalServiceKit/src/Util/AppContext.h @@ -10,8 +10,16 @@ typedef void (^BackgroundTaskExpirationHandler)(void); @protocol AppContext -- (BOOL)isMainApp; -- (BOOL)isMainAppAndActive; +@property (nonatomic, readonly) BOOL isMainApp; +@property (nonatomic, readonly) BOOL isMainAppAndActive; + +// Whether the user is using a right-to-left language like Arabic +@property (nonatomic, readonly) BOOL isRTL; + +@property (nonatomic, readonly) BOOL isRunningTests; + +// Useful for translating coordinates to the "entire screen" +@property (nonatomic, readonly) UIView *keyWindow; // Should only be called if isMainApp is YES. // @@ -32,7 +40,7 @@ typedef void (^BackgroundTaskExpirationHandler)(void); // Should only be called if isMainApp is YES. - (void)setMainAppBadgeNumber:(NSInteger)value; -- (BOOL)isRTL; + - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle; // Returns the VC that should be used to present alerts, modals, etc. @@ -45,8 +53,6 @@ typedef void (^BackgroundTaskExpirationHandler)(void); // but should only be necessary to call if isMainApp is YES. - (void)doMultiDeviceUpdateWithProfileKey:(OWSAES256Key *)profileKey; -- (BOOL)isRunningTests; - // Should be a NOOP if isMainApp is NO. - (void)setNetworkActivityIndicatorVisible:(BOOL)value; diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 1127191d3..58d7c7996 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -45,7 +45,7 @@ public class ShareViewController: UINavigationController, SAELoadViewDelegate, S // TODO: // [UIUtil applySignalAppearence]; - if CurrentAppContext().isRunningTests() { + if CurrentAppContext().isRunningTests { // TODO: Do we need to implement isRunningTests in the SAE context? return } diff --git a/SignalShareExtension/utils/ShareAppExtensionContext.m b/SignalShareExtension/utils/ShareAppExtensionContext.m index 46806ebd3..d6ca2d524 100644 --- a/SignalShareExtension/utils/ShareAppExtensionContext.m +++ b/SignalShareExtension/utils/ShareAppExtensionContext.m @@ -92,6 +92,11 @@ NS_ASSUME_NONNULL_BEGIN return [self.rootViewController findFrontmostViewController:YES]; } +- (UIView *)keyWindow +{ + return self.rootViewController.view; +} + - (void)openSystemSettings { OWSFail(@"%@ called %s.", self.logTag, __PRETTY_FUNCTION__);