Open message search results.

pull/1/head
Matthew Chen 7 years ago
parent 00c2d47a9a
commit 27b6a5e5bb

@ -19,7 +19,9 @@ typedef NS_ENUM(NSUInteger, ConversationViewAction) {
@property (nonatomic, readonly) TSThread *thread; @property (nonatomic, readonly) TSThread *thread;
- (void)configureForThread:(TSThread *)thread action:(ConversationViewAction)action; - (void)configureForThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId;
- (void)popKeyBoard; - (void)popKeyBoard;

@ -195,6 +195,8 @@ typedef enum : NSUInteger {
@property (nonatomic) NSUInteger lastRangeLength; @property (nonatomic) NSUInteger lastRangeLength;
@property (nonatomic) ConversationViewAction actionOnOpen; @property (nonatomic) ConversationViewAction actionOnOpen;
@property (nonatomic, nullable) NSString *focusMessageIdOnOpen;
@property (nonatomic) BOOL peek; @property (nonatomic) BOOL peek;
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSContactsManager *contactsManager;
@ -426,11 +428,16 @@ typedef enum : NSUInteger {
[self hideInputIfNeeded]; [self hideInputIfNeeded];
} }
- (void)configureForThread:(TSThread *)thread action:(ConversationViewAction)action - (void)configureForThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId
{ {
OWSAssert(thread);
_thread = thread; _thread = thread;
_isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]]; _isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
self.actionOnOpen = action; self.actionOnOpen = action;
self.focusMessageIdOnOpen = focusMessageId;
_cellMediaCache = [NSCache new]; _cellMediaCache = [NSCache new];
// Cache the cell media for ~24 cells. // Cache the cell media for ~24 cells.
self.cellMediaCache.countLimit = 24; self.cellMediaCache.countLimit = 24;
@ -698,13 +705,35 @@ typedef enum : NSUInteger {
return nil; return nil;
} }
- (NSIndexPath *_Nullable)indexPathOfMessageOnOpen
{
OWSAssert(self.focusMessageIdOnOpen);
NSInteger row = 0;
for (ConversationViewItem *viewItem in self.viewItems) {
if ([viewItem.interaction.uniqueId isEqualToString:self.focusMessageIdOnOpen]) {
return [NSIndexPath indexPathForRow:row inSection:0];
}
row++;
}
return nil;
}
- (void)scrollToDefaultPosition - (void)scrollToDefaultPosition
{ {
if (self.isUserScrolling) { if (self.isUserScrolling) {
return; return;
} }
NSIndexPath *_Nullable indexPath = [self indexPathOfUnreadMessagesIndicator]; NSIndexPath *_Nullable indexPath = nil;
if (self.focusMessageIdOnOpen) {
indexPath = [self indexPathOfMessageOnOpen];
}
if (!indexPath) {
indexPath = [self indexPathOfUnreadMessagesIndicator];
}
if (indexPath) { if (indexPath) {
if (indexPath.section == 0 && indexPath.row == 0) { if (indexPath.section == 0 && indexPath.row == 0) {
[self.collectionView setContentOffset:CGPointZero animated:NO]; [self.collectionView setContentOffset:CGPointZero animated:NO];
@ -1081,8 +1110,9 @@ typedef enum : NSUInteger {
break; break;
} }
// Clear the "on open" state after the view has been presented.
self.actionOnOpen = ConversationViewActionNone; self.actionOnOpen = ConversationViewActionNone;
self.focusMessageIdOnOpen = nil;
self.isViewCompletelyAppeared = YES; self.isViewCompletelyAppeared = YES;
self.viewHasEverAppeared = YES; self.viewHasEverAppeared = YES;
@ -1557,7 +1587,7 @@ typedef enum : NSUInteger {
// Dont auto-scroll afterloading more messagesunless we havemore unseen messages. // Dont auto-scroll afterloading more messagesunless we havemore unseen messages.
// //
// Otherwise, tapping on "load more messages" autoscrolls you downward which is completely wrong. // Otherwise, tapping on "load more messages" autoscrolls you downward which is completely wrong.
if (hasEarlierUnseenMessages) { if (hasEarlierUnseenMessages && !self.focusMessageIdOnOpen) {
[self scrollToUnreadIndicatorAnimated]; [self scrollToUnreadIndicatorAnimated];
} }
} }

@ -79,7 +79,9 @@ class ConversationSearchViewController: UITableViewController {
} }
let thread = searchResult.thread let thread = searchResult.thread
SignalApp.shared().presentConversation(for: thread.threadRecord, action: .compose) SignalApp.shared().presentConversation(for: thread.threadRecord,
action: .compose,
focusMessageId: searchResult.messageId)
} }
} }

