66//
77
88import SwiftUI
9- import UniformTypeIdentifiers
109
1110/// Full-tab favorites view with folder hierarchy and bottom toolbar
1211struct 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
319333private struct FolderContextMenu : View {
0 commit comments