diff --git a/frontend/apps/editor2d/package.json b/frontend/apps/editor2d/package.json index f499a49418..6ecbedcace 100644 --- a/frontend/apps/editor2d/package.json +++ b/frontend/apps/editor2d/package.json @@ -22,7 +22,6 @@ "preview": "vite preview" }, "dependencies": { - "@devnomic/marquee": "^1.0.3", "@fortawesome/fontawesome-svg-core": "^6.7.2", "@fortawesome/free-brands-svg-icons": "^6.7.2", "@fortawesome/pro-regular-svg-icons": "^6.7.2", @@ -52,8 +51,8 @@ "@preact/signals-react-transform": "^0.4.0", "@tauri-apps/cli": "^2.4.0", "@types/deep-equal": "^1.0.4", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "@types/uuid": "^10.0.0", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.20", diff --git a/frontend/apps/editor2d/src/GenerationRootComponent/BackgroundGallery.tsx b/frontend/apps/editor2d/src/GenerationRootComponent/BackgroundGallery.tsx index 901d59e23f..00fdf6a831 100644 --- a/frontend/apps/editor2d/src/GenerationRootComponent/BackgroundGallery.tsx +++ b/frontend/apps/editor2d/src/GenerationRootComponent/BackgroundGallery.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { Marquee } from "@devnomic/marquee"; +// import { Marquee } from "@devnomic/marquee"; import "@devnomic/marquee/dist/index.css"; function getRandomImages(count: number) { @@ -21,16 +21,18 @@ interface ImageColumnProps { duration?: number; } -function ImageColumn({ - images, - delay, - reverse = false, - duration = 100, - isLoaded, -}: ImageColumnProps) { +function ImageColumn( + { + // images, + // delay, + // reverse = false, + // duration = 100, + // isLoaded, + }: ImageColumnProps, +) { return (
- ))} - + */}
); } diff --git a/frontend/apps/editor2d/src/components/PromptBox.tsx b/frontend/apps/editor2d/src/components/PromptBox.tsx index cb775dbb89..b6a0dbf79f 100644 --- a/frontend/apps/editor2d/src/components/PromptBox.tsx +++ b/frontend/apps/editor2d/src/components/PromptBox.tsx @@ -36,6 +36,7 @@ import { PopoverItem } from "~/components/reusable/Popover"; import { Api, ApiManager } from "~/KonvaApp/Api"; import { useJobContext } from "~/components/JobContext"; import { IsDesktopApp } from "@storyteller/tauri-utils"; +import { GalleryItem, GalleryModal } from "@storyteller/ui-gallery-modal"; interface ReferenceImage { id: string; @@ -56,6 +57,11 @@ export const PromptBox = () => { const [prompt, setPrompt] = useState(""); const [isEnqueueing, setisEnqueueing] = useState(false); const [useSystemPrompt, setUseSystemPrompt] = useState(true); + const [isGalleryModalOpen, setIsGalleryModalOpen] = useState(false); + const [selectedGalleryImages, setSelectedGalleryImages] = useState( + [], + ); + const [activeGalleryTab, setActiveGalleryTab] = useState("my-media"); const [referenceImages, setReferenceImages] = useState([]); const [uploadingImages, setUploadingImages] = useState< { id: string; file: File }[] @@ -153,8 +159,40 @@ export const PromptBox = () => { fileInputRef.current?.click(); }; - const handleLibrarySelect = () => { - console.log("Opening library selector"); + const handleGallerySelect = () => { + setIsGalleryModalOpen(true); + }; + + const handleGalleryClose = () => { + setIsGalleryModalOpen(false); + setSelectedGalleryImages([]); + }; + + const handleImageSelect = (id: string) => { + setSelectedGalleryImages((prev) => { + if (prev.includes(id)) { + return prev.filter((imageId) => imageId !== id); + } + if (prev.length >= 4) { + return prev; + } + return [...prev, id]; + }); + }; + + const handleGalleryImages = (selectedItems: GalleryItem[]) => { + selectedItems.forEach((item) => { + if (!item.fullImage) return; + const referenceImage: ReferenceImage = { + id: Math.random().toString(36).substring(7), + url: item.fullImage, + file: new File([], "library-image"), + mediaToken: item.id, + }; + setReferenceImages((prev) => [...prev, referenceImage]); + }); + setIsGalleryModalOpen(false); + setSelectedGalleryImages([]); }; const handleAction = (action: string) => { @@ -162,8 +200,8 @@ export const PromptBox = () => { case "upload": handleUploadClick(); break; - case "library": - handleLibrarySelect(); + case "gallery": + handleGallerySelect(); break; default: console.log("Unknown action:", action); @@ -292,7 +330,7 @@ export const PromptBox = () => { ); const isDesktop = IsDesktopApp(); - console.log('Is this a desktop app?', isDesktop); + console.log("Is this a desktop app?", isDesktop); if (isDesktop) { handleTauriEnqueue(); @@ -324,158 +362,176 @@ export const PromptBox = () => { }; return ( -
- {(referenceImages.length > 0 || uploadingImages.length > 0) && ( -
- {referenceImages.map((image) => ( -
- Reference - -
- ))} - {uploadingImages.map(({ id, file }) => { - const previewUrl = URL.createObjectURL(file); - return ( + <> +
+ {(referenceImages.length > 0 || uploadingImages.length > 0) && ( +
+ {referenceImages.map((image) => (
-
- Uploading preview + Reference + +
+ ))} + {uploadingImages.map(({ id, file }) => { + const previewUrl = URL.createObjectURL(file); + return ( +
+
+ Uploading preview +
+
+ +
-
+ ); + })} +
+ )} +
+ +
+ , + action: "upload", + }, + { + label: "Choose from library", + selected: false, + icon: , + action: "gallery", + }, + ]} + onPanelAction={handleAction} + showIconsInList + buttonClassName="backdrop-blur-none bg-transparent hover:bg-transparent py-1.5 px-0 pr-1 m-0 hover:opacity-50 transition-opacity duration-100 ring-0 border-none focus:ring-0 outline-none" + triggerIcon={ + + } + /> + +