From 86e144668882a39dc05d72b321f939b9b4e9d9b8 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 14 Jun 2022 14:12:25 -0700 Subject: [PATCH] sync title/description changes with core data and server --- .../App/Views/LinkedItemTitleEditView.swift | 21 ++--- .../Sources/Models/DataModels/FeedItem.swift | 12 ++- .../Mutations/UpdateLinkedItemTitle.swift | 77 +++++++++++++++++++ 3 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateLinkedItemTitle.swift diff --git a/apple/OmnivoreKit/Sources/App/Views/LinkedItemTitleEditView.swift b/apple/OmnivoreKit/Sources/App/Views/LinkedItemTitleEditView.swift index 911a12d2f..e8911c89d 100644 --- a/apple/OmnivoreKit/Sources/App/Views/LinkedItemTitleEditView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/LinkedItemTitleEditView.swift @@ -4,10 +4,8 @@ import SwiftUI import Views @MainActor final class LinkedItemTitleEditViewModel: ObservableObject { - @Published var isLoading = false @Published var title = "" @Published var description = "" - @Published var errorMessage: String? func load(item: LinkedItem) { title = item.unwrappedTitle @@ -15,17 +13,17 @@ import Views } func submit(dataService: DataService, item: LinkedItem) { - isLoading = true - print(item.title) - print(dataService.currentViewer?.unwrappedName) - isLoading = false + dataService.updateLinkedItemTitleAndDescription( + itemID: item.unwrappedID, + title: title, + description: description + ) } } struct LinkedItemTitleEditView: View { @EnvironmentObject var dataService: DataService @Environment(\.presentationMode) private var presentationMode - @Environment(\.horizontalSizeClass) var horizontalSizeClass @StateObject var viewModel = LinkedItemTitleEditViewModel() let item: LinkedItem @@ -56,13 +54,7 @@ struct LinkedItemTitleEditView: View { .strokeBorder(Color.appGrayBorder, lineWidth: 1) .background(RoundedRectangle(cornerRadius: 8).fill(Color.systemBackground)) ) - .frame(height: 160) - } - - if let errorMessage = viewModel.errorMessage { - Text(errorMessage) - .font(.appCaption) - .foregroundColor(.red) + .frame(height: 200) } } .padding() @@ -80,6 +72,7 @@ struct LinkedItemTitleEditView: View { Button( action: { viewModel.submit(dataService: dataService, item: item) + presentationMode.wrappedValue.dismiss() }, label: { Text("Save").foregroundColor(.appGrayTextContrast) } ) diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift index d74f21aeb..1150a8632 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/FeedItem.swift @@ -111,7 +111,9 @@ public extension LinkedItem { inContext context: NSManagedObjectContext, newReadingProgress: Double? = nil, newAnchorIndex: Int? = nil, - newIsArchivedValue: Bool? = nil + newIsArchivedValue: Bool? = nil, + newTitle: String? = nil, + newDescription: String? = nil ) { context.perform { if let newReadingProgress = newReadingProgress { @@ -126,6 +128,14 @@ public extension LinkedItem { self.isArchived = newIsArchivedValue } + if let newTitle = newTitle { + self.title = newTitle + } + + if let newDescription = newDescription { + self.descriptionText = newDescription + } + guard context.hasChanges else { return } self.updatedAt = Date() diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateLinkedItemTitle.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateLinkedItemTitle.swift new file mode 100644 index 000000000..3f2884436 --- /dev/null +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/UpdateLinkedItemTitle.swift @@ -0,0 +1,77 @@ +import CoreData +import Foundation +import Models +import SwiftGraphQL + +extension DataService { + public func updateLinkedItemTitleAndDescription(itemID: String, title: String, description: String) { + backgroundContext.perform { [weak self] in + guard let self = self else { return } + guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) else { return } + + linkedItem.update( + inContext: self.backgroundContext, + newTitle: title, + newDescription: description + ) + + // Send update to server + self.syncLinkedItemTitleAndDescription( + itemID: itemID, + objectID: linkedItem.objectID, + title: title, + description: description + ) + } + } + + func syncLinkedItemTitleAndDescription( + itemID: String, + objectID: NSManagedObjectID, + title: String, + description: String + ) { + enum MutationResult { + case saved(title: String) + case error(errorMessage: String) + } + + let selection = Selection { + try $0.on( + updatePageError: .init { .error(errorMessage: try $0.errorCodes().first.toString()) }, + updatePageSuccess: .init { + .saved(title: try $0.updatedPage(selection: Selection.Article { try $0.title() })) + } + ) + } + + let mutation = Selection.Mutation { + try $0.updatePage( + input: .init(description: OptionalArgument(description), pageId: itemID, title: OptionalArgument(title)), + selection: selection + ) + } + + let path = appEnvironment.graphqlPath + let headers = networker.defaultHeaders + let context = backgroundContext + + send(mutation, to: path, headers: headers) { result in + let data = try? result.get() + let syncStatus: ServerSyncStatus = data == nil ? .needsUpdate : .isNSync + + context.perform { + guard let linkedItem = context.object(with: objectID) as? LinkedItem 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)") + } + } + } + } +}