Skip to content

Commit 5b4df29

Browse files
committed
fix: replace janky drag-drop with native 'Move to' context menu submenu
1 parent ad8884c commit 5b4df29

1 file changed

Lines changed: 38 additions & 24 deletions

File tree

TablePro/Views/Sidebar/FavoritesTabView.swift

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
//
77

88
import SwiftUI
9-
import UniformTypeIdentifiers
109

1110
/// Full-tab favorites view with folder hierarchy and bottom toolbar
1211
struct FavoritesTabView: View {
@@ -78,9 +77,6 @@ struct FavoritesTabView: View {
7877
.onDeleteCommand {
7978
deleteSelectedFavorites()
8079
}
81-
.onDrop(of: [.plainText], isTargeted: nil) { providers in
82-
handleDrop(providers: providers, targetFolderId: nil)
83-
}
8480
}
8581

8682
/// Renders tree items with DisclosureGroup for folders.
@@ -104,9 +100,6 @@ struct FavoritesTabView: View {
104100
coordinator: coordinator
105101
)
106102
}
107-
.onDrag {
108-
NSItemProvider(object: favorite.id.uuidString as NSString)
109-
}
110103
case .folder(let folder, let children):
111104
DisclosureGroup(isExpanded: Binding(
112105
get: { viewModel.expandedFolderIds.contains(folder.id) },
@@ -163,24 +156,7 @@ struct FavoritesTabView: View {
163156
}
164157
)
165158
}
166-
.onDrop(of: [.plainText], isTargeted: nil) { providers in
167-
handleDrop(providers: providers, targetFolderId: folder.id)
168-
}
169-
}
170-
}
171-
172-
private func handleDrop(providers: [NSItemProvider], targetFolderId: UUID?) -> Bool {
173-
guard let provider = providers.first else { return false }
174-
provider.loadObject(ofClass: NSString.self) { object, _ in
175-
guard let idString = object as? String, let favoriteId = UUID(uuidString: idString) else { return }
176-
Task { @MainActor in
177-
viewModel.moveFavorite(id: favoriteId, toFolder: targetFolderId)
178-
if let targetFolderId {
179-
viewModel.expandedFolderIds.insert(targetFolderId)
180-
}
181-
}
182159
}
183-
return true
184160
}
185161

186162
private func deleteSelectedFavorites() {
@@ -282,6 +258,10 @@ private struct FavoriteItemContextMenu: View {
282258
let viewModel: FavoritesSidebarViewModel
283259
weak var coordinator: MainContentCoordinator?
284260

261+
private var folders: [SQLFavoriteFolder] {
262+
collectFolders(from: viewModel.treeItems)
263+
}
264+
285265
var body: some View {
286266
Button(String(localized: "Edit...")) {
287267
viewModel.editFavorite(favorite)
@@ -306,6 +286,29 @@ private struct FavoriteItemContextMenu: View {
306286
Label(String(localized: "Run in New Tab"), systemImage: "play")
307287
}
308288

289+
if !folders.isEmpty {
290+
Divider()
291+
292+
Menu(String(localized: "Move to")) {
293+
if favorite.folderId != nil {
294+
Button(String(localized: "Root Level")) {
295+
viewModel.moveFavorite(id: favorite.id, toFolder: nil)
296+
}
297+
298+
Divider()
299+
}
300+
301+
ForEach(folders) { folder in
302+
if folder.id != favorite.folderId {
303+
Button(folder.name) {
304+
viewModel.moveFavorite(id: favorite.id, toFolder: folder.id)
305+
viewModel.expandedFolderIds.insert(folder.id)
306+
}
307+
}
308+
}
309+
}
310+
}
311+
309312
Divider()
310313

311314
Button(role: .destructive) {
@@ -314,6 +317,17 @@ private struct FavoriteItemContextMenu: View {
314317
Label(String(localized: "Delete"), systemImage: "trash")
315318
}
316319
}
320+
321+
private func collectFolders(from items: [FavoriteTreeItem]) -> [SQLFavoriteFolder] {
322+
var result: [SQLFavoriteFolder] = []
323+
for item in items {
324+
if case .folder(let folder, let children) = item {
325+
result.append(folder)
326+
result.append(contentsOf: collectFolders(from: children))
327+
}
328+
}
329+
return result
330+
}
317331
}
318332

319333
private struct FolderContextMenu: View {

0 commit comments

Comments
 (0)