@ -11,6 +11,9 @@
@interface HomeViewController : OWSViewController @interface HomeViewController : OWSViewController
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action; - (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action;
- (void)presentThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId;
- (void)showNewConversationView; - (void)showNewConversationView;

@ -424,7 +424,7 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
ConversationViewController *vc = [ConversationViewController new]; ConversationViewController *vc = [ConversationViewController new];
TSThread *thread = [self threadForIndexPath:indexPath]; TSThread *thread = [self threadForIndexPath:indexPath];
self.lastThread = thread; self.lastThread = thread;
[vc configureForThread:thread action:ConversationViewActionNone]; [vc configureForThread:thread action:ConversationViewActionNone focusMessageId:nil];
[vc peekSetup]; [vc peekSetup];
return vc; return vc;
@ -1000,6 +1000,13 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
} }
- (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action - (void)presentThread:(TSThread *)thread action:(ConversationViewAction)action
{
[self presentThread:thread action:action focusMessageId:nil];
}
- (void)presentThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId
{ {
if (thread == nil) { if (thread == nil) {
OWSFail(@"Thread unexpectedly nil"); OWSFail(@"Thread unexpectedly nil");
@ -1008,11 +1015,11 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
// We do this synchronously if we're already on the main thread. // We do this synchronously if we're already on the main thread.
DispatchMainThreadSafe(^{ DispatchMainThreadSafe(^{
ConversationViewController *mvc = [ConversationViewController new]; ConversationViewController *viewController = [ConversationViewController new];
[mvc configureForThread:thread action:action]; [viewController configureForThread:thread action:action focusMessageId:focusMessageId];
self.lastThread = thread; self.lastThread = thread;
[self pushTopLevelViewController:mvc animateDismissal:YES animatePresentation:YES]; [self pushTopLevelViewController:viewController animateDismissal:YES animatePresentation:YES];
}); });
} }

@ -45,10 +45,7 @@ import SignalMessaging
isVideo: Bool) -> Bool { isVideo: Bool) -> Bool {
// Rather than an init-assigned dependency property, we access `callUIAdapter` via Environment // Rather than an init-assigned dependency property, we access `callUIAdapter` via Environment
// because it can change after app launch due to user settings // because it can change after app launch due to user settings
guard let callUIAdapter = SignalApp.shared().callUIAdapter else { let callUIAdapter = SignalApp.shared().callUIAdapter
owsFail("\(TAG) can't initiate call because callUIAdapter is nil")
return false
}
guard let frontmostViewController = UIApplication.shared.frontmostViewController else { guard let frontmostViewController = UIApplication.shared.frontmostViewController else {
owsFail("\(TAG) could not identify frontmostViewController in \(#function)") owsFail("\(TAG) could not identify frontmostViewController in \(#function)")
return false return false

@ -4,6 +4,8 @@
#import "ConversationViewController.h" #import "ConversationViewController.h"
NS_ASSUME_NONNULL_BEGIN
@class AccountManager; @class AccountManager;
@class CallService; @class CallService;
@class CallUIAdapter; @class CallUIAdapter;
@ -17,8 +19,8 @@
@interface SignalApp : NSObject @interface SignalApp : NSObject
@property (nonatomic, weak) HomeViewController *homeViewController; @property (nonatomic, nullable, weak) HomeViewController *homeViewController;
@property (nonatomic, weak) OWSNavigationController *signUpFlowNavigationController; @property (nonatomic, nullable, weak) OWSNavigationController *signUpFlowNavigationController;
// TODO: Convert to singletons? // TODO: Convert to singletons?
@property (nonatomic, readonly) OWSWebRTCCallMessageHandler *callMessageHandler; @property (nonatomic, readonly) OWSWebRTCCallMessageHandler *callMessageHandler;
@ -40,6 +42,9 @@
- (void)presentConversationForThreadId:(NSString *)threadId; - (void)presentConversationForThreadId:(NSString *)threadId;
- (void)presentConversationForThread:(TSThread *)thread; - (void)presentConversationForThread:(TSThread *)thread;
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action; - (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action;
- (void)presentConversationForThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId;
#pragma mark - Methods #pragma mark - Methods
@ -48,3 +53,5 @@
+ (void)clearAllNotifications; + (void)clearAllNotifications;
@end @end
NS_ASSUME_NONNULL_END

@ -13,6 +13,8 @@
#import <SignalServiceKit/TSGroupThread.h> #import <SignalServiceKit/TSGroupThread.h>
#import <SignalServiceKit/Threading.h> #import <SignalServiceKit/Threading.h>
NS_ASSUME_NONNULL_BEGIN
@interface SignalApp () @interface SignalApp ()
@property (nonatomic) OWSWebRTCCallMessageHandler *callMessageHandler; @property (nonatomic) OWSWebRTCCallMessageHandler *callMessageHandler;
@ -186,6 +188,13 @@
} }
- (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action - (void)presentConversationForThread:(TSThread *)thread action:(ConversationViewAction)action
{
[self presentConversationForThread:thread action:action focusMessageId:nil];
}
- (void)presentConversationForThread:(TSThread *)thread
action:(ConversationViewAction)action
focusMessageId:(nullable NSString *)focusMessageId
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
@ -207,7 +216,7 @@
} }
} }
[self.homeViewController presentThread:thread action:action]; [self.homeViewController presentThread:thread action:action focusMessageId:focusMessageId];
}); });
} }
@ -248,3 +257,5 @@
} }
@end @end
NS_ASSUME_NONNULL_END

