From f45568644e75d95874997a8c0746cd8e5c638e86 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 3 Jul 2023 12:05:43 +1000 Subject: [PATCH] Fixed a somehow reproducable crash Fixed a crash when autoLoadNextPageIfNeeded was run after the table data was updated but before the tableView was reloaded resulting in a index out of bounds exception --- Session/Conversations/ConversationVC.swift | 8 ++++++-- Session/Home/HomeVC.swift | 10 +++++++--- .../MessageRequestsViewController.swift | 9 +++++++-- .../DocumentTitleViewController.swift | 4 ++-- .../MediaTileViewController.swift | 4 ++-- Session/Shared/SessionTableViewController.swift | 9 +++++++-- .../Settings/NotificationContentViewModelSpec.swift | 3 +++ 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 6e95bce32..d25342c47 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -875,7 +875,6 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers guard self.hasLoadedInitialInteractionData else { // Need to dispatch async to prevent this from causing glitches in the push animation DispatchQueue.main.async { - self.hasLoadedInitialInteractionData = true self.viewModel.updateInteractionData(updatedData) // Update the empty state @@ -883,6 +882,7 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers UIView.performWithoutAnimation { self.tableView.reloadData() + self.hasLoadedInitialInteractionData = true self.performInitialScrollIfNeeded() } } @@ -1191,7 +1191,11 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers } private func autoLoadNextPageIfNeeded() { - guard !self.isAutoLoadingNextPage && !self.isLoadingMore else { return } + guard + self.hasLoadedInitialInteractionData && + !self.isAutoLoadingNextPage && + !self.isLoadingMore + else { return } self.isAutoLoadingNextPage = true diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 5ddb4823c..bc524a220 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -409,8 +409,6 @@ final class HomeVC: BaseVC, SessionUtilRespondingViewController, UITableViewData // Ensure the first load runs without animations (if we don't do this the cells will animate // in from a frame of CGRect.zero) guard hasLoadedInitialThreadData else { - hasLoadedInitialThreadData = true - UIView.performWithoutAnimation { [weak self] in // Hide the 'loading conversations' label (now that we have received conversation data) self?.loadingConversationsLabel.isHidden = true @@ -422,6 +420,8 @@ final class HomeVC: BaseVC, SessionUtilRespondingViewController, UITableViewData ) self?.viewModel.updateThreadData(updatedData) + self?.tableView.reloadData() + self?.hasLoadedInitialThreadData = true } return } @@ -460,7 +460,11 @@ final class HomeVC: BaseVC, SessionUtilRespondingViewController, UITableViewData } private func autoLoadNextPageIfNeeded() { - guard !self.isAutoLoadingNextPage && !self.isLoadingMore else { return } + guard + self.hasLoadedInitialThreadData && + !self.isAutoLoadingNextPage && + !self.isLoadingMore + else { return } self.isAutoLoadingNextPage = true diff --git a/Session/Home/Message Requests/MessageRequestsViewController.swift b/Session/Home/Message Requests/MessageRequestsViewController.swift index b7c63b57d..efc5f2e99 100644 --- a/Session/Home/Message Requests/MessageRequestsViewController.swift +++ b/Session/Home/Message Requests/MessageRequestsViewController.swift @@ -232,9 +232,10 @@ class MessageRequestsViewController: BaseVC, SessionUtilRespondingViewController // Ensure the first load runs without animations (if we don't do this the cells will animate // in from a frame of CGRect.zero) guard hasLoadedInitialThreadData else { - hasLoadedInitialThreadData = true UIView.performWithoutAnimation { handleThreadUpdates(updatedData, changeset: changeset, initialLoad: true) + tableView.reloadData() + hasLoadedInitialThreadData = true } return } @@ -271,7 +272,11 @@ class MessageRequestsViewController: BaseVC, SessionUtilRespondingViewController } private func autoLoadNextPageIfNeeded() { - guard !self.isAutoLoadingNextPage && !self.isLoadingMore else { return } + guard + self.hasLoadedInitialThreadData && + !self.isAutoLoadingNextPage && + !self.isLoadingMore + else { return } self.isAutoLoadingNextPage = true diff --git a/Session/Media Viewing & Editing/DocumentTitleViewController.swift b/Session/Media Viewing & Editing/DocumentTitleViewController.swift index f95682a55..d7a84d87e 100644 --- a/Session/Media Viewing & Editing/DocumentTitleViewController.swift +++ b/Session/Media Viewing & Editing/DocumentTitleViewController.swift @@ -153,7 +153,7 @@ public class DocumentTileViewController: UIViewController, UITableViewDelegate, } private func autoLoadNextPageIfNeeded() { - guard !self.isAutoLoadingNextPage else { return } + guard self.hasLoadedInitialData && !self.isAutoLoadingNextPage else { return } self.isAutoLoadingNextPage = true @@ -204,11 +204,11 @@ public class DocumentTileViewController: UIViewController, UITableViewDelegate, // Ensure the first load runs without animations (if we don't do this the cells will animate // in from a frame of CGRect.zero) guard hasLoadedInitialData else { - self.hasLoadedInitialData = true self.viewModel.updateGalleryData(updatedGalleryData) UIView.performWithoutAnimation { self.tableView.reloadData() + self.hasLoadedInitialData = true self.performInitialScrollIfNeeded() } return diff --git a/Session/Media Viewing & Editing/MediaTileViewController.swift b/Session/Media Viewing & Editing/MediaTileViewController.swift index 649ed132a..5d24475b9 100644 --- a/Session/Media Viewing & Editing/MediaTileViewController.swift +++ b/Session/Media Viewing & Editing/MediaTileViewController.swift @@ -246,7 +246,7 @@ public class MediaTileViewController: UIViewController, UICollectionViewDataSour } private func autoLoadNextPageIfNeeded() { - guard !self.isAutoLoadingNextPage else { return } + guard self.hasLoadedInitialData && !self.isAutoLoadingNextPage else { return } self.isAutoLoadingNextPage = true @@ -307,12 +307,12 @@ public class MediaTileViewController: UIViewController, UICollectionViewDataSour // Ensure the first load runs without animations (if we don't do this the cells will animate // in from a frame of CGRect.zero) guard hasLoadedInitialData else { - self.hasLoadedInitialData = true self.viewModel.updateGalleryData(updatedGalleryData) self.updateSelectButton(updatedData: updatedGalleryData, inBatchSelectMode: isInBatchSelectMode) UIView.performWithoutAnimation { self.collectionView.reloadData() + self.hasLoadedInitialData = true self.performInitialScrollIfNeeded() } return diff --git a/Session/Shared/SessionTableViewController.swift b/Session/Shared/SessionTableViewController.swift index f1a01d854..3f37f079c 100644 --- a/Session/Shared/SessionTableViewController.swift +++ b/Session/Shared/SessionTableViewController.swift @@ -227,9 +227,10 @@ class SessionTableViewController