Merge branch 'ios-candidate' into main

This commit is contained in:
Maurice Parker 2021-04-15 14:30:32 -05:00
commit 6a4c761ed8
11 changed files with 133 additions and 23 deletions

View File

@ -443,21 +443,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
}
public func syncArticleStatus(completion: ((Result<Void, Error>) -> Void)? = nil) {
delegate.sendArticleStatus(for: self) { [unowned self] result in
switch result {
case .success:
self.delegate.refreshArticleStatus(for: self) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
delegate.syncArticleStatus(for: self, completion: completion)
}
public func importOPML(_ opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {

View File

@ -26,6 +26,7 @@ protocol AccountDelegate {
func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void)
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void)
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)?)
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))

View File

@ -92,6 +92,24 @@ final class CloudKitAccountDelegate: AccountDelegate {
standardRefreshAll(for: account, completion: completion)
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
sendArticleStatus(for: account, showProgress: false, completion: completion)
}

View File

@ -150,6 +150,24 @@ final class FeedWranglerAccountDelegate: AccountDelegate {
}
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func refreshArticles(for account: Account, page: Int = 0, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Refreshing articles, page: %d...", page)

View File

@ -112,6 +112,24 @@ final class FeedbinAccountDelegate: AccountDelegate {
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Sending article statuses...")

View File

@ -145,6 +145,24 @@ final class FeedlyAccountDelegate: AccountDelegate {
operationQueue.add(syncAllOperation)
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
// Ensure remote articles have the same status as they do locally.
let send = FeedlySendArticleStatusesOperation(database: database, service: caller, log: log)

View File

@ -96,6 +96,10 @@ final class LocalAccountDelegate: AccountDelegate {
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
completion?(.success(()))
}
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
completion(.success(()))
}

View File

@ -114,6 +114,24 @@ final class NewsBlurAccountDelegate: AccountDelegate {
}
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func sendArticleStatus(for account: Account, completion: @escaping (Result<Void, Error>) -> ()) {
os_log(.debug, log: log, "Sending story statuses...")

View File

@ -131,6 +131,29 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
}
func syncArticleStatus(for account: Account, completion: ((Result<Void, Error>) -> Void)? = nil) {
guard variant != .inoreader else {
completion?(.success(()))
return
}
sendArticleStatus(for: account) { result in
switch result {
case .success:
self.refreshArticleStatus(for: account) { result in
switch result {
case .success:
completion?(.success(()))
case .failure(let error):
completion?(.failure(error))
}
}
case .failure(let error):
completion?(.failure(error))
}
}
}
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Sending article statuses...")

View File

@ -370,22 +370,28 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
return IndexPath(row: 0, section: destIndexPath.section)
} else {
let identifier = makeIdentifier(sortedNodes[index])
let candidateIndexPath = dataSource.indexPath(for: identifier)!
let movementAdjustment = sourceIndexPath < destIndexPath ? 1 : 0
return IndexPath(row: candidateIndexPath.row - movementAdjustment, section: candidateIndexPath.section)
if let candidateIndexPath = dataSource.indexPath(for: identifier) {
let movementAdjustment = sourceIndexPath < destIndexPath ? 1 : 0
return IndexPath(row: candidateIndexPath.row - movementAdjustment, section: candidateIndexPath.section)
} else {
return sourceIndexPath
}
}
} else {
if index >= sortedNodes.count {
let identifier = makeIdentifier(sortedNodes[sortedNodes.count - 1])
let lastSortedIndexPath = dataSource.indexPath(for: identifier)!
let movementAdjustment = sourceIndexPath > destIndexPath ? 1 : 0
return IndexPath(row: lastSortedIndexPath.row + movementAdjustment, section: lastSortedIndexPath.section)
if let lastSortedIndexPath = dataSource.indexPath(for: identifier) {
let movementAdjustment = sourceIndexPath > destIndexPath ? 1 : 0
return IndexPath(row: lastSortedIndexPath.row + movementAdjustment, section: lastSortedIndexPath.section)
} else {
return sourceIndexPath
}
} else {
let movementAdjustment = sourceIndexPath < destIndexPath ? 1 : 0
let identifer = makeIdentifier(sortedNodes[index - movementAdjustment])
return dataSource.indexPath(for: identifer)!
return dataSource.indexPath(for: identifer) ?? sourceIndexPath
}
}

View File

@ -1,7 +1,7 @@
// High Level Settings common to both the iOS application and any extensions we bundle with it
MARKETING_VERSION = 6.0
CURRENT_PROJECT_VERSION = 600
CURRENT_PROJECT_VERSION = 601
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon