sync title/description changes with core data and server

This commit is contained in:
Satindar Dhillon 2022-06-14 14:12:25 -07:00
parent 64e146380f
commit 86e1446688
3 changed files with 95 additions and 15 deletions

View file

@ -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) }
)

View file

@ -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()

View file

@ -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<MutationResult, Unions.UpdatePageResult> {
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)")
}
}
}
}
}