diff --git a/OTP.xcodeproj/xcuserdata/shadowfacts.xcuserdatad/xcschemes/xcschememanagement.plist b/OTP.xcodeproj/xcuserdata/shadowfacts.xcuserdatad/xcschemes/xcschememanagement.plist index bdba5c9..1b484cc 100644 --- a/OTP.xcodeproj/xcuserdata/shadowfacts.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/OTP.xcodeproj/xcuserdata/shadowfacts.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ OTP.xcscheme_^#shared#^_ orderHint - 1 + 0 OTPKit.xcscheme_^#shared#^_ orderHint - 0 + 1 diff --git a/OTP/KeyData.swift b/OTP/KeyData.swift index cf25ff6..9d2fbd2 100644 --- a/OTP/KeyData.swift +++ b/OTP/KeyData.swift @@ -43,6 +43,15 @@ struct KeyData: Codable { } } + mutating func addOrUpdateFolders(_ folders: [Folder]) { + for f in folders { + guard !self.folders.contains(where: { $0.id == f.id }) else { + continue + } + self.folders.append(f) + } + } + mutating func updateKey(entryID id: UUID, newKey: TOTPKey) { guard let index = entries.firstIndex(where: { $0.id == id }) else { return diff --git a/OTP/KeyStore.swift b/OTP/KeyStore.swift index b973492..0291b0d 100644 --- a/OTP/KeyStore.swift +++ b/OTP/KeyStore.swift @@ -51,6 +51,7 @@ class KeyStore: ObservableObject { data = newStore } else { data.addOrUpdateEntries(newStore.entries) + data.addOrUpdateFolders(newStore.folders) } } diff --git a/OTP/Views/AddQRView.swift b/OTP/Views/AddQRView.swift index 0444583..89cd091 100644 --- a/OTP/Views/AddQRView.swift +++ b/OTP/Views/AddQRView.swift @@ -84,6 +84,8 @@ extension AddQRView { return "Scanner: Bad Input" case .scanner(.badOutput): return "Scanner: Bad Output" + case .scanner(.initError(let e)): + return ("Scanner: Initialization: \(e)") } } } diff --git a/OTP/Views/FoldersSection.swift b/OTP/Views/FoldersSection.swift index 2697563..69be14a 100644 --- a/OTP/Views/FoldersSection.swift +++ b/OTP/Views/FoldersSection.swift @@ -6,6 +6,7 @@ // import SwiftUI +import UniformTypeIdentifiers struct FoldersSection: View { @ObservedObject private var store: KeyStore = .shared @@ -15,6 +16,20 @@ struct FoldersSection: View { Section { ForEach(store.sortedFolders) { (folder) in FolderRow(store: store, folder: folder) + .onDrop(of: [.text], isTargeted: nil) { providers in + guard let provider = providers.first, + provider.canLoadObject(ofClass: NSString.self) else { + return false + } + provider.loadObject(ofClass: NSString.self) { object, _ in + guard let str = object as? NSString, + let id = UUID(uuidString: str as String) else { + return + } + store.moveEntryToFolder(entryID: id, folderID: folder.id) + } + return true + } } .onDelete { (indices) in let folderIDs = indices.map { store.sortedFolders[$0].id } diff --git a/OTP/Views/KeysSection.swift b/OTP/Views/KeysSection.swift index e523ea4..5f784a5 100644 --- a/OTP/Views/KeysSection.swift +++ b/OTP/Views/KeysSection.swift @@ -35,9 +35,11 @@ struct KeysSection: View { ForEach(filteredEntries) { (entry) in KeyView(key: entry.key, currentCode: entry.code) // disabled because dropping onto list rows does not work :/ -// .onDrag { -// NSItemProvider(object: entry.id.uuidString as NSString) -// } + .onDrag { + let provider = NSItemProvider() + provider.registerObject(entry.id.uuidString as NSString, visibility: .ownProcess) + return provider + } .contextMenu { self.keyMenu(entry: entry) }