feat(npcs): inspect cards, Show overlay, and optional external link

Clicking an NPC tile opens description cards (multi-select accordion); Show puts avatars on screen. Optional URL opens a webview tab. Avatar pan in the editor commits on pointer up.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-08-19 10:42:57 +08:00
parent 1a9f0f2557
commit 0f4bb76b41
35 changed files with 1189 additions and 259 deletions
@@ -21,4 +21,22 @@ void test('video playback: renderer hooks/components do not tick React each fram
// Регресс: раньше был RAF loop с setState на каждом кадре.
assert.doesNotMatch(previewSrc, /\brequestAnimationFrame\s*\(\s*loop\s*\)/);
assert.doesNotMatch(previewSrc, /\brequestAnimationFrame\s*\(\s*loop\b/);
// timeupdate пишет scrub в DOM, без setState корня превью (дорого поверх декода видео).
assert.doesNotMatch(previewSrc, /\bsetTick\b/);
assert.ok(previewSrc.includes('paintScrub'));
assert.ok(previewSrc.includes('scrubFillRef'));
});
void test('editor scene cards do not decode full video files', () => {
const graph = fs.readFileSync(
path.join(root, 'app', 'renderer', 'editor', 'graph', 'SceneGraph.tsx'),
'utf8',
);
const editor = fs.readFileSync(
path.join(root, 'app', 'renderer', 'editor', 'EditorApp.tsx'),
'utf8',
);
assert.doesNotMatch(graph, /<video\b/);
assert.doesNotMatch(graph, /ContainedVideo/);
assert.doesNotMatch(editor, /sceneThumbVideo/);
});