Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Has been cancelled
CI / Lint, Typecheck & Unit Tests (push) Has been cancelled
Docs Build / Build docs site (push) Has been cancelled
Publish @openmaic packages / Build, validate & publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

58 lines
2.1 KiB
TypeScript

import type { Action } from '@/lib/types/action';
import { useCanvasStore } from '@/lib/store/canvas';
/**
* Which canvas effect a cue glyph replays on hover.
* `none` = tooltip only, no canvas effect (the cue has no bound slide element).
*/
export type CuePreview =
| { kind: 'spotlight'; elementId: string }
| { kind: 'laser'; elementId: string }
| { kind: 'none' };
/**
* Decide how a cue should replay on the edit canvas.
*
* A `laser` cue must replay as the real laser pointer — NOT a spotlight (the
* original ActionsBar fired `setSpotlight` for every cue, so laser cues were
* wrongly rendered as a spotlight). Every other element-bound cue (spotlight,
* play_video, whiteboard draws that carry a slide elementId) keeps the
* spotlight highlight. A cue with no bound element gets no canvas preview.
*/
export function cuePreviewFor(action: Action): CuePreview {
const elementId = (action as { elementId?: string }).elementId;
if (!elementId) return { kind: 'none' };
if (action.type === 'laser') return { kind: 'laser', elementId };
return { kind: 'spotlight', elementId };
}
// ---- canvas-side effect (single home for the setSpotlight/setLaser dance) ----
/** Clear any spotlight/laser preview from the canvas. */
export function clearCuePreview(): void {
const cs = useCanvasStore.getState();
cs.setSpotlight('');
cs.clearLaser();
}
/**
* Replay a cue effect for an explicit cue type + element on the canvas, clearing
* the sibling effect first so a previous hover never lingers. `laser` drives the
* laser pointer, anything else drives the spotlight.
*/
export function previewCueEffect(cueType: string, elementId: string): void {
clearCuePreview();
if (!elementId) return;
if (cueType === 'laser') useCanvasStore.getState().setLaser(elementId);
else useCanvasStore.getState().setSpotlight(elementId);
}
/** Apply the preview decided by {@link cuePreviewFor}. */
export function applyCuePreview(preview: CuePreview): void {
if (preview.kind === 'none') {
clearCuePreview();
return;
}
previewCueEffect(preview.kind, preview.elementId);
}