mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Track 'persisted' viewItems separately
This commit is contained in:
parent
e3610d4360
commit
087e320036
|
@ -702,7 +702,7 @@ typedef enum : NSUInteger {
|
|||
|
||||
- (NSArray<id<ConversationViewItem>> *)viewItems
|
||||
{
|
||||
return self.conversationViewModel.viewItems;
|
||||
return self.conversationViewModel.allViewItems;
|
||||
}
|
||||
|
||||
- (ThreadDynamicInteractions *)dynamicInteractions
|
||||
|
|
|
@ -80,7 +80,7 @@ typedef NS_ENUM(NSUInteger, ConversationUpdateItemType) {
|
|||
|
||||
@interface ConversationViewModel : NSObject
|
||||
|
||||
@property (nonatomic, readonly) NSArray<id<ConversationViewItem>> *viewItems;
|
||||
@property (nonatomic, readonly) NSArray<id<ConversationViewItem>> *allViewItems;
|
||||
@property (nonatomic, nullable) NSString *focusMessageIdOnOpen;
|
||||
@property (nonatomic, readonly, nullable) ThreadDynamicInteractions *dynamicInteractions;
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
// * If we do the third step, we must call resetContentAndLayout afterward.
|
||||
@property (nonatomic) YapDatabaseViewMappings *messageMappings;
|
||||
|
||||
@property (nonatomic) NSArray<id<ConversationViewItem>> *viewItems;
|
||||
@property (nonatomic) NSArray<id<ConversationViewItem>> *allViewItems;
|
||||
@property (nonatomic) NSMutableDictionary<NSString *, id<ConversationViewItem>> *viewItemCache;
|
||||
|
||||
@property (nonatomic) NSUInteger lastRangeLength;
|
||||
|
@ -165,6 +165,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
|
||||
@property (nonatomic, nullable) ConversationProfileState *conversationProfileState;
|
||||
@property (nonatomic) BOOL hasTooManyOutgoingMessagesToBlockCached;
|
||||
@property (nonatomic) NSArray<id<ConversationViewItem>> *persistedViewItems;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -489,7 +490,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
|
||||
- (nullable id<ConversationViewItem>)viewItemForUnreadMessagesIndicator
|
||||
{
|
||||
for (id<ConversationViewItem> viewItem in self.viewItems) {
|
||||
for (id<ConversationViewItem> viewItem in self.allViewItems) {
|
||||
if (viewItem.unreadIndicator) {
|
||||
return viewItem;
|
||||
}
|
||||
|
@ -596,7 +597,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
}
|
||||
|
||||
NSMutableArray<NSString *> *oldItemIdList = [NSMutableArray new];
|
||||
for (id<ConversationViewItem> viewItem in self.viewItems) {
|
||||
for (id<ConversationViewItem> viewItem in self.allViewItems) {
|
||||
[oldItemIdList addObject:viewItem.itemId];
|
||||
}
|
||||
|
||||
|
@ -659,7 +660,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
return;
|
||||
}
|
||||
|
||||
OWSLogVerbose(@"self.viewItems.count: %zd -> %zd", oldItemIdList.count, self.viewItems.count);
|
||||
OWSLogVerbose(@"self.viewItems.count: %zd -> %zd", oldItemIdList.count, self.allViewItems.count);
|
||||
|
||||
[self updateViewWithOldItemIdList:oldItemIdList updatedItemSet:updatedItemSet];
|
||||
}
|
||||
|
@ -673,7 +674,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
OWSLogVerbose(@"");
|
||||
|
||||
NSMutableArray<NSString *> *oldItemIdList = [NSMutableArray new];
|
||||
for (id<ConversationViewItem> viewItem in self.viewItems) {
|
||||
for (id<ConversationViewItem> viewItem in self.allViewItems) {
|
||||
[oldItemIdList addObject:viewItem.itemId];
|
||||
}
|
||||
|
||||
|
@ -685,7 +686,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
return;
|
||||
}
|
||||
|
||||
OWSLogVerbose(@"self.viewItems.count: %zd -> %zd", oldItemIdList.count, self.viewItems.count);
|
||||
OWSLogVerbose(@"self.viewItems.count: %zd -> %zd", oldItemIdList.count, self.allViewItems.count);
|
||||
|
||||
[self updateViewWithOldItemIdList:oldItemIdList updatedItemSet:[NSSet set]];
|
||||
}
|
||||
|
@ -710,7 +711,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
|
||||
NSMutableArray<NSString *> *newItemIdList = [NSMutableArray new];
|
||||
NSMutableDictionary<NSString *, id<ConversationViewItem>> *newViewItemMap = [NSMutableDictionary new];
|
||||
for (id<ConversationViewItem> viewItem in self.viewItems) {
|
||||
for (id<ConversationViewItem> viewItem in self.allViewItems) {
|
||||
[newItemIdList addObject:viewItem.itemId];
|
||||
newViewItemMap[viewItem.itemId] = viewItem;
|
||||
}
|
||||
|
@ -1150,6 +1151,32 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
return offersMessage;
|
||||
}
|
||||
|
||||
|
||||
- (id<ConversationViewItem>)addViewItemWithInteraction:(TSInteraction *)interaction
|
||||
conversationStyle:(ConversationStyle *)conversationStyle
|
||||
isGroupThread:(BOOL)isGroupThread
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
viewItemCache:
|
||||
(NSMutableDictionary<NSString *, id<ConversationViewItem>> *)viewItemCache
|
||||
toViewItems:(NSMutableArray<id<ConversationViewItem>> *)viewItems
|
||||
{
|
||||
OWSAssertDebug(interaction.uniqueId.length > 0);
|
||||
|
||||
id<ConversationViewItem> _Nullable viewItem = self.viewItemCache[interaction.uniqueId];
|
||||
if (!viewItem) {
|
||||
viewItem = [[ConversationInteractionViewItem alloc] initWithInteraction:interaction
|
||||
isGroupThread:isGroupThread
|
||||
transaction:transaction
|
||||
conversationStyle:conversationStyle];
|
||||
}
|
||||
[viewItems addObject:viewItem];
|
||||
OWSAssertDebug(
|
||||
!viewItemCache[interaction.uniqueId] || [interaction isKindOfClass:[OWSTypingIndicatorInteraction class]]);
|
||||
viewItemCache[interaction.uniqueId] = viewItem;
|
||||
|
||||
return viewItem;
|
||||
}
|
||||
|
||||
// This is a key method. It builds or rebuilds the list of
|
||||
// cell view models.
|
||||
//
|
||||
|
@ -1166,21 +1193,15 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
[self ensureConversationProfileState];
|
||||
|
||||
__block BOOL hasError = NO;
|
||||
id<ConversationViewItem> (^tryToAddViewItem)(TSInteraction *, YapDatabaseReadTransaction *) = ^(TSInteraction *interaction, YapDatabaseReadTransaction *transaction) {
|
||||
OWSAssertDebug(interaction.uniqueId.length > 0);
|
||||
|
||||
id<ConversationViewItem> _Nullable viewItem = self.viewItemCache[interaction.uniqueId];
|
||||
if (!viewItem) {
|
||||
viewItem = [[ConversationInteractionViewItem alloc] initWithInteraction:interaction
|
||||
isGroupThread:isGroupThread
|
||||
transaction:transaction
|
||||
conversationStyle:conversationStyle];
|
||||
}
|
||||
[viewItems addObject:viewItem];
|
||||
OWSAssertDebug(!viewItemCache[interaction.uniqueId]);
|
||||
viewItemCache[interaction.uniqueId] = viewItem;
|
||||
return viewItem;
|
||||
};
|
||||
id<ConversationViewItem> (^tryToAddViewItem)(TSInteraction *, YapDatabaseReadTransaction *)
|
||||
= ^(TSInteraction *interaction, YapDatabaseReadTransaction *transaction) {
|
||||
return [self addViewItemWithInteraction:interaction
|
||||
conversationStyle:conversationStyle
|
||||
isGroupThread:isGroupThread
|
||||
transaction:transaction
|
||||
viewItemCache:viewItemCache
|
||||
toViewItems:viewItems];
|
||||
};
|
||||
|
||||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
|
||||
|
@ -1242,17 +1263,6 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
return [left.interaction compareForSorting:right.interaction];
|
||||
}];
|
||||
|
||||
if (self.typingIndicatorsSender) {
|
||||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
id<ConversationViewItem> _Nullable lastViewItem = viewItems.lastObject;
|
||||
uint64_t typingIndicatorTimestamp = (lastViewItem ? lastViewItem.interaction.timestamp + 1 : 1);
|
||||
TSInteraction *interaction =
|
||||
[[OWSTypingIndicatorInteraction alloc] initWithThread:self.thread
|
||||
timestamp:typingIndicatorTimestamp
|
||||
recipientId:self.typingIndicatorsSender];
|
||||
tryToAddViewItem(interaction, transaction);
|
||||
}];
|
||||
}
|
||||
// Flag to ensure that we only increment once per launch.
|
||||
if (hasError) {
|
||||
OWSLogWarn(@"incrementing version of: %@", TSMessageDatabaseViewExtensionName);
|
||||
|
@ -1260,13 +1270,36 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
}
|
||||
|
||||
self.viewItemCache = viewItemCache;
|
||||
self.viewItems = [self prepareViewItemsForDisplay:viewItems];
|
||||
self.persistedViewItems = [viewItems copy];
|
||||
self.allViewItems = [self prepareViewItemsForDisplay:viewItems];
|
||||
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
- (NSArray<id<ConversationViewItem>> *)prepareViewItemsForDisplay:(NSArray<id<ConversationViewItem>> *)viewItems
|
||||
- (NSArray<id<ConversationViewItem>> *)prepareViewItemsForDisplay:(NSArray<id<ConversationViewItem>> *)viewItemsArg
|
||||
{
|
||||
NSArray<id<ConversationViewItem>> *viewItems = viewItemsArg;
|
||||
if (self.typingIndicatorsSender) {
|
||||
NSMutableArray<id<ConversationViewItem>> *mutableViewItems = [viewItems mutableCopy];
|
||||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
id<ConversationViewItem> _Nullable lastViewItem = viewItems.lastObject;
|
||||
uint64_t typingIndicatorTimestamp = (lastViewItem ? lastViewItem.interaction.timestamp + 1 : 1);
|
||||
TSInteraction *interaction =
|
||||
[[OWSTypingIndicatorInteraction alloc] initWithThread:self.thread
|
||||
timestamp:typingIndicatorTimestamp
|
||||
recipientId:self.typingIndicatorsSender];
|
||||
|
||||
[self addViewItemWithInteraction:interaction
|
||||
conversationStyle:self.delegate.conversationStyle
|
||||
isGroupThread:self.thread.isGroupThread
|
||||
transaction:transaction
|
||||
viewItemCache:self.viewItemCache
|
||||
toViewItems:mutableViewItems];
|
||||
|
||||
}];
|
||||
viewItems = [mutableViewItems copy];
|
||||
}
|
||||
|
||||
// Update the "break" properties (shouldShowDate and unreadIndicator) of the view items.
|
||||
BOOL shouldShowDateOnNextViewItem = YES;
|
||||
uint64_t previousViewItemTimestamp = 0;
|
||||
|
@ -1509,14 +1542,15 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
conversationStyle:self.delegate.conversationStyle];
|
||||
}];
|
||||
|
||||
ConversationUpdateItem *updateItem = [[ConversationUpdateItem alloc] initWithUpdateItemType:ConversationUpdateItemType_Insert
|
||||
oldIndex:0
|
||||
newIndex:self.viewItems.count
|
||||
viewItem:viewItem];
|
||||
ConversationUpdateItem *updateItem =
|
||||
[[ConversationUpdateItem alloc] initWithUpdateItemType:ConversationUpdateItemType_Insert
|
||||
oldIndex:0
|
||||
newIndex:self.persistedViewItems.count
|
||||
viewItem:viewItem];
|
||||
|
||||
NSMutableArray<id <ConversationViewItem>> *viewItems = [self.viewItems mutableCopy];
|
||||
NSMutableArray<id<ConversationViewItem>> *viewItems = [self.persistedViewItems mutableCopy];
|
||||
[viewItems addObject:viewItem];
|
||||
self.viewItems = [self prepareViewItemsForDisplay:viewItems];
|
||||
self.allViewItems = [self prepareViewItemsForDisplay:viewItems];
|
||||
ConversationUpdate *conversationUpdate = [[ConversationUpdate alloc] initWithConversationUpdateType:ConversationUpdateType_Diff
|
||||
updateItems:@[updateItem]
|
||||
shouldAnimateUpdates:NO];
|
||||
|
@ -1666,7 +1700,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
OWSFailDebug(@"Could not locate view item for quoted reply.");
|
||||
return nil;
|
||||
}
|
||||
NSUInteger viewItemIndex = [self.viewItems indexOfObject:viewItem];
|
||||
NSUInteger viewItemIndex = [self.allViewItems indexOfObject:viewItem];
|
||||
if (viewItemIndex == NSNotFound) {
|
||||
OWSFailDebug(@"Could not locate view item index for quoted reply.");
|
||||
return nil;
|
||||
|
@ -1718,7 +1752,7 @@ static const int kYapDatabaseRangeMinLength = 0;
|
|||
|
||||
// Update the view items if necessary.
|
||||
// We don't have to do this if they haven't been configured yet.
|
||||
if (didChange && self.viewItems != nil) {
|
||||
if (didChange && self.allViewItems != nil) {
|
||||
[self updateForTransientItems];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue