feat(ui): confirm ending a show and surface help

End-session buttons, Escape, and window close share one confirm. Help is a question-mark icon on the control panel and after the version. About opens directly. Scene editor follows the UI language.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-10-02 08:10:54 +08:00
parent d228b9aab7
commit 060bbd471a
12 changed files with 245 additions and 176 deletions
@@ -112,10 +112,11 @@ void test('createWindows: окно НПС закрывается с multi-window
assert.ok(src.includes('will-attach-webview'));
});
void test('createWindows: закрытие пульта закрывает сессионные окна и презентацию', () => {
void test('createWindows: закрытие пульта и презентации спрашивает confirm', () => {
const src = readCreateWindows();
assert.match(src, /kind === 'control'/);
assert.match(src, /closePlaySessionAuxiliaryWindows[\s\S]*closePresentationWindow/);
assert.match(src, /kind === 'control'[\s\S]*?e\.preventDefault\(\)[\s\S]*?requestCloseMultiWindowConfirm/);
assert.match(src, /kind === 'presentation'[\s\S]*?e\.preventDefault\(\)[\s\S]*?requestCloseMultiWindowConfirm/);
assert.match(src, /export function closeMultiWindow[\s\S]*closePlaySessionAuxiliaryWindows/);
});
void test('createWindows: production — loadFile для HTML (не только file://)', () => {
+11 -24
View File
@@ -220,20 +220,6 @@ function closePlaySessionAuxiliaryWindows(): void {
closeNpcsWindow();
}
function closePresentationWindow(): void {
const pres = windows.get('presentation');
if (pres && !pres.isDestroyed()) {
pres.close();
}
}
function closeControlWindow(): void {
const ctrl = windows.get('control');
if (ctrl && !ctrl.isDestroyed()) {
ctrl.close();
}
}
function quitAppFromEditorClose(): void {
markAppQuitting();
app.quit();
@@ -535,20 +521,18 @@ function createWindow(kind: WindowKind, opts?: CreateWindowOpts): BrowserWindow
});
}
if (kind === 'control') {
win.on('close', () => {
win.on('close', (e) => {
if (appQuitting || closingPlaySession) return;
closingPlaySession = true;
closePlaySessionAuxiliaryWindows();
closePresentationWindow();
e.preventDefault();
requestCloseMultiWindowConfirm();
});
}
if (kind === 'presentation') {
bindPresentationContentSizeTracking(win);
win.on('close', () => {
win.on('close', (e) => {
if (appQuitting || closingPlaySession) return;
closingPlaySession = true;
closePlaySessionAuxiliaryWindows();
closeControlWindow();
e.preventDefault();
requestCloseMultiWindowConfirm();
});
}
win.on('closed', () => windows.delete(kind));
@@ -684,10 +668,13 @@ export function closeMultiWindow(): void {
}
}
/** Фокус пульта + событие: Escape с презентации спрашивает подтверждение там. */
/** Фокус пульта + событие: выход из показа спрашивает подтверждение на пульте. */
export function requestCloseMultiWindowConfirm(): void {
const ctrl = windows.get('control');
if (!ctrl || ctrl.isDestroyed()) return;
if (!ctrl || ctrl.isDestroyed()) {
closeMultiWindow();
return;
}
if (ctrl.isMinimized()) ctrl.restore();
ctrl.show();
ctrl.focus();