From 8a54a243a4ba6a428bd649221cddb69f73b17f8f Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 19 Apr 2021 09:35:09 +1000 Subject: [PATCH] Fix long conversation crash the right way --- Session/Conversations/ConversationVC.swift | 3 ++- Session/Conversations/ConversationViewModel.h | 18 ++++++++++++++++++ Session/Conversations/ConversationViewModel.m | 18 ------------------ SignalUtilitiesKit/Utilities/ThreadUtil.m | 8 ++++++++ 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index be4246af5..61824915d 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -149,7 +149,8 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat Storage.read { transaction in unreadCount = self.thread.unreadMessageCount(transaction: transaction) } - unreadViewItems = unreadCount != 0 ? [ConversationViewItem](viewItems[viewItems.endIndex - Int(unreadCount) ..< viewItems.endIndex]) : [] + let clampedUnreadCount = min(unreadCount, UInt(kConversationInitialMaxRangeSize)) + unreadViewItems = clampedUnreadCount != 0 ? [ConversationViewItem](viewItems[viewItems.endIndex - Int(clampedUnreadCount) ..< viewItems.endIndex]) : [] } required init?(coder: NSCoder) { diff --git a/Session/Conversations/ConversationViewModel.h b/Session/Conversations/ConversationViewModel.h index d679dbcd9..08151c201 100644 --- a/Session/Conversations/ConversationViewModel.h +++ b/Session/Conversations/ConversationViewModel.h @@ -91,6 +91,24 @@ typedef NS_ENUM(NSUInteger, ConversationUpdateItemType) { #pragma mark - +// Always load up to n messages when user arrives. +// +// The smaller this number is, the faster the conversation can display. +// To test, shrink you accessibility font as much as possible, then count how many 1-line system info messages (our +// shortest cells) can fit on screen at a time on an iPhoneX +// +// PERF: we could do less messages on shorter (older, slower) devices +// PERF: we could cache the cell height, since some messages will be much taller. +static const int kYapDatabasePageSize = 250; + +// Never show more than n messages in conversation view when user arrives. +static const int kConversationInitialMaxRangeSize = 250; + +// Never show more than n messages in conversation view at a time. +static const int kYapDatabaseRangeMaxLength = 250; + +#pragma mark - + @interface ConversationViewModel : NSObject @property (nonatomic, readonly) ConversationViewState *viewState; diff --git a/Session/Conversations/ConversationViewModel.m b/Session/Conversations/ConversationViewModel.m index 2b8952cca..86ad1f5e7 100644 --- a/Session/Conversations/ConversationViewModel.m +++ b/Session/Conversations/ConversationViewModel.m @@ -162,24 +162,6 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - -// Always load up to n messages when user arrives. -// -// The smaller this number is, the faster the conversation can display. -// To test, shrink you accessibility font as much as possible, then count how many 1-line system info messages (our -// shortest cells) can fit on screen at a time on an iPhoneX -// -// PERF: we could do less messages on shorter (older, slower) devices -// PERF: we could cache the cell height, since some messages will be much taller. -static const int kYapDatabasePageSize = 25000; - -// Never show more than n messages in conversation view when user arrives. -static const int kConversationInitialMaxRangeSize = 25000; - -// Never show more than n messages in conversation view at a time. -static const int kYapDatabaseRangeMaxLength = 25000; - -#pragma mark - - @interface ConversationViewModel () @property (nonatomic, weak) id delegate; diff --git a/SignalUtilitiesKit/Utilities/ThreadUtil.m b/SignalUtilitiesKit/Utilities/ThreadUtil.m index 62a5963fe..4922fc4f5 100644 --- a/SignalUtilitiesKit/Utilities/ThreadUtil.m +++ b/SignalUtilitiesKit/Utilities/ThreadUtil.m @@ -198,6 +198,14 @@ NS_ASSUME_NONNULL_BEGIN visibleUnseenMessageCount++; interactionAfterUnreadIndicator = interaction; + + if (visibleUnseenMessageCount + 1 >= maxRangeSize) { + // If there are more unseen messages than can be displayed in the + // messages view, show the unread indicator at the top of the + // displayed messages. + *stop = YES; + hasMoreUnseenMessages = YES; + } }]; if (!interactionAfterUnreadIndicator) {