From 302410d4b26d3f4f9c35a9ebdc1b01dd3db06c2a Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Mon, 25 Apr 2022 11:09:14 -0700 Subject: [PATCH] use core data to mark items as archived --- .../App/Views/Home/HomeFeedViewModel.swift | 23 +------- .../Sources/Models/DataModels/FeedItem.swift | 7 +-- .../DataService/Mutations/ArchiveLink.swift | 57 +++++++++---------- 3 files changed, 30 insertions(+), 57 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index aa714f261..38a68cd71 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -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) { diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift index afda2c4a6..3df45fda1 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift @@ -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 { diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/ArchiveLink.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/ArchiveLink.swift index 389f12f04..34479dd96 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/ArchiveLink.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/ArchiveLink.swift @@ -1,13 +1,19 @@ -import Combine import Foundation import Models import SwiftGraphQL -public extension DataService { - func archiveLinkPublisher( - itemID: String, - archived: Bool - ) -> AnyPublisher { +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() } }