@ -7,10 +7,14 @@ import SignalServiceKit
public class ConversationSearchResult { public class ConversationSearchResult {
public let thread: ThreadViewModel public let thread: ThreadViewModel
public let messageId: String?
public let snippet: String? public let snippet: String?
init(thread: ThreadViewModel, snippet: String?) { init(thread: ThreadViewModel, messageId: String?, snippet: String?) {
self.thread = thread self.thread = thread
self.messageId = messageId
self.snippet = snippet self.snippet = snippet
} }
} }
@ -71,7 +75,7 @@ public class ConversationSearcher: NSObject {
if let thread = match as? TSThread { if let thread = match as? TSThread {
let threadViewModel = ThreadViewModel(thread: thread, transaction: transaction) let threadViewModel = ThreadViewModel(thread: thread, transaction: transaction)
let snippet: String? = thread.lastMessageText(transaction: transaction) let snippet: String? = thread.lastMessageText(transaction: transaction)
let searchResult = ConversationSearchResult(thread: threadViewModel, snippet: snippet) let searchResult = ConversationSearchResult(thread: threadViewModel, messageId: nil, snippet: snippet)
if let contactThread = thread as? TSContactThread { if let contactThread = thread as? TSContactThread {
let recipientId = contactThread.contactIdentifier() let recipientId = contactThread.contactIdentifier()
@ -82,14 +86,14 @@ public class ConversationSearcher: NSObject {
let thread = message.thread(with: transaction) let thread = message.thread(with: transaction)
let threadViewModel = ThreadViewModel(thread: thread, transaction: transaction) let threadViewModel = ThreadViewModel(thread: thread, transaction: transaction)
let searchResult = ConversationSearchResult(thread: threadViewModel, snippet: snippet) let searchResult = ConversationSearchResult(thread: threadViewModel, messageId: message.uniqueId, snippet: snippet)
messages.append(searchResult) messages.append(searchResult)
} else if let signalAccount = match as? SignalAccount { } else if let signalAccount = match as? SignalAccount {
let searchResult = ContactSearchResult(signalAccount: signalAccount) let searchResult = ContactSearchResult(signalAccount: signalAccount)
contacts.append(searchResult) contacts.append(searchResult)
} else { } else {
Logger.debug("\(self.logTag) in \(#function) unhandled item: \(match)") owsFail("\(self.logTag) in \(#function) unhandled item: \(match)")
} }
} }

Loading…
Cancel
Save