From 7f3128c958b234701054726c3708b86035e323e2 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Fri, 8 Feb 2019 13:37:38 -0500 Subject: [PATCH] Add prefetching for images in table views --- .../ConversationTableViewController.swift | 24 +++++++++++++++++ .../NotificationsTableViewController.swift | 18 +++++++++++++ .../Profile/ProfileTableViewController.swift | 26 +++++++++++++++++++ .../TimelineTableViewController.swift | 24 +++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/Tusker/Screens/Conversation/ConversationTableViewController.swift b/Tusker/Screens/Conversation/ConversationTableViewController.swift index 83b13669dd..d26d5f14f7 100644 --- a/Tusker/Screens/Conversation/ConversationTableViewController.swift +++ b/Tusker/Screens/Conversation/ConversationTableViewController.swift @@ -40,6 +40,8 @@ class ConversationTableViewController: EnhancedTableViewController { tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") tableView.register(UINib(nibName: "ConversationMainStatusTableViewCell", bundle: nil), forCellReuseIdentifier: "mainStatusCell") + tableView.prefetchDataSource = self + statusIDs = [mainStatusID] guard let mainStatus = MastodonCache.status(for: mainStatusID) else { fatalError("Missing cached status \(mainStatusID!)") } @@ -147,3 +149,25 @@ class ConversationTableViewController: EnhancedTableViewController { } extension ConversationTableViewController: StatusTableViewCellDelegate {} + +extension ConversationTableViewController: UITableViewDataSourcePrefetching { + func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.get(status.account.avatar, completion: nil) + for attachment in status.attachments { + ImageCache.attachments.get(attachment.url, completion: nil) + } + } + } + + func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.cancel(status.account.avatar) + for attachment in status.attachments { + ImageCache.attachments.cancel(attachment.url) + } + } + } +} diff --git a/Tusker/Screens/Notifications/NotificationsTableViewController.swift b/Tusker/Screens/Notifications/NotificationsTableViewController.swift index 1c06586dff..cadc7a9a11 100644 --- a/Tusker/Screens/Notifications/NotificationsTableViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsTableViewController.swift @@ -44,6 +44,8 @@ class NotificationsTableViewController: EnhancedTableViewController { tableView.register(UINib(nibName: "ActionNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "actionCell") tableView.register(UINib(nibName: "FollowNotificationTableViewCell", bundle: nil), forCellReuseIdentifier: "followCell") + tableView.prefetchDataSource = self + let request = MastodonController.client.getNotifications() MastodonController.client.run(request) { result in guard case let .success(notifications, pagination) = result else { fatalError() } @@ -150,3 +152,19 @@ class NotificationsTableViewController: EnhancedTableViewController { } extension NotificationsTableViewController: StatusTableViewCellDelegate {} + +extension NotificationsTableViewController: UITableViewDataSourcePrefetching { + func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + let notification = notifications[indexPath.row] + ImageCache.avatars.get(notification.account.avatar, completion: nil) + } + } + + func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + let notification = notifications[indexPath.row] + ImageCache.avatars.cancel(notification.account.url) + } + } +} diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index 09ec03cccf..e61e82d551 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -59,6 +59,8 @@ class ProfileTableViewController: EnhancedTableViewController, PreferencesAdapti tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") tableView.register(UINib(nibName: "ProfileHeaderTableViewCell", bundle: nil), forCellReuseIdentifier: "headerCell") + tableView.prefetchDataSource = self + if let accountID = accountID { if MastodonCache.account(for: accountID) != nil { updateAccountUI() @@ -283,3 +285,27 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate { } } } + +extension ProfileTableViewController: UITableViewDataSourcePrefetching { + func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard indexPath.section == 1, + let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.get(status.account.avatar, completion: nil) + for attachment in status.attachments { + ImageCache.attachments.get(attachment.url, completion: nil) + } + } + } + + func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard indexPath.section == 1, + let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.cancel(status.account.avatar) + for attachment in status.attachments { + ImageCache.attachments.cancel(attachment.url) + } + } + } +} diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 6313ffdc0f..f397235bf5 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -71,6 +71,8 @@ class TimelineTableViewController: EnhancedTableViewController { tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") + tableView.prefetchDataSource = self + guard MastodonController.client?.accessToken != nil else { return } let request = MastodonController.client.getStatuses(timeline: timeline) MastodonController.client.run(request) { response in @@ -168,3 +170,25 @@ class TimelineTableViewController: EnhancedTableViewController { } extension TimelineTableViewController: StatusTableViewCellDelegate {} + +extension TimelineTableViewController: UITableViewDataSourcePrefetching { + func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.get(status.account.avatar, completion: nil) + for attachment in status.attachments { + ImageCache.attachments.get(attachment.url, completion: nil) + } + } + } + + func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { + for indexPath in indexPaths { + guard let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } + ImageCache.avatars.cancel(status.account.avatar) + for attachment in status.attachments { + ImageCache.attachments.cancel(attachment.url) + } + } + } +}