mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Faster conversation presentation.
There are multiple places in the codebase we present a conversation. We used to have some very conservative machinery around how this was done, for fear of failing to present the call view controller, which would have left a hidden call in the background. We've since addressed that concern more thoroughly via the separate calling UIWindow. As such, the remaining presentation machinery is overly complex and inflexible for what we need. Sometimes we want to animate-push the conversation. (tap on home, tap on "send message" in contact card/group members) Sometimes we want to dismiss a modal, to reveal the conversation behind it (contact picker, group creation) Sometimes we want to present the conversation with no animation (becoming active from a notification) We also want to ensure that we're never pushing more than one conversation view controller, which was previously a problem since we were "pushing" a newly constructed VC in response to these myriad actions. It turned out there were certain code paths that caused multiple actions to be fired in rapid succession which pushed multiple ConversationVC's. The built-in method: `setViewControllers:animated` easily ensures we only have one ConversationVC on the stack, while being composable enough to faciliate the various more efficient animations we desire. The only thing lost with the complex methods is that the naive `presentViewController:` can fail, e.g. if another view is already presented. E.g. if an alert appears *just* before the user taps compose, the contact picker will fail to present. Since we no longer depend on this for presenting the CallViewController, this isn't catostrophic, and in fact, arguable preferable, since we want the user to read and dismiss any alert explicitly. // FREEBIE
This commit is contained in:
parent
ae44b316aa
commit
7e8b2e3034
|
@ -62,12 +62,12 @@ public class ContactShareViewHelper: NSObject, CNContactViewControllerDelegate {
|
|||
}
|
||||
guard phoneNumbers.count > 1 else {
|
||||
let recipientId = phoneNumbers.first!
|
||||
SignalApp.shared().presentConversation(forRecipientId: recipientId, action: action)
|
||||
SignalApp.shared().presentConversation(forRecipientId: recipientId, action: action, animated: true)
|
||||
return
|
||||
}
|
||||
|
||||
showPhoneNumberPicker(phoneNumbers: phoneNumbers, fromViewController: fromViewController, completion: { (recipientId) in
|
||||
SignalApp.shared().presentConversation(forRecipientId: recipientId, action: action)
|
||||
SignalApp.shared().presentConversation(forRecipientId: recipientId, action: action, animated: true)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -544,17 +544,17 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
actionSheet.addAction(UIAlertAction(title: NSLocalizedString("ACTION_SEND_MESSAGE",
|
||||
comment: "Label for 'send message' button in contact view."),
|
||||
style: .default) { _ in
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .compose)
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .compose, animated: true)
|
||||
})
|
||||
actionSheet.addAction(UIAlertAction(title: NSLocalizedString("ACTION_AUDIO_CALL",
|
||||
comment: "Label for 'audio call' button in contact view."),
|
||||
style: .default) { _ in
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .audioCall)
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .audioCall, animated: true)
|
||||
})
|
||||
actionSheet.addAction(UIAlertAction(title: NSLocalizedString("ACTION_VIDEO_CALL",
|
||||
comment: "Label for 'video call' button in contact view."),
|
||||
style: .default) { _ in
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .videoCall)
|
||||
SignalApp.shared().presentConversation(forRecipientId: e164, action: .videoCall, animated: true)
|
||||
})
|
||||
} else {
|
||||
// TODO: We could offer callPhoneNumberWithSystemCall.
|
||||
|
|
|
@ -1133,22 +1133,6 @@ typedef enum : NSUInteger {
|
|||
[self updateBackButtonUnreadCount];
|
||||
[self autoLoadMoreIfNecessary];
|
||||
|
||||
switch (self.actionOnOpen) {
|
||||
case ConversationViewActionNone:
|
||||
break;
|
||||
case ConversationViewActionCompose:
|
||||
[self popKeyBoard];
|
||||
break;
|
||||
case ConversationViewActionAudioCall:
|
||||
[self startAudioCall];
|
||||
break;
|
||||
case ConversationViewActionVideoCall:
|
||||
[self startVideoCall];
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the "on open" state after the view has been presented.
|
||||
self.actionOnOpen = ConversationViewActionNone;
|
||||
self.focusMessageIdOnOpen = nil;
|
||||
|
||||
self.isViewCompletelyAppeared = YES;
|
||||
|
@ -1173,6 +1157,23 @@ typedef enum : NSUInteger {
|
|||
[self becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
switch (self.actionOnOpen) {
|
||||
case ConversationViewActionNone:
|
||||
break;
|
||||
case ConversationViewActionCompose:
|
||||
[self popKeyBoard];
|
||||
break;
|
||||
case ConversationViewActionAudioCall:
|
||||
[self startAudioCall];
|
||||
break;
|
||||
case ConversationViewActionVideoCall:
|
||||
[self startVideoCall];
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the "on open" state after the view has been presented.
|
||||
self.actionOnOpen = ConversationViewActionNone;
|
||||
}
|
||||
|
||||
// `viewWillDisappear` is called whenever the view *starts* to disappear,
|
||||
|
|
|
@ -1338,7 +1338,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
{
|
||||
NSString *recipientId = [self unregisteredRecipientId];
|
||||
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
|
||||
[SignalApp.sharedApp presentConversationForThread:thread];
|
||||
[SignalApp.sharedApp presentConversationForThread:thread animated:YES];
|
||||
}
|
||||
|
||||
+ (void)createUnregisteredGroupThread
|
||||
|
@ -1356,7 +1356,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
TSGroupModel *model =
|
||||
[[TSGroupModel alloc] initWithTitle:groupName memberIds:recipientIds image:nil groupId:groupId];
|
||||
TSGroupThread *thread = [TSGroupThread getOrCreateThreadWithGroupModel:model];
|
||||
[SignalApp.sharedApp presentConversationForThread:thread];
|
||||
|
||||
[SignalApp.sharedApp presentConversationForThread:thread animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -512,7 +512,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}];
|
||||
OWSAssert(thread);
|
||||
|
||||
[SignalApp.sharedApp presentConversationForThread:thread];
|
||||
[SignalApp.sharedApp presentConversationForThread:thread animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -137,7 +137,7 @@ class ConversationSearchViewController: UITableViewController {
|
|||
}
|
||||
|
||||
let thread = searchResult.thread
|
||||
SignalApp.shared().presentConversation(for: thread.threadRecord, action: .compose)
|
||||
SignalApp.shared().presentConversation(for: thread.threadRecord, action: .compose, animated: true)
|
||||
|
||||
case .contacts:
|
||||
let sectionResults = searchResultSet.contacts
|
||||
|
@ -146,7 +146,7 @@ class ConversationSearchViewController: UITableViewController {
|
|||
return
|
||||
}
|
||||
|
||||
SignalApp.shared().presentConversation(forRecipientId: searchResult.recipientId, action: .compose)
|
||||
SignalApp.shared().presentConversation(forRecipientId: searchResult.recipientId, action: .compose, animated: true)
|
||||
|
||||
case .messages:
|
||||
let sectionResults = searchResultSet.messages
|
||||
|
@ -157,8 +157,9 @@ class ConversationSearchViewController: UITableViewController {
|
|||
|
||||
let thread = searchResult.thread
|
||||
SignalApp.shared().presentConversation(for: thread.threadRecord,
|
||||
action: .compose,
|
||||
focusMessageId: searchResult.messageId)
|
||||
action: .none,
|
||||
focusMessageId: searchResult.messageId,
|
||||
animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,20 +12,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface HomeViewController : OWSViewController
|
||||
|
||||
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action;
|
||||
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentThread:(TSThread *)thread
|
||||
action:(ConversationViewAction)action
|
||||
focusMessageId:(nullable NSString *)focusMessageId;
|
||||
focusMessageId:(nullable NSString *)focusMessageId
|
||||
animated:(BOOL)isAnimated;
|
||||
|
||||
// Used by force-touch Springboard icon shortcut
|
||||
- (void)showNewConversationView;
|
||||
|
||||
- (void)presentTopLevelModalViewController:(UIViewController *)viewController
|
||||
animateDismissal:(BOOL)animateDismissal
|
||||
animatePresentation:(BOOL)animatePresentation;
|
||||
- (void)pushTopLevelViewController:(UIViewController *)viewController
|
||||
animateDismissal:(BOOL)animateDismissal
|
||||
animatePresentation:(BOOL)animatePresentation;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -554,9 +554,8 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
//
|
||||
// We just want to make sure contact access is *complete* before showing the compose
|
||||
// screen to avoid flicker.
|
||||
OWSNavigationController *navigationController =
|
||||
[[OWSNavigationController alloc] initWithRootViewController:viewController];
|
||||
[self presentTopLevelModalViewController:navigationController animateDismissal:YES animatePresentation:YES];
|
||||
OWSNavigationController *modal = [[OWSNavigationController alloc] initWithRootViewController:viewController];
|
||||
[self.navigationController presentViewController:modal animated:YES completion:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -744,8 +743,6 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
ExperienceUpgradesPageViewController *experienceUpgradeViewController =
|
||||
[[ExperienceUpgradesPageViewController alloc] initWithExperienceUpgrades:unseenUpgrades];
|
||||
[self presentViewController:experienceUpgradeViewController animated:YES completion:nil];
|
||||
} else if (!self.hasEverAppeared && [ProfileViewController shouldDisplayProfileViewOnLaunch]) {
|
||||
[ProfileViewController presentForUpgradeOrNag:self];
|
||||
} else {
|
||||
[OWSAlerts showIOSUpgradeNagIfNecessary];
|
||||
}
|
||||
|
@ -1156,7 +1153,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
}
|
||||
case HomeViewControllerSectionConversations: {
|
||||
TSThread *thread = [self threadForIndexPath:indexPath];
|
||||
[self presentThread:thread action:ConversationViewActionNone];
|
||||
[self presentThread:thread action:ConversationViewActionNone animated:YES];
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
break;
|
||||
}
|
||||
|
@ -1167,14 +1164,15 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
}
|
||||
}
|
||||
|
||||
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action
|
||||
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action animated:(BOOL)isAnimated
|
||||
{
|
||||
[self presentThread:thread action:action focusMessageId:nil];
|
||||
[self presentThread:thread action:action focusMessageId:nil animated:isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentThread:(TSThread *)thread
|
||||
action:(ConversationViewAction)action
|
||||
focusMessageId:(nullable NSString *)focusMessageId
|
||||
animated:(BOOL)isAnimated
|
||||
{
|
||||
if (thread == nil) {
|
||||
OWSFail(@"Thread unexpectedly nil");
|
||||
|
@ -1183,79 +1181,14 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
|
||||
// We do this synchronously if we're already on the main thread.
|
||||
DispatchMainThreadSafe(^{
|
||||
ConversationViewController *viewController = [ConversationViewController new];
|
||||
[viewController configureForThread:thread action:action focusMessageId:focusMessageId];
|
||||
ConversationViewController *conversationVC = [ConversationViewController new];
|
||||
[conversationVC configureForThread:thread action:action focusMessageId:focusMessageId];
|
||||
self.lastThread = thread;
|
||||
|
||||
[self pushTopLevelViewController:viewController animateDismissal:YES animatePresentation:YES];
|
||||
[self.navigationController setViewControllers:@[ self, conversationVC ] animated:isAnimated];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)presentTopLevelModalViewController:(UIViewController *)viewController
|
||||
animateDismissal:(BOOL)animateDismissal
|
||||
animatePresentation:(BOOL)animatePresentation
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(viewController);
|
||||
|
||||
[self presentViewControllerWithBlock:^{
|
||||
[self presentViewController:viewController animated:animatePresentation completion:nil];
|
||||
}
|
||||
animateDismissal:animateDismissal];
|
||||
}
|
||||
|
||||
- (void)pushTopLevelViewController:(UIViewController *)viewController
|
||||
animateDismissal:(BOOL)animateDismissal
|
||||
animatePresentation:(BOOL)animatePresentation
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(viewController);
|
||||
|
||||
[self presentViewControllerWithBlock:^{
|
||||
[self.navigationController pushViewController:viewController animated:animatePresentation];
|
||||
}
|
||||
animateDismissal:animateDismissal];
|
||||
}
|
||||
|
||||
- (void)presentViewControllerWithBlock:(void (^)(void))presentationBlock animateDismissal:(BOOL)animateDismissal
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssert(presentationBlock);
|
||||
|
||||
// Presenting a "top level" view controller has three steps:
|
||||
//
|
||||
// First, dismiss any presented modal.
|
||||
// Second, pop to the root view controller if necessary.
|
||||
// Third present the new view controller using presentationBlock.
|
||||
|
||||
// Define a block to perform the second step.
|
||||
void (^dismissNavigationBlock)(void) = ^{
|
||||
if (self.navigationController.viewControllers.lastObject != self) {
|
||||
[CATransaction begin];
|
||||
[CATransaction setCompletionBlock:^{
|
||||
presentationBlock();
|
||||
}];
|
||||
|
||||
[self.navigationController popToViewController:self animated:animateDismissal];
|
||||
|
||||
[CATransaction commit];
|
||||
} else {
|
||||
presentationBlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Perform the first step.
|
||||
if (self.presentedViewController) {
|
||||
if ([self.presentedViewController isKindOfClass:[CallViewController class]]) {
|
||||
OWSProdInfo([OWSAnalyticsEvents errorCouldNotPresentViewDueToCall]);
|
||||
return;
|
||||
}
|
||||
[self.presentedViewController dismissViewControllerAnimated:animateDismissal completion:dismissNavigationBlock];
|
||||
} else {
|
||||
dismissNavigationBlock();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Groupings
|
||||
|
||||
- (YapDatabaseViewMappings *)threadMappings
|
||||
|
|
|
@ -823,11 +823,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
- (void)newConversationWithThread:(TSThread *)thread
|
||||
{
|
||||
OWSAssert(thread != nil);
|
||||
[self dismissViewControllerAnimated:YES
|
||||
completion:^() {
|
||||
[SignalApp.sharedApp presentConversationForThread:thread
|
||||
action:ConversationViewActionCompose];
|
||||
}];
|
||||
[SignalApp.sharedApp presentConversationForThread:thread action:ConversationViewActionCompose animated:NO];
|
||||
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)showNewGroupView:(id)sender
|
||||
|
|
|
@ -452,30 +452,24 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
|
|||
DDLogError(@"Group creation successful.");
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self dismissViewControllerAnimated:YES
|
||||
completion:^{
|
||||
// Pop to new group thread.
|
||||
[SignalApp.sharedApp presentConversationForThread:thread];
|
||||
}];
|
||||
|
||||
[SignalApp.sharedApp presentConversationForThread:thread action:ConversationViewActionCompose animated:NO];
|
||||
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
});
|
||||
};
|
||||
|
||||
void (^failureHandler)(NSError *error) = ^(NSError *error) {
|
||||
DDLogError(@"Group creation failed: %@", error);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self dismissViewControllerAnimated:YES
|
||||
completion:^{
|
||||
// Add an error message to the new group indicating
|
||||
// that group creation didn't succeed.
|
||||
[[[TSErrorMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
||||
TSErrorMessage *errorMessage = [[TSErrorMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
||||
inThread:thread
|
||||
failedMessageType:TSErrorMessageGroupCreationFailed]
|
||||
save];
|
||||
failedMessageType:TSErrorMessageGroupCreationFailed];
|
||||
[errorMessage save];
|
||||
|
||||
[SignalApp.sharedApp presentConversationForThread:thread];
|
||||
}];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[SignalApp.sharedApp presentConversationForThread:thread action:ConversationViewActionCompose animated:NO];
|
||||
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (void)presentForAppSettings:(UINavigationController *)navigationController;
|
||||
+ (void)presentForRegistration:(UINavigationController *)navigationController;
|
||||
+ (void)presentForUpgradeOrNag:(HomeViewController *)presentingController NS_SWIFT_NAME(presentForUpgradeOrNag(from:));
|
||||
+ (void)presentForUpgradeOrNag:(HomeViewController *)fromViewController NS_SWIFT_NAME(presentForUpgradeOrNag(from:));
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -558,15 +558,13 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat
|
|||
[navigationController pushViewController:vc animated:YES];
|
||||
}
|
||||
|
||||
+ (void)presentForUpgradeOrNag:(HomeViewController *)presentingController
|
||||
+ (void)presentForUpgradeOrNag:(HomeViewController *)fromViewController
|
||||
{
|
||||
OWSAssert(presentingController);
|
||||
OWSAssert(fromViewController);
|
||||
|
||||
ProfileViewController *vc = [[ProfileViewController alloc] initWithMode:ProfileViewMode_UpgradeOrNag];
|
||||
OWSNavigationController *navigationController = [[OWSNavigationController alloc] initWithRootViewController:vc];
|
||||
[presentingController presentTopLevelModalViewController:navigationController
|
||||
animateDismissal:YES
|
||||
animatePresentation:YES];
|
||||
[fromViewController presentViewController:navigationController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
|
|
@ -403,12 +403,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
{
|
||||
OWSAssert(recipientId.length > 0);
|
||||
|
||||
[SignalApp.sharedApp presentConversationForRecipientId:recipientId action:ConversationViewActionCompose];
|
||||
[SignalApp.sharedApp presentConversationForRecipientId:recipientId
|
||||
action:ConversationViewActionCompose
|
||||
animated:YES];
|
||||
}
|
||||
|
||||
- (void)callMember:(NSString *)recipientId
|
||||
{
|
||||
[SignalApp.sharedApp presentConversationForRecipientId:recipientId action:ConversationViewActionAudioCall];
|
||||
[SignalApp.sharedApp presentConversationForRecipientId:recipientId
|
||||
action:ConversationViewActionAudioCall
|
||||
animated:YES];
|
||||
}
|
||||
|
||||
- (void)showSafetyNumberView:(NSString *)recipientId
|
||||
|
|
|
@ -35,16 +35,24 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (instancetype)sharedApp;
|
||||
|
||||
#pragma mark - View Convenience Methods
|
||||
#pragma mark - Conversation Presentation
|
||||
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId
|
||||
action:(ConversationViewAction)action
|
||||
animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentConversationForThreadId:(NSString *)threadId animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentConversationForThread:(TSThread *)thread animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action animated:(BOOL)isAnimated;
|
||||
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId;
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId action:(ConversationViewAction)action;
|
||||
- (void)presentConversationForThreadId:(NSString *)threadId;
|
||||
- (void)presentConversationForThread:(TSThread *)thread;
|
||||
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action;
|
||||
- (void)presentConversationForThread:(TSThread *)thread
|
||||
action:(ConversationViewAction)action
|
||||
focusMessageId:(nullable NSString *)focusMessageId;
|
||||
focusMessageId:(nullable NSString *)focusMessageId
|
||||
animated:(BOOL)isAnimated;
|
||||
|
||||
#pragma mark - Methods
|
||||
|
||||
|
|
|
@ -152,24 +152,24 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - View Convenience Methods
|
||||
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId animated:(BOOL)isAnimated
|
||||
{
|
||||
[self presentConversationForRecipientId:recipientId action:ConversationViewActionNone];
|
||||
[self presentConversationForRecipientId:recipientId action:ConversationViewActionNone animated:(BOOL)isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId action:(ConversationViewAction)action
|
||||
- (void)presentConversationForRecipientId:(NSString *)recipientId
|
||||
action:(ConversationViewAction)action
|
||||
animated:(BOOL)isAnimated
|
||||
{
|
||||
DispatchMainThreadSafe(^{
|
||||
__block TSThread *thread = nil;
|
||||
[OWSPrimaryStorage.dbReadWriteConnection
|
||||
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||
thread = [TSContactThread getOrCreateThreadWithContactId:recipientId transaction:transaction];
|
||||
}];
|
||||
[self presentConversationForThread:thread action:action];
|
||||
});
|
||||
[self presentConversationForThread:thread action:action animated:(BOOL)isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentConversationForThreadId:(NSString *)threadId
|
||||
- (void)presentConversationForThreadId:(NSString *)threadId animated:(BOOL)isAnimated
|
||||
{
|
||||
OWSAssert(threadId.length > 0);
|
||||
|
||||
|
@ -179,22 +179,23 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return;
|
||||
}
|
||||
|
||||
[self presentConversationForThread:thread];
|
||||
[self presentConversationForThread:thread animated:isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentConversationForThread:(TSThread *)thread
|
||||
- (void)presentConversationForThread:(TSThread *)thread animated:(BOOL)isAnimated
|
||||
{
|
||||
[self presentConversationForThread:thread action:ConversationViewActionNone];
|
||||
[self presentConversationForThread:thread action:ConversationViewActionNone animated:isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action
|
||||
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action animated:(BOOL)isAnimated
|
||||
{
|
||||
[self presentConversationForThread:thread action:action focusMessageId:nil];
|
||||
[self presentConversationForThread:thread action:action focusMessageId:nil animated:isAnimated];
|
||||
}
|
||||
|
||||
- (void)presentConversationForThread:(TSThread *)thread
|
||||
action:(ConversationViewAction)action
|
||||
focusMessageId:(nullable NSString *)focusMessageId
|
||||
animated:(BOOL)isAnimated
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
|
@ -216,7 +217,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
}
|
||||
|
||||
[self.homeViewController presentThread:thread action:action focusMessageId:focusMessageId];
|
||||
[self.homeViewController presentThread:thread action:action focusMessageId:focusMessageId animated:isAnimated];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,11 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe
|
|||
}
|
||||
|
||||
self.hasPresentedConversationSinceLastDeactivation = YES;
|
||||
[SignalApp.sharedApp presentConversationForThreadId:threadId];
|
||||
|
||||
// This will happen before the app is visible. By making this animated:NO, the conversation screen
|
||||
// will be visible to the user immediately upon opening the app, rather than having to watch it animate
|
||||
// in from the homescreen.
|
||||
[SignalApp.sharedApp presentConversationForThreadId:threadId animated:NO];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
|
|
Loading…
Reference in a new issue