feat: drag photos onto a folder to move them
Bulk-move via drag-and-drop. Drop a photo (or multi-selection) on
any folder row in the LeftSidebar and the files move on disk +
photo.folder_id updates atomically.
Backend
- New POST /photos/move accepting { photo_ids, target_id }. The
target_id can be either a Folder id OR a SourceRoot id (the
sidebar exposes source roots today, so the same drag target
needs to resolve either).
- Resolves source roots to their on-disk path and looks up / creates
the canonical Folder row via the existing scan get_or_create_folder
helper, so dedupe + path normalization stay consistent with the
scanner.
- Per-photo loop with shutil.move; per-file failures (target name
collision, missing source, OS error) are collected into a
structured `errors` array and don't abort the batch.
- Skips photos that are already in the target folder so re-drops
are a no-op.
Frontend
- New photos.move(ids, targetId) helper in api.ts.
- LeftSidebar grows a moveDropMutation alongside the existing
discard one. handleDrop dispatches by id prefix:
'discarded' → discard, 'folder-{id}' → move.
- Folder rows now report acceptsDrop and get the same drag-over
highlight as heap drops, in primary tint instead of reject.
- onSuccess invalidates both the photos query and the folders
query so the new folder counts in the sidebar refresh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,16 @@ export const photos = {
|
||||
return response.data
|
||||
},
|
||||
|
||||
/** Move photos into a target folder (or source root). Returns
|
||||
* { moved, errors[] }. */
|
||||
move: async (photoIds: string[], targetId: string) => {
|
||||
const response = await api.post('/photos/move', {
|
||||
photo_ids: photoIds,
|
||||
target_id: targetId,
|
||||
})
|
||||
return response.data as { status: string; moved: number; errors: Array<{ id: string; error: string }> }
|
||||
},
|
||||
|
||||
getThumbnailUrl: (photoId: string, size: 'small' | 'medium' | 'large' = 'medium') => {
|
||||
return `${API_BASE_URL}/photos/${photoId}/thumb/${size}`
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user