From 008fcfeaa72e8869b6f4c12f89f7bc0c2b71d8a8 Mon Sep 17 00:00:00 2001 From: Tanish Manku Date: Wed, 13 May 2026 09:08:43 -0700 Subject: [PATCH] pagescene: finish anonymous-use polish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Gate File → Load my scene for anon: route through promptSignup instead of opening a dialog that would just error-toast on the silent listUserMediaFiles failure. - Remove dead SettingsModal mount in Controls3D (no UI ever triggered it). Drops the @storyteller/ui-settings-modal import from this file. - New AnonHintChip pill in the top-right corner of the playground ("Sign up to save"). Renders only when currentUserToken is undefined AND not in view-only mode; click routes to promptSignup. Tauri users never see it. - Scaffolding for view-only PreviewBox: new component renders a small card with the author's generation result; returns null when no URL is supplied. Mounted in Stage3DBody under the isViewOnly guard, reading sceneMeta.previewImageUrl (new optional field). Data-path wiring (populating previewImageUrl from adapter.loadScene's response) is the next step — leaving the UI plumbing in place so that follow-up is purely data, not layout surgery. --- .../libs/components/pagescene/src/index.ts | 3 ++ .../pagescene/src/lib/PageSceneStore.ts | 4 ++ .../pagescene/src/lib/Stage3DBody.tsx | 9 +++- .../lib/comps/AnonHintChip/AnonHintChip.tsx | 33 +++++++++++++++ .../src/lib/comps/AnonHintChip/index.ts | 1 + .../src/lib/comps/Controls3D/Controls3D.tsx | 9 ---- .../ControlsTopButtons/ControlsTopButtons.tsx | 34 ++++++++------- .../src/lib/comps/PreviewBox/PreviewBox.tsx | 42 +++++++++++++++++++ .../src/lib/comps/PreviewBox/index.ts | 2 + 9 files changed, 112 insertions(+), 25 deletions(-) create mode 100644 frontend/libs/components/pagescene/src/lib/comps/AnonHintChip/AnonHintChip.tsx create mode 100644 frontend/libs/components/pagescene/src/lib/comps/AnonHintChip/index.ts create mode 100644 frontend/libs/components/pagescene/src/lib/comps/PreviewBox/PreviewBox.tsx create mode 100644 frontend/libs/components/pagescene/src/lib/comps/PreviewBox/index.ts diff --git a/frontend/libs/components/pagescene/src/index.ts b/frontend/libs/components/pagescene/src/index.ts index b2a556e1bd..ae56930e8b 100644 --- a/frontend/libs/components/pagescene/src/index.ts +++ b/frontend/libs/components/pagescene/src/index.ts @@ -187,6 +187,7 @@ export { getSceneGenerationMetaData } from "./lib/sceneMetadata"; // signalScene, addToast, loadingBarData/IsShowing signals, etc.) // are either surfaced via adapter slots or replaced with // lib-internal state. +export { AnonHintChip } from "./lib/comps/AnonHintChip"; export { AssetMenu, AssetModal } from "./lib/comps/AssetMenu"; export { Controls3D } from "./lib/comps/Controls3D"; export { ControlsTopButtons } from "./lib/comps/ControlsTopButtons"; @@ -199,6 +200,8 @@ export { EditorCanvas, CameraViewCanvas } from "./lib/comps/EngineCanvases"; export { Outliner } from "./lib/comps/Outliner"; export { ControlPanelSceneObject } from "./lib/comps/ControlPanelSceneObject"; export { SceneContainer } from "./lib/comps/SceneContainer"; +export { PreviewBox } from "./lib/comps/PreviewBox"; +export type { PreviewBoxProps } from "./lib/comps/PreviewBox"; export { PreviewEngineCamera } from "./lib/comps/PreviewEngineCamera"; export { PreviewImages } from "./lib/comps/PreviewImages"; export { OnboardingHelper } from "./lib/comps/OnboardingHelper"; diff --git a/frontend/libs/components/pagescene/src/lib/PageSceneStore.ts b/frontend/libs/components/pagescene/src/lib/PageSceneStore.ts index b67a8bb043..288b38b265 100644 --- a/frontend/libs/components/pagescene/src/lib/PageSceneStore.ts +++ b/frontend/libs/components/pagescene/src/lib/PageSceneStore.ts @@ -22,6 +22,10 @@ export interface SceneMeta { ownerToken: string | undefined; isModified: boolean | undefined; isInitializing: boolean; + // URL to the author's generation result for this scene, shown in + // view-only mode's PreviewBox. Host populates this from the + // adapter.loadScene response. Optional; absent ⇒ no preview rendered. + previewImageUrl?: string; } export type SceneObjectKind = "object" | "character" | "shape"; diff --git a/frontend/libs/components/pagescene/src/lib/Stage3DBody.tsx b/frontend/libs/components/pagescene/src/lib/Stage3DBody.tsx index c2f17a5a28..41aea44557 100644 --- a/frontend/libs/components/pagescene/src/lib/Stage3DBody.tsx +++ b/frontend/libs/components/pagescene/src/lib/Stage3DBody.tsx @@ -33,6 +33,7 @@ import type { PopoverItem } from "@storyteller/ui-popover"; import { v4 as uuidv4 } from "uuid"; import { EngineContext } from "./contexts/EngineContext/EngineContext"; +import { AnonHintChip } from "./comps/AnonHintChip"; import { ControlPanelSceneObject } from "./comps/ControlPanelSceneObject"; import { Controls3D } from "./comps/Controls3D"; import { ControlsTopButtons } from "./comps/ControlsTopButtons"; @@ -41,6 +42,7 @@ import { FocalLengthDisplay } from "./comps/FocalLengthDisplay/FocalLengthDispla import { OnboardingHelper } from "./comps/OnboardingHelper"; import { Outliner } from "./comps/Outliner"; import { PoseModeSelector } from "./comps/PoseModeSelector"; +import { PreviewBox } from "./comps/PreviewBox"; import { PreviewEngineCamera } from "./comps/PreviewEngineCamera"; import { SceneContainer } from "./comps/SceneContainer"; import { addCharacter, addObject, setCameraAspect } from "./actions"; @@ -74,6 +76,7 @@ export const Stage3DBody = () => { (s) => s.setIsPromptBoxFocused, ); const gridVisible = usePageSceneStore((s) => s.gridVisible); + const previewImageUrl = usePageSceneStore((s) => s.sceneMeta.previewImageUrl); const isViewOnly = useIsViewOnly(); const addCamera = usePageSceneStore((s) => s.addCamera); const updateCamera = usePageSceneStore((s) => s.updateCamera); @@ -344,6 +347,9 @@ export const Stage3DBody = () => {
+
+ +
)} @@ -364,8 +370,7 @@ export const Stage3DBody = () => { {!isViewOnly && } - {/* Future: slot when isViewOnly — shows the - author's generated still next to the camera. */} + {isViewOnly && } {!isViewOnly &&