From 562cb99c512ee36f368fdf42c66ac1ed2cf04a8c Mon Sep 17 00:00:00 2001 From: BFlat Date: Fri, 9 May 2025 21:53:58 +0700 Subject: [PATCH] 2d editor fixes (#596) - left toolbar now updates properly - modals open properly - styling fixes - adjusted canvas center positioning to accommodate top header bar --- .../RenderingPrimitives/RealTimeDrawEngine.ts | 74 ++++++------ .../src/pages/Page2d/KonvaCanvasContainer.tsx | 4 +- .../src/pages/Page2d/KonvaRootComponent.tsx | 112 ++++++++++++------ .../app/src/pages/Page2d/SignaledDialogs.tsx | 2 - .../src/pages/Page2d/SignaledToolbarMain.tsx | 3 +- .../DialogAddImage/DialogAddImage.tsx | 69 +++++------ .../DialogEditText/DialogEditText.tsx | 46 +++---- .../features/ToolbarMain/ToolbarMain.tsx | 24 ++-- .../app/src/pages/Page2d/components/styles.ts | 2 +- .../pages/Page2d/components/ui/ComboBox.tsx | 4 +- .../Page2d/components/ui/TextEditor/styles.ts | 4 +- .../uiAccess/toolbarMain/toolbarMain.ts | 4 +- .../app/src/pages/PageEnigma/PageEditor.tsx | 37 +++--- .../promptbox/src/lib/PromptBox2D.tsx | 52 ++++---- 14 files changed, 245 insertions(+), 192 deletions(-) diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaApp/RenderingPrimitives/RealTimeDrawEngine.ts b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaApp/RenderingPrimitives/RealTimeDrawEngine.ts index 72e42ba702..fc0f4abe94 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaApp/RenderingPrimitives/RealTimeDrawEngine.ts +++ b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaApp/RenderingPrimitives/RealTimeDrawEngine.ts @@ -3,11 +3,16 @@ import { invoke } from "@tauri-apps/api/core"; import { listen } from "@tauri-apps/api/event"; import { FileUtilities } from "../../utilities/FileUtilities"; -import { ImageNode, TextNode, ShapeNode, PreviewCopyNode, PaintNode } from "../Nodes"; +import { + ImageNode, + TextNode, + ShapeNode, + PreviewCopyNode, + PaintNode, +} from "../Nodes"; import { MediaNode } from "../types"; import { RenderTask } from "./RenderTask"; - import { isLoadingVisible, loadingProgress, @@ -22,7 +27,6 @@ interface ServerSettings { } export class RealTimeDrawEngine { - private imageNodes: (ImageNode | TextNode | ShapeNode | PaintNode)[]; public offScreenCanvas: OffscreenCanvas; @@ -45,7 +49,6 @@ export class RealTimeDrawEngine { public captureCanvas: Konva.Rect; public backgroundRasterRect: Konva.Image; - public fps: number = 24; public currentPrompt: string; @@ -97,10 +100,9 @@ export class RealTimeDrawEngine { ) => void; onPreviewCopyCallback?: (previewCopy: Konva.Image) => void; // New Parameter }) { - this.imageNodes = []; this.onDrawCallback = onDraw; - + // TODO: Make this dynamic and update this on change of canvas. this.width = width * 1.5; this.height = height * 1; @@ -108,7 +110,6 @@ export class RealTimeDrawEngine { this.positionX = window.innerWidth - this.width; this.positionY = window.innerHeight - this.height; - this.offScreenCanvas = offScreenCanvas; this.offScreenCanvas.width = this.width; this.offScreenCanvas.height = this.height; @@ -150,7 +151,6 @@ export class RealTimeDrawEngine { this.mediaLayerRef.add(this.captureCanvas); this.captureCanvas.setZIndex(0); - this.listenToServerEvents(); } @@ -520,7 +520,8 @@ export class RealTimeDrawEngine { // Calculate new position to center the canvas in the window this.positionX = (window.innerWidth - this.width) / 2; - this.positionY = (window.innerHeight - this.height) / 2; + const headerPadding = 56; + this.positionY = (window.innerHeight - headerPadding - this.height) / 2; console.log("New centered position:", this.positionX, this.positionY); @@ -636,7 +637,6 @@ export class RealTimeDrawEngine { public isProcessing = false; private handleNodeDragEnd = async () => { // Clean up any existing state - //await this.render(); }; @@ -662,7 +662,7 @@ export class RealTimeDrawEngine { } public removeNodes(node: MediaNode) { - if ( + if ( node instanceof ImageNode || node instanceof TextNode || node instanceof ShapeNode || @@ -819,7 +819,6 @@ export class RealTimeDrawEngine { await this.startServer(); } - private async renderFrame(config: { layerOfInterest: Konva.Layer; // layer where the element that you want to clip lives. // XY and height of a captureCanvas ( region of interest ) @@ -832,38 +831,33 @@ export class RealTimeDrawEngine { quality?: number; // 1.0 is the best. test: boolean; // true == blob else Image Bitmap }): Promise { - - const box = config.layerOfInterest.getClientRect(); - const stage = config.layerOfInterest.getStage(); + const box = config.layerOfInterest.getClientRect(); + const stage = config.layerOfInterest.getStage(); - const x = config.x !== undefined ? config.x : Math.floor(box.x); - const y = config.y !== undefined ? config.y : Math.floor(box.y); - const pixelRatio = config.pixelRatio || 1; + const x = config.x !== undefined ? config.x : Math.floor(box.x); + const y = config.y !== undefined ? config.y : Math.floor(box.y); + const pixelRatio = config.pixelRatio || 1; - // Clone the required layer from the stage - // Set the right details (like removing highlight stroke) - // Then render the cloned stage to a bitmap - const stageClone = this.cloneStageForRender( - stage, - config.layerOfInterest, - ); - const stageBlob = (await stageClone.toBlob({ - x: x, - y: y, - width: config.width || Math.ceil(box.width), - height: config.height || Math.ceil(box.height), - pixelRatio: pixelRatio, - })) as Blob; + // Clone the required layer from the stage + // Set the right details (like removing highlight stroke) + // Then render the cloned stage to a bitmap + const stageClone = this.cloneStageForRender(stage, config.layerOfInterest); + const stageBlob = (await stageClone.toBlob({ + x: x, + y: y, + width: config.width || Math.ceil(box.width), + height: config.height || Math.ceil(box.height), + pixelRatio: pixelRatio, + })) as Blob; - // if config.test is true, the result is downloaded to the local files - // config.test = true; - if (config.test) { - await FileUtilities.blobToFileJpeg(stageBlob, "1"); - } - - const result = await createImageBitmap(stageBlob); - return result; + // if config.test is true, the result is downloaded to the local files + // config.test = true; + if (config.test) { + await FileUtilities.blobToFileJpeg(stageBlob, "1"); + } + const result = await createImageBitmap(stageBlob); + return result; } // Add method to create or update background diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaCanvasContainer.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaCanvasContainer.tsx index 0c291ebefa..c8728921e0 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaCanvasContainer.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaCanvasContainer.tsx @@ -9,6 +9,8 @@ export const KonvaCanvasContainer = forwardRef< >(({ className, ...props }, ref) => { // useRenderCounter("KonvaCanvasContainer"); - const classes = twMerge("pegboard -z-10", className); + const classes = twMerge("pegboard -z-10", "h-[calc(100vh-56px)]", className); return
; }); + +KonvaCanvasContainer.displayName = "KonvaCanvasContainer"; diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaRootComponent.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaRootComponent.tsx index 933c0260a7..413e8cbe26 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/KonvaRootComponent.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/KonvaRootComponent.tsx @@ -4,7 +4,7 @@ import { useCallback, useRef, useState } from "react"; import { KonvaCanvasContainer } from "./KonvaCanvasContainer"; import { ContextualToolbarNode } from "./ContextualToolbarNode"; // import { SignaledCanvasDragDropFiles } from "./SignaledCanvasDragDropFiles"; -import { SignaledDialogs } from "./SignaledDialogs"; +// import { SignaledDialogs } from "./SignaledDialogs"; import { SignaledToolbarMain } from "./SignaledToolbarMain"; // The KonvaApp is the root of the Konva stage @@ -33,7 +33,17 @@ import { uploadImage } from "../../components/reusable/UploadModalMedia/uploadIm // import { EncodeImageBitmapToBase64 } from "./utilities/EncodeImageBitmapToBase64"; import { JobProvider, useJobContext } from "./JobContext"; import { RealTimeDrawEngine } from "./KonvaApp/RenderingPrimitives/RealTimeDrawEngine"; -import { VideoResolutions } from "./KonvaApp/constants"; +// import { VideoResolutions } from "./KonvaApp/constants"; + +import { + DialogAddImage, + DialogEditText, + DialogError, +} from "./components/features"; +import { dispatchUiEvents } from "./signals"; +import { useSignals } from "@preact/signals-react/runtime"; +import { dialogError } from "./signals/uiAccess/dialogError"; + export const KonvaRootComponent = ({ className, sceneToken, @@ -41,6 +51,7 @@ export const KonvaRootComponent = ({ className: string; sceneToken?: string; }) => { + useSignals(); // This is a hook that will log the number of times the component has rerendered // Let's make sure we only log once useRenderCounter("KonvaRootComponent"); @@ -53,29 +64,38 @@ export const KonvaRootComponent = ({ const engineRef = useRef(null); const renderEngineRef = useRef(null); - const konvaContainerCallbackRef = useCallback((node: HTMLDivElement) => { - // Only initialize if we have a node and haven't initialized yet - if (node !== null && !isEngineReady && engineRef.current === null) { - try { - const options = { - navigate: navigate, - sceneToken: sceneToken, - }; - + const konvaContainerCallbackRef = useCallback( + (node: HTMLDivElement) => { + // Only initialize if we have a node and haven't initialized yet + if (node !== null && !isEngineReady && engineRef.current === null) { + try { + const options = { + navigate: navigate, + sceneToken: sceneToken, + }; - engineRef.current = KonvaApp(node, options); - renderEngineRef.current = engineRef.current.realTimeDrawEngine; - // Only set ready if initialization succeeded - if (engineRef.current) { - setIsEngineReady(true); + engineRef.current = KonvaApp(node, options); + renderEngineRef.current = engineRef.current.realTimeDrawEngine; + // Only set ready if initialization succeeded + if (engineRef.current) { + setIsEngineReady(true); + } + } catch (error) { + console.error("Failed to initialize KonvaApp:", error); + engineRef.current = null; + setIsEngineReady(false); } - } catch (error) { - console.error("Failed to initialize KonvaApp:", error); - engineRef.current = null; - setIsEngineReady(false); } - } - }, [navigate, sceneToken, isEngineReady]); + }, + [navigate, sceneToken, isEngineReady], + ); + + // Modal stuff + const props = dialogError.signal.value; + const { isShowing, title, message } = props; + const onClose = useCallback(() => { + dialogError.hide(); + }, []); return ( <> @@ -95,7 +115,6 @@ export const KonvaRootComponent = ({ {/* Conditionally render the UI components that need the engine */} {isEngineReady && engineRef.current && ( - {/* { - // will set the snapshot of the canvas internally. - await renderEngineRef.current?.render(); - }} - /> - + EncodeImageBitmapToBase64={EncodeImageBitmapToBase64} + useJobContext={useJobContext} + onEnqueuePressed={async () => { + // will set the snapshot of the canvas internally. + await renderEngineRef.current?.render(); + }} + />{" "} + + - + /> */} )} + + {/* Modals */} + + { + dispatchUiEvents.addTextToEngine(data); + }} + closeCallback={appUiContext.resetAll} + /> + + { + dispatchUiEvents.addImageToEngine(file); + }} + /> + + ); }; diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/SignaledDialogs.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/SignaledDialogs.tsx index d9f8709def..a00db1d47c 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/SignaledDialogs.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/SignaledDialogs.tsx @@ -6,11 +6,9 @@ import { DialogEditText, DialogError, } from "./components/features"; - import { AppUiSignalType } from "./contextSignals/appUi"; import { dialogError } from "./signals/uiAccess/dialogError"; - export const SignaledDialogs = ({ appUiSignal, resetAll, diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/SignaledToolbarMain.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/SignaledToolbarMain.tsx index e8188b8393..0cf18508d1 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/SignaledToolbarMain.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/SignaledToolbarMain.tsx @@ -13,6 +13,7 @@ import { AppUiContextInterface } from "./contextSignals/appUi"; import { twMerge } from "tailwind-merge"; import { paperWrapperStyles } from "./components/styles"; import { dispatchUiEvents } from "./signals/uiEvents"; +import { useSignals } from "@preact/signals-react/runtime"; export const SignaledToolbarMain = ({ // layoutSignal, @@ -21,7 +22,7 @@ export const SignaledToolbarMain = ({ layoutSignal: LayoutSignalType; appUiContext: AppUiContextInterface; }) => { - + useSignals(); const loadingBar = toolbarMain.loadingBar.signal.value; const getButtonDispatcher = (buttonName: ToolbarMainButtonNames) => { switch (buttonName) { diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogAddImage/DialogAddImage.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogAddImage/DialogAddImage.tsx index 596c18145f..d017af7d3d 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogAddImage/DialogAddImage.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogAddImage/DialogAddImage.tsx @@ -6,8 +6,7 @@ import { FileUploader } from "../../../components/reusable/FileUploader"; import { Button } from "@storyteller/ui-button"; import { IMAGE_FILE_TYPE } from "../../../constants/fileTypeEnums"; - -import { BaseDialog } from "../../../components/ui/BaseDialog"; +import { Modal } from "@storyteller/ui-modal"; export const DialogAddImage = ({ stagedImage = null, @@ -39,38 +38,40 @@ export const DialogAddImage = ({ } return ( - - Upload Image -
- { - setAssetFile(file); - if (file) { - onAddImage(file); - handleClose(); - } - }} - /> - {currFile && ( -
- -
- )} + +
+ Upload Image +
+ { + setAssetFile(file); + if (file) { + onAddImage(file); + handleClose(); + } + }} + /> + {currFile && ( +
+ upload img +
+ )} +
+
+ +
-
- -
- +
); }; diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogEditText/DialogEditText.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogEditText/DialogEditText.tsx index e1587ca10d..e60062ec18 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogEditText/DialogEditText.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/DialogEditText/DialogEditText.tsx @@ -31,14 +31,12 @@ export type TextNodeData = { text: string; } & TextFormatData; - import { useState } from "react"; import { DialogTitle } from "@headlessui/react"; import { Button, TextEditor } from "../../../components/ui"; -import { BaseDialog } from "../../../components/ui/BaseDialog"; - +import { Modal } from "@storyteller/ui-modal"; export const DialogEditText = ({ isOpen, @@ -92,26 +90,28 @@ export const DialogEditText = ({ closeCallback(); }; return ( - - Edit Text - -
- - + +
+ Edit Text + +
+ + +
- +
); }; diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/ToolbarMain/ToolbarMain.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/ToolbarMain/ToolbarMain.tsx index ece0f8320e..f428fc5911 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/components/features/ToolbarMain/ToolbarMain.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/components/features/ToolbarMain/ToolbarMain.tsx @@ -2,10 +2,8 @@ import { faArrowRotateLeft, faArrowRotateRight, faCircle, - faEraser, faFilePlus, faImage, - faImages, faLocationArrow, faPaintbrush, faShapes, @@ -19,18 +17,18 @@ import { Fragment, MouseEventHandler } from "react"; import { twMerge } from "tailwind-merge"; import { ToolbarButton } from "../../../components/features/ToolbarButton"; -import { Tooltip } from "~/components/ui/Tooltip"; +// import { Tooltip } from "~/components/ui/Tooltip"; // style and constants import { paperWrapperStyles, toolTipStyles } from "../../../components/styles"; import { ToolbarMainButtonNames } from "./enum"; -import { dispatchUiEvents, uiEvents } from "../../../signals/uiEvents"; +import { dispatchUiEvents } from "../../../signals/uiEvents"; import { paintColor } from "../../../signals/uiEvents/toolbarMain/paintMode"; -import { ColorPicker } from "../../../components/ui/TextEditor/ColorPicker"; +// import { ColorPicker } from "../../../components/ui/TextEditor/ColorPicker"; import { PaintModeMenu } from "../../../components/ui/ToolbarMain/PaintModeMenu"; -import { EraseModeMenu } from "../../../components/ui/ToolbarMain/EraseModeMenu"; -import { BackgroundMenu } from "../../../components/ui/ToolbarMain/BackgroundMenu"; -import { bgColor } from "../../../signals/uiEvents/toolbarMain/backgroundMenu"; +// import { EraseModeMenu } from "../../../components/ui/ToolbarMain/EraseModeMenu"; +// import { BackgroundMenu } from "../../../components/ui/ToolbarMain/BackgroundMenu"; +// import { bgColor } from "../../../signals/uiEvents/toolbarMain/backgroundMenu"; export const ToolbarMain = ({ disabled = false, @@ -53,7 +51,7 @@ export const ToolbarMain = ({ paperWrapperStyles, "glass", disabled && - "pointer-events-none cursor-default bg-ui-border shadow-md", + "bg-ui-border pointer-events-none cursor-default shadow-md", )} >
@@ -234,11 +232,11 @@ export const ToolbarMain = ({ /> */}
-
+ {/*
- {/* +
-
*/} +
-
+
*/}
); diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/components/styles.ts b/frontend/apps/editor3d/app/src/pages/Page2d/components/styles.ts index c5a4a9d8b7..63586988fe 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/components/styles.ts +++ b/frontend/apps/editor3d/app/src/pages/Page2d/components/styles.ts @@ -1,7 +1,7 @@ import { twMerge } from "tailwind-merge"; export const paperWrapperStyles = - "rounded-xl border border-ui-border p-1.5 shadow-lg bg-ui-panel"; + "rounded-xl border border-ui-panel-border p-1.5 shadow-lg bg-ui-background"; export const transitionTimingStyles = "transition duration-150 ease-in-out"; diff --git a/frontend/apps/editor3d/app/src/pages/Page2d/components/ui/ComboBox.tsx b/frontend/apps/editor3d/app/src/pages/Page2d/components/ui/ComboBox.tsx index 9c5b8c3889..88cc8a25cb 100644 --- a/frontend/apps/editor3d/app/src/pages/Page2d/components/ui/ComboBox.tsx +++ b/frontend/apps/editor3d/app/src/pages/Page2d/components/ui/ComboBox.tsx @@ -29,7 +29,7 @@ export const Combobox = ({ options, value, onChange }: ComboBoxInterface) => { onChange={onChange} onClose={() => setQuery("")} > -
+
font} @@ -41,7 +41,7 @@ export const Combobox = ({ options, value, onChange }: ComboBoxInterface) => {
{filteredOptions.map((option, idx) => ( {
- - {}} - videoSrc2D="/resources/videos/artcraft-canvas-demo.mp4" - videoSrc3D="/resources/videos/artcraft-3d-demo.mp4" - openAiLogo="/resources/images/openai-logo.png" - onOpenChange={(isOpen: boolean) => { - if (isOpen) { - disableHotkeyInput(DomLevels.DIALOGUE); - } else { - enableHotkeyInput(DomLevels.DIALOGUE); - } - }} - onArtCraftAuthSuccess={(userInfo: any) => { - authentication.status.value = AUTH_STATUS.LOGGED_IN; - authentication.userInfo.value = userInfo; - }} - /> ); }; @@ -382,7 +364,26 @@ export const PageEditor = () => { appTabIdSignal={appTabId} setAppTabId={setAppTabId} /> + {appTabId.value === "3D" ? : } + + {}} + videoSrc2D="/resources/videos/artcraft-canvas-demo.mp4" + videoSrc3D="/resources/videos/artcraft-3d-demo.mp4" + openAiLogo="/resources/images/openai-logo.png" + onOpenChange={(isOpen: boolean) => { + if (isOpen) { + disableHotkeyInput(DomLevels.DIALOGUE); + } else { + enableHotkeyInput(DomLevels.DIALOGUE); + } + }} + onArtCraftAuthSuccess={(userInfo: any) => { + authentication.status.value = AUTH_STATUS.LOGGED_IN; + authentication.userInfo.value = userInfo; + }} + /> ); }; diff --git a/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx b/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx index 63e58c0388..d14d6f1565 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBox2D.tsx @@ -2,7 +2,12 @@ import { useState, useRef, useEffect } from "react"; import { invoke } from "@tauri-apps/api/core"; import { useSignals } from "@preact/signals-react/runtime"; import { toast } from "sonner"; -import { JobContextType, MaybeCanvasRenderBitmapType, UploaderState, UploaderStates } from "@storyteller/common"; +import { + JobContextType, + MaybeCanvasRenderBitmapType, + UploaderState, + UploaderStates, +} from "@storyteller/common"; import { downloadFileFromUrl } from "@storyteller/api"; import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover"; import { Tooltip } from "@storyteller/ui-tooltip"; @@ -36,14 +41,18 @@ interface ReferenceImage { } interface PromptBox2DProps { - uploadImage: ({ title, assetFile, progressCallback, }: { + uploadImage: ({ + title, + assetFile, + progressCallback, + }: { title: string; assetFile: File; progressCallback: (newState: UploaderState) => void; }) => Promise; - getCanvasRenderBitmap: () => MaybeCanvasRenderBitmapType - EncodeImageBitmapToBase64: (imageBitmap: ImageBitmap) => Promise - useJobContext: () => JobContextType + getCanvasRenderBitmap: () => MaybeCanvasRenderBitmapType; + EncodeImageBitmapToBase64: (imageBitmap: ImageBitmap) => Promise; + useJobContext: () => JobContextType; onEnqueuePressed?: () => void | Promise; } @@ -55,7 +64,7 @@ export const PromptBox2D = ({ onEnqueuePressed, }: PromptBox2DProps) => { useSignals(); - + console.log("Is this a desktop app?", IsDesktopApp()); const [isModalOpen, setIsModalOpen] = useState(false); const [content, setContent] = useState(""); @@ -68,7 +77,7 @@ export const PromptBox2D = ({ const [useSystemPrompt, setUseSystemPrompt] = useState(true); const [isGalleryModalOpen, setIsGalleryModalOpen] = useState(false); const [selectedGalleryImages, setSelectedGalleryImages] = useState( - [], + [] ); const [activeGalleryTab, setActiveGalleryTab] = useState("my-media"); const [referenceImages, setReferenceImages] = useState([]); @@ -108,7 +117,7 @@ export const PromptBox2D = ({ prev.map((item) => ({ ...item, selected: item.label === selectedItem.label, - })), + })) ); }; @@ -122,7 +131,9 @@ export const PromptBox2D = ({ const reader = new FileReader(); reader.onloadend = () => { uploadImage({ - title: `reference-image-${Math.random().toString(36).substring(2, 15)}`, + title: `reference-image-${Math.random() + .toString(36) + .substring(2, 15)}`, assetFile: file, progressCallback: (newState) => { console.debug("Upload progress:", newState.data); @@ -135,7 +146,7 @@ export const PromptBox2D = ({ }; setReferenceImages((prev) => [...prev, referenceImage]); setUploadingImages((prev) => - prev.filter((img) => img.id !== uploadId), + prev.filter((img) => img.id !== uploadId) ); toast.success("Reference image added."); } else if ( @@ -143,7 +154,7 @@ export const PromptBox2D = ({ newState.status === UploaderStates.imageCreateError ) { setUploadingImages((prev) => - prev.filter((img) => img.id !== uploadId), + prev.filter((img) => img.id !== uploadId) ); toast.error("Upload failed. Please try again."); @@ -266,7 +277,7 @@ export const PromptBox2D = ({ disable_system_prompt: !useSystemPrompt, prompt: prompt, maybe_additional_images: referenceImages.map( - (image) => image.mediaToken, + (image) => image.mediaToken ), maybe_number_of_samples: 1, }, @@ -279,12 +290,11 @@ export const PromptBox2D = ({ const api = new PromptsApi(); // to take the snapshot of the canvas // Call onEnqueuePressed if it exists - - + let image = getCanvasRenderBitmap(); if (image === undefined) { toast.error( - "Error: Unable to generate image. Please check the input and try again.", + "Error: Unable to generate image. Please check the input and try again." ); return; } @@ -350,7 +360,7 @@ export const PromptBox2D = ({ "Enqueuing with prompt:", prompt, "and reference images:", - referenceImages, + referenceImages ); const isDesktop = IsDesktopApp(); @@ -364,7 +374,7 @@ export const PromptBox2D = ({ } catch (error) { console.error("Error during image generation:", error); toast.error( - "An error occurred while generating the image. Please try again.", + "An error occurred while generating the image. Please try again." ); } finally { await new Promise((resolve) => setTimeout(resolve, 100)); @@ -382,7 +392,7 @@ export const PromptBox2D = ({ const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); - + handleEnqueue(); } }; @@ -473,7 +483,7 @@ export const PromptBox2D = ({ ]} 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" + buttonClassName="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={ } @@ -488,8 +498,8 @@ export const PromptBox2D = ({ onChange={handleChange} onPaste={handlePaste} onKeyDown={handleKeyDown} - onFocus={() => { }} - onBlur={() => { }} + onFocus={() => {}} + onBlur={() => {}} />