Add marking starred and read context menu items to Timeline
This commit is contained in:
parent
538d886bf4
commit
a102b9f63d
|
@ -15,6 +15,50 @@ struct TimelineContextMenu: View {
|
||||||
|
|
||||||
@ViewBuilder var body: some View {
|
@ViewBuilder var body: some View {
|
||||||
|
|
||||||
|
if timelineModel.canMarkIndicatedArticlesAsRead(timelineItem.article) {
|
||||||
|
Button {
|
||||||
|
timelineModel.markIndicatedArticlesAsRead(timelineItem.article)
|
||||||
|
} label: {
|
||||||
|
Text("Mark as Read")
|
||||||
|
#if os(iOS)
|
||||||
|
AppAssets.readOpenImage
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if timelineModel.canMarkIndicatedArticlesAsUnread(timelineItem.article) {
|
||||||
|
Button {
|
||||||
|
timelineModel.markIndicatedArticlesAsUnread(timelineItem.article)
|
||||||
|
} label: {
|
||||||
|
Text("Mark as Unread")
|
||||||
|
#if os(iOS)
|
||||||
|
AppAssets.readClosedImage
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if timelineModel.canMarkIndicatedArticlesAsStarred(timelineItem.article) {
|
||||||
|
Button {
|
||||||
|
timelineModel.markIndicatedArticlesAsStarred(timelineItem.article)
|
||||||
|
} label: {
|
||||||
|
Text("Mark as Starred")
|
||||||
|
#if os(iOS)
|
||||||
|
AppAssets.starClosedImage
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if timelineModel.canMarkIndicatedArticlesAsUnstarred(timelineItem.article) {
|
||||||
|
Button {
|
||||||
|
timelineModel.markIndicatedArticlesAsUnstarred(timelineItem.article)
|
||||||
|
} label: {
|
||||||
|
Text("Mark as Unstarred")
|
||||||
|
#if os(iOS)
|
||||||
|
AppAssets.starOpenImage
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if timelineModel.canMarkAboveAsRead(timelineItem.article) {
|
if timelineModel.canMarkAboveAsRead(timelineItem.article) {
|
||||||
Button {
|
Button {
|
||||||
timelineModel.markAboveAsRead(timelineItem.article)
|
timelineModel.markAboveAsRead(timelineItem.article)
|
||||||
|
|
|
@ -133,18 +133,56 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canMarkIndicatedArticlesAsRead(_ article: Article) -> Bool {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
return articles.anyArticleIsUnread()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markIndicatedArticlesAsRead(_ article: Article) {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
markArticlesWithUndo(articles, statusKey: .read, flag: true)
|
||||||
|
}
|
||||||
|
|
||||||
func markSelectedArticlesAsRead() {
|
func markSelectedArticlesAsRead() {
|
||||||
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingRead: true, undoManager: undoManager) else {
|
markArticlesWithUndo(selectedArticles, statusKey: .read, flag: true)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
runCommand(markReadCommand)
|
func canMarkIndicatedArticlesAsUnread(_ article: Article) -> Bool {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
return articles.anyArticleIsReadAndCanMarkUnread()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markIndicatedArticlesAsUnread(_ article: Article) {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
markArticlesWithUndo(articles, statusKey: .read, flag: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markSelectedArticlesAsUnread() {
|
func markSelectedArticlesAsUnread() {
|
||||||
guard let undoManager = undoManager, let markUnreadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingRead: false, undoManager: undoManager) else {
|
markArticlesWithUndo(selectedArticles, statusKey: .read, flag: false)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
runCommand(markUnreadCommand)
|
func canMarkAboveAsRead(_ article: Article) -> Bool {
|
||||||
|
let article = indicatedAboveArticle(article)
|
||||||
|
return articles.articlesAbove(article: article).canMarkAllAsRead()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markAboveAsRead(_ article: Article) {
|
||||||
|
let article = indicatedAboveArticle(article)
|
||||||
|
let articlesToMark = articles.articlesAbove(article: article)
|
||||||
|
guard !articlesToMark.isEmpty else { return }
|
||||||
|
markArticlesWithUndo(articlesToMark, statusKey: .read, flag: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func canMarkBelowAsRead(_ article: Article) -> Bool {
|
||||||
|
let article = indicatedBelowArticle(article)
|
||||||
|
return articles.articlesBelow(article: article).canMarkAllAsRead()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markBelowAsRead(_ article: Article) {
|
||||||
|
let article = indicatedBelowArticle(article)
|
||||||
|
let articlesToMark = articles.articlesBelow(article: article)
|
||||||
|
guard !articlesToMark.isEmpty else { return }
|
||||||
|
markArticlesWithUndo(articlesToMark, statusKey: .read, flag: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleStarredStatusForSelectedArticles() {
|
func toggleStarredStatusForSelectedArticles() {
|
||||||
|
@ -158,50 +196,34 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canMarkIndicatedArticlesAsStarred(_ article: Article) -> Bool {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
return articles.anyArticleIsUnstarred()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markIndicatedArticlesAsStarred(_ article: Article) {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
markArticlesWithUndo(articles, statusKey: .starred, flag: true)
|
||||||
|
}
|
||||||
|
|
||||||
func markSelectedArticlesAsStarred() {
|
func markSelectedArticlesAsStarred() {
|
||||||
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingStarred: true, undoManager: undoManager) else {
|
markArticlesWithUndo(selectedArticles, statusKey: .starred, flag: true)
|
||||||
return
|
|
||||||
}
|
|
||||||
runCommand(markReadCommand)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canMarkIndicatedArticlesAsUnstarred(_ article: Article) -> Bool {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
return articles.anyArticleIsStarred()
|
||||||
|
}
|
||||||
|
|
||||||
|
func markIndicatedArticlesAsUnstarred(_ article: Article) {
|
||||||
|
let articles = indicatedArticles(article)
|
||||||
|
markArticlesWithUndo(articles, statusKey: .starred, flag: false)
|
||||||
|
}
|
||||||
|
|
||||||
func markSelectedArticlesAsUnstarred() {
|
func markSelectedArticlesAsUnstarred() {
|
||||||
guard let undoManager = undoManager, let markUnreadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingStarred: false, undoManager: undoManager) else {
|
markArticlesWithUndo(selectedArticles, statusKey: .starred, flag: false)
|
||||||
return
|
|
||||||
}
|
|
||||||
runCommand(markUnreadCommand)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func canMarkAboveAsRead(_ article: Article) -> Bool {
|
|
||||||
let article = correctedAboveArticle(article)
|
|
||||||
return articles.articlesAbove(article: article).canMarkAllAsRead()
|
|
||||||
}
|
|
||||||
|
|
||||||
func canMarkBelowAsRead(_ article: Article) -> Bool {
|
|
||||||
let article = correctedBelowArticle(article)
|
|
||||||
return articles.articlesBelow(article: article).canMarkAllAsRead()
|
|
||||||
}
|
|
||||||
|
|
||||||
func markAboveAsRead(_ article: Article) {
|
|
||||||
let article = correctedAboveArticle(article)
|
|
||||||
let articlesToMark = articles.articlesAbove(article: article)
|
|
||||||
guard !articlesToMark.isEmpty else { return }
|
|
||||||
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articlesToMark, markingRead: true, undoManager: undoManager) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
runCommand(markReadCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func markBelowAsRead(_ article: Article) {
|
|
||||||
let article = correctedBelowArticle(article)
|
|
||||||
let articlesToMark = articles.articlesBelow(article: article)
|
|
||||||
guard !articlesToMark.isEmpty else { return }
|
|
||||||
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articlesToMark, markingRead: true, undoManager: undoManager) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
runCommand(markReadCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func articleFor(_ articleID: String) -> Article? {
|
func articleFor(_ articleID: String) -> Article? {
|
||||||
return idToArticleDictionary[articleID]
|
return idToArticleDictionary[articleID]
|
||||||
}
|
}
|
||||||
|
@ -230,7 +252,15 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
||||||
|
|
||||||
private extension TimelineModel {
|
private extension TimelineModel {
|
||||||
|
|
||||||
func correctedAboveArticle(_ article: Article) -> Article {
|
func indicatedArticles(_ article: Article) -> [Article] {
|
||||||
|
if selectedArticles.contains(article) {
|
||||||
|
return selectedArticles
|
||||||
|
} else {
|
||||||
|
return [article]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func indicatedAboveArticle(_ article: Article) -> Article {
|
||||||
if selectedArticles.contains(article) {
|
if selectedArticles.contains(article) {
|
||||||
return selectedArticles.first!
|
return selectedArticles.first!
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,7 +268,7 @@ private extension TimelineModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func correctedBelowArticle(_ article: Article) -> Article {
|
func indicatedBelowArticle(_ article: Article) -> Article {
|
||||||
if selectedArticles.contains(article) {
|
if selectedArticles.contains(article) {
|
||||||
return selectedArticles.last!
|
return selectedArticles.last!
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,6 +276,13 @@ private extension TimelineModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func markArticlesWithUndo(_ articles: [Article], statusKey: ArticleStatus.Key, flag: Bool) {
|
||||||
|
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articles, statusKey: statusKey, flag: flag, undoManager: undoManager) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
runCommand(markReadCommand)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Notifications
|
// MARK: Notifications
|
||||||
|
|
||||||
@objc func statusesDidChange(_ note: Notification) {
|
@objc func statusesDidChange(_ note: Notification) {
|
||||||
|
|
Loading…
Reference in New Issue