From f793e1b02d9dc43812707126ddd0d8fb9fd25f7c Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 25 Jul 2020 16:07:12 -0500 Subject: [PATCH] Reimplement toggle read/unread for selected toolbar item. --- Multiplatform/Shared/SceneModel.swift | 2 +- .../Shared/Timeline/TimelineModel.swift | 162 ++++++++++-------- 2 files changed, 88 insertions(+), 76 deletions(-) diff --git a/Multiplatform/Shared/SceneModel.swift b/Multiplatform/Shared/SceneModel.swift index 3e221caa3..682060f28 100644 --- a/Multiplatform/Shared/SceneModel.swift +++ b/Multiplatform/Shared/SceneModel.swift @@ -68,7 +68,7 @@ final class SceneModel: ObservableObject { /// Toggles the read status for the selected articles func toggleReadStatusForSelectedArticles() { -// timelineModel.toggleReadStatusForSelectedArticles() + timelineModel.toggleReadStatusForSelectedArticlesSubject.send() } /// Toggles the star status for the selected articles diff --git a/Multiplatform/Shared/Timeline/TimelineModel.swift b/Multiplatform/Shared/Timeline/TimelineModel.swift index 7bbae55c9..77c8a25f3 100644 --- a/Multiplatform/Shared/Timeline/TimelineModel.swift +++ b/Multiplatform/Shared/Timeline/TimelineModel.swift @@ -36,6 +36,9 @@ class TimelineModel: ObservableObject, UndoableCommandRunner { var selectedArticlesPublisher: AnyPublisher<[Article], Never>? var articleStatusChangePublisher: AnyPublisher, Never>? + var toggleReadStatusForSelectedArticlesSubject = PassthroughSubject() + + var readFilterEnabledTable = [FeedIdentifier: Bool]() var undoManager: UndoManager? @@ -56,8 +59,67 @@ class TimelineModel: ObservableObject, UndoableCommandRunner { subscribeToSelectedArticleSelectionChanges() subscribeToArticleStatusChanges() // subscribeToAccountDidDownloadArticles() + subscribeToArticleMarkingEvents() } + // MARK: API + + func toggleReadFilter() { +// guard let filter = isReadFiltered, let feedID = feeds.first?.feedID else { return } +// readFilterEnabledTable[feedID] = !filter +// isReadFiltered = !filter +// self.fetchArticles() + } + + @discardableResult + func goToNextUnread() -> Bool { +// var startIndex: Int +// if let firstArticle = selectedArticles.first, let index = timelineItems.firstIndex(where: { $0.article == firstArticle }) { +// startIndex = index +// } else { +// startIndex = 0 +// } +// +// for i in startIndex.. Article? { + return timelineItems[articleID]?.article + } + + func findPrevArticle(_ article: Article) -> Article? { + return nil +// guard let index = articles.firstIndex(of: article), index > 0 else { +// return nil +// } +// return articles[index - 1] + } + + func findNextArticle(_ article: Article) -> Article? { + return nil +// guard let index = articles.firstIndex(of: article), index + 1 != articles.count else { +// return nil +// } +// return articles[index + 1] + } + + func selectArticle(_ article: Article) { + // TODO: Implement me! + } + +} + +// MARK: Private + +private extension TimelineModel { + // MARK: Subscriptions func subscribeToArticleStatusChanges() { @@ -194,82 +256,32 @@ class TimelineModel: ObservableObject, UndoableCommandRunner { .sink { markArticles(Set([$0]), statusKey: .read, flag: true) } .store(in: &cancellables) } - - // MARK: API - - func toggleReadFilter() { -// guard let filter = isReadFiltered, let feedID = feeds.first?.feedID else { return } -// readFilterEnabledTable[feedID] = !filter -// isReadFiltered = !filter -// self.fetchArticles() - } - - func toggleReadStatusForSelectedArticles() { -// guard !selectedArticles.isEmpty else { -// return -// } -// if selectedArticles.anyArticleIsUnread() { -// markSelectedArticlesAsRead() -// } else { -// markSelectedArticlesAsUnread() -// } - } - @discardableResult - func goToNextUnread() -> Bool { -// var startIndex: Int -// if let firstArticle = selectedArticles.first, let index = timelineItems.firstIndex(where: { $0.article == firstArticle }) { -// startIndex = index -// } else { -// startIndex = 0 -// } -// -// for i in startIndex.. Article? { - return timelineItems[articleID]?.article - } - - func findPrevArticle(_ article: Article) -> Article? { - return nil -// guard let index = articles.firstIndex(of: article), index > 0 else { -// return nil -// } -// return articles[index - 1] - } - - func findNextArticle(_ article: Article) -> Article? { - return nil -// guard let index = articles.firstIndex(of: article), index + 1 != articles.count else { -// return nil -// } -// return articles[index + 1] - } - - func selectArticle(_ article: Article) { - // TODO: Implement me! - } - -} - -// MARK: Private - -private extension TimelineModel { - - func markArticlesWithUndo(_ articles: [Article], statusKey: ArticleStatus.Key, flag: Bool) { - if let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articles, statusKey: statusKey, flag: flag, undoManager: undoManager) { - runCommand(markReadCommand) - } else { - markArticles(Set(articles), statusKey: statusKey, flag: flag) - } + func subscribeToArticleMarkingEvents() { + guard let selectedArticlesPublisher = selectedArticlesPublisher else { return } + + let toggleReadPublisher = toggleReadStatusForSelectedArticlesSubject + .withLatestFrom(selectedArticlesPublisher) + .filter { !$0.isEmpty } + .map {selectedArticles -> ([Article], ArticleStatus.Key, Bool) in + if selectedArticles.anyArticleIsUnread() { + return (selectedArticles, ArticleStatus.Key.read, true) + } else { + return (selectedArticles, ArticleStatus.Key.read, false) + } + } + + toggleReadPublisher + .sink { [weak self] (articles, key, flag) in + if let undoManager = self?.undoManager, + let markReadCommand = MarkStatusCommand(initialArticles: articles, statusKey: key, flag: flag, undoManager: undoManager) { + self?.runCommand(markReadCommand) + } else { + markArticles(Set(articles), statusKey: key, flag: flag) + } + } + .store(in: &cancellables) + } // MARK: Timeline Management