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
+9 -5
View File
@@ -124,6 +124,11 @@ if (process.platform === 'win32' && app.isPackaged && process.env.DND_DISABLE_GP
app.disableHardwareAcceleration();
}
if (process.platform === 'darwin') {
app.commandLine.appendSwitch('enable-gpu-rasterization');
app.commandLine.appendSwitch('enable-zero-copy');
}
if (process.platform === 'win32') {
app.setAppUserModelId('com.ttrpgplayer.app');
}
@@ -368,9 +373,7 @@ function syncSceneTrapsForProject(project: Project): void {
function emitVideoState(): void {
const state = videoStore.getState();
for (const win of BrowserWindow.getAllWindows()) {
win.webContents.send(ipcChannels.video.stateChanged, { state });
}
sendToAppWindows(ipcChannels.video.stateChanged, { state }, ['control', 'presentation']);
}
// Периодически чистим истёкшие эффекты (в основном молнии).
@@ -620,7 +623,7 @@ async function main() {
openNpcsWindow();
const npcId = req?.npcId ? asNpcId(String(req.npcId)) : null;
if (npcId) {
npcsOverlayStore.dispatch({ kind: 'show', npcId });
npcsOverlayStore.dispatch({ kind: 'inspect.show', npcId });
emitNpcsOverlayState();
}
return { ok: true };
@@ -981,10 +984,11 @@ async function main() {
);
registerHandler(
ipcChannels.project.updateNpcFields,
async ({ npcId, name, description, groupId, ringColor, disposition, imageOffset, imageScale }) => {
async ({ npcId, name, description, externalUrl, groupId, ringColor, disposition, imageOffset, imageScale }) => {
const project = await projectStore.updateNpcFields(npcId, {
...(typeof name === 'string' ? { name } : {}),
...(typeof description === 'string' ? { description } : {}),
...(typeof externalUrl === 'string' ? { externalUrl } : {}),
...(groupId !== undefined ? { groupId } : {}),
...(ringColor !== undefined ? { ringColor } : {}),
...(disposition !== undefined ? { disposition } : {}),