use core data to mark items as archived

This commit is contained in:
Satindar Dhillon
2022-04-25 11:09:14 -07:00
parent 2cff1a6f72
commit 302410d4b2
3 changed files with 30 additions and 57 deletions

View File

@ -107,29 +107,12 @@ import Views
}
func setLinkArchived(dataService: DataService, linkId: String, archived: Bool) {
isLoading = true
// First remove the link from the internal list,
// then make a call to remove it. The isLoading block should
// prevent our local change from being overwritten, but we
// might need to cache a local list of archived links
// TODO: remove this by making list always fetch from Coredata
if let itemIndex = items.firstIndex(where: { $0.id == linkId }) {
items.remove(at: itemIndex)
}
dataService.archiveLinkPublisher(itemID: linkId, archived: archived)
.sink(
receiveCompletion: { [weak self] completion in
guard case .failure = completion else { return }
self?.isLoading = false
NSNotification.operationFailed(message: archived ? "Failed to archive link" : "Failed to unarchive link")
},
receiveValue: { [weak self] _ in
self?.isLoading = false
Snackbar.show(message: archived ? "Link archived" : "Link moved to Inbox")
}
)
.store(in: &subscriptions)
dataService.archiveLink(itemID: linkId, archived: archived)
Snackbar.show(message: archived ? "Link archived" : "Link moved to Inbox")
}
func removeLink(dataService: DataService, linkId: String) {

View File

@ -77,8 +77,7 @@ public extension LinkedItem {
inContext context: NSManagedObjectContext,
newReadingProgress: Double? = nil,
newAnchorIndex: Int? = nil,
newIsArchivedValue: Bool? = nil,
needsServerSync: Bool = false
newIsArchivedValue: Bool? = nil
) {
context.perform {
if let newReadingProgress = newReadingProgress {
@ -93,10 +92,6 @@ public extension LinkedItem {
self.isArchived = newIsArchivedValue
}
if needsServerSync {
self.serverSyncStatus = Int64(ServerSyncStatus.needsUpdate.rawValue)
}
guard context.hasChanges else { return }
do {

View File

@ -1,13 +1,19 @@
import Combine
import Foundation
import Models
import SwiftGraphQL
public extension DataService {
func archiveLinkPublisher(
itemID: String,
archived: Bool
) -> AnyPublisher<String, BasicError> {
extension DataService {
public func archiveLink(itemID: String, archived: Bool) {
// Update CoreData
if let linkedItem = LinkedItem.lookup(byID: itemID, inContext: backgroundContext) {
linkedItem.update(inContext: backgroundContext, newIsArchivedValue: archived)
}
// Send update to server
syncLinkArchiveStatus(itemID: itemID, archived: archived)
}
func syncLinkArchiveStatus(itemID: String, archived: Bool) {
enum MutationResult {
case success(linkId: String)
case error(errorCode: Enums.ArchiveLinkErrorCode)
@ -32,35 +38,24 @@ public extension DataService {
let path = appEnvironment.graphqlPath
let headers = networker.defaultHeaders
let context = backgroundContext
return Deferred {
Future { promise in
send(mutation, to: path, headers: headers) { result in
switch result {
case let .success(payload):
if payload.errors != nil {
promise(.failure(.message(messageText: "Error archiving link")))
}
send(mutation, to: path, headers: headers) { result in
let data = try? result.get()
let syncStatus: ServerSyncStatus = data == nil ? .needsUpdate : .isNSync
switch payload.data {
case let .success(linkId):
if let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) {
linkedItem.update(
inContext: self.backgroundContext,
newIsArchivedValue: archived
)
}
promise(.success(linkId))
case .error:
promise(.failure(.message(messageText: "Error archiving link")))
}
case .failure:
promise(.failure(.message(messageText: "Error archiving link")))
}
context.perform {
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: context) else { return }
linkedItem.serverSyncStatus = Int64(syncStatus.rawValue)
do {
try context.save()
logger.debug("LinkedItem updated succesfully")
} catch {
context.rollback()
logger.debug("Failed to update LinkedItem: \(error.localizedDescription)")
}
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}