Add modal activity indicator view.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent b0186754b8
commit ab00342d67

@ -90,6 +90,7 @@
34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */; }; 34D8C0281ED3673300188D7C /* DebugUITableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */; };
34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; }; 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */; };
34D9134B1F62D4A500722898 /* SignalAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D913491F62D4A500722898 /* SignalAttachment.swift */; }; 34D9134B1F62D4A500722898 /* SignalAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D913491F62D4A500722898 /* SignalAttachment.swift */; };
34D9134D1F66DB7C00722898 /* ModalActivityIndicatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D9134C1F66DB7C00722898 /* ModalActivityIndicatorViewController.swift */; };
34D99C8C1F27B13B00D284D6 /* OWSViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C8B1F27B13B00D284D6 /* OWSViewController.m */; }; 34D99C8C1F27B13B00D284D6 /* OWSViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C8B1F27B13B00D284D6 /* OWSViewController.m */; };
34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; }; 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */; };
34D99C941F2937CC00D284D6 /* OWSSwiftUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C921F2937CC00D284D6 /* OWSSwiftUtils.swift */; }; 34D99C941F2937CC00D284D6 /* OWSSwiftUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C921F2937CC00D284D6 /* OWSSwiftUtils.swift */; };
@ -551,6 +552,7 @@
34D8C0291ED3685800188D7C /* DebugUIContacts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIContacts.h; sourceTree = "<group>"; }; 34D8C0291ED3685800188D7C /* DebugUIContacts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIContacts.h; sourceTree = "<group>"; };
34D8C02A1ED3685800188D7C /* DebugUIContacts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIContacts.m; sourceTree = "<group>"; }; 34D8C02A1ED3685800188D7C /* DebugUIContacts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIContacts.m; sourceTree = "<group>"; };
34D913491F62D4A500722898 /* SignalAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalAttachment.swift; sourceTree = "<group>"; }; 34D913491F62D4A500722898 /* SignalAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalAttachment.swift; sourceTree = "<group>"; };
34D9134C1F66DB7C00722898 /* ModalActivityIndicatorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalActivityIndicatorViewController.swift; sourceTree = "<group>"; };
34D99C8A1F27B13B00D284D6 /* OWSViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSViewController.h; sourceTree = "<group>"; }; 34D99C8A1F27B13B00D284D6 /* OWSViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSViewController.h; sourceTree = "<group>"; };
34D99C8B1F27B13B00D284D6 /* OWSViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSViewController.m; sourceTree = "<group>"; }; 34D99C8B1F27B13B00D284D6 /* OWSViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSViewController.m; sourceTree = "<group>"; };
34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = "<group>"; }; 34D99C911F2937CC00D284D6 /* OWSAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAnalytics.swift; sourceTree = "<group>"; };
@ -1029,6 +1031,7 @@
34B3F84C1E8DF1700035BE1A /* InviteFlow.swift */, 34B3F84C1E8DF1700035BE1A /* InviteFlow.swift */,
34B3F84D1E8DF1700035BE1A /* LockInteractionController.h */, 34B3F84D1E8DF1700035BE1A /* LockInteractionController.h */,
34B3F84E1E8DF1700035BE1A /* LockInteractionController.m */, 34B3F84E1E8DF1700035BE1A /* LockInteractionController.m */,
34D9134C1F66DB7C00722898 /* ModalActivityIndicatorViewController.swift */,
34B3F84F1E8DF1700035BE1A /* NewContactThreadViewController.h */, 34B3F84F1E8DF1700035BE1A /* NewContactThreadViewController.h */,
34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */, 34B3F8501E8DF1700035BE1A /* NewContactThreadViewController.m */,
34B3F8541E8DF1700035BE1A /* NewGroupViewController.h */, 34B3F8541E8DF1700035BE1A /* NewGroupViewController.h */,
@ -2263,6 +2266,7 @@
451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */, 451686AB1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift in Sources */,
76EB058A18170B33006006FC /* Release.m in Sources */, 76EB058A18170B33006006FC /* Release.m in Sources */,
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */, 45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
34D9134D1F66DB7C00722898 /* ModalActivityIndicatorViewController.swift in Sources */,
4563ADF11F22BD7100DEB8C7 /* OWS106EnsureProfileComplete.swift in Sources */, 4563ADF11F22BD7100DEB8C7 /* OWS106EnsureProfileComplete.swift in Sources */,
450873C71D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */, 450873C71D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */,
76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */, 76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */,

