diff --git a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift index 88f0ac440..5e5425728 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift @@ -157,7 +157,7 @@ private extension TimelineViewController { func menu(for articles: [Article]) -> NSMenu? { let menu = NSMenu(title: "") - if articles.anyArticleIsUnread() { + if articles.anyArticleIsUnreadAndCanMarkRead() { menu.addItem(markReadMenuItem(articles)) } if articles.anyArticleIsReadAndCanMarkUnread() { @@ -169,10 +169,10 @@ private extension TimelineViewController { if articles.anyArticleIsStarred() { menu.addItem(markUnstarredMenuItem(articles)) } - if let first = articles.first, self.articles.articlesAbove(article: first).canMarkAllAsRead() { + if let first = articles.first, self.articles.articlesAbove(article: first).canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) { menu.addItem(markAboveReadMenuItem(articles)) } - if let last = articles.last, self.articles.articlesBelow(article: last).canMarkAllAsRead() { + if let last = articles.last, self.articles.articlesBelow(article: last).canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) { menu.addItem(markBelowReadMenuItem(articles)) } diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index bad5e798c..a7aad29ab 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -259,7 +259,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr } func canMarkAllAsRead() -> Bool { - return articles.canMarkAllAsRead() + return articles.canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) } func canMarkSelectedArticlesAsRead() -> Bool { @@ -493,7 +493,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr func markReadCommandStatus() -> MarkCommandValidationStatus { let articles = selectedArticles - if articles.anyArticleIsUnread() { + if articles.anyArticleIsUnreadAndCanMarkRead() { return .canMark } @@ -518,12 +518,12 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr func canMarkAboveArticlesAsRead() -> Bool { guard let first = selectedArticles.first else { return false } - return articles.articlesAbove(article: first).canMarkAllAsRead() + return articles.articlesAbove(article: first).canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) } func canMarkBelowArticlesAsRead() -> Bool { guard let last = selectedArticles.last else { return false } - return articles.articlesBelow(article: last).canMarkAllAsRead() + return articles.articlesBelow(article: last).canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) } func markOlderArticlesRead(_ selectedArticles: [Article]) { diff --git a/Shared/Timeline/ArticleArray.swift b/Shared/Timeline/ArticleArray.swift index af2a7ce12..689784b75 100644 --- a/Shared/Timeline/ArticleArray.swift +++ b/Shared/Timeline/ArticleArray.swift @@ -54,8 +54,8 @@ extension Array where Element == Article { return ArticleSorter.sortedByDate(articles: self, sortDirection: sortDirection, groupByFeed: groupByFeed) } - func canMarkAllAsRead() -> Bool { - return anyArticleIsUnread() + func canMarkAllAsRead(exemptArticles: Set
= .init()) -> Bool { + return anyArticleIsUnreadAndCanMarkRead(exemptArticles: exemptArticles) } func anyArticlePassesTest(_ test: ((Article) -> Bool)) -> Bool { @@ -71,8 +71,8 @@ extension Array where Element == Article { return anyArticlePassesTest { $0.status.read && $0.isAvailableToMarkUnread } } - func anyArticleIsUnread() -> Bool { - return anyArticlePassesTest { !$0.status.read } + func anyArticleIsUnreadAndCanMarkRead(exemptArticles: Set
= .init()) -> Bool { + return anyArticlePassesTest { !(exemptArticles.contains($0) || $0.status.read) } } func anyArticleIsStarred() -> Bool { diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift index 64da8c3e0..1fbf7fd85 100644 --- a/iOS/MasterTimeline/MasterTimelineViewController.swift +++ b/iOS/MasterTimeline/MasterTimelineViewController.swift @@ -679,7 +679,7 @@ private extension MasterTimelineViewController { func updateToolbar() { guard firstUnreadButton != nil else { return } - markAllAsReadButton.isEnabled = coordinator.isTimelineUnreadAvailable + markAllAsReadButton.isEnabled = coordinator.canMarkAllAsRead() firstUnreadButton.isEnabled = coordinator.isTimelineUnreadAvailable if coordinator.isRootSplitCollapsed { @@ -925,7 +925,7 @@ private extension MasterTimelineViewController { } let articles = Array(fetchedArticles) - guard articles.canMarkAllAsRead(), let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else { + guard coordinator.canMarkAllAsRead(articles), let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else { return nil } @@ -948,7 +948,7 @@ private extension MasterTimelineViewController { } let articles = Array(fetchedArticles) - guard articles.canMarkAllAsRead(), let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else { + guard coordinator.canMarkAllAsRead(articles), let contentView = self.tableView.cellForRow(at: indexPath)?.contentView else { return nil } diff --git a/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px 1.png b/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px 1.png deleted file mode 100644 index efdd38490..000000000 Binary files a/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px 1.png and /dev/null differ diff --git a/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px.png b/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px.png deleted file mode 100644 index efdd38490..000000000 Binary files a/iOS/Resources/Assets.xcassets/About.imageset/AppIcon-1024px.png and /dev/null differ diff --git a/iOS/Resources/Assets.xcassets/About.imageset/Contents.json b/iOS/Resources/Assets.xcassets/About.imageset/Contents.json deleted file mode 100644 index d3a718431..000000000 --- a/iOS/Resources/Assets.xcassets/About.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "AppIcon-1024px 1.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "AppIcon-1024px.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index b65b2dd59..85f4febc5 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -1042,10 +1042,18 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, Logging { completion?() } } + + func canMarkAllAsRead() -> Bool { + return articles.canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) + } + + func canMarkAllAsRead(_ articles: [Article]) -> Bool { + return articles.canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) + } func canMarkAboveAsRead(for article: Article) -> Bool { let articlesAboveArray = articles.articlesAbove(article: article) - return articlesAboveArray.canMarkAllAsRead() + return articlesAboveArray.canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) } func markAboveAsRead() { @@ -1063,7 +1071,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, Logging { func canMarkBelowAsRead(for article: Article) -> Bool { let articleBelowArray = articles.articlesBelow(article: article) - return articleBelowArray.canMarkAllAsRead() + return articleBelowArray.canMarkAllAsRead(exemptArticles: directlyMarkedAsUnreadArticles) } func markBelowAsRead() { diff --git a/iOS/Settings/AboutView.swift b/iOS/Settings/AboutView.swift index 70cd411e2..091635e5c 100644 --- a/iOS/Settings/AboutView.swift +++ b/iOS/Settings/AboutView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import RSCore struct AboutView: View, LoadableAboutData { @@ -35,9 +36,10 @@ struct AboutView: View, LoadableAboutData { HStack { Spacer() VStack(alignment: .center, spacing: 8) { - Image("About") + Image(uiImage: RSImage.appIconImage!) .resizable() .frame(width: 75, height: 75) + .cornerRadius(11) Text(Bundle.main.appName) .font(.headline)