Implement go to next unread
This commit is contained in:
parent
de10e81e31
commit
68a569ec0b
|
@ -55,7 +55,10 @@ final class SceneModel: ObservableObject {
|
|||
|
||||
/// Goes to the next unread item found in Sidebar and Timeline order, top to bottom
|
||||
func goToNextUnread() {
|
||||
|
||||
if !timelineModel.goToNextUnread() {
|
||||
sidebarModel.goToNextUnread()
|
||||
timelineModel.goToNextUnread()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Article Management API
|
||||
|
|
|
@ -77,8 +77,22 @@ struct SidebarItem: Identifiable {
|
|||
self.nameForDisplay = feed.nameForDisplay
|
||||
}
|
||||
|
||||
/// Add a sidebar item to the child list
|
||||
mutating func addChild(_ sidebarItem: SidebarItem) {
|
||||
children.append(sidebarItem)
|
||||
}
|
||||
|
||||
/// Recursively visits each sidebar item. Return true when done visiting.
|
||||
@discardableResult
|
||||
func visit(_ block: (SidebarItem) -> Bool) -> Bool {
|
||||
let stop = block(self)
|
||||
if !stop {
|
||||
for child in children {
|
||||
if child.visit(block) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return stop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,14 +43,11 @@ class SidebarModel: ObservableObject, UndoableCommandRunner {
|
|||
// MARK: API
|
||||
|
||||
func goToNextUnread() {
|
||||
guard let lastSelectedFeed = selectedFeeds.last,
|
||||
let currentSidebarItem = sidebarItems.first(where: { $0.feed?.feedID == lastSelectedFeed.feedID }) else {
|
||||
return
|
||||
}
|
||||
guard let startFeed = selectedFeeds.first ?? sidebarItems.first?.children.first?.feed else { return }
|
||||
|
||||
if !goToNextUnread(startingAt: currentSidebarItem) {
|
||||
if let firstSidebarItem = sidebarItems.first {
|
||||
goToNextUnread(startingAt: firstSidebarItem)
|
||||
if !goToNextUnread(startingAt: startFeed) {
|
||||
if let firstFeed = sidebarItems.first?.children.first?.feed {
|
||||
goToNextUnread(startingAt: firstFeed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,15 +190,30 @@ private extension SidebarModel {
|
|||
}
|
||||
|
||||
@discardableResult
|
||||
func goToNextUnread(startingAt: SidebarItem) -> Bool {
|
||||
guard let startIndex = sidebarItems.firstIndex(where: { $0.id == startingAt.id }) else { return false }
|
||||
|
||||
for i in startIndex..<sidebarItems.count {
|
||||
if sidebarItems[i].unreadCount > 0, let feedID = sidebarItems[i].feed?.feedID {
|
||||
select(feedID)
|
||||
return true
|
||||
func goToNextUnread(startingAt: Feed) -> Bool {
|
||||
|
||||
var foundStartFeed = false
|
||||
var nextSidebarItem: SidebarItem? = nil
|
||||
for section in sidebarItems {
|
||||
if nextSidebarItem == nil {
|
||||
section.visit { sidebarItem in
|
||||
if !foundStartFeed && sidebarItem.feed?.feedID == startingAt.feedID {
|
||||
foundStartFeed = true
|
||||
return false
|
||||
}
|
||||
if foundStartFeed && sidebarItem.unreadCount > 0 {
|
||||
nextSidebarItem = sidebarItem
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let nextFeedID = nextSidebarItem?.feed?.feedID {
|
||||
select(nextFeedID)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -315,12 +315,23 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
|
|||
openIndicatedArticleInBrowser(article)
|
||||
}
|
||||
|
||||
func canGoToNextUnread() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func goToNextUnread() {
|
||||
@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..<timelineItems.count {
|
||||
if !timelineItems[i].article.status.read {
|
||||
select(timelineItems[i].article.articleID)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func articleFor(_ articleID: String) -> Article? {
|
||||
|
@ -382,6 +393,11 @@ private extension TimelineModel {
|
|||
runCommand(markReadCommand)
|
||||
}
|
||||
|
||||
func select(_ articleID: String) {
|
||||
selectedArticleIDs = Set([articleID])
|
||||
selectedArticleID = articleID
|
||||
}
|
||||
|
||||
// MARK: Timeline Management
|
||||
|
||||
func resetReadFilter() {
|
||||
|
|
Loading…
Reference in New Issue