feat: enhance library and studio image references - #105
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR enhances the desktop Gallery (Library) and Studio workflows by adding bulk selection/actions in the Gallery, improving visibility/management of reference images in Studio composers, and introducing “Edit” entry points that open Studio with an image preloaded as a reference. It also pins the Vitest coverage provider version for consistent coverage validation.
Changes:
- Add bulk selection UI + bulk actions (favorite, add-to-board, delete) to the Gallery page.
- Add removable reference thumbnails as composer “attachments” in Studio image/video rails, and add “Edit” actions from Gallery/Studio items that open Studio with the selected image as a reference.
- Introduce
imagent://external/...support for previewing user-selected local reference images, and pin@vitest/coverage-v8to4.1.5.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ui/src/composites/GalleryItemCardImageVariant.tsx | Wires new onEdit action into the image card variant’s action menu. |
| packages/ui/src/composites/GalleryItemCard.types.ts | Adds onEdit to GalleryItemCardProps. |
| packages/ui/src/composites/GalleryItemCard.shared.tsx | Adds “Edit” menu item to shared action menu content. |
| package.json | Pins @vitest/coverage-v8 version. |
| bun.lock | Lockfile update to reflect pinned @vitest/coverage-v8. |
| apps/desktop/src/renderer/state/useUIStore.ts | Adds openImageEditor(referencePath) navigation helper and draft update logic. |
| apps/desktop/src/renderer/pages/Studio/videoRail.tsx | Adds reference/asset thumbnail attachments to the video composer shell. |
| apps/desktop/src/renderer/pages/Studio/utils.ts | Adds resolveReferenceUrl and formatting tweaks. |
| apps/desktop/src/renderer/pages/Studio/referencePicker.tsx | Exports thumbnail strip component for reuse; updates reference UI presentation. |
| apps/desktop/src/renderer/pages/Studio/imageRail.tsx | Adds reference/asset thumbnail attachments to the image composer shell. |
| apps/desktop/src/renderer/pages/Studio/galleryRail.tsx | Adds “Edit” affordance for image gallery thumbnails to open Studio with reference. |
| apps/desktop/src/renderer/pages/Studio/composer.tsx | Adds attachments slot to composer shell layout. |
| apps/desktop/src/renderer/pages/Gallery/index.tsx | Implements bulk selection/actions; adds onEdit wiring into item cards and preview. |
| apps/desktop/src/renderer/pages/Gallery/components.tsx | Adds “Edit” action in lightbox preview controls. |
| apps/desktop/src/renderer/i18n/messages.zh.ts | Adds Chinese translations for bulk selection/actions strings. |
| apps/desktop/src/renderer/i18n/messages.en.ts | Adds English strings for bulk selection/actions. |
| apps/desktop/src/main/main.ts | Extends imagent:// protocol handler to support external absolute-path fetches. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
132
to
147
| const url = new URL(request.url); | ||
| const relPath = decodeURIComponent(url.pathname.replace(/^\/+/, "")); | ||
| const absPath = path.normalize(path.join(dataDirAbs, relPath)); | ||
| if (!absPath.startsWith(dataDirAbs)) { | ||
| const requestPath = decodeURIComponent(url.pathname.replace(/^\/+/, "")); | ||
| const absPath = | ||
| url.hostname === "local" | ||
| ? path.normalize(path.join(dataDirAbs, requestPath)) | ||
| : url.hostname === "external" | ||
| ? path.normalize(requestPath) | ||
| : null; | ||
| if ( | ||
| !absPath || | ||
| (url.hostname === "local" && !absPath.startsWith(dataDirAbs)) || | ||
| (url.hostname === "external" && !path.isAbsolute(absPath)) | ||
| ) { | ||
| return new Response("forbidden", { status: 403 }); | ||
| } | ||
| return net.fetch(pathToFileURL(absPath).toString()); |
Comment on lines
+515
to
+520
| openImageEditor: (referencePath) => { | ||
| const next: ImageDraft = { | ||
| ...get().studioDraft.image, | ||
| references: [referencePath], | ||
| referenceRoles: { [referencePath]: "freeform" }, | ||
| }; |
Comment on lines
+133
to
+143
| const openImageEditorWithReference = async (item: GalleryItem): Promise<void> => { | ||
| try { | ||
| openImageEditor(await resolveGalleryAbsolutePath(item.relPath)); | ||
| } catch (err) { | ||
| pushToast({ | ||
| title: t("studio.referenceFailed"), | ||
| description: (err as Error)?.message ?? String(err), | ||
| variant: "error", | ||
| }); | ||
| } | ||
| }; |
Comment on lines
+261
to
+271
| const handleEditImage = async (item: GalleryItem): Promise<void> => { | ||
| try { | ||
| openImageEditor(await resolveGalleryAbsolutePath(item.relPath)); | ||
| } catch (err) { | ||
| pushToast({ | ||
| title: t("studio.referenceFailed"), | ||
| description: (err as Error)?.message ?? String(err), | ||
| variant: "error", | ||
| }); | ||
| } | ||
| }; |
Comment on lines
512
to
+518
| {references.map((path) => ( | ||
| <ReferenceChip key={path} label={fileName(path)} onRemove={() => onRemoveReference(path)} /> | ||
| <ReferenceThumbnail | ||
| key={path} | ||
| label={fileName(path)} | ||
| src={resolveReferenceUrl(path)} | ||
| onRemove={() => onRemoveReference(path)} | ||
| /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Validation
bun run --filter @imagent/ui buildbun run --filter @imagent/studio typecheckbunx biome check apps/desktop/src/renderer/pages/Studio/composer.tsx apps/desktop/src/renderer/pages/Studio/referencePicker.tsx apps/desktop/src/renderer/pages/Studio/imageRail.tsx apps/desktop/src/renderer/pages/Studio/videoRail.tsx