mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
use credata for updating item labels
This commit is contained in:
parent
d7bc70fcd1
commit
acb1ae6c53
4 changed files with 45 additions and 78 deletions
|
|
@ -48,7 +48,7 @@ import Views
|
|||
loadItems(isRefresh: true)
|
||||
}
|
||||
.sheet(item: $viewModel.itemUnderLabelEdit) { item in
|
||||
ApplyLabelsView(mode: .item(item)) { _ in }
|
||||
ApplyLabelsView(mode: .item(item))
|
||||
}
|
||||
}
|
||||
.navigationTitle("Home")
|
||||
|
|
@ -111,9 +111,7 @@ import Views
|
|||
}
|
||||
.padding(.horizontal)
|
||||
.sheet(isPresented: $showLabelsSheet) {
|
||||
ApplyLabelsView(mode: .list(viewModel.selectedLabels)) { labels in
|
||||
viewModel.selectedLabels = labels
|
||||
}
|
||||
ApplyLabelsView(mode: .list(viewModel.selectedLabels))
|
||||
}
|
||||
}
|
||||
if prefersListLayout {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ struct ApplyLabelsView: View {
|
|||
}
|
||||
|
||||
let mode: Mode
|
||||
let commitLabelChanges: ([LinkedItemLabel]) -> Void
|
||||
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@Environment(\.presentationMode) private var presentationMode
|
||||
|
|
@ -100,14 +99,11 @@ struct ApplyLabelsView: View {
|
|||
action: {
|
||||
switch mode {
|
||||
case let .item(feedItem):
|
||||
viewModel.saveItemLabelChanges(itemID: feedItem.unwrappedID, dataService: dataService) { labels in
|
||||
commitLabelChanges(labels)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}
|
||||
viewModel.saveItemLabelChanges(itemID: feedItem.unwrappedID, dataService: dataService)
|
||||
case .list:
|
||||
commitLabelChanges(viewModel.selectedLabels)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
break
|
||||
}
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
},
|
||||
label: { Text(mode.confirmButtonText).foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
|
|
|
|||
|
|
@ -74,23 +74,8 @@ import Views
|
|||
.store(in: &subscriptions)
|
||||
}
|
||||
|
||||
func saveItemLabelChanges(
|
||||
itemID: String,
|
||||
dataService: DataService,
|
||||
onComplete: @escaping ([LinkedItemLabel]) -> Void
|
||||
) {
|
||||
isLoading = true
|
||||
dataService.updateArticleLabelsPublisher(itemID: itemID, labelIDs: selectedLabels.map(\.unwrappedID)).sink(
|
||||
receiveCompletion: { [weak self] _ in
|
||||
self?.isLoading = false
|
||||
},
|
||||
receiveValue: { labelIDs in
|
||||
onComplete(
|
||||
labelIDs.compactMap { dataService.viewContext.object(with: $0) as? LinkedItemLabel }
|
||||
)
|
||||
}
|
||||
)
|
||||
.store(in: &subscriptions)
|
||||
func saveItemLabelChanges(itemID: String, dataService: DataService) {
|
||||
dataService.updateItemLabels(itemID: itemID, labelNames: selectedLabels.map(\.unwrappedName))
|
||||
}
|
||||
|
||||
func addLabelToItem(_ label: LinkedItemLabel) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,33 @@
|
|||
import Combine
|
||||
import CoreData
|
||||
import Foundation
|
||||
import Models
|
||||
import SwiftGraphQL
|
||||
|
||||
public extension DataService {
|
||||
// swiftlint:disable:next function_body_length
|
||||
func updateArticleLabelsPublisher(
|
||||
itemID: String,
|
||||
labelIDs: [String]
|
||||
) -> AnyPublisher<[NSManagedObjectID], BasicError> {
|
||||
extension DataService {
|
||||
public func updateItemLabels(itemID: String, labelNames: [String]) {
|
||||
backgroundContext.perform { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) else { return }
|
||||
|
||||
if let existingLabels = linkedItem.labels {
|
||||
linkedItem.removeFromLabels(existingLabels)
|
||||
}
|
||||
|
||||
var labelIDs = [String]()
|
||||
|
||||
for labelName in labelNames {
|
||||
if let labelObject = LinkedItemLabel.lookup(byName: labelName, inContext: self.backgroundContext) {
|
||||
linkedItem.addToLabels(labelObject)
|
||||
labelIDs.append(labelObject.unwrappedID)
|
||||
}
|
||||
}
|
||||
|
||||
// Send update to server
|
||||
self.syncLabelUpdates(itemID: itemID, labelIDs: labelIDs)
|
||||
}
|
||||
}
|
||||
|
||||
func syncLabelUpdates(itemID: String, labelIDs: [String]) {
|
||||
enum MutationResult {
|
||||
case saved(feedItem: [InternalLinkedItemLabel])
|
||||
case error(errorCode: Enums.SetLabelsErrorCode)
|
||||
|
|
@ -34,54 +52,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 let graphqlError = payload.errors {
|
||||
promise(.failure(.message(messageText: graphqlError.first.debugDescription)))
|
||||
}
|
||||
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 .saved(labels):
|
||||
self.backgroundContext.perform {
|
||||
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: self.backgroundContext) else {
|
||||
promise(.failure(.message(messageText: "failed to set labels")))
|
||||
return
|
||||
}
|
||||
context.perform {
|
||||
guard let linkedItem = LinkedItem.lookup(byID: itemID, inContext: context) else { return }
|
||||
linkedItem.serverSyncStatus = Int64(syncStatus.rawValue)
|
||||
|
||||
if let existingLabels = linkedItem.labels {
|
||||
linkedItem.removeFromLabels(existingLabels)
|
||||
}
|
||||
for label in labels {
|
||||
if let labelObject = LinkedItemLabel.lookup(byName: label.name, inContext: self.backgroundContext) {
|
||||
linkedItem.addToLabels(labelObject)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
try self.backgroundContext.save()
|
||||
logger.debug("Item labels updated")
|
||||
let labelObjects = linkedItem.labels.asArray(of: LinkedItemLabel.self)
|
||||
promise(.success(labelObjects.map(\.objectID)))
|
||||
} catch {
|
||||
self.backgroundContext.rollback()
|
||||
logger.debug("Failed to update item labels: \(error.localizedDescription)")
|
||||
promise(.failure(.message(messageText: "failed to set labels")))
|
||||
}
|
||||
}
|
||||
case .error:
|
||||
promise(.failure(.message(messageText: "failed to set labels")))
|
||||
}
|
||||
case .failure:
|
||||
promise(.failure(.message(messageText: "failed to set labels")))
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
logger.debug("Item labels updated succesfully")
|
||||
} catch {
|
||||
context.rollback()
|
||||
logger.debug("Failed to update item labels: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
.receive(on: DispatchQueue.main)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue