Clean up thread model

This commit is contained in:
nielsandriesse 2021-05-05 09:53:18 +10:00
parent 1bfc5617bf
commit 21acdfc835
18 changed files with 51 additions and 140 deletions

View File

@ -139,8 +139,9 @@ CGFloat kIconViewLength = 24;
- (nullable NSString *)threadName
{
NSString *threadName = self.thread.name;
if (self.thread.contactIdentifier) {
return [[LKStorage.shared getContactWithSessionID:self.thread.contactIdentifier] displayNameFor:SNContactContextRegular] ?: @"Anonymous";
if ([self.thread isKindOfClass:TSContactThread.class]) {
TSContactThread *thread = (TSContactThread *)self.thread;
return [[LKStorage.shared getContactWithSessionID:thread.contactIdentifier] displayNameFor:SNContactContextRegular] ?: @"Anonymous";
} else if (threadName.length == 0 && [self isGroupThread]) {
threadName = [MessageStrings newGroupDefaultTitle];
}
@ -367,7 +368,8 @@ CGFloat kIconViewLength = 24;
if (self.thread.isGroupThread) {
displayName = @"the group";
} else {
displayName = [[LKStorage.shared getContactWithSessionID:self.thread.contactIdentifier] displayNameFor:SNContactContextRegular] ?: @"anonymous";
TSContactThread *thread = (TSContactThread *)self.thread;
displayName = [[LKStorage.shared getContactWithSessionID:thread.contactIdentifier] displayNameFor:SNContactContextRegular] ?: @"anonymous";
}
subtitleLabel.text = [NSString stringWithFormat:NSLocalizedString(@"When enabled, messages between you and %@ will disappear after they have been seen.", ""), displayName];
subtitleLabel.textColor = LKColors.text;
@ -738,7 +740,7 @@ CGFloat kIconViewLength = 24;
subtitleView.font = [LKFonts spaceMonoOfSize:LKValues.smallFontSize];
subtitleView.lineBreakMode = NSLineBreakByCharWrapping;
subtitleView.numberOfLines = 2;
subtitleView.text = self.thread.contactIdentifier;
subtitleView.text = ((TSContactThread *)self.thread).contactIdentifier;
subtitleView.textAlignment = NSTextAlignmentCenter;
[stackView addArrangedSubview:subtitleView];
}
@ -1084,7 +1086,7 @@ CGFloat kIconViewLength = 24;
- (void)copySessionID
{
UIPasteboard.generalPasteboard.string = self.thread.contactIdentifier;
UIPasteboard.generalPasteboard.string = ((TSContactThread *)self.thread).contactIdentifier;
}
- (void)showMediaGallery
@ -1135,7 +1137,7 @@ CGFloat kIconViewLength = 24;
- (void)saveName
{
if (![self.thread isKindOfClass:TSContactThread.class]) { return; }
SNContact *contact = [LKStorage.shared getContactWithSessionID:self.thread.contactIdentifier];
SNContact *contact = [LKStorage.shared getContactWithSessionID:((TSContactThread *)self.thread).contactIdentifier];
if (contact == nil) { return; }
NSString *text = [self.displayNameTextField.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
contact.nickname = text.length > 0 ? text : nil;
@ -1186,7 +1188,7 @@ CGFloat kIconViewLength = 24;
OWSAssertDebug(recipientId.length > 0);
if (recipientId.length > 0 && [self.thread isKindOfClass:[TSContactThread class]] &&
[self.thread.contactIdentifier isEqualToString:recipientId]) {
[((TSContactThread *)self.thread).contactIdentifier isEqualToString:recipientId]) {
[self updateTableContents];
}
}

View File

@ -76,7 +76,7 @@ final class ConversationTitleView : UIView {
} else if thread.isNoteToSelf() {
return "Note to Self"
} else {
let sessionID = thread.contactIdentifier()!
let sessionID = (thread as! TSContactThread).contactIdentifier()
var result = sessionID
Storage.read { transaction in
result = Storage.shared.getContact(with: sessionID)?.displayName(for: .regular) ?? "Anonymous"

View File

@ -337,8 +337,8 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
self.present(alert, animated: true, completion: nil)
}
delete.backgroundColor = Colors.destructive
if thread is TSContactThread {
let publicKey = thread.contactIdentifier()!
if let thread = thread as? TSContactThread {
let publicKey = thread.contactIdentifier()
let blockingManager = SSKEnvironment.shared.blockingManager
let isBlocked = blockingManager.isRecipientIdBlocked(publicKey)
let block = UITableViewRowAction(style: .normal, title: NSLocalizedString("BLOCK_LIST_BLOCK_BUTTON", comment: "")) { _, _ in

View File

@ -5,7 +5,7 @@ enum ContactUtilities {
var result: [String] = []
Storage.read { transaction in
TSContactThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSContactThread, thread.shouldThreadBeVisible else { return }
guard let thread = object as? TSContactThread, thread.shouldBeVisible else { return }
result.append(thread.contactIdentifier())
}
}

View File

@ -234,7 +234,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
}
TSThread *thread = (TSThread *)object;
if (thread.shouldThreadBeVisible) {
if (thread.shouldBeVisible) {
// Do nothing; we never hide threads that have ever had a message.
} else {
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName];
@ -244,7 +244,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
}
}
return [thread isArchivedWithTransaction:transaction] ? TSArchiveGroup : TSInboxGroup;
return TSInboxGroup;
}];
YapDatabaseViewSorting *viewSorting = [self threadSorting];

View File

@ -50,7 +50,7 @@ public final class OpenGroupManagerV2 : NSObject {
storage.write(with: { transaction in
let transaction = transaction as! YapDatabaseReadWriteTransaction
let thread = TSGroupThread.getOrCreateThread(with: model, transaction: transaction)
thread.shouldThreadBeVisible = true
thread.shouldBeVisible = true
thread.save(with: transaction)
storage.setV2OpenGroup(openGroup, for: thread.uniqueId!, using: transaction)
}, completion: {

View File

@ -202,7 +202,7 @@ extension MessageReceiver {
userProfile.profileName = contact.displayName
userProfile.save(with: transaction)
let thread = TSContactThread.getOrCreateThread(withContactId: sessionID, transaction: transaction)
thread.shouldThreadBeVisible = true
thread.shouldBeVisible = true
thread.save(with: transaction)
}
// Closed groups

View File

@ -10,8 +10,6 @@ extern NSString *const TSContactThreadPrefix;
@interface TSContactThread : TSThread
@property (nonatomic) BOOL hasDismissedOffers;
- (instancetype)initWithContactId:(NSString *)contactId;
+ (instancetype)getOrCreateThreadWithContactId:(NSString *)contactId NS_SWIFT_NAME(getOrCreateThread(contactId:));

View File

@ -58,18 +58,16 @@ NSString *const TSContactThreadPrefix = @"c";
return @[ self.contactIdentifier ];
}
- (BOOL)isGroupThread {
return false;
}
- (BOOL)hasSafetyNumbers
- (BOOL)isGroupThread
{
return NO;
}
- (NSString *)name
{
return [[LKStorage.shared getContactWithSessionID:self.contactIdentifier] displayNameFor:SNContactContextRegular] ?: self.contactIdentifier;
NSString *sessionID = self.contactIdentifier;
SNContact *contact = [LKStorage.shared getContactWithSessionID:sessionID];
return [contact displayNameFor:SNContactContextRegular] ?: sessionID;
}
+ (NSString *)threadIdFromContactId:(NSString *)contactId {

View File

@ -232,7 +232,7 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific
- (void)softDeleteGroupThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self removeAllThreadInteractionsWithTransaction:transaction];
self.shouldThreadBeVisible = NO;
self.shouldBeVisible = NO;
[self saveWithTransaction:transaction];
}

View File

@ -10,17 +10,17 @@ BOOL IsNoteToSelfEnabled(void);
@class OWSDisappearingMessagesConfiguration;
@class TSInteraction;
@class TSInvalidIdentityKeyReceivingErrorMessage;
/**
* TSThread is the superclass of TSContactThread and TSGroupThread
*/
@interface TSThread : TSYapDatabaseObject
@property (nonatomic) BOOL shouldThreadBeVisible;
@property (nonatomic) BOOL shouldBeVisible;
@property (nonatomic, readonly) NSDate *creationDate;
@property (nonatomic, readonly) BOOL isArchivedByLegacyTimestampForSorting;
@property (nonatomic, readonly) TSInteraction *lastInteraction;
@property (atomic, readonly) BOOL isMuted;
@property (atomic, readonly, nullable) NSDate *mutedUntilDate;
/**
* Whether the object is a group thread or not.
@ -36,12 +36,6 @@ BOOL IsNoteToSelfEnabled(void);
*/
- (NSString *)name;
/**
* @returns
* Signal Id (e164) of the contact if it's a contact thread.
*/
- (nullable NSString *)contactIdentifier;
/**
* @returns recipientId for each recipient in the thread
*/
@ -67,7 +61,7 @@ BOOL IsNoteToSelfEnabled(void);
/**
* 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.
*
* @return Thread preview string.
*/
@ -85,27 +79,6 @@ BOOL IsNoteToSelfEnabled(void);
*/
- (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction;
#pragma mark Archival
/**
* @return YES if no new messages have been sent or received since the thread was last archived.
*/
- (BOOL)isArchivedWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* Archives a thread
*
* @param transaction Database transaction.
*/
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
/**
* Unarchives a thread
*
* @param transaction Database transaction.
*/
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)removeAllThreadInteractionsWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (TSInteraction *)getLastInteractionWithTransaction:(YapDatabaseReadTransaction *)transaction;
@ -114,6 +87,7 @@ BOOL IsNoteToSelfEnabled(void);
- (OWSDisappearingMessagesConfiguration *)disappearingMessagesConfigurationWithTransaction:
(YapDatabaseReadTransaction *)transaction;
- (uint32_t)disappearingMessagesDurationWithTransaction:(YapDatabaseReadTransaction *)transaction;
#pragma mark Drafts
@ -135,10 +109,7 @@ BOOL IsNoteToSelfEnabled(void);
*/
- (void)setDraft:(NSString *)draftString transaction:(YapDatabaseReadWriteTransaction *)transaction;
@property (atomic, readonly) BOOL isMuted;
@property (atomic, readonly, nullable) NSDate *mutedUntilDate;
#pragma mark - Update With... Methods
#pragma mark Muting
- (void)updateWithMutedUntilDate:(NSDate *)mutedUntilDate transaction:(YapDatabaseReadWriteTransaction *)transaction;

View File

@ -25,26 +25,18 @@ BOOL IsNoteToSelfEnabled(void)
@property (nonatomic, copy, nullable) NSString *messageDraft;
@property (atomic, nullable) NSDate *mutedUntilDate;
// DEPRECATED - not used since migrating to sortId
// but keeping these properties around to ease any pain in the back-forth
// migration while testing. Eventually we can safely delete these as they aren't used anywhere.
@property (nonatomic, nullable) NSDate *lastMessageDate DEPRECATED_ATTRIBUTE;
@property (nonatomic, nullable) NSDate *archivalDate DEPRECATED_ATTRIBUTE;
@end
#pragma mark -
@implementation TSThread
#pragma mark - Dependencies
#pragma mark Dependencies
- (TSAccountManager *)tsAccountManager
{
return SSKEnvironment.shared.tsAccountManager;
}
#pragma mark -
#pragma mark Initialization
+ (NSString *)collection {
return @"TSThread";
@ -69,19 +61,17 @@ BOOL IsNoteToSelfEnabled(void)
return self;
}
// renamed `hasEverHadMessage` -> `shouldThreadBeVisible`
if (!_shouldThreadBeVisible) {
// renamed `hasEverHadMessage` -> `shouldBeVisible`
if (!_shouldBeVisible) {
NSNumber *_Nullable legacy_hasEverHadMessage = [coder decodeObjectForKey:@"hasEverHadMessage"];
if (legacy_hasEverHadMessage != nil) {
_shouldThreadBeVisible = legacy_hasEverHadMessage.boolValue;
_shouldBeVisible = legacy_hasEverHadMessage.boolValue;
}
}
NSDate *_Nullable lastMessageDate = [coder decodeObjectOfClass:NSDate.class forKey:@"lastMessageDate"];
NSDate *_Nullable archivalDate = [coder decodeObjectOfClass:NSDate.class forKey:@"archivalDate"];
_isArchivedByLegacyTimestampForSorting =
[self.class legacyIsArchivedWithLastMessageDate:lastMessageDate archivalDate:archivalDate];
return self;
}
@ -141,7 +131,7 @@ BOOL IsNoteToSelfEnabled(void)
return [self.contactIdentifier isEqual:[SNGeneralUtilities getUserPublicKey]];
}
#pragma mark - To be subclassed.
#pragma mark To be subclassed.
- (BOOL)isGroupThread {
return NO;
@ -162,7 +152,7 @@ BOOL IsNoteToSelfEnabled(void)
return @[];
}
#pragma mark - Interactions
#pragma mark Interactions
/**
* Iterate over this thread's interactions
@ -343,15 +333,15 @@ BOOL IsNoteToSelfEnabled(void)
return;
}
if (!self.shouldThreadBeVisible) {
self.shouldThreadBeVisible = YES;
if (!self.shouldBeVisible) {
self.shouldBeVisible = YES;
[self saveWithTransaction:transaction];
} else {
[self touchWithTransaction:transaction];
}
}
#pragma mark - Disappearing Messages
#pragma mark Disappearing Messages
- (OWSDisappearingMessagesConfiguration *)disappearingMessagesConfigurationWithTransaction:
(YapDatabaseReadTransaction *)transaction
@ -361,7 +351,6 @@ BOOL IsNoteToSelfEnabled(void)
- (uint32_t)disappearingMessagesDurationWithTransaction:(YapDatabaseReadTransaction *)transaction
{
OWSDisappearingMessagesConfiguration *config = [self disappearingMessagesConfigurationWithTransaction:transaction];
if (!config.isEnabled) {
@ -371,54 +360,7 @@ BOOL IsNoteToSelfEnabled(void)
}
}
#pragma mark - Archival
- (BOOL)isArchivedWithTransaction:(YapDatabaseReadTransaction *)transaction;
{
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
archivalDate:(nullable NSDate *)archivalDate
{
if (!archivalDate) {
return NO;
}
if (!lastMessageDate) {
return YES;
}
return [archivalDate compare:lastMessageDate] != NSOrderedAscending;
}
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) {
uint64_t latestId = [SSKIncrementingIdFinder previousIdWithKey:TSInteraction.collection
transaction:transaction];
thread.archivedAsOfMessageSortId = @(latestId);
}];
[self markAllAsReadWithTransaction:transaction];
}
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) {
thread.archivedAsOfMessageSortId = nil;
}];
}
#pragma mark - Drafts
#pragma mark Drafts
- (NSString *)currentDraftWithTransaction:(YapDatabaseReadTransaction *)transaction {
TSThread *thread = [TSThread fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
@ -435,14 +377,13 @@ BOOL IsNoteToSelfEnabled(void)
[thread saveWithTransaction:transaction];
}
#pragma mark - Muted
#pragma mark Muting
- (BOOL)isMuted
{
NSDate *mutedUntilDate = self.mutedUntilDate;
NSDate *now = [NSDate date];
return (mutedUntilDate != nil &&
[mutedUntilDate timeIntervalSinceDate:now] > 0);
return (mutedUntilDate != nil && [mutedUntilDate timeIntervalSinceDate:now] > 0);
}
- (void)updateWithMutedUntilDate:(NSDate *)mutedUntilDate transaction:(YapDatabaseReadWriteTransaction *)transaction

View File

@ -192,7 +192,7 @@ public class FullTextSearchFinder: NSObject {
if let groupThread = object as? TSGroupThread {
return self.groupThreadIndexer.index(groupThread, transaction: transaction)
} else if let contactThread = object as? TSContactThread {
guard contactThread.shouldThreadBeVisible else {
guard contactThread.shouldBeVisible else {
// If we've never sent/received a message in a TSContactThread,
// then we want it to appear in the "Other Contacts" section rather
// than in the "Conversations" section.

View File

@ -200,9 +200,9 @@ NS_ASSUME_NONNULL_BEGIN
TSThread *thread = [[transaction extension:TSThreadDatabaseViewExtensionName]
objectAtIndexPath:[NSIndexPath indexPathForItem:(NSInteger)item inSection:(NSInteger)section]
withMappings:self.threadMappings];
if (!thread.shouldThreadBeVisible) { continue; }
if (!thread.shouldBeVisible) { continue; }
if ([thread isKindOfClass:TSContactThread.class]) {
NSString *publicKey = thread.contactIdentifier;
NSString *publicKey = ((TSContactThread *)thread).contactIdentifier;
if ([[LKStorage.shared getContactWithSessionID:publicKey] name] == nil) { continue; }
[threads addObject:thread];
} else {

View File

@ -162,7 +162,7 @@ public class MessageApprovalViewController: OWSViewController, UITextViewDelegat
return recipientRow
}
let publicKey = thread.contactIdentifier()!
let publicKey = contactThread.contactIdentifier()
nameLabel.text = Storage.shared.getContact(with: publicKey)?.displayName(for: .regular) ?? publicKey
nameLabel.textColor = Theme.primaryColor

View File

@ -37,7 +37,7 @@ extension ConfigurationMessage {
guard let profile = object as? OWSUserProfile, let displayName = profile.profileName else { return }
let publicKey = profile.recipientId
let threadID = TSContactThread.threadId(fromContactId: publicKey)
guard let thread = TSContactThread.fetch(uniqueId: threadID, transaction: transaction), thread.shouldThreadBeVisible
guard let thread = TSContactThread.fetch(uniqueId: threadID, transaction: transaction), thread.shouldBeVisible
&& !SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey) else { return }
let profilePictureURL = profile.avatarUrlPath
let profileKey = profile.profileKey?.keyData

View File

@ -81,8 +81,9 @@ public final class ProfilePictureView : UIView {
}
update()
} else { // A one-to-one chat
hasTappableProfilePicture = OWSProfileManager.shared().profileAvatar(forRecipientId: thread.contactIdentifier()!) != nil
update(for: thread.contactIdentifier()!)
let thread = thread as! TSContactThread
hasTappableProfilePicture = OWSProfileManager.shared().profileAvatar(forRecipientId: thread.contactIdentifier()) != nil
update(for: thread.contactIdentifier())
}
}

View File

@ -175,13 +175,13 @@ const CGFloat kContactCellAvatarTextMargin = 12;
}
BOOL isNoteToSelf
= (!thread.isGroupThread && [thread.contactIdentifier isEqualToString:self.tsAccountManager.localNumber]);
= ([thread isKindOfClass:TSContactThread.class] && [((TSContactThread *)thread).contactIdentifier isEqualToString:self.tsAccountManager.localNumber]);
if (isNoteToSelf) {
threadName = NSLocalizedString(@"NOTE_TO_SELF", @"Label for 1:1 conversation with yourself.");
}
if ([thread isKindOfClass:[TSContactThread class]]) {
self.recipientId = thread.contactIdentifier;
self.recipientId = ((TSContactThread *)thread).contactIdentifier;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(otherUsersProfileDidChange:)