tui: gallery — move-to-folder action with folder picker #138

Closed
opened 2026-04-14 20:12:31 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As a user organizing my gallery, I want to move selected items to a folder via a keybind + picker overlay, so that I can categorize without leaving the keyboard.

Background

GalleryItem has a folder: String field and the storage already filters by folder, but there's no UI to change an item's folder. GTK supports drag-drop folder moves.

Acceptance criteria

Picker overlay

  • New OverlayKind::FolderPicker { item_ids: Vec<Uuid> } opens via m from grid/list/detail
  • Reuses the existing string_picker component populated from self.folders plus a "(root)" entry
  • Header: Move N item(s) to:
  • Type to filter, Enter to apply

Storage

  • Add pub fn move_to_folder(&self, ids: &[Uuid], folder: &str) -> Result<()> to GalleryStorage
  • After successful move, publish LoomEvent::GalleryChanged so the gallery refreshes

New folder

  • Ctrl+N from the picker opens a small text input overlay to create a folder name
  • On confirm, the folder is added to self.folders and applied as the move target

Tests

  • Unit: move_to_folder updates the rows and round-trips through list(&filter)
  • Unit: empty folder string maps to root

Out of scope

  • Folder rename / delete
  • Nested folder hierarchy
  • Drag-drop (terminal limitation)

References

  • crates/loom-tui/src/screens/gallery.rs (folders: Vec<String>)
  • crates/loom-tui/src/components/string_picker.rs (reusable picker)
  • crates/loom-core/src/services/storage.rs
## User story As a user organizing my gallery, I want to move selected items to a folder via a keybind + picker overlay, so that I can categorize without leaving the keyboard. ## Background `GalleryItem` has a `folder: String` field and the storage already filters by folder, but there's no UI to change an item's folder. GTK supports drag-drop folder moves. ## Acceptance criteria ### Picker overlay - [ ] New `OverlayKind::FolderPicker { item_ids: Vec<Uuid> }` opens via `m` from grid/list/detail - [ ] Reuses the existing `string_picker` component populated from `self.folders` plus a "(root)" entry - [ ] Header: `Move N item(s) to:` - [ ] Type to filter, Enter to apply ### Storage - [ ] Add `pub fn move_to_folder(&self, ids: &[Uuid], folder: &str) -> Result<()>` to `GalleryStorage` - [ ] After successful move, publish `LoomEvent::GalleryChanged` so the gallery refreshes ### New folder - [ ] `Ctrl+N` from the picker opens a small text input overlay to create a folder name - [ ] On confirm, the folder is added to `self.folders` and applied as the move target ### Tests - [ ] Unit: `move_to_folder` updates the rows and round-trips through `list(&filter)` - [ ] Unit: empty folder string maps to root ## Out of scope - Folder rename / delete - Nested folder hierarchy - Drag-drop (terminal limitation) ## References - `crates/loom-tui/src/screens/gallery.rs` (`folders: Vec<String>`) - `crates/loom-tui/src/components/string_picker.rs` (reusable picker) - `crates/loom-core/src/services/storage.rs`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom#138
No description provided.