Revert using combine for toolbar buttons as it was inconsistent with context menus

This commit is contained in:
Maurice Parker
2020-07-27 15:43:58 -05:00
parent c3ca910e20
commit b77e2164cd
2 changed files with 55 additions and 75 deletions

View File

@@ -61,22 +61,22 @@ final class SceneModel: ObservableObject {
/// Marks all the articles in the Timeline as read
func markAllAsRead() {
timelineModel.markAllAsReadSubject.send()
timelineModel.markAllAsRead()
}
/// Toggles the read status for the selected articles
func toggleReadStatusForSelectedArticles() {
timelineModel.toggleReadStatusForSelectedArticlesSubject.send()
timelineModel.toggleReadStatusForSelectedArticles()
}
/// Toggles the star status for the selected articles
func toggleStarredStatusForSelectedArticles() {
timelineModel.toggleStarredStatusForSelectedArticlesSubject.send()
timelineModel.toggleStarredStatusForSelectedArticles()
}
/// Opens the selected article in an external browser
func openSelectedArticleInBrowser() {
timelineModel.openSelectedArticlesInBrowserSubject.send()
timelineModel.openSelectedArticleInBrowser()
}
/// Retrieves the article before the given article in the Timeline

View File

@@ -43,10 +43,6 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
var articlesSubject = ReplaySubject<[Article], Never>(bufferSize: 1)
var markAllAsReadSubject = PassthroughSubject<Void, Never>()
var toggleReadStatusForSelectedArticlesSubject = PassthroughSubject<Void, Never>()
var toggleStarredStatusForSelectedArticlesSubject = PassthroughSubject<Void, Never>()
var openSelectedArticlesInBrowserSubject = PassthroughSubject<Void, Never>()
var changeReadFilterSubject = PassthroughSubject<Bool, Never>()
var selectNextUnreadSubject = PassthroughSubject<Bool, Never>()
@@ -71,8 +67,6 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
subscribeToArticleFetchChanges()
subscribeToArticleSelectionChanges()
subscribeToArticleStatusChanges()
subscribeToArticleMarkingEvents()
subscribeToOpenInBrowserEvents()
}
// MARK: API
@@ -120,6 +114,17 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
// TODO: Implement me!
}
func toggleReadStatusForSelectedArticles() {
guard !selectedArticles.isEmpty else {
return
}
if selectedArticles.anyArticleIsUnread() {
markSelectedArticlesAsRead()
} else {
markSelectedArticlesAsUnread()
}
}
func canMarkIndicatedArticlesAsRead(_ timelineItem: TimelineItem) -> Bool {
let articles = indicatedTimelineItems(timelineItem).map { $0.article }
return articles.anyArticleIsUnread()
@@ -130,6 +135,10 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
markArticlesWithUndo(articles, statusKey: .read, flag: true)
}
func markSelectedArticlesAsRead() {
markArticlesWithUndo(selectedArticles, statusKey: .read, flag: true)
}
func canMarkIndicatedArticlesAsUnread(_ timelineItem: TimelineItem) -> Bool {
let articles = indicatedTimelineItems(timelineItem).map { $0.article }
return articles.anyArticleIsReadAndCanMarkUnread()
@@ -140,6 +149,10 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
markArticlesWithUndo(articles, statusKey: .read, flag: false)
}
func markSelectedArticlesAsUnread() {
markArticlesWithUndo(selectedArticles, statusKey: .read, flag: false)
}
func canMarkAboveAsRead(_ timelineItem: TimelineItem) -> Bool {
let timelineItem = indicatedAboveTimelineItem(timelineItem)
return articles.articlesAbove(position: timelineItem.position).canMarkAllAsRead()
@@ -174,6 +187,25 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
markArticlesWithUndo(articlesToMark, statusKey: .read, flag: true)
}
func canMarkAllAsRead() -> Bool {
return articles.canMarkAllAsRead()
}
func markAllAsRead() {
markArticlesWithUndo(articles, statusKey: .read, flag: true)
}
func toggleStarredStatusForSelectedArticles() {
guard !selectedArticles.isEmpty else {
return
}
if selectedArticles.anyArticleIsUnstarred() {
markSelectedArticlesAsStarred()
} else {
markSelectedArticlesAsUnstarred()
}
}
func canMarkIndicatedArticlesAsStarred(_ timelineItem: TimelineItem) -> Bool {
let articles = indicatedTimelineItems(timelineItem).map { $0.article }
return articles.anyArticleIsUnstarred()
@@ -184,6 +216,10 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
markArticlesWithUndo(articles, statusKey: .starred, flag: true)
}
func markSelectedArticlesAsStarred() {
markArticlesWithUndo(selectedArticles, statusKey: .starred, flag: true)
}
func canMarkIndicatedArticlesAsUnstarred(_ timelineItem: TimelineItem) -> Bool {
let articles = indicatedTimelineItems(timelineItem).map { $0.article }
return articles.anyArticleIsStarred()
@@ -194,11 +230,20 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
markArticlesWithUndo(articles, statusKey: .starred, flag: false)
}
func markSelectedArticlesAsUnstarred() {
markArticlesWithUndo(selectedArticles, statusKey: .starred, flag: false)
}
func canOpenIndicatedArticleInBrowser(_ timelineItem: TimelineItem) -> Bool {
guard indicatedTimelineItems(timelineItem).count == 1 else { return false }
return timelineItem.article.preferredLink != nil
}
func openSelectedArticleInBrowser() {
guard let article = selectedArticles.first else { return }
openIndicatedArticleInBrowser(article)
}
func openIndicatedArticleInBrowser(_ timelineItem: TimelineItem) {
openIndicatedArticleInBrowser(timelineItem.article)
}
@@ -440,71 +485,6 @@ private extension TimelineModel {
.sink { markArticles(Set([$0]), statusKey: .read, flag: true) }
.store(in: &cancellables)
}
func subscribeToArticleMarkingEvents() {
guard let selectedArticlesPublisher = selectedArticlesPublisher else { return }
let markAllAsReadPublisher = markAllAsReadSubject
.withLatestFrom(articlesSubject)
.filter { !$0.isEmpty }
.map { articles -> ([Article], ArticleStatus.Key, Bool) in
return (articles, ArticleStatus.Key.read, true)
}
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)
}
}
let toggleStarred = toggleStarredStatusForSelectedArticlesSubject
.withLatestFrom(selectedArticlesPublisher)
.filter { !$0.isEmpty }
.map { selectedArticles -> ([Article], ArticleStatus.Key, Bool) in
if selectedArticles.anyArticleIsUnstarred() {
return (selectedArticles, ArticleStatus.Key.starred, true)
} else {
return (selectedArticles, ArticleStatus.Key.starred, false)
}
}
markAllAsReadPublisher
.merge(with: toggleReadPublisher, toggleStarred)
.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)
}
func subscribeToOpenInBrowserEvents() {
guard let selectedArticlesPublisher = selectedArticlesPublisher else { return }
let selectedArticleOpenInBrowserPublisher = openSelectedArticlesInBrowserSubject
.withLatestFrom(selectedArticlesPublisher)
.compactMap { $0.first?.preferredLink }
selectedArticleOpenInBrowserPublisher
.sink { link in
#if os(macOS)
Browser.open(link, invertPreference: NSApp.currentEvent?.modifierFlags.contains(.shift) ?? false)
#else
guard let url = URL(string: link) else { return }
UIApplication.shared.open(url, options: [:])
#endif
}
.store(in: &cancellables)
}
// MARK: Article Fetching