@ -538,7 +538,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler { completionHandler:(void (^)(BOOL succeeded))completionHandler {
if ([TSAccountManager isRegistered]) { if ([TSAccountManager isRegistered]) {
[[Environment getCurrent].signalsViewController composeNew]; [[Environment getCurrent].signalsViewController showNewConversationView];
completionHandler(YES); completionHandler(YES);
} else { } else {
UIAlertController *controller = UIAlertController *controller =

@ -374,12 +374,24 @@
- (void)proceedToUnregistration - (void)proceedToUnregistration
{ {
[TSAccountManager unregisterTextSecureWithSuccess:^{ [ModalActivityIndicatorViewController
[Environment resetAppData]; presentFromViewController:self
} canCancel:NO
failure:^(NSError *error) { presentCompletion:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"UNREGISTER_SIGNAL_FAIL", @"")]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
}]; [TSAccountManager unregisterTextSecureWithSuccess:^{
[Environment resetAppData];
}
failure:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[modalActivityIndicator dismissWithCompletion:^{
[OWSAlerts
showAlertWithTitle:NSLocalizedString(@"UNREGISTER_SIGNAL_FAIL", @"")];
}];
});
}];
});
}];
} }
#pragma mark - Socket Status Notifications #pragma mark - Socket Status Notifications

@ -3445,31 +3445,51 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
{ {
OWSAssert([NSThread isMainThread]); OWSAssert([NSThread isMainThread]);
AVAsset *video = [AVAsset assetWithURL:movieURL]; [ModalActivityIndicatorViewController
AVAssetExportSession *exportSession = presentFromViewController:self
[AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality]; canCancel:YES
exportSession.shouldOptimizeForNetworkUse = YES; presentCompletion:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
exportSession.outputFileType = AVFileTypeMPEG4; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *compressedVideoUrl = [[self videoTempFolder] AVAsset *video = [AVAsset assetWithURL:movieURL];
URLByAppendingPathComponent:[[[NSUUID UUID] UUIDString] stringByAppendingPathExtension:@"mp4"]]; AVAssetExportSession *exportSession =
exportSession.outputURL = compressedVideoUrl; [AVAssetExportSession exportSessionWithAsset:video
[exportSession exportAsynchronouslyWithCompletionHandler:^{ presetName:AVAssetExportPresetMediumQuality];
dispatch_async(dispatch_get_main_queue(), ^{ exportSession.shouldOptimizeForNetworkUse = YES;
id<DataSource> _Nullable dataSource = [DataSourcePath dataSourceWithURL:compressedVideoUrl]; exportSession.outputFileType = AVFileTypeMPEG4;
[dataSource setSourceFilename:filename]; NSURL *compressedVideoUrl = [[self videoTempFolder]
SignalAttachment *attachment = URLByAppendingPathComponent:[[[NSUUID UUID] UUIDString]
[SignalAttachment attachmentWithDataSource:dataSource dataUTI:(NSString *)kUTTypeMPEG4]; stringByAppendingPathExtension:@"mp4"]];
if (!attachment || [attachment hasError]) { exportSession.outputURL = compressedVideoUrl;
DDLogError(@"%@ %s Invalid attachment: %@.", [exportSession exportAsynchronouslyWithCompletionHandler:^{
self.tag, dispatch_async(dispatch_get_main_queue(), ^{
__PRETTY_FUNCTION__, OWSAssert([NSThread isMainThread]);
attachment ? [attachment errorName] : @"Missing data");
[self showErrorAlertForAttachment:attachment]; if (modalActivityIndicator.wasCancelled) {
} else { return;
[self tryToSendAttachmentIfApproved:attachment skipApprovalDialog:skipApprovalDialog]; }
}
}); [modalActivityIndicator dismissWithCompletion:^{
}]; id<DataSource> _Nullable dataSource =
[DataSourcePath dataSourceWithURL:compressedVideoUrl];
[dataSource setSourceFilename:filename];
SignalAttachment *attachment =
[SignalAttachment attachmentWithDataSource:dataSource
dataUTI:(NSString *)kUTTypeMPEG4];
if (!attachment || [attachment hasError]) {
DDLogError(@"%@ %s Invalid attachment: %@.",
self.tag,
__PRETTY_FUNCTION__,
attachment ? [attachment errorName] : @"Missing data");
[self showErrorAlertForAttachment:attachment];
} else {
[self tryToSendAttachmentIfApproved:attachment
skipApprovalDialog:skipApprovalDialog];
}
}];
});
}];
});
}];
} }

@ -18,7 +18,7 @@
- (void)updateInboxCountLabel; - (void)updateInboxCountLabel;
- (void)composeNew; - (void)showNewConversationView;
- (void)presentTopLevelModalViewController:(UIViewController *)viewController - (void)presentTopLevelModalViewController:(UIViewController *)viewController
animateDismissal:(BOOL)animateDismissal animateDismissal:(BOOL)animateDismissal

