From 66d5095f69a543be206de02192da89b56bf39d22 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Thu, 10 Apr 2025 12:33:42 +0700 Subject: [PATCH] many asset modal changes and sidebar removal --- .../pages/PageEnigma/DragAndDrop/DndAsset.ts | 11 ++ .../app/pages/PageEnigma/PageEditor.tsx | 10 +- .../PageEnigma/comps/AssetMenu/AssetMenu.tsx | 10 +- .../PageEnigma/comps/AssetMenu/AssetModal.tsx | 121 +++++++++++++++--- .../comps/SceneContainer/SceneContainer.tsx | 10 +- .../SidePanelTabs/sharedComps/ItemElement.tsx | 2 +- .../pages/PageEnigma/signals/assetModal.ts | 4 + .../app/pages/PageEnigma/signals/index.ts | 1 + 8 files changed, 133 insertions(+), 36 deletions(-) create mode 100644 frontend/editor3d/app/pages/PageEnigma/signals/assetModal.ts diff --git a/frontend/editor3d/app/pages/PageEnigma/DragAndDrop/DndAsset.ts b/frontend/editor3d/app/pages/PageEnigma/DragAndDrop/DndAsset.ts index 9add5bb681..88f3aaaf02 100644 --- a/frontend/editor3d/app/pages/PageEnigma/DragAndDrop/DndAsset.ts +++ b/frontend/editor3d/app/pages/PageEnigma/DragAndDrop/DndAsset.ts @@ -13,6 +13,8 @@ import { overTimeline, sidePanelWidth, timelineHeight, + assetModalVisibleDuringDrag, + reopenAfterDragSignal, } from "~/pages/PageEnigma/signals"; import { pageHeight, pageWidth } from "~/signals"; import { addShape } from "~/pages/PageEnigma/signals/shape"; @@ -42,6 +44,7 @@ class DndAsset { this.initY = event.pageY; canDrop.value = false; this.notDropText = ""; + assetModalVisibleDuringDrag.value = false; window.addEventListener("pointerup", this.onPointerUp); window.addEventListener("pointermove", this.onPointerMove); } @@ -54,6 +57,14 @@ class DndAsset { this.overElement = null; overTimeline.value = false; this.notDropText = ""; + if (reopenAfterDragSignal.value) { + assetModalVisibleDuringDrag.value = true; + } else { + assetModalVisibleDuringDrag.value = true; + setTimeout(() => { + assetModalVisibleDuringDrag.value = false; + }, 0); + } } } diff --git a/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx b/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx index afa8c6b48b..b7d1538aaa 100644 --- a/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx +++ b/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx @@ -23,7 +23,6 @@ import { } from "~/pages/PageEnigma/signals"; import { EditorCanvas } from "./comps/EngineCanvases"; import { SceneContainer } from "./comps/SceneContainer"; -import { AspectRatioMenu } from "./comps/AspectRatioMenu"; import { Outliner } from "./comps/Outliner"; import { CameraAspectRatio } from "./enums"; import { PromptBox } from "./comps/PromptBox"; @@ -95,7 +94,6 @@ export const PageEditor = () => { className="flex" style={{ height, - width, }} >
@@ -136,10 +134,12 @@ export const PageEditor = () => {
- + + + { {/* Side panel */} -
+ {/*
-
+
*/} {/* Timeline */} diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx index ba8ea8b22d..1114003d17 100644 --- a/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx +++ b/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx @@ -2,6 +2,7 @@ import { faCube, faMagicWandSparkles } from "@fortawesome/pro-solid-svg-icons"; import { Button, Tooltip } from "~/components"; import { useState } from "react"; import { AssetModal } from "./AssetModal"; +import { assetModalVisibleDuringDrag } from "../../signals"; export const AssetMenu = () => { const [isModalOpen, setIsModalOpen] = useState(false); @@ -11,6 +12,11 @@ export const AssetMenu = () => { console.log("Adding asset..."); }; + const handleOpenModal = () => { + assetModalVisibleDuringDrag.value = true; + setIsModalOpen(true); + }; + return ( <>
@@ -18,7 +24,7 @@ export const AssetMenu = () => {
diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx index 6b04a87a31..f84b4454f1 100644 --- a/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx +++ b/frontend/editor3d/app/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx @@ -3,16 +3,30 @@ import { faPlus, faSearch, faChevronRight, + faChevronLeft, + faLayerGroup, + faUser, + faSun, + faTree, + faCube, } from "@fortawesome/pro-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button, CloseButton, Input, Tooltip } from "~/components"; import { TabSelector } from "~/components/reusable/TabSelector"; -import { useState, useEffect, useMemo } from "react"; +import { useState, useEffect, useMemo, useRef } from "react"; import { ItemElements } from "../SidePanelTabs/sharedComps/ItemElements"; -import { demoSkyboxItems, demoShapeItems } from "../../signals"; +import { + demoSkyboxItems, + demoShapeItems, + demoCharacterItems, + assetModalVisibleDuringDrag, + reopenAfterDragSignal, +} from "../../signals"; import { MediaItem } from "../../models"; import { useUserObjects, useFeaturedObjects } from "../SidePanelTabs/hooks"; import { FilterEngineCategories } from "~/enums"; +import { twMerge } from "tailwind-merge"; +import { useSignals } from "@preact/signals-react/runtime"; interface AssetModalProps { isOpen: boolean; @@ -23,6 +37,7 @@ interface AssetModalProps { type AssetTab = { id: string; label: string; + icon: typeof faLayerGroup; engineCategory?: FilterEngineCategories; items: MediaItem[]; }; @@ -36,9 +51,9 @@ const AllTabSection = ({ items: MediaItem[]; onViewAll: () => void; }) => ( -
+
-

{label}

+

{label}

-
+
{ + useSignals(); const [activeLibraryTab, setActiveLibraryTab] = useState("library"); const [activeAssetTab, setActiveAssetTab] = useState("all"); const [searchTerm, setSearchTerm] = useState(""); + const [reopenAfterAdd, setReopenAfterAdd] = useState(true); + const searchInputRef = useRef(null); + + // Update the signal when the preference changes + useEffect(() => { + reopenAfterDragSignal.value = reopenAfterAdd; + }, [reopenAfterAdd]); + + useEffect(() => { + if (isOpen) { + // Small delay to ensure the modal is fully mounted + const timer = setTimeout(() => { + searchInputRef.current?.focus(); + }, 100); + return () => clearTimeout(timer); + } + }, [isOpen]); // Fetch objects for different categories const { userObjects: userCharacters } = useUserObjects({ @@ -103,25 +136,29 @@ export const AssetModal = ({ { id: "mine", label: "Mine" }, ]; + // eslint-disable-next-line react-hooks/exhaustive-deps const assetTabs: AssetTab[] = [ - { id: "all", label: "All", items: [] }, + { id: "all", label: "All", icon: faLayerGroup, items: [] }, { id: "character", label: "Character", + icon: faUser, engineCategory: FilterEngineCategories.CHARACTER, items: activeLibraryTab === "library" - ? (featuredCharacters ?? []) + ? [...demoCharacterItems.value, ...(featuredCharacters ?? [])] : (userCharacters ?? []), }, { id: "skybox", label: "Skybox", + icon: faSun, items: demoSkyboxItems.value, }, { id: "nature", label: "Nature", + icon: faTree, engineCategory: FilterEngineCategories.SET_DRESSING, items: activeLibraryTab === "library" @@ -131,6 +168,7 @@ export const AssetModal = ({ { id: "objects", label: "Objects", + icon: faCube, engineCategory: FilterEngineCategories.OBJECT, items: activeLibraryTab === "library" @@ -171,12 +209,13 @@ export const AssetModal = ({ if (searchTerm && activeAssetTab !== "all") { setActiveAssetTab("all"); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchTerm]); const renderContent = () => { if (activeAssetTab === "all" && !searchTerm) { return ( -
+
{assetTabs.slice(1).map((tab) => ( { + onAddAsset(); + if (reopenAfterAdd) { + // Small delay to allow the modal to close and reopen + setTimeout(() => { + onClose(); + }, 100); + } else { + onClose(); + } + }; + return (
-
+

3D Assets


-
+
{assetTabs.map((tab) => ( ))}
+
+ setReopenAfterAdd(e.target.checked)} + className="h-4 w-4 rounded-lg border-gray-300 bg-gray-700 text-brand-primary focus:ring-brand-primary" + /> + +
-
+
-
+
-
+
+ {activeAssetTab !== "all" && !searchTerm && ( +
+ + {currentTab.label} +
+ )} {renderContent()}
-
- -
diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/SceneContainer/SceneContainer.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/SceneContainer/SceneContainer.tsx index c71d6f259e..fb52a50062 100644 --- a/frontend/editor3d/app/pages/PageEnigma/comps/SceneContainer/SceneContainer.tsx +++ b/frontend/editor3d/app/pages/PageEnigma/comps/SceneContainer/SceneContainer.tsx @@ -1,12 +1,7 @@ import { useCallback, useContext } from "react"; import { useSignals } from "@preact/signals-react/runtime"; import { pageHeight, pageWidth } from "~/signals"; -import { - editorLetterBox, - timelineHeight, - sidePanelWidth, - sidePanelVisible, -} from "~/pages/PageEnigma/signals"; +import { editorLetterBox, timelineHeight } from "~/pages/PageEnigma/signals"; import { EngineContext } from "~/pages/PageEnigma/contexts/EngineContext"; import { Letterbox } from "./Letterbox"; @@ -14,8 +9,7 @@ export const SceneContainer = ({ children }: { children: React.ReactNode }) => { useSignals(); const editorEngine = useContext(EngineContext); - const containerWidth = - pageWidth.value - (sidePanelVisible.value ? sidePanelWidth.value : 0) - 84; + const containerWidth = pageWidth.value; const containerHeight = pageHeight.value - timelineHeight.value - 64; diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/SidePanelTabs/sharedComps/ItemElement.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/SidePanelTabs/sharedComps/ItemElement.tsx index 819f3167d4..2c1cf89464 100644 --- a/frontend/editor3d/app/pages/PageEnigma/comps/SidePanelTabs/sharedComps/ItemElement.tsx +++ b/frontend/editor3d/app/pages/PageEnigma/comps/SidePanelTabs/sharedComps/ItemElement.tsx @@ -66,7 +66,7 @@ export const ItemElement = ({ item }: Props) => { /> )}
-
+
{item.name || item.media_id}
diff --git a/frontend/editor3d/app/pages/PageEnigma/signals/assetModal.ts b/frontend/editor3d/app/pages/PageEnigma/signals/assetModal.ts new file mode 100644 index 0000000000..b66116b5d2 --- /dev/null +++ b/frontend/editor3d/app/pages/PageEnigma/signals/assetModal.ts @@ -0,0 +1,4 @@ +import { signal } from "@preact/signals-react"; + +export const assetModalVisibleDuringDrag = signal(true); +export const reopenAfterDragSignal = signal(true); diff --git a/frontend/editor3d/app/pages/PageEnigma/signals/index.ts b/frontend/editor3d/app/pages/PageEnigma/signals/index.ts index e3c2a1d293..f348ce199e 100644 --- a/frontend/editor3d/app/pages/PageEnigma/signals/index.ts +++ b/frontend/editor3d/app/pages/PageEnigma/signals/index.ts @@ -18,3 +18,4 @@ export * from "./stylizeTab"; export * from "./timing"; export * from "./timeline"; export * from "./error"; +export * from "./assetModal";