diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerAPICaller.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerAPICaller.swift index 0a947ccac..06e880298 100644 --- a/Account/Sources/Account/FeedWrangler/FeedWranglerAPICaller.swift +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerAPICaller.swift @@ -189,76 +189,46 @@ final class FeedWranglerAPICaller: NSObject { } } } - - func retrieveUnreadFeedItems(page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItem], Error>) -> Void) { - let url = FeedWranglerConfig.clientURL - .appendingPathComponent("feed_items/list") - .appendingQueryItems([ - URLQueryItem(name: "read", value: "false"), - URLQueryItem(name: "offset", value: String(page * FeedWranglerConfig.pageSize)), - ]) - - standardSend(url: url, resultType: FeedWranglerFeedItemsRequest.self) { result in - switch result { - case .success(let (_, results)): - completion(.success(results?.feedItems ?? [])) + + func retrieveUnreadFeedItemIds(completion: @escaping (Result<[FeedWranglerFeedItemId], Error>) -> Void) { + retrieveAllFeedItemIds(filters: [URLQueryItem(name: "read", value: "false")], completion: completion) + } + + func retrieveStarredFeedItemIds(completion: @escaping (Result<[FeedWranglerFeedItemId], Error>) -> Void) { + retrieveAllFeedItemIds(filters: [URLQueryItem(name: "starred", value: "true")], completion: completion) + } + + private func retrieveAllFeedItemIds(filters: [URLQueryItem] = [], foundItems: [FeedWranglerFeedItemId] = [], page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItemId], Error>) -> Void) { + retrieveFeedItemIds(filters: filters, page: page) { result in + switch result { + case .success(let newItems): + if newItems.count > 0 { + self.retrieveAllFeedItemIds(filters: filters, foundItems: foundItems + newItems, page: (page + 1), completion: completion) + } else { + completion(.success(foundItems + newItems)) + } + + case .failure(let error): + completion(.failure(error)) + } + } + } + + private func retrieveFeedItemIds(filters: [URLQueryItem] = [], page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItemId], Error>) -> Void) { + let url = FeedWranglerConfig.clientURL + .appendingPathComponent("feed_items/list_ids") + .appendingQueryItems(filters + [URLQueryItem(name: "offset", value: String(page * FeedWranglerConfig.idsPageSize))]) + + standardSend(url: url, resultType: FeedWranglerFeedItemIdsRequest.self) { result in + switch result { + case .success(let (_, results)): + completion(.success(results?.feedItems ?? [])) - case .failure(let error): - completion(.failure(error)) - } - } - } - - func retrieveAllUnreadFeedItems(foundItems: [FeedWranglerFeedItem] = [], page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItem], Error>) -> Void) { - retrieveUnreadFeedItems(page: page) { result in - switch result { - case .success(let newItems): - if newItems.count > 0 { - self.retrieveAllUnreadFeedItems(foundItems: foundItems + newItems, page: (page + 1), completion: completion) - } else { - completion(.success(foundItems + newItems)) - } - - case .failure(let error): - completion(.failure(error)) - } - } - } - - func retrieveStarredFeedItems(page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItem], Error>) -> Void) { - let url = FeedWranglerConfig.clientURL - .appendingPathComponent("feed_items/list") - .appendingQueryItems([ - URLQueryItem(name: "starred", value: "true"), - URLQueryItem(name: "offset", value: String(page * FeedWranglerConfig.pageSize)), - ]) - - standardSend(url: url, resultType: FeedWranglerFeedItemsRequest.self) { result in - switch result { - case .success(let (_, results)): - completion(.success(results?.feedItems ?? [])) - - case .failure(let error): - completion(.failure(error)) - } - } - } - - func retrieveAllStarredFeedItems(foundItems: [FeedWranglerFeedItem] = [], page: Int = 0, completion: @escaping (Result<[FeedWranglerFeedItem], Error>) -> Void) { - retrieveStarredFeedItems(page: page) { result in - switch result { - case .success(let newItems): - if newItems.count > 0 { - self.retrieveAllStarredFeedItems(foundItems: foundItems + newItems, page: (page + 1), completion: completion) - } else { - completion(.success(foundItems + newItems)) - } - - case .failure(let error): - completion(.failure(error)) - } - } - } + case .failure(let error): + completion(.failure(error)) + } + } + } func updateArticleStatus(_ articleID: String, _ statuses: [SyncStatus], completion: @escaping () -> Void) { diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerAccountDelegate.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerAccountDelegate.swift index 37c6aa212..7e44c6e1d 100644 --- a/Account/Sources/Account/FeedWrangler/FeedWranglerAccountDelegate.swift +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerAccountDelegate.swift @@ -249,7 +249,7 @@ final class FeedWranglerAccountDelegate: AccountDelegate { let group = DispatchGroup() group.enter() - caller.retrieveAllUnreadFeedItems { result in + caller.retrieveUnreadFeedItemIds { result in switch result { case .success(let items): self.syncArticleReadState(account, items) @@ -263,7 +263,7 @@ final class FeedWranglerAccountDelegate: AccountDelegate { // starred group.enter() - caller.retrieveAllStarredFeedItems { result in + caller.retrieveStarredFeedItemIds { result in switch result { case .success(let items): self.syncArticleStarredState(account, items) @@ -554,7 +554,7 @@ private extension FeedWranglerAccountDelegate { } } - func syncArticleReadState(_ account: Account, _ unreadFeedItems: [FeedWranglerFeedItem]) { + func syncArticleReadState(_ account: Account, _ unreadFeedItems: [FeedWranglerFeedItemId]) { let unreadServerItemIDs = Set(unreadFeedItems.map { String($0.feedItemID) }) account.fetchUnreadArticleIDs { articleIDsResult in guard let unreadLocalItemIDs = try? articleIDsResult.get() else { @@ -567,7 +567,7 @@ private extension FeedWranglerAccountDelegate { } } - func syncArticleStarredState(_ account: Account, _ starredFeedItems: [FeedWranglerFeedItem]) { + func syncArticleStarredState(_ account: Account, _ starredFeedItems: [FeedWranglerFeedItemId]) { let starredServerItemIDs = Set(starredFeedItems.map { String($0.feedItemID) }) account.fetchStarredArticleIDs { articleIDsResult in guard let starredLocalItemIDs = try? articleIDsResult.get() else { diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift index 5d41fba17..eca64e64a 100644 --- a/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerConfig.swift @@ -11,6 +11,7 @@ import Secrets enum FeedWranglerConfig { static let pageSize = 100 + static let idsPageSize = 1000 static let clientPath = "https://feedwrangler.net/api/v2/" static let clientURL = { URL(string: FeedWranglerConfig.clientPath)! diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemId.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemId.swift new file mode 100644 index 000000000..856131b13 --- /dev/null +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemId.swift @@ -0,0 +1,19 @@ +// +// File.swift +// +// +// Created by Jonathan Bennett on 2021-01-14. +// + + +import Foundation + +struct FeedWranglerFeedItemId: Hashable, Codable { + + let feedItemID: Int + + enum CodingKeys: String, CodingKey { + case feedItemID = "feed_item_id" + } + +} diff --git a/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemIdsRequest.swift b/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemIdsRequest.swift new file mode 100644 index 000000000..dda666285 --- /dev/null +++ b/Account/Sources/Account/FeedWrangler/FeedWranglerFeedItemIdsRequest.swift @@ -0,0 +1,25 @@ +// +// FeedWranglerFeedItemsRequest.swift +// Account +// +// Created by Jonathan Bennett on 2021-01-14. +// Copyright © 2019 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +struct FeedWranglerFeedItemIdsRequest: Hashable, Codable { + + let count: Int + let feedItems: [FeedWranglerFeedItemId] + let error: String? + let result: String + + enum CodingKeys: String, CodingKey { + case count = "count" + case feedItems = "feed_items" + case error = "error" + case result = "result" + } + +}