@ -175,7 +175,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
self.navigationItem.rightBarButtonItem = self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose
target:self target:self
action:@selector(composeNew)]; action:@selector(showNewConversationView)];
ReminderView *archiveReminderView = [ReminderView new]; ReminderView *archiveReminderView = [ReminderView new];
archiveReminderView.text = NSLocalizedString( archiveReminderView.text = NSLocalizedString(
@ -346,7 +346,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
[self.navigationController pushViewController:vc animated:NO]; [self.navigationController pushViewController:vc animated:NO];
} }
- (void)composeNew - (void)showNewConversationView
{ {
NewContactThreadViewController *viewController = [NewContactThreadViewController new]; NewContactThreadViewController *viewController = [NewContactThreadViewController new];

@ -0,0 +1,152 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
import MediaPlayer
// A modal view that be used during blocking interactions (e.g. waiting on response from
// service or on the completion of a long-running local operation).
class ModalActivityIndicatorViewController: OWSViewController {
let TAG = "[ModalActivityIndicatorViewController]"
let canCancel: Bool
public var wasCancelled: Bool = false
var activityIndicator: UIActivityIndicatorView?
var presentTimer: Timer?
var wasDimissed: Bool = false
// MARK: Initializers
@available(*, unavailable, message:"use canCancel:completion: constructor instead.")
required init?(coder aDecoder: NSCoder) {
self.canCancel = false
super.init(coder: aDecoder)
owsFail("\(self.TAG) invalid constructor")
}
required init(canCancel: Bool) {
self.canCancel = canCancel
super.init(nibName: nil, bundle: nil)
}
public class func present(fromViewController: UIViewController,
canCancel: Bool, presentCompletion : @escaping (ModalActivityIndicatorViewController) -> Void) {
AssertIsOnMainThread()
let view = ModalActivityIndicatorViewController(canCancel:canCancel)
// Present this modal _over_ the current view contents.
view.modalPresentationStyle = .overFullScreen
fromViewController.present(view,
animated: false) {
presentCompletion(view)
}
}
public func dismiss(completion : @escaping () -> Void) {
AssertIsOnMainThread()
if !wasDimissed {
// Only dismiss once.
self.dismiss(animated:false, completion: completion)
wasDimissed = true
} else {
// If already dismissed, wait a beat then call completion.
DispatchQueue.main.async {
completion()
}
}
}
override func loadView() {
super.loadView()
self.view.backgroundColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 0.25)
self.view.isOpaque = false
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle:.whiteLarge)
self.activityIndicator = activityIndicator
self.view.addSubview(activityIndicator)
activityIndicator.autoCenterInSuperview()
if canCancel {
let cancelButton = UIButton(type:.custom)
cancelButton.setTitle(CommonStrings.cancelButton, for: .normal)
cancelButton.setTitleColor(UIColor.white, for: .normal)
cancelButton.backgroundColor = UIColor.ows_darkGray()
cancelButton.titleLabel?.font = UIFont.ows_mediumFont(withSize:ScaleFromIPhone5To7Plus(18, 22))
cancelButton.layer.cornerRadius = ScaleFromIPhone5To7Plus(4, 5)
cancelButton.clipsToBounds = true
cancelButton.addTarget(self, action:#selector(cancelPressed), for:.touchUpInside)
let buttonWidth = ScaleFromIPhone5To7Plus(140, 160)
let buttonHeight = ScaleFromIPhone5To7Plus(40, 50)
self.view.addSubview(cancelButton)
cancelButton.autoHCenterInSuperview()
cancelButton.autoPinEdge(toSuperviewEdge: .bottom, withInset:50)
cancelButton.autoSetDimension(.width, toSize:buttonWidth)
cancelButton.autoSetDimension(.height, toSize:buttonHeight)
}
// Hide the modal until the presentation animation completes.
self.view.layer.opacity = 0.0
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.activityIndicator?.startAnimating()
// Hide the the modal and wait for a second before revealing it,
// to avoid "blipping" in the modal during short blocking operations.
//
// NOTE: It will still intercept user interactions while hidden, as it
// should.
let kPresentationDelaySeconds = TimeInterval(1)
self.presentTimer?.invalidate()
self.presentTimer = Timer.weakScheduledTimer(withTimeInterval: kPresentationDelaySeconds, target: self, selector: #selector(presentTimerFired), userInfo: nil, repeats: false)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
clearTimer()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.activityIndicator?.stopAnimating()
clearTimer()
}
private func clearTimer() {
self.presentTimer?.invalidate()
self.presentTimer = nil
}
func presentTimerFired() {
AssertIsOnMainThread()
clearTimer()
// Fade in the modal.
UIView.animate(withDuration: 0.35) {
self.view.layer.opacity = 1.0
}
}
func cancelPressed() {
AssertIsOnMainThread()
wasCancelled = true
dismiss {
}
}
}

@ -483,36 +483,32 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
}); });
}; };
UIAlertController *alertController = [ModalActivityIndicatorViewController
[UIAlertController alertControllerWithTitle:NSLocalizedString(@"GROUP_CREATING", nil) presentFromViewController:self
message:nil canCancel:NO
preferredStyle:UIAlertControllerStyleAlert]; presentCompletion:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
TSOutgoingMessage *message =
[self presentViewController:alertController [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
animated:YES inThread:thread
completion:^{ groupMetaMessage:TSGroupMessageNew];
TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] // This will save the message.
inThread:thread [message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)];
groupMetaMessage:TSGroupMessageNew];
if (model.groupImage) {
// This will save the message. NSData *data = UIImagePNGRepresentation(model.groupImage);
[message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)]; id<DataSource> _Nullable dataSource =
[DataSourceValue dataSourceWithData:data fileExtension:@"png"];
if (model.groupImage) { [self.messageSender sendAttachmentData:dataSource
NSData *data = UIImagePNGRepresentation(model.groupImage); contentType:OWSMimeTypeImagePng
id<DataSource> _Nullable dataSource = sourceFilename:nil
[DataSourceValue dataSourceWithData:data fileExtension:@"png"]; inMessage:message
[self.messageSender sendAttachmentData:dataSource success:successHandler
contentType:OWSMimeTypeImagePng failure:failureHandler];
sourceFilename:nil } else {
inMessage:message [self.messageSender sendMessage:message success:successHandler failure:failureHandler];
success:successHandler }
failure:failureHandler]; }];
} else {
[self.messageSender sendMessage:message success:successHandler failure:failureHandler];
}
}];
} }
- (TSGroupModel *)makeGroup - (TSGroupModel *)makeGroup

