EmboDi / src /shared /interaction-session.mjs
xlt99's picture
Upload 180 files
970fc3e verified
Raw History Blame Contribute Delete
5.07 kB
function createInteractionSession() {
let current = null;
return {
open({ ids, revision, spatialKey, standalone = false }) {
if (!Array.isArray(ids) || !ids.length && !standalone || new Set(ids).size !== ids.length || ids.some((id) => typeof id !== "string") || !Number.isInteger(revision) || typeof spatialKey !== "string") throw new Error("Select an object first");
current = { ids: [...ids], revision, spatialKey, mode: "interaction" };
},
draft() {
if (!current) throw new Error("Select an object first");
current.mode = "draft";
},
demonstration() {
if (!current) throw Error("Select a door");
current.mode = "demonstration";
},
close() {
current = null;
},
valid({ revision, spatialKey, ids }) {
return !current || current.revision === revision && current.spatialKey === spatialKey && current.ids.every((id) => ids.includes(id));
},
snapshot: () => current ? structuredClone(current) : null,
active: () => current !== null,
drawing: () => current?.mode === "draft"
};
}
function objectActions(context) {
if (context.authoring && context.actorSelected) return [];
if (context.phase !== "explore" || !context.objectSelection?.length || context.actorPlacing) return [];
if (context.objectInteraction?.mode === "draft") return [];
const disabled = !!context.editingBusy || !!context.job || !!context.saving || !!context.finishing;
return [{ id: "objectInteraction", label: "Interaction 路 Set behavior", disabled }, { id: "objectTransform", label: "Transform 路 Move and turn", disabled }];
}
function interactionActions(context) {
if (!context.objectInteraction) return [];
if (context.objectInteraction.mode === "demonstration") return context.demonstration?.state === "recording" ? [{ id: "demonstrationStop", label: "X 路 Stop and prepare interaction" }] : context.demonstration?.state === "saving" ? [{ id: "demonstrationStop", label: "Saving demonstration...", disabled: true }] : [...context.demonstration?.state === "ready" ? [{ id: "demonstrationApply", label: "Prepare door interaction" }] : [], { id: context.demonstration?.canRetry ? "demonstrationRetry" : "demonstrationStart", label: context.demonstration?.canRetry ? "X 路 Retry saving" : "X 路 Start demonstration" }, { id: "interactionClose", label: "Back" }];
if (context.authoring && context.objectInteraction.mode === "draft" && context.draft?.kind === "regions") return [
{ id: "draftApply", label: "Finish sketch", disabled: !context.draft?.regionCount || context.draft?.drawing },
{ id: "draftUndo", label: "Undo last region", disabled: !context.draft?.canUndo },
{ id: "draftCancel", label: "Cancel drawing" }
];
if (context.authoring && context.objectInteraction.mode === "draft") return [
{ id: "draftApply", label: "Save curve", disabled: !context.draft?.pointCount || context.draft?.drawing },
{ id: "draftSmooth", label: "Smoothing: " + (context.draft?.smoothingLabel || "Standard"), disabled: !!context.draft?.drawing },
...context.draft?.mode === "space3d" ? [{ id: "brushNear", label: "Tip nearer", disabled: context.draft.drawing }, { id: "brushFar", label: "Tip farther", disabled: context.draft.drawing }] : [],
{ id: "draftClear", label: "Redraw curve" },
{ id: "draftUndo", label: "Undo stroke", disabled: !context.draft?.canUndo },
{ id: "draftCancel", label: "Cancel drawing" }
];
if (context.objectInteraction.mode === "draft") return [
...context.videoState === "recording" ? [{ id: "record", label: "Stop and save recording 路 B" }] : [],
{ id: "draftApply", label: "Finish and prepare path", disabled: !context.draft?.pointCount || context.draft?.drawing },
{ id: "draftClear", label: "Clear draft" },
{ id: "draftUndo", label: "Undo stroke", disabled: !context.draft?.canUndo },
{ id: "draftCancel", label: "Cancel and exit Draft" }
];
if (context.authoring && context.door && context.objectInteraction.ids.length === 1 && context.objectInteraction.ids[0] === context.door.id) return [
{ id: "regionDraft", label: "Draw regions" },
...context.floodAvailable ? [{ id: "floodPreview", label: "Replay interaction" }] : [],
{ id: "interactionVoice", label: "Voice description 路 Hold X" },
{ id: "interactionClose", label: "Back" }
];
if (context.authoring) return [{ id: "drawFloor", label: "Draw on floor 路 2D" }, { id: "drawSpace", label: "Draw in air 路 3D" }, { id: "interactionVoice", label: "Describe intent 路 hold X" }, { id: "interactionClose", label: "Back" }];
return [
{ id: "interactionDraft", label: "Draft 路 Ground sketch" },
{ id: "interactionVoice", label: "Voice 路 Spoken request" },
{ id: "interactionDemonstration", label: "Video demonstration", disabled: !context.door || context.objectInteraction.ids.length !== 1 || context.objectInteraction.ids[0] !== context.door.id },
{ id: "interactionClose", label: "Back to object controls" }
];
}
export {
createInteractionSession,
interactionActions,
objectActions
};