feat(gallery): add-to-album submenu on the image right-click menu

Right-clicking an image in the Gallery or Timeline now offers an
"Add to Album" submenu listing all albums with their counts — the first
use of the new SubMenu primitive. Filing a single image away no longer
requires starting a multi-select.
This commit is contained in:
2026-07-03 23:54:40 +01:00
parent 83081928f6
commit 5d46ee5b94
2 changed files with 24 additions and 4 deletions
+7 -3
View File
@@ -56,12 +56,16 @@ aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
from whatever collection you are already browsing. Videos are skipped, controls
tuck themselves away after a few seconds, and Settings lets you pick the pace
and whether playback follows the current order or goes random.
- **Add to album from the right-click menu** — right-click any image in the
Gallery or Timeline and file it straight into an album from the new "Add to
Album" submenu. One image, one click, zero ceremony.
### Changed
- **Consistent right-click menus** — the folder, album, image, and theme menus
now share one look and behavior: they stay inside the window instead of
spilling off the edge, close on Escape, and support proper submenus.
- **Right-click menus got their act together** — images, folders, albums, and
the theme switcher now share one menu style with one set of manners: they
stay on screen instead of wandering off the edge, all close on Escape, and
they can do proper submenus now.
- **Neater lightbox details** — image and video metadata now sits in two columns,
so the info panel shows more at a glance with less scrolling.
- **Faster Explore revisits** — returning to a folder's visual clusters should
+17 -1
View File
@@ -1,5 +1,5 @@
import { ImageRecord, useGalleryStore } from "../store";
import { ContextMenu, MenuItem, MenuLabel, MenuSeparator } from "./menu";
import { ContextMenu, MenuItem, MenuLabel, MenuSeparator, SubMenu } from "./menu";
import { Tooltip } from "./Tooltip";
/** Right-click menu for an image tile. Shared by the Gallery grid and the Timeline. */
@@ -17,6 +17,8 @@ export function ImageContextMenu({
const openImage = useGalleryStore((state) => state.openImage);
const updateImageDetails = useGalleryStore((state) => state.updateImageDetails);
const findSimilar = useGalleryStore((state) => state.findSimilar);
const albums = useGalleryStore((state) => state.albums);
const addToAlbum = useGalleryStore((state) => state.addToAlbum);
const canFindSimilar = image.embedding_status === "ready";
return (
@@ -31,6 +33,20 @@ export function ImageContextMenu({
disabled={!canFindSimilar}
onSelect={() => findSimilar(image.id, image.folder_id)}
/>
<SubMenu label="Add to Album" panelClassName="max-h-64 overflow-y-auto">
{albums.length === 0 ? (
<MenuItem label="No albums yet" disabled />
) : (
albums.map((album) => (
<MenuItem
key={album.id}
label={album.name}
hint={album.image_count.toLocaleString()}
onSelect={() => void addToAlbum(album.id, [image.id])}
/>
))
)}
</SubMenu>
<MenuSeparator />
<MenuLabel>Rating</MenuLabel>
<div className="flex items-center gap-0.5 px-2 pb-1.5">