diff --git a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift index a56aa07aa..7d0b46e52 100644 --- a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift @@ -23,19 +23,13 @@ public final class PDFViewerViewModel: ObservableObject { } public func createHighlight(shortId: String, highlightID: String, quote: String, patch: String) { - services.dataService - .createHighlightPublisher( - shortId: shortId, - highlightID: highlightID, - quote: quote, - patch: patch, - articleId: linkedItem.unwrappedID - ) - .sink { [weak self] completion in - guard case let .failure(error) = completion else { return } - self?.errorMessage = error.localizedDescription - } receiveValue: { _ in } - .store(in: &subscriptions) + _ = services.dataService.createHighlight( + shortId: shortId, + highlightID: highlightID, + quote: quote, + patch: patch, + articleId: linkedItem.unwrappedID + ) } public func mergeHighlight( diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift index 39d902c12..4db2620dd 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift @@ -43,7 +43,7 @@ final class WebReaderViewModel: ObservableObject { replyHandler: @escaping WKScriptMessageReplyHandler, dataService: DataService ) { - dataService.createHighlightPublisher( + let result = dataService.createHighlight( shortId: messageBody["shortId"] as? String ?? "", highlightID: messageBody["id"] as? String ?? "", quote: messageBody["quote"] as? String ?? "", @@ -51,17 +51,8 @@ final class WebReaderViewModel: ObservableObject { articleId: messageBody["articleId"] as? String ?? "", annotation: messageBody["annotation"] as? String ?? "" ) - .sink { completion in - guard case .failure = completion else { return } - replyHandler([], "createHighlight: Error encoding response") - } receiveValue: { result in - if let result = result { - replyHandler(["result": result], nil) - } else { - replyHandler([], "createHighlight: Error encoding response") - } - } - .store(in: &subscriptions) + + return replyHandler(["result": result], nil) } func deleteHighlight( diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateHighlight.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateHighlight.swift index 614b6e29e..9afba24a0 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateHighlight.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/CreateHighlight.swift @@ -1,17 +1,52 @@ -import Combine +import CoreData import Foundation import Models import SwiftGraphQL -public extension DataService { - func createHighlightPublisher( +extension DataService { + public func createHighlight( shortId: String, highlightID: String, quote: String, patch: String, articleId: String, annotation: String? = nil - ) -> AnyPublisher<[String: Any]?, BasicError> { + ) -> [String: Any]? { + let internalHighlight = InternalHighlight( + id: highlightID, + shortId: shortId, + quote: quote, + prefix: nil, suffix: nil, + patch: patch, + annotation: annotation, + createdAt: nil, + updatedAt: nil, + createdByMe: true + ) + + internalHighlight.persist(context: backgroundContext, associatedItemID: articleId) + + // Send update to server + syncHighlightCreation( + shortId: shortId, + highlightID: highlightID, + quote: quote, + patch: patch, + articleId: articleId, + annotation: annotation + ) + + return internalHighlight.encoded() + } + + func syncHighlightCreation( + shortId: String, + highlightID: String, + quote: String, + patch: String, + articleId: String, + annotation: String? + ) { enum MutationResult { case saved(highlight: InternalHighlight) case error(errorCode: Enums.CreateHighlightErrorCode) @@ -42,33 +77,29 @@ 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 let graphqlError = payload.errors { - promise(.failure(.message(messageText: "graphql error: \(graphqlError)"))) - } + send(mutation, to: path, headers: headers) { result in + let data = try? result.get() + let syncStatus: ServerSyncStatus = data == nil ? .needsCreation : .isNSync - switch payload.data { - case let .saved(highlight: highlight): - highlight.persist( - context: self.backgroundContext, - associatedItemID: articleId - ) - promise(.success(highlight.encoded())) - case let .error(errorCode: errorCode): - promise(.failure(.message(messageText: errorCode.rawValue))) - } - case .failure: - promise(.failure(.message(messageText: "graphql error"))) - } + context.perform { + let fetchRequest: NSFetchRequest = Highlight.fetchRequest() + fetchRequest.predicate = NSPredicate( + format: "id == %@", highlightID + ) + + guard let highlight = (try? context.fetch(fetchRequest))?.first else { return } + highlight.serverSyncStatus = Int64(syncStatus.rawValue) + + do { + try context.save() + logger.debug("Highlight created succesfully") + } catch { + context.rollback() + logger.debug("Failed to create Highlight: \(error.localizedDescription)") } } } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() } } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/RemoveLink.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/RemoveLink.swift index f914ab326..fb2f7f8da 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/RemoveLink.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/RemoveLink.swift @@ -1,4 +1,3 @@ -import Combine import CoreData import Foundation import Models