Support move operation

This commit is contained in:
Jackson Harper
2023-12-04 13:02:35 +08:00
parent bfd3365f28
commit ee375274b8
6 changed files with 99 additions and 8 deletions

View File

@ -59,7 +59,7 @@ struct AnimatingCellHeight: AnimatableModifier {
viewModel.searchTerm.isEmpty &&
viewModel.selectedLabels.isEmpty &&
viewModel.negatedLabels.isEmpty &&
viewModel.appliedFilter?.name == "inbox"
viewModel.appliedFilter?.name.lowercased() == "inbox"
}
var body: some View {
@ -740,7 +740,7 @@ struct AnimatingCellHeight: AnimatableModifier {
case .moveToInbox:
return AnyView(Button(
action: {
// viewModel.addLabel(dataService: dataService, item: item, label: "Inbox", color)
viewModel.moveToFolder(dataService: dataService, item: item, folder: "inbox")
},
label: {
Label(title: { Text("Move to Library") },

View File

@ -258,6 +258,17 @@ import Views
dataService.updateLinkReadingProgress(itemID: item.unwrappedID, readingProgress: 0, anchorIndex: 0, force: true)
}
func moveToFolder(dataService: DataService, item: Models.LibraryItem, folder: String) {
Task {
do {
try await dataService.moveItem(itemID: item.unwrappedID, folder: folder)
snackbar("Item moved")
} catch {
snackbar("Error performing operation")
}
}
}
func bulkAction(dataService: DataService, action: BulkAction, items: [String]) {
if items.count < 1 {
snackbar("No items selected")

View File

@ -6,4 +6,5 @@ public enum ServerSyncStatus: Int {
case needsDeletion
case needsCreation
case needsUpdate
case needsMove
}

View File

@ -0,0 +1,71 @@
import CoreData
import Foundation
import Models
import SwiftGraphQL
public extension DataService {
func moveItem(itemID: String, folder: String) async throws {
backgroundContext.performAndWait {
if let linkedItem = Models.LibraryItem.lookup(byID: itemID, inContext: backgroundContext) {
linkedItem.folder = folder
linkedItem.serverSyncStatus = Int64(ServerSyncStatus.needsUpdate.rawValue)
}
do {
try backgroundContext.save()
logger.debug("LinkedItem updated succesfully")
} catch {
backgroundContext.rollback()
logger.debug("Failed to update LinkedItem: \(error.localizedDescription)")
}
}
try await syncMoveToFolder(itemID: itemID, folder: folder)
}
func syncMoveToFolder(itemID: String, folder: String) async throws {
enum MutationResult {
case result(itemID: String)
case error(errorMessage: String)
}
let articleSavingRequestSelection = Selection.ArticleSavingRequest {
try $0.id()
}
let selection = Selection<MutationResult, Unions.MoveToFolderResult> {
try $0.on(
moveToFolderError: .init { .error(errorMessage: try $0.errorCodes().first?.rawValue ?? "Unknown Error") },
moveToFolderSuccess: .init {
.result(itemID: try $0.articleSavingRequest(selection: articleSavingRequestSelection))
}
)
}
let mutation = Selection.Mutation {
try $0.moveToFolder(
folder: folder,
id: itemID,
selection: selection
)
}
let path = appEnvironment.graphqlPath
let headers = networker.defaultHeaders
return try await withCheckedThrowingContinuation { continuation in
send(mutation, to: path, headers: headers) { queryResult in
guard let payload = try? queryResult.get() else {
continuation.resume(throwing: BasicError.message(messageText: "network error"))
return
}
switch payload.data {
case let .result(itemID: _):
continuation.resume()
case let .error(errorMessage: errorMessage):
continuation.resume(throwing: BasicError.message(messageText: errorMessage))
}
}
}
}
}

View File

@ -157,6 +157,15 @@ public extension DataService {
anchorIndex: Int(item.readingProgressAnchor),
force: item.isPDF
)
case .needsMove:
item.serverSyncStatus = Int64(ServerSyncStatus.isSyncing.rawValue)
syncLinkArchiveStatus(itemID: item.unwrappedID, archived: item.isArchived)
syncLinkReadingProgress(
itemID: item.unwrappedID,
readingProgress: item.readingProgress,
anchorIndex: Int(item.readingProgressAnchor),
force: item.isPDF
)
}
}
}
@ -184,6 +193,9 @@ public extension DataService {
} else {
highlight.serverSyncStatus = Int64(ServerSyncStatus.isNSync.rawValue)
}
case .needsMove:
// Highlights can't be moved
break
}
}
}

View File

@ -19,22 +19,18 @@ public struct SyncStatusIcon: View {
private var cloudIconName: String {
switch status {
// case .isNSync:
// return "checkmark.icloud"
case .isNSync:
return "exclamationmark.icloud"
case .isSyncing, .needsCreation, .needsDeletion, .needsUpdate:
case .isSyncing, .needsCreation, .needsDeletion, .needsUpdate, .needsMove:
return "icloud"
}
}
private var cloudIconColor: Color {
switch status {
// case .isNSync:
// return .blue
case .isNSync:
return .red
case .isSyncing, .needsCreation, .needsDeletion, .needsUpdate:
case .isSyncing, .needsCreation, .needsDeletion, .needsUpdate, .needsMove:
return .appGrayText
}
}