mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 23:00:03 +00:00
feat(cli): expose Studio selection through preview (#1777)
Add a small Studio selection channel so agents can ask a running preview server for the element the user selected in Studio. This keeps the UX on the existing npx hyperframes preview surface while giving agents a stable source file, target selector, timeline time, and thumbnail URL for follow-up edits.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import type { StudioSelectionSnapshot } from "@hyperframes/studio-server";
|
||||
import type { DomEditSelection } from "../components/editor/domEditing";
|
||||
|
||||
function round3(value: number): number {
|
||||
return Math.round(value * 1000) / 1000;
|
||||
}
|
||||
|
||||
function thumbnailUrl({
|
||||
projectId,
|
||||
selection,
|
||||
currentTime,
|
||||
}: {
|
||||
projectId: string;
|
||||
selection: DomEditSelection;
|
||||
currentTime: number;
|
||||
}): string {
|
||||
const compPath = encodeURIComponent(
|
||||
selection.compositionPath || selection.sourceFile || "index.html",
|
||||
);
|
||||
const params = new URLSearchParams({
|
||||
t: String(round3(currentTime)),
|
||||
format: "png",
|
||||
});
|
||||
if (selection.selector) params.set("selector", selection.selector);
|
||||
if (selection.selectorIndex != null) params.set("selectorIndex", String(selection.selectorIndex));
|
||||
return `/api/projects/${encodeURIComponent(projectId)}/thumbnail/${compPath}?${params.toString()}`;
|
||||
}
|
||||
|
||||
export function buildStudioSelectionSnapshot({
|
||||
projectId,
|
||||
selection,
|
||||
currentTime,
|
||||
}: {
|
||||
projectId: string;
|
||||
selection: DomEditSelection;
|
||||
currentTime: number;
|
||||
}): StudioSelectionSnapshot {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
projectId,
|
||||
compositionPath: selection.compositionPath,
|
||||
sourceFile: selection.sourceFile,
|
||||
currentTime: round3(currentTime),
|
||||
target: {
|
||||
id: selection.id,
|
||||
hfId: selection.hfId,
|
||||
selector: selection.selector,
|
||||
selectorIndex: selection.selectorIndex,
|
||||
},
|
||||
label: selection.label,
|
||||
tagName: selection.tagName,
|
||||
boundingBox: {
|
||||
x: round3(selection.boundingBox.x),
|
||||
y: round3(selection.boundingBox.y),
|
||||
width: round3(selection.boundingBox.width),
|
||||
height: round3(selection.boundingBox.height),
|
||||
},
|
||||
textContent: selection.textContent,
|
||||
dataAttributes: { ...selection.dataAttributes },
|
||||
inlineStyles: { ...selection.inlineStyles },
|
||||
computedStyles: { ...selection.computedStyles },
|
||||
textFields: selection.textFields.map((field) => ({
|
||||
key: field.key,
|
||||
label: field.label,
|
||||
value: field.value,
|
||||
tagName: field.tagName,
|
||||
source: field.source,
|
||||
})),
|
||||
capabilities: { ...selection.capabilities },
|
||||
thumbnailUrl: thumbnailUrl({ projectId, selection, currentTime }),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user