Update thread's sorting order based on whatever the currently last message is

pull/1/head
Michael Kirk 7 years ago
parent 02692e42bd
commit fe7d69e9c6

@ -59,9 +59,6 @@ class OWS110SortIdMigration: OWSDatabaseMigration {
Logger.info("re-archiving \(archivedThreads.count) threads which were previously archived") Logger.info("re-archiving \(archivedThreads.count) threads which were previously archived")
for archivedThread in archivedThreads { for archivedThread in archivedThreads {
// latestMessageSortId will have been modified by saving all
// the interactions above, make sure we get the latest value.
archivedThread.reload(with: transaction)
archivedThread.archiveThread(with: transaction) archivedThread.archiveThread(with: transaction)
} }
} }

@ -5,7 +5,21 @@
import Foundation import Foundation
import SignalServiceKit import SignalServiceKit
public class ConversationSearchResult: Comparable { public typealias MessageSortKey = UInt64
public struct ConversationSortKey: Comparable {
let creationDate: Date
let lastMessageReceivedAtDate: Date?
// MARK: Comparable
public static func < (lhs: ConversationSortKey, rhs: ConversationSortKey) -> Bool {
let lhsDate = lhs.lastMessageReceivedAtDate ?? lhs.creationDate
let rhsDate = rhs.lastMessageReceivedAtDate ?? rhs.creationDate
return lhsDate < rhsDate
}
}
public class ConversationSearchResult<SortKey>: Comparable where SortKey: Comparable {
public let thread: ThreadViewModel public let thread: ThreadViewModel
public let messageId: String? public let messageId: String?
@ -13,9 +27,9 @@ public class ConversationSearchResult: Comparable {
public let snippet: String? public let snippet: String?
private let sortKey: UInt64 private let sortKey: SortKey
init(thread: ThreadViewModel, sortKey: UInt64, messageId: String? = nil, messageDate: Date? = nil, snippet: String? = nil) { init(thread: ThreadViewModel, sortKey: SortKey, messageId: String? = nil, messageDate: Date? = nil, snippet: String? = nil) {
self.thread = thread self.thread = thread
self.sortKey = sortKey self.sortKey = sortKey
self.messageId = messageId self.messageId = messageId
@ -65,11 +79,11 @@ public class ContactSearchResult: Comparable {
public class SearchResultSet { public class SearchResultSet {
public let searchText: String public let searchText: String
public let conversations: [ConversationSearchResult] public let conversations: [ConversationSearchResult<ConversationSortKey>]
public let contacts: [ContactSearchResult] public let contacts: [ContactSearchResult]
public let messages: [ConversationSearchResult] public let messages: [ConversationSearchResult<MessageSortKey>]
public init(searchText: String, conversations: [ConversationSearchResult], contacts: [ContactSearchResult], messages: [ConversationSearchResult]) { public init(searchText: String, conversations: [ConversationSearchResult<ConversationSortKey>], contacts: [ContactSearchResult], messages: [ConversationSearchResult<MessageSortKey>]) {
self.searchText = searchText self.searchText = searchText
self.conversations = conversations self.conversations = conversations
self.contacts = contacts self.contacts = contacts
@ -101,9 +115,9 @@ public class ConversationSearcher: NSObject {
transaction: YapDatabaseReadTransaction, transaction: YapDatabaseReadTransaction,
contactsManager: ContactsManagerProtocol) -> SearchResultSet { contactsManager: ContactsManagerProtocol) -> SearchResultSet {
var conversations: [ConversationSearchResult] = [] var conversations: [ConversationSearchResult<ConversationSortKey>] = []
var contacts: [ContactSearchResult] = [] var contacts: [ContactSearchResult] = []
var messages: [ConversationSearchResult] = [] var messages: [ConversationSearchResult<MessageSortKey>] = []
var existingConversationRecipientIds: Set<String> = Set() var existingConversationRecipientIds: Set<String> = Set()
@ -111,7 +125,8 @@ 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 sortKey = thread.latestMessageSortId let sortKey = ConversationSortKey(creationDate: thread.creationDate,
lastMessageReceivedAtDate: thread.lastInteractionForInbox(transaction: transaction)?.receivedAtDate())
let searchResult = ConversationSearchResult(thread: threadViewModel, sortKey: sortKey) let searchResult = ConversationSearchResult(thread: threadViewModel, sortKey: sortKey)
if let contactThread = thread as? TSContactThread { if let contactThread = thread as? TSContactThread {

@ -72,12 +72,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
* @return the latest sortId of a message in the thread or 0 if there are no messages in that
* thread.
*/
@property (nonatomic, readonly) uint64_t latestMessageSortId;
/** /**
* Returns the string that will be displayed typically in a conversations view as a preview of the last message * Returns the string that will be displayed typically in a conversations view as a preview of the last message
*received in this thread. *received in this thread.
@ -103,7 +97,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
* @return YES if no new messages have been sent or received since the thread was last archived. * @return YES if no new messages have been sent or received since the thread was last archived.
*/ */
- (BOOL)isArchived; - (BOOL)isArchivedWithTransaction:(YapDatabaseReadTransaction *)transaction;
/** /**
* Archives a thread * Archives a thread

@ -15,6 +15,7 @@
#import "TSInteraction.h" #import "TSInteraction.h"
#import "TSInvalidIdentityKeyReceivingErrorMessage.h" #import "TSInvalidIdentityKeyReceivingErrorMessage.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -24,8 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) NSDate *creationDate; @property (nonatomic) NSDate *creationDate;
@property (nonatomic, nullable) NSString *conversationColorName; @property (nonatomic, nullable) NSString *conversationColorName;
@property (nonatomic) uint64_t latestMessageSortId; @property (nonatomic) NSNumber *archivedAsOfMessageSortId;
@property (nonatomic) uint64_t archivedAsOfMessageSortId;
@property (nonatomic, copy, nullable) NSString *messageDraft; @property (nonatomic, copy, nullable) NSString *messageDraft;
@property (atomic, nullable) NSDate *mutedUntilDate; @property (atomic, nullable) NSDate *mutedUntilDate;
@ -350,9 +350,8 @@ NS_ASSUME_NONNULL_BEGIN
return; return;
} }
self.hasEverHadMessage = YES; if (!self.hasEverHadMessage) {
if (lastMessage.sortId > self.latestMessageSortId) { self.hasEverHadMessage = YES;
self.latestMessageSortId = lastMessage.sortId;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
} }
} }
@ -379,9 +378,15 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Archival #pragma mark - Archival
- (BOOL)isArchived - (BOOL)isArchivedWithTransaction:(YapDatabaseReadTransaction *)transaction;
{ {
return self.archivedAsOfMessageSortId >= self.latestMessageSortId; if (!self.archivedAsOfMessageSortId) {
return NO;
}
TSInteraction *_Nullable latestInteraction = [self lastInteractionForInboxWithTransaction:transaction];
uint64_t latestSortIdForInbox = latestInteraction ? latestInteraction.sortId : 0;
return self.archivedAsOfMessageSortId.unsignedLongLongValue >= latestSortIdForInbox;
} }
+ (BOOL)legacyIsArchivedWithLastMessageDate:(nullable NSDate *)lastMessageDate + (BOOL)legacyIsArchivedWithLastMessageDate:(nullable NSDate *)lastMessageDate
@ -402,7 +407,9 @@ NS_ASSUME_NONNULL_BEGIN
{ {
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) { changeBlock:^(TSThread *thread) {
thread.archivedAsOfMessageSortId = self.latestMessageSortId; uint64_t latestId = [SSKIncrementingIdFinder previousIdWithKey:TSInteraction.collection
transaction:transaction];
thread.archivedAsOfMessageSortId = @(latestId);
}]; }];
[self markAllAsReadWithTransaction:transaction]; [self markAllAsReadWithTransaction:transaction];
@ -412,7 +419,7 @@ NS_ASSUME_NONNULL_BEGIN
{ {
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) { changeBlock:^(TSThread *thread) {
thread.archivedAsOfMessageSortId = 0; thread.archivedAsOfMessageSortId = nil;
}]; }];
} }

@ -9,6 +9,12 @@ public class SSKIncrementingIdFinder: NSObject {
private static let collectionName = "IncrementingIdCollection" private static let collectionName = "IncrementingIdCollection"
@objc
public class func previousId(key: String, transaction: YapDatabaseReadTransaction) -> UInt64 {
let previousId: UInt64 = transaction.object(forKey: key, inCollection: collectionName) as? UInt64 ?? 0
return previousId
}
@objc @objc
public class func nextId(key: String, transaction: YapDatabaseReadWriteTransaction) -> UInt64 { public class func nextId(key: String, transaction: YapDatabaseReadWriteTransaction) -> UInt64 {
let previousId: UInt64 = transaction.object(forKey: key, inCollection: collectionName) as? UInt64 ?? 0 let previousId: UInt64 = transaction.object(forKey: key, inCollection: collectionName) as? UInt64 ?? 0

@ -293,7 +293,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
} }
} }
return thread.isArchived ? TSArchiveGroup : TSInboxGroup; return [thread isArchivedWithTransaction:transaction] ? TSArchiveGroup : TSInboxGroup;
}]; }];
YapDatabaseViewSorting *viewSorting = [self threadSorting]; YapDatabaseViewSorting *viewSorting = [self threadSorting];
@ -304,7 +304,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
[[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]]; [[YapWhitelistBlacklist alloc] initWithWhitelist:[NSSet setWithObject:[TSThread collection]]];
YapDatabaseView *databaseView = YapDatabaseView *databaseView =
[[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options]; [[YapDatabaseAutoView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"4" options:options];
[storage asyncRegisterExtension:databaseView withName:TSThreadDatabaseViewExtensionName]; [storage asyncRegisterExtension:databaseView withName:TSThreadDatabaseViewExtensionName];
} }
@ -329,11 +329,16 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
TSThread *thread1 = (TSThread *)object1; TSThread *thread1 = (TSThread *)object1;
TSThread *thread2 = (TSThread *)object2; TSThread *thread2 = (TSThread *)object2;
if ([group isEqualToString:TSArchiveGroup] || [group isEqualToString:TSInboxGroup]) { if ([group isEqualToString:TSArchiveGroup] || [group isEqualToString:TSInboxGroup]) {
if (thread1.latestMessageSortId == 0 && thread2.latestMessageSortId == 0) {
return [thread1.creationDate compare:thread2.creationDate];
}
return [@(thread1.latestMessageSortId) compare:@(thread2.latestMessageSortId)]; TSInteraction *_Nullable lastInteractionForInbox1 =
[thread1 lastInteractionForInboxWithTransaction:transaction];
NSDate *date1 = lastInteractionForInbox1 ? lastInteractionForInbox1.receivedAtDate : thread1.creationDate;
TSInteraction *_Nullable lastInteractionForInbox2 =
[thread2 lastInteractionForInboxWithTransaction:transaction];
NSDate *date2 = lastInteractionForInbox2 ? lastInteractionForInbox2.receivedAtDate : thread2.creationDate;
return [date1 compare:date2];
} }
return NSOrderedSame; return NSOrderedSame;

Loading…
Cancel
Save