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).
This commit is contained in:
Tanish Manku committed 2026-04-28 23:13:57 -07:00
1 parent 11a0ac82b6
commit 21d3617970
7 files changed
+53 -33

No files matched your search

@@ -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;
@@ -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;
}
@@ -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);
};
@@ -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 (
<>
<Modal
isOpen={assetModalVisible.value && assetModalVisibleDuringDrag.value}
isOpen={assetModalVisible && assetModalVisibleDuringDrag}
onClose={handleClose}
className="relative h-[640px] max-w-4xl"
childPadding={false}
@@ -593,7 +607,7 @@ export const AssetModal = () => {
<div className="mt-auto flex items-center gap-2 pt-3">
<Checkbox
id="reopen-after-add"
checked={reopenAfterDragSignal.value}
checked={reopenAfterDrag}
onChange={handleReopenChange}
label="Reopen after adding"
/>
@@ -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 = () => {
@@ -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);
@@ -8,4 +8,3 @@ export * from "./selectedItem";
export * from "./sidePanel";
export * from "./sizing";
export * from "./stylizeTab";
export * from "./assetModal";