Skip to content

Commit 14a7b5b

Browse files
committed
Don’t reload Reader views from deep links if they’re already displayed
1 parent 062274a commit 14a7b5b

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

WordPress/Classes/System/Root View/ReaderPresenter.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ public final class ReaderPresenter: NSObject, SplitViewDisplayable {
199199
/// column (split view) or pushing to the navigation stack.
200200
private func show(_ viewController: UIViewController, isLargeTitle: Bool = false) {
201201
if let splitViewController {
202+
guard !self.contentIsAlreadyDisplayed(viewController, in: splitViewController, for: .secondary) else {
203+
return
204+
}
202205
(viewController as? ReaderStreamViewController)?.isNotificationsBarButtonEnabled = true
203206

204207
let navigationVC = UINavigationController(rootViewController: viewController)
@@ -207,6 +210,11 @@ public final class ReaderPresenter: NSObject, SplitViewDisplayable {
207210
}
208211
splitViewController.setViewController(navigationVC, for: .secondary)
209212
} else {
213+
// Don't push a view controller on top of another with the same content
214+
guard !self.contentIsAlreadyDisplayed(viewController, in: mainNavigationController) else {
215+
return
216+
}
217+
210218
mainNavigationController.safePushViewController(viewController, animated: true)
211219
}
212220
}
@@ -215,14 +223,59 @@ public final class ReaderPresenter: NSObject, SplitViewDisplayable {
215223
/// the `.secondary` column (split view) or to the main navigation stack.
216224
private func push(_ viewController: UIViewController) {
217225
if let splitViewController {
226+
// Don't push a view controller on top of another with the same content
227+
guard !contentIsAlreadyDisplayed(viewController, in: splitViewController, for: .secondary) else {
228+
return
229+
}
218230
let navigationVC = splitViewController.viewController(for: .secondary) as? UINavigationController
219231
wpAssert(navigationVC != nil)
220232
navigationVC?.safePushViewController(viewController, animated: true)
221233
} else {
234+
// Don't push a view controller on top of another with the same content
235+
guard !self.contentIsAlreadyDisplayed(viewController, in: mainNavigationController) else {
236+
return
237+
}
238+
222239
mainNavigationController.safePushViewController(viewController, animated: true)
223240
}
224241
}
225242

243+
private func contentIsAlreadyDisplayed(_ viewController: UIViewController, in nav: UINavigationController) -> Bool {
244+
if let current = nav.topViewController as? ContentIdentifiable {
245+
if let new = viewController as? ContentIdentifiable {
246+
if new.contentIdentifier == current.contentIdentifier {
247+
return true
248+
}
249+
}
250+
}
251+
252+
return false
253+
}
254+
255+
private func contentIsAlreadyDisplayed(
256+
_ viewController: UIViewController,
257+
in split: UISplitViewController,
258+
for column: UISplitViewController.Column
259+
) -> Bool {
260+
guard let top = split.viewController(for: column) else {
261+
return false
262+
}
263+
264+
if let nav = top as? UINavigationController {
265+
return contentIsAlreadyDisplayed(viewController, in: nav)
266+
}
267+
268+
if let current = top as? ContentIdentifiable {
269+
if let new = viewController as? ContentIdentifiable {
270+
if new.contentIdentifier == current.contentIdentifier {
271+
return true
272+
}
273+
}
274+
}
275+
276+
return false
277+
}
278+
226279
// MARK: - Deep Links (ReaderNavigationPath)
227280

228281
func navigate(to path: ReaderNavigationPath) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Foundation
2+
3+
/// A protocol representing a content identifier – it could be a URL, ISBN, etc
4+
///
5+
/// More than one object might share a content identifier – two objects with the same identifier represent the same content.
6+
///
7+
public protocol ContentIdentifiable {
8+
var contentIdentifier: String? { get }
9+
}

WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,24 @@ extension ReaderStreamViewController: UITableViewDelegate, JPScrollViewDelegate
16371637
}
16381638
}
16391639

1640+
extension ReaderStreamViewController: ContentIdentifiable {
1641+
var contentIdentifier: String? {
1642+
if let siteId = self.siteID {
1643+
return "https://wordpress.com/reader/feeds/\(siteId)/"
1644+
}
1645+
1646+
if let tagSlug = self.tagSlug {
1647+
return "https://wordpress.com/tag/\(tagSlug)"
1648+
}
1649+
1650+
if let readerTopic {
1651+
return readerTopic.path
1652+
}
1653+
1654+
return nil
1655+
}
1656+
}
1657+
16401658
private enum Strings {
16411659
static let postRemoved = NSLocalizedString("reader.savedPostRemovedNotificationTitle", value: "Saved post removed", comment: "Notification title for when saved post is removed")
16421660
}

WordPress/Classes/ViewRelated/Reader/Detail/ReaderDetailViewController.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,3 +1313,14 @@ extension ReaderDetailViewController: BorderedButtonTableViewCellDelegate {
13131313
)
13141314
}
13151315
}
1316+
1317+
extension ReaderDetailViewController: ContentIdentifiable {
1318+
var contentIdentifier: String? {
1319+
// Only ever try to resolve this based on the site ID and post ID – the post object is fetched later
1320+
if let siteId = self.coordinator?.siteID?.intValue, let postId = self.coordinator?.postID?.intValue {
1321+
return "https://wordpress.com/reader/feeds/\(siteId)/posts/\(postId)"
1322+
}
1323+
1324+
return nil
1325+
}
1326+
}

0 commit comments

Comments
 (0)