Support move operation
This commit is contained in:
@ -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") },
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -6,4 +6,5 @@ public enum ServerSyncStatus: Int {
|
||||
case needsDeletion
|
||||
case needsCreation
|
||||
case needsUpdate
|
||||
case needsMove
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user