The Studio viewer now covers everything the classic overlay did, so the classic runtime (toolbar, panzoom, A/B and side-by-side engine, scopes, loupe, probe, grading and WebGL video processors, filmstrip, context menu, keyboard handling), its styles and its tests are deleted. - Every open request goes to the Studio viewer; requestViewerOpen no longer falls back to a viewer singleton. - Drop the classic-only settings (use classic viewer, pan without zoom, disable WebGL) and their internal options and constants. - Studio tells the grid which asset it ended on when it closes, and the rating hotkeys yield to it while it is open. - Remove dead helpers left behind (image processor, media player helpers, 3D helpers, metadata block, viewerbar controls variant) and unused CSS. - Update the viewer tutorial, hotkeys doc and changelog.
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
/**
|
|
* Shared state of the Studio viewer (the default main viewer).
|
|
*
|
|
* A tiny reactive singleton: open/close, the asset list and the current
|
|
* index. The Vue overlay renders from it; `ViewerPortal` routes OPEN_VIEWER
|
|
* requests here.
|
|
*/
|
|
|
|
import { reactive } from "vue";
|
|
|
|
|
|
export const studioViewerState = reactive({
|
|
open: false,
|
|
assets: [] as any[],
|
|
index: 0,
|
|
/** Bumped on every open so the overlay can reset per-session UI. */
|
|
session: 0,
|
|
/** Compare mode requested by the opener ("wipe", "side") or "". */
|
|
compare: "" as "" | "wipe" | "side",
|
|
});
|
|
|
|
export function currentStudioAsset(): any {
|
|
return studioViewerState.assets[studioViewerState.index] ?? null;
|
|
}
|
|
|
|
/** Map the classic viewer's open modes to a Studio compare mode. */
|
|
export function studioCompareForMode(mode = ""): "" | "wipe" | "side" {
|
|
const m = String(mode || "")
|
|
.trim()
|
|
.toLowerCase();
|
|
if (m === "ab") return "wipe";
|
|
if (m === "sidebyside") return "side";
|
|
return "";
|
|
}
|
|
|
|
export function openStudioViewer(assets: unknown[], index = 0, mode = ""): boolean {
|
|
const list = (Array.isArray(assets) ? assets : []).filter(Boolean);
|
|
if (!list.length) return false;
|
|
studioViewerState.assets = list;
|
|
studioViewerState.index = Math.max(0, Math.min(Number(index) || 0, list.length - 1));
|
|
studioViewerState.compare = list.length > 1 ? studioCompareForMode(mode) : "";
|
|
studioViewerState.session += 1;
|
|
studioViewerState.open = true;
|
|
return true;
|
|
}
|
|
|
|
export function closeStudioViewer(): void {
|
|
studioViewerState.open = false;
|
|
}
|
|
|
|
export function goToStudioIndex(index: number): void {
|
|
const count = studioViewerState.assets.length;
|
|
if (!count) return;
|
|
studioViewerState.index = ((Math.floor(index) % count) + count) % count;
|
|
}
|
|
|
|
export function stepStudioViewer(delta: number): void {
|
|
goToStudioIndex(studioViewerState.index + delta);
|
|
}
|