Implement Timeline read filter
This commit is contained in:
parent
e24716c944
commit
6c236fc0e3
|
@ -33,7 +33,7 @@ struct SidebarView: View {
|
|||
AppAssets.filterInactiveImage
|
||||
}
|
||||
})
|
||||
.padding(.top).padding(.trailing)
|
||||
.padding(.top, 8).padding(.trailing)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
ZStack {
|
||||
|
|
|
@ -23,7 +23,7 @@ struct TimelineContainerView: View {
|
|||
.environmentObject(sceneModel.timelineModel)
|
||||
.onAppear {
|
||||
sceneModel.timelineModel.undoManager = undoManager
|
||||
sceneModel.timelineModel.rebuildTimelineItems(feeds: feeds)
|
||||
sceneModel.timelineModel.fetchArticles(feeds: feeds)
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
|
|
|
@ -22,8 +22,8 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
|||
|
||||
@Published var nameForDisplay = ""
|
||||
@Published var timelineItems = [TimelineItem]()
|
||||
@Published var selectedArticleIDs = Set<String>()
|
||||
@Published var selectedArticleID: String? = .none
|
||||
@Published var selectedArticleIDs = Set<String>() // Don't use directly. Use selectedArticles
|
||||
@Published var selectedArticleID: String? = .none // Don't use directly. Use selectedArticles
|
||||
@Published var selectedArticles = [Article]()
|
||||
@Published var isReadFiltered = false
|
||||
|
||||
|
@ -33,6 +33,7 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
|||
private var selectedArticleIDsCancellable: AnyCancellable?
|
||||
private var selectedArticleIDCancellable: AnyCancellable?
|
||||
private var selectedArticlesCancellable: AnyCancellable?
|
||||
private var selectedReadFilteredCancellable: AnyCancellable?
|
||||
|
||||
private var fetchSerialNumber = 0
|
||||
private let fetchRequestQueue = FetchRequestQueue()
|
||||
|
@ -95,11 +96,16 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedReadFilteredCancellable = $isReadFiltered.sink { [weak self] filter in
|
||||
guard let self = self else { return }
|
||||
self.rebuildTimelineItems(isReadFiltered: filter)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: API
|
||||
|
||||
func rebuildTimelineItems(feeds: [Feed]) {
|
||||
func fetchArticles(feeds: [Feed]) {
|
||||
if feeds.count == 1 {
|
||||
nameForDisplay = feeds.first!.nameForDisplay
|
||||
} else {
|
||||
|
@ -259,8 +265,20 @@ private extension TimelineModel {
|
|||
|
||||
func replaceArticles(with unsortedArticles: Set<Article>) {
|
||||
articles = Array(unsortedArticles).sortedByDate(sortDirection ? .orderedDescending : .orderedAscending, groupByFeed: groupByFeed)
|
||||
timelineItems = articles.map { TimelineItem(article: $0) }
|
||||
rebuildTimelineItems(isReadFiltered: isReadFiltered)
|
||||
// TODO: Update unread counts and other item done in didSet on AppKit
|
||||
}
|
||||
|
||||
func rebuildTimelineItems(isReadFiltered: Bool) {
|
||||
let selectedArticleIDs = selectedArticles.map { $0.articleID }
|
||||
|
||||
timelineItems = articles.compactMap { article in
|
||||
if isReadFiltered && article.status.read && !selectedArticleIDs.contains(article.articleID) {
|
||||
return nil
|
||||
} else {
|
||||
return TimelineItem(article: article)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,16 +15,34 @@ struct TimelineView: View {
|
|||
|
||||
@ViewBuilder var body: some View {
|
||||
#if os(macOS)
|
||||
ZStack {
|
||||
NavigationLink(destination: ArticleContainerView(articles: timelineModel.selectedArticles), isActive: $navigate) {
|
||||
EmptyView()
|
||||
}.hidden()
|
||||
List(timelineModel.timelineItems, selection: $timelineModel.selectedArticleIDs) { timelineItem in
|
||||
TimelineItemView(timelineItem: timelineItem)
|
||||
VStack {
|
||||
HStack {
|
||||
Spacer()
|
||||
Button (action: {
|
||||
withAnimation {
|
||||
timelineModel.isReadFiltered.toggle()
|
||||
}
|
||||
}, label: {
|
||||
if timelineModel.isReadFiltered {
|
||||
AppAssets.filterActiveImage
|
||||
} else {
|
||||
AppAssets.filterInactiveImage
|
||||
}
|
||||
})
|
||||
.padding(.top, 8).padding(.trailing)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
ZStack {
|
||||
NavigationLink(destination: ArticleContainerView(articles: timelineModel.selectedArticles), isActive: $navigate) {
|
||||
EmptyView()
|
||||
}.hidden()
|
||||
List(timelineModel.timelineItems, selection: $timelineModel.selectedArticleIDs) { timelineItem in
|
||||
TimelineItemView(timelineItem: timelineItem)
|
||||
}
|
||||
}
|
||||
.onChange(of: timelineModel.selectedArticleIDs) { value in
|
||||
navigate = !timelineModel.selectedArticleIDs.isEmpty
|
||||
}
|
||||
}
|
||||
.onChange(of: timelineModel.selectedArticleIDs) { value in
|
||||
navigate = !timelineModel.selectedArticleIDs.isEmpty
|
||||
}
|
||||
#else
|
||||
List(timelineModel.timelineItems) { timelineItem in
|
||||
|
|
Loading…
Reference in New Issue