From 21d36179705d4ef3e79cbcfc8c6599bdce596e62 Mon Sep 17 00:00:00 2001 From: Tanish Manku Date: Tue, 28 Apr 2026 23:13:57 -0700 Subject: [PATCH] PageEnigma refactor Phase 5c: migrate assetModal signal slice to the store assetModal.ts (deleted): - AssetMenu: setAssetModalVisibleDuringDrag(true) on open - AssetModal: reads assetModalVisible / assetModalVisibleDuringDrag / reopenAfterDrag from the store, writes via the matching setters. Modal close drives setAssetModalVisible(false); the reopen-after-add checkbox writes through setReopenAfterDrag (note: store field is reopenAfterDrag, not the old reopenAfterDragSignal name) - Controls3D: handleOpenModal flips both setters from the store; the empty-scene tooltip useEffect reads assetModalVisible from the store - keybinds_controls: 'b' shortcut opens the asset modal via the store - DragAndDrop/DndAsset: pointerdown clears assetModalVisibleDuringDrag, pointerup restores it from reopenAfterDrag, click (no drag) restores it to true. All through the store now. signals/index.ts no longer re-exports assetModal. Four signal files gone so far in Phase 5; signals/ now down to 13 leaves (camera, demoAssets, dragAndDrop, engine, hotkeys, objectPanel, outliner, precisionSelectorMenu, promptBox, selectedItem, selectedMode, sidePanel, sizing, stylizeTab). --- .../pages/PageEnigma/DragAndDrop/DndAsset.ts | 10 +++--- .../PageEnigma/Editor/keybinds_controls.ts | 8 ++--- .../PageEnigma/comps/AssetMenu/AssetMenu.tsx | 4 +-- .../PageEnigma/comps/AssetMenu/AssetModal.tsx | 36 +++++++++++++------ .../comps/Controls3D/Controls3D.tsx | 22 +++++++++--- .../pages/PageEnigma/signals/assetModal.ts | 5 --- .../app/src/pages/PageEnigma/signals/index.ts | 1 - 7 files changed, 53 insertions(+), 33 deletions(-) delete mode 100644 frontend/apps/artcraft/app/src/pages/PageEnigma/signals/assetModal.ts diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/DragAndDrop/DndAsset.ts b/frontend/apps/artcraft/app/src/pages/PageEnigma/DragAndDrop/DndAsset.ts index e5f65a3e0e..5e9625266f 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/DragAndDrop/DndAsset.ts +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/DragAndDrop/DndAsset.ts @@ -4,9 +4,8 @@ import { canDrop, currPosition, dragItem, - assetModalVisibleDuringDrag, - reopenAfterDragSignal, } from "~/pages/PageEnigma/signals"; +import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore"; import { pageHeight, pageWidth } from "~/signals"; import { AssetType } from "~/enums"; import type Editor from "~/pages/PageEnigma/Editor/editor"; @@ -49,7 +48,7 @@ class DndAsset { this.isDragging = false; canDrop.value = false; this.notDropText = ""; - assetModalVisibleDuringDrag.value = false; + usePageEnigmaStore.getState().setAssetModalVisibleDuringDrag(false); window.addEventListener("pointerup", this.onPointerUp); window.addEventListener("pointermove", this.onPointerMove); } @@ -61,7 +60,8 @@ class DndAsset { canDrop.value = false; this.overElement = null; this.notDropText = ""; - assetModalVisibleDuringDrag.value = reopenAfterDragSignal.value; + const store = usePageEnigmaStore.getState(); + store.setAssetModalVisibleDuringDrag(store.reopenAfterDrag); } this.editor = null; } @@ -81,7 +81,7 @@ class DndAsset { window.removeEventListener("pointermove", this.onPointerMove); if (!this.isDragging) { - assetModalVisibleDuringDrag.value = true; + usePageEnigmaStore.getState().setAssetModalVisibleDuringDrag(true); dragItem.value = null; currPosition.value = { currX: 0, currY: 0 }; this.editor = null; diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/Editor/keybinds_controls.ts b/frontend/apps/artcraft/app/src/pages/PageEnigma/Editor/keybinds_controls.ts index 843430844a..8bf4176464 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/Editor/keybinds_controls.ts +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/Editor/keybinds_controls.ts @@ -4,9 +4,8 @@ import { hotkeysStatus, outlinerState, showObjectPanel, - assetModalVisible, - assetModalVisibleDuringDrag, } from "../signals"; +import { usePageEnigmaStore } from "../PageEnigmaStore"; import { OrbitControls, OutlinePass, @@ -368,8 +367,9 @@ export class MouseControls { return; } else if (event.key === "b") { // Open asset modal - assetModalVisible.value = true; - assetModalVisibleDuringDrag.value = true; + const store = usePageEnigmaStore.getState(); + store.setAssetModalVisible(true); + store.setAssetModalVisibleDuringDrag(true); return; } diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx index 714d00a157..5913f1ca71 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetMenu.tsx @@ -3,13 +3,13 @@ import { Tooltip } from "~/components"; import { Button } from "@storyteller/ui-button"; import { useState } from "react"; import { AssetModal } from "./AssetModal"; -import { assetModalVisibleDuringDrag } from "../../signals"; +import { usePageEnigmaStore } from "../../PageEnigmaStore"; export const AssetMenu = () => { const [isModalOpen, setIsModalOpen] = useState(false); const handleOpenModal = () => { - assetModalVisibleDuringDrag.value = true; + usePageEnigmaStore.getState().setAssetModalVisibleDuringDrag(true); setIsModalOpen(true); }; diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx index d13b68954f..76fb851329 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/AssetMenu/AssetModal.tsx @@ -32,10 +32,9 @@ import { demoShapeItems, demoCharacterItems, demoMemeItems, - assetModalVisibleDuringDrag, - reopenAfterDragSignal, - assetModalVisible, } from "../../signals"; +import { useShallow } from "zustand/shallow"; +import { usePageEnigmaStore } from "../../PageEnigmaStore"; import { MediaItem } from "../../models"; import { useUserObjects, useFeaturedObjects } from "../SidePanelTabs/hooks"; import { FilterEngineCategories, FilterMediaType } from "~/enums"; @@ -105,6 +104,21 @@ const MEME_OVERRIDES = ["ai trump"]; export const AssetModal = () => { useSignals(); + const { + assetModalVisible, + assetModalVisibleDuringDrag, + reopenAfterDrag, + setAssetModalVisible, + setReopenAfterDrag, + } = usePageEnigmaStore( + useShallow((s) => ({ + assetModalVisible: s.assetModalVisible, + assetModalVisibleDuringDrag: s.assetModalVisibleDuringDrag, + reopenAfterDrag: s.reopenAfterDrag, + setAssetModalVisible: s.setAssetModalVisible, + setReopenAfterDrag: s.setReopenAfterDrag, + })), + ); const [activeLibraryTab, setActiveLibraryTab] = useState("library"); const [activeAssetTab, setActiveAssetTab] = useState("all"); const [searchTerm, setSearchTerm] = useState(""); @@ -118,20 +132,20 @@ export const AssetModal = () => { const newValue = e.target.checked; // Force the update to be asynchronous setTimeout(() => { - reopenAfterDragSignal.value = newValue; + setReopenAfterDrag(newValue); }, 0); }; const handleClose = () => { - assetModalVisible.value = false; + setAssetModalVisible(false); }; const handleOpen = () => { - assetModalVisible.value = true; + setAssetModalVisible(true); }; useEffect(() => { - if (assetModalVisible.value) { + if (assetModalVisible) { // Check for stored category and tab from upload const lastUploadedTab = sessionStorage.getItem("lastUploadedTab"); if (lastUploadedTab) { @@ -152,7 +166,7 @@ export const AssetModal = () => { } return undefined; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [assetModalVisible.value]); + }, [assetModalVisible]); // Fetch objects for different categories const { @@ -486,7 +500,7 @@ export const AssetModal = () => { // }; const handleUploadSuccess = (category: FilterEngineCategories) => { - if (reopenAfterDragSignal.value) { + if (reopenAfterDrag) { // Small delay to allow the modal to close and reopen setTimeout(() => { handleClose(); @@ -523,7 +537,7 @@ export const AssetModal = () => { return ( <> {
diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/Controls3D/Controls3D.tsx b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/Controls3D/Controls3D.tsx index 61a0d971f6..d670c887a5 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/Controls3D/Controls3D.tsx +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/comps/Controls3D/Controls3D.tsx @@ -14,7 +14,8 @@ import { Tooltip } from "@storyteller/ui-tooltip"; import { SettingsModal } from "@storyteller/ui-settings-modal"; import { EngineContext } from "../../contexts/EngineContext"; import { useContext, useEffect, useState } from "react"; -import { assetModalVisibleDuringDrag, assetModalVisible } from "../../signals"; +import { useShallow } from "zustand/shallow"; +import { usePageEnigmaStore } from "../../PageEnigmaStore"; import { useTabStore } from "~/pages/Stores/TabState"; // import { v4 as uuidv4 } from "uuid"; // import { addObject } from "../../signals/objectGroup/addObject"; @@ -43,6 +44,17 @@ import { UploadModalSplat } from "~/components/reusable/UploadModalSplat"; export const Controls3D = () => { useSignals(); const editorEngine = useContext(EngineContext); + const { + assetModalVisible, + setAssetModalVisible, + setAssetModalVisibleDuringDrag, + } = usePageEnigmaStore( + useShallow((s) => ({ + assetModalVisible: s.assetModalVisible, + setAssetModalVisible: s.setAssetModalVisible, + setAssetModalVisibleDuringDrag: s.setAssetModalVisibleDuringDrag, + })), + ); const [showEmptySceneTooltip, setShowEmptySceneTooltip] = useState(false); // Action reminder is now handled through signals const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); @@ -57,7 +69,7 @@ export const Controls3D = () => { const checkSceneEmpty = () => { const isSceneEmpty = outlinerState.items.value.length === 0 && - !assetModalVisible.value && + !assetModalVisible && !galleryModalVisibleViewMode.value && !isAddAssetPopoverOpen && !upload3DIsShowing && @@ -78,7 +90,7 @@ export const Controls3D = () => { }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [ - assetModalVisible.value, + assetModalVisible, galleryModalVisibleViewMode.value, isAddAssetPopoverOpen, upload3DIsShowing, @@ -119,8 +131,8 @@ export const Controls3D = () => { // }, []); const handleOpenModal = () => { - assetModalVisibleDuringDrag.value = true; - assetModalVisible.value = true; + setAssetModalVisibleDuringDrag(true); + setAssetModalVisible(true); }; const handleOpenCreate3dModal = () => { diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/assetModal.ts b/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/assetModal.ts deleted file mode 100644 index c1eab50cda..0000000000 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/assetModal.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { signal } from "@preact/signals-react"; - -export const assetModalVisibleDuringDrag = signal(true); -export const reopenAfterDragSignal = signal(false); -export const assetModalVisible = signal(false); diff --git a/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/index.ts b/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/index.ts index b82ade3aac..6db447f146 100644 --- a/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/index.ts +++ b/frontend/apps/artcraft/app/src/pages/PageEnigma/signals/index.ts @@ -8,4 +8,3 @@ export * from "./selectedItem"; export * from "./sidePanel"; export * from "./sizing"; export * from "./stylizeTab"; -export * from "./assetModal";