@ -310,51 +310,46 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien
if ([self.delegate shouldValidatePhoneNumbers]) { if ([self.delegate shouldValidatePhoneNumbers]) {
// Show an alert while validating the recipient. // Show an alert while validating the recipient.
__block BOOL wasCancelled = NO;
UIAlertController *activityAlert = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"ALERT_VALIDATE_RECIPIENT_TITLE",
@"A title for the alert shown while validating a signal account")
message:NSLocalizedString(@"ALERT_VALIDATE_RECIPIENT_MESSAGE",
@"A message for the alert shown while validating a signal account")
preferredStyle:UIAlertControllerStyleAlert];
[activityAlert addAction:[UIAlertAction actionWithTitle:CommonStrings.cancelButton
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *_Nonnull action) {
wasCancelled = YES;
}]];
[[UIApplication sharedApplication].frontmostViewController presentViewController:activityAlert
animated:YES
completion:nil];
__weak SelectRecipientViewController *weakSelf = self; __weak SelectRecipientViewController *weakSelf = self;
[[ContactsUpdater sharedUpdater] lookupIdentifiers:possiblePhoneNumbers [ModalActivityIndicatorViewController
success:^(NSArray<SignalRecipient *> *recipients) { presentFromViewController:self
OWSAssert([NSThread isMainThread]); canCancel:YES
OWSAssert(recipients.count > 0); presentCompletion:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (wasCancelled) { [[ContactsUpdater sharedUpdater] lookupIdentifiers:possiblePhoneNumbers
return; success:^(NSArray<SignalRecipient *> *recipients) {
} OWSAssert([NSThread isMainThread]);
OWSAssert(recipients.count > 0);
NSString *recipientId = recipients[0].uniqueId;
[activityAlert dismissViewControllerAnimated:NO if (modalActivityIndicator.wasCancelled) {
completion:^{ return;
[weakSelf.delegate phoneNumberWasSelected:recipientId]; }
}];
} NSString *recipientId = recipients[0].uniqueId;
failure:^(NSError *error) { [modalActivityIndicator
OWSAssert([NSThread isMainThread]); dismissViewControllerAnimated:NO
if (wasCancelled) { completion:^{
return; [weakSelf.delegate phoneNumberWasSelected:recipientId];
} }];
[activityAlert dismissViewControllerAnimated:NO }
completion:^{ failure:^(NSError *error) {
[OWSAlerts OWSAssert([NSThread isMainThread]);
showAlertWithTitle:NSLocalizedString(@"ALERT_ERROR_TITLE", if (modalActivityIndicator.wasCancelled) {
@"Title for a generic error alert.") return;
message:error.localizedDescription]; }
}]; [modalActivityIndicator
}]; dismissViewControllerAnimated:NO
completion:^{
[OWSAlerts
showAlertWithTitle:
NSLocalizedString(@"ALERT_ERROR_TITLE",
@"Title for a generic error alert.")
message:error.localizedDescription];
}];
}];
});
}];
} else { } else {
NSString *recipientId = possiblePhoneNumbers[0]; NSString *recipientId = possiblePhoneNumbers[0];
[self.delegate phoneNumberWasSelected:recipientId]; [self.delegate phoneNumberWasSelected:recipientId];

Loading…
Cancel
Save