mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Merge branch 'ios-ui' of https://github.com/stuartbreckenridge/NetNewsWire into ios-ui
This commit is contained in:
@@ -6,7 +6,17 @@
|
||||
<description>Most recent NetNewsWire changes with links to updates.</description>
|
||||
<language>en</language>
|
||||
|
||||
<item>
|
||||
<item>
|
||||
<title>NetNewsWire 6.1b4</title>
|
||||
<description><![CDATA[
|
||||
<p>Fixed a few font and sizing issues.</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 27 Feb 2022 21:50:00 -0800</pubDate>
|
||||
<enclosure url="https://github.com/Ranchero-Software/NetNewsWire/releases/download/mac-6.1b4/NetNewsWire6.1b4.zip" sparkle:version="6103" sparkle:shortVersionString="6.1b4" length="10897726" type="application/zip" />
|
||||
<sparkle:minimumSystemVersion>10.15.0</sparkle:minimumSystemVersion>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>NetNewsWire 6.1b3</title>
|
||||
<description><![CDATA[
|
||||
<p>Two new themes: Hyperlegible and NewsFax</p>
|
||||
|
||||
@@ -408,11 +408,11 @@ private extension AppDelegate {
|
||||
|
||||
// set expiration handler
|
||||
task.expirationHandler = { [weak task] in
|
||||
DispatchQueue.main.sync {
|
||||
self.suspendApplication()
|
||||
}
|
||||
os_log("Accounts refresh processing terminated for running too long.", log: self.log, type: .info)
|
||||
task?.setTaskCompleted(success: false)
|
||||
DispatchQueue.main.async {
|
||||
self.suspendApplication()
|
||||
task?.setTaskCompleted(success: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -563,6 +563,14 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner, Ma
|
||||
}
|
||||
}
|
||||
|
||||
if let rowChanges = changes.rowChanges {
|
||||
for rowChange in rowChanges {
|
||||
if let reloads = rowChange.reloadIndexPaths, !reloads.isEmpty {
|
||||
tableView.reloadRows(at: reloads, with: .none)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completion?()
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ struct ShadowTableChanges {
|
||||
var section: Int
|
||||
var deletes: Set<Int>?
|
||||
var inserts: Set<Int>?
|
||||
var reloads: Set<Int>?
|
||||
var moves: Set<ShadowTableChanges.Move>?
|
||||
|
||||
var isEmpty: Bool {
|
||||
@@ -41,15 +42,21 @@ struct ShadowTableChanges {
|
||||
return inserts.map { IndexPath(row: $0, section: section) }
|
||||
}
|
||||
|
||||
var reloadIndexPaths: [IndexPath]? {
|
||||
guard let reloads = reloads else { return nil }
|
||||
return reloads.map { IndexPath(row: $0, section: section) }
|
||||
}
|
||||
|
||||
var moveIndexPaths: [(IndexPath, IndexPath)]? {
|
||||
guard let moves = moves else { return nil }
|
||||
return moves.map { (IndexPath(row: $0.from, section: section), IndexPath(row: $0.to, section: section)) }
|
||||
}
|
||||
|
||||
init(section: Int, deletes: Set<Int>?, inserts: Set<Int>?, moves: Set<Move>?) {
|
||||
init(section: Int, deletes: Set<Int>?, inserts: Set<Int>?, reloads: Set<Int>?, moves: Set<Move>?) {
|
||||
self.section = section
|
||||
self.deletes = deletes
|
||||
self.inserts = inserts
|
||||
self.reloads = reloads
|
||||
self.moves = moves
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,16 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
private var fetchSerialNumber = 0
|
||||
private let fetchRequestQueue = FetchRequestQueue()
|
||||
|
||||
// Which Containers are expanded
|
||||
private var expandedTable = Set<ContainerIdentifier>()
|
||||
|
||||
// Which Containers used to be expanded. Reset by rebuilding the Shadow Table.
|
||||
private var lastExpandedTable = Set<ContainerIdentifier>()
|
||||
|
||||
// Which Feeds have the Read Articles Filter enabled
|
||||
private var readFilterEnabledTable = [FeedIdentifier: Bool]()
|
||||
|
||||
// Flattened tree structure for the Sidebar
|
||||
private var shadowTable = [(sectionID: String, feedNodes: [FeedNode])]()
|
||||
|
||||
private(set) var preSearchTimelineFeed: Feed?
|
||||
@@ -675,8 +683,11 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
rebuildBackingStores()
|
||||
}
|
||||
|
||||
/// This is a special function that expects the caller to change the disclosure arrow state outside this function.
|
||||
/// Failure to do so will get the Sidebar into an invalid state.
|
||||
func expand(_ node: Node) {
|
||||
guard let containerID = (node.representedObject as? ContainerIdentifiable)?.containerID else { return }
|
||||
lastExpandedTable.insert(containerID)
|
||||
expand(containerID)
|
||||
}
|
||||
|
||||
@@ -698,8 +709,11 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
clearTimelineIfNoLongerAvailable()
|
||||
}
|
||||
|
||||
/// This is a special function that expects the caller to change the disclosure arrow state outside this function.
|
||||
/// Failure to do so will get the Sidebar into an invalid state.
|
||||
func collapse(_ node: Node) {
|
||||
guard let containerID = (node.representedObject as? ContainerIdentifiable)?.containerID else { return }
|
||||
lastExpandedTable.remove(containerID)
|
||||
collapse(containerID)
|
||||
}
|
||||
|
||||
@@ -1080,7 +1094,9 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
||||
|
||||
rebuildBackingStores(initialLoad: initialLoad, completion: {
|
||||
self.treeControllerDelegate.resetFilterExceptions()
|
||||
self.selectFeed(webFeed, animations: animations, completion: completion)
|
||||
self.selectFeed(nil) {
|
||||
self.selectFeed(webFeed, animations: animations, completion: completion)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
@@ -1512,9 +1528,10 @@ private extension SceneCoordinator {
|
||||
currentFeedIndexPath = indexPathFor(timelineFeed as AnyObject)
|
||||
}
|
||||
|
||||
// Compute the differences in the shadow table rows
|
||||
// Compute the differences in the shadow table rows and the expanded table entries
|
||||
var changes = [ShadowTableChanges.RowChanges]()
|
||||
|
||||
let expandedTableDifference = lastExpandedTable.symmetricDifference(expandedTable)
|
||||
|
||||
for (section, newSectionRows) in newShadowTable.enumerated() {
|
||||
var moves = Set<ShadowTableChanges.Move>()
|
||||
var inserts = Set<Int>()
|
||||
@@ -1540,9 +1557,22 @@ private extension SceneCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
changes.append(ShadowTableChanges.RowChanges(section: section, deletes: deletes, inserts: inserts, moves: moves))
|
||||
// We need to reload the difference in expanded rows to get the disclosure arrows correct when programmatically changing their state
|
||||
var reloads = Set<Int>()
|
||||
|
||||
for (index, newFeedNode) in newSectionRows.feedNodes.enumerated() {
|
||||
if let newFeedNodeContainerID = (newFeedNode.node.representedObject as? Container)?.containerID {
|
||||
if expandedTableDifference.contains(newFeedNodeContainerID) {
|
||||
reloads.insert(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changes.append(ShadowTableChanges.RowChanges(section: section, deletes: deletes, inserts: inserts, reloads: reloads, moves: moves))
|
||||
}
|
||||
|
||||
lastExpandedTable = expandedTable
|
||||
|
||||
// Compute the difference in the shadow table sections
|
||||
var moves = Set<ShadowTableChanges.Move>()
|
||||
var inserts = Set<Int>()
|
||||
|
||||
Reference in New Issue
Block a user