From 3cbb4da788c2a0f58c5250e1e581ddd96194714d Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sun, 19 Jul 2020 13:23:08 -0500 Subject: [PATCH] Add Sidebar go to next functionality --- Multiplatform/Shared/SceneModel.swift | 14 +++++ .../Shared/Sidebar/SidebarModel.swift | 56 +++++++++++++++---- .../Shared/Timeline/TimelineModel.swift | 8 +++ 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/Multiplatform/Shared/SceneModel.swift b/Multiplatform/Shared/SceneModel.swift index d25c807f7..2ba227520 100644 --- a/Multiplatform/Shared/SceneModel.swift +++ b/Multiplatform/Shared/SceneModel.swift @@ -120,6 +120,12 @@ private extension SceneModel { // MARK: Subscriptions func subscribeToToolbarChangeEvents() { + NotificationCenter.default.publisher(for: .UnreadCountDidChange) + .compactMap { $0.object as? AccountManager } + .sink { [weak self] accountManager in + self?.updateNextUnreadButtonState(accountManager: accountManager) + }.store(in: &cancellables) + let combinedPublisher = timelineModel.$articles.combineLatest(timelineModel.$selectedArticles, NotificationCenter.default.publisher(for: .StatusesDidChange)) @@ -131,6 +137,14 @@ private extension SceneModel { // MARK: Button State Updates + func updateNextUnreadButtonState(accountManager: AccountManager) { + if accountManager.unreadCount > 0 { + self.nextUnreadButtonState = false + } else { + self.nextUnreadButtonState = nil + } + } + func updateMarkAllAsReadButtonsState(articles: [Article]) { if articles.canMarkAllAsRead() { markAllAsReadButtonState = false diff --git a/Multiplatform/Shared/Sidebar/SidebarModel.swift b/Multiplatform/Shared/Sidebar/SidebarModel.swift index 4da083269..b58b65a7d 100644 --- a/Multiplatform/Shared/Sidebar/SidebarModel.swift +++ b/Multiplatform/Shared/Sidebar/SidebarModel.swift @@ -39,6 +39,21 @@ class SidebarModel: ObservableObject, UndoableCommandRunner { subscribeToSelectedFeedChanges() subscribeToReadFilterChanges() } + + // MARK: API + + func goToNextUnread() { + guard let lastSelectedFeed = selectedFeeds.last, + let currentSidebarItem = sidebarItems.first(where: { $0.feed?.feedID == lastSelectedFeed.feedID }) else { + return + } + + if !goToNextUnread(startingAt: currentSidebarItem) { + if let firstSidebarItem = sidebarItems.first { + goToNextUnread(startingAt: firstSidebarItem) + } + } + } } @@ -107,16 +122,7 @@ private extension SidebarModel { }.store(in: &cancellables) } - // MARK: - - func findFeed(_ feedID: FeedIdentifier) -> Feed? { - switch feedID { - case .smartFeed: - return SmartFeedsController.shared.find(by: feedID) - default: - return AccountManager.shared.existingFeed(with: feedID) - } - } + // MARK: Sidebar Building func sort(_ folders: Set) -> [Folder] { return folders.sorted(by: { $0.nameForDisplay.localizedStandardCompare($1.nameForDisplay) == .orderedAscending }) @@ -175,4 +181,34 @@ private extension SidebarModel { sidebarItems = items } + // MARK: + + func findFeed(_ feedID: FeedIdentifier) -> Feed? { + switch feedID { + case .smartFeed: + return SmartFeedsController.shared.find(by: feedID) + default: + return AccountManager.shared.existingFeed(with: feedID) + } + } + + @discardableResult + func goToNextUnread(startingAt: SidebarItem) -> Bool { + guard let startIndex = sidebarItems.firstIndex(where: { $0.id == startingAt.id }) else { return false } + + for i in startIndex.. 0, let feedID = sidebarItems[i].feed?.feedID { + select(feedID) + return true + } + } + + return false + } + + func select(_ feedID: FeedIdentifier) { + selectedFeedIdentifiers = Set([feedID]) + selectedFeedIdentifier = feedID + } + } diff --git a/Multiplatform/Shared/Timeline/TimelineModel.swift b/Multiplatform/Shared/Timeline/TimelineModel.swift index f258d35c2..f8bf78e16 100644 --- a/Multiplatform/Shared/Timeline/TimelineModel.swift +++ b/Multiplatform/Shared/Timeline/TimelineModel.swift @@ -315,6 +315,14 @@ class TimelineModel: ObservableObject, UndoableCommandRunner { openIndicatedArticleInBrowser(article) } + func canGoToNextUnread() -> Bool { + return false + } + + func goToNextUnread() { + + } + func articleFor(_ articleID: String) -> Article? { return idToArticleDictionary[articleID] }