'use client';
import { useMemo } from 'react';
import { SceneRenderer } from '@/components/stage/scene-renderer';
import { useStageStore } from '@/lib/store/stage';
import type { Scene, SceneContent } from '@/lib/types/stage';
import type { SceneEditorSurface, SurfaceState } from './scene-editor-surface';
/**
* NOOP_SURFACE — the read-only fallback surface used by the shell when no
* editor surface is registered for the current `scene.type` (today:
* interactive / pbl — slide and quiz have real surfaces). The shell resolves
* `surface ?? NOOP_SURFACE`, so it always renders a single, structurally
* stable `` regardless of scene type. Switching to an unregistered
* scene type therefore only swaps the
* `surface.SurfaceComponent` inside the frame — `` and the
* `leftRail` slot stay mounted, eliminating the chrome remount flicker that
* the previous two-component-types branch caused.
*
* The canvas is `SceneRenderer mode="playback"` — feature-parity with the
* playback surface (interactive iframes load, quiz options render, PBL board
* paints).
*
* `sceneType` is a placeholder ('slide'); NOOP_SURFACE is never `register()`d,
* only used as a fallback from `resolve(...) ?? NOOP_SURFACE`. The field is
* required by the surface contract but its value is never read in this path.
*/
function NoopCanvas() {
const scenes = useStageStore.use.scenes();
const currentSceneId = useStageStore.use.currentSceneId();
const scene = useMemo(
() => scenes.find((s) => s.id === currentSceneId) ?? null,
[scenes, currentSceneId],
);
if (!scene) return null;
return ;
}
const EMPTY_STATE: SurfaceState = {
content: {} as SceneContent,
selection: undefined,
hasSelection: false,
insertItems: [],
floatingActions: [],
commands: [],
hints: [],
};
function useNoopSurfaceState(): SurfaceState {
// No state, no subscriptions — the chrome shows nothing surface-specific for
// read-only scene types. Returning the module-level constant keeps the hook
// signature minimal (zero internal hooks) and equality-stable across renders.
return EMPTY_STATE;
}
export const NOOP_SURFACE: SceneEditorSurface = {
sceneType: 'slide',
SurfaceComponent: NoopCanvas,
useSurfaceState: useNoopSurfaceState,
};