fix(npcs): faster editor open, save progress, black screen crash

Warm and show the NPC window sooner, lazy-load ReactFlow/TipTap, overlay save progress like materials, and fix the undefined controlStyles crash after creating an NPC.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-07-30 08:50:05 +08:00
parent c7bf7cf449
commit e687303c57
10 changed files with 247 additions and 106 deletions
+25 -8
View File
@@ -63,6 +63,7 @@ import {
sendToAppWindows,
togglePresentationFullscreen,
waitForEditorWindowReady,
warmNpcsEditorWindow,
} from './windows/createWindows';
function emitZipProgress(evt: {
@@ -95,6 +96,16 @@ function emitMaterialUpsertProgress(evt: {
}
}
function emitNpcUpsertProgress(evt: {
percent: number;
stage: string;
detail?: string;
}): void {
for (const win of BrowserWindow.getAllWindows()) {
win.webContents.send(ipcChannels.project.npcUpsertProgress, evt);
}
}
/**
* Отключение GPU ломает скорость вторичных окон (презентация/пульт — WebGL). По умолчанию не трогаем.
* При чёрном экране в упакованной сборке: `DND_DISABLE_GPU=1`.
@@ -508,6 +519,7 @@ async function main() {
registerHandler(ipcChannels.project.create, async ({ name }) => {
const project = await projectStore.createProject(name);
emitSessionState();
warmNpcsEditorWindow();
return { project };
});
registerHandler(ipcChannels.project.open, async ({ projectId }) => {
@@ -517,9 +529,11 @@ async function main() {
emitSceneViewState();
emitSceneTokensSessionState();
emitSessionState();
warmNpcsEditorWindow();
return { project };
});
registerHandler(ipcChannels.project.close, async () => {
closeNpcsEditorWindow();
await projectStore.closeOpenProject();
effectsStore.clear();
materialsOverlayStore.clear();
@@ -760,14 +774,17 @@ async function main() {
}
filePath = filePaths[0];
}
const project = await projectStore.upsertNpc({
...(npcId ? { npcId } : {}),
name,
...(typeof description === 'string' ? { description } : {}),
...(filePath ? { filePath } : {}),
...(groupId !== undefined ? { groupId } : {}),
...(binding !== undefined ? { binding } : {}),
});
const project = await projectStore.upsertNpc(
{
...(npcId ? { npcId } : {}),
name,
...(typeof description === 'string' ? { description } : {}),
...(filePath ? { filePath } : {}),
...(groupId !== undefined ? { groupId } : {}),
...(binding !== undefined ? { binding } : {}),
},
(p) => emitNpcUpsertProgress(p),
);
syncNpcsOverlayWithProject(project);
emitNpcsOverlayState();
emitSessionState();