Редактор: превью с поворотом, проекты, безопасное сохранение zip, dev-меню
RotatedImage: размер контейнера через clientWidth/Height (не getBoundingClientRect), чтобы cover при 90°/270° работал под zoom React Flow; убраны отладочные логи. Главное меню в dev: пункт «Вид» с DevTools (Ctrl+Shift+I без пустого application menu). Список проектов: project.list без лицензии; список подгружается при неактивной лицензии; ProjectPicker с подсказками; listProjects пропускает битые zip. Сохранение проектов: atomicReplace — замена zip без rm до commit; восстановление *.dnd.zip.tmp при старте; тесты. EditorApp: блокировка UI при открытых окнах презентации и пульта; стили оверлея. Made-with: Cursor
This commit is contained in:
+34
-1
@@ -21,6 +21,7 @@ import {
|
||||
createEditorWindowDeferred,
|
||||
createWindows,
|
||||
focusEditorWindow,
|
||||
isMultiWindowOpen,
|
||||
markAppQuitting,
|
||||
openMultiWindow,
|
||||
togglePresentationFullscreen,
|
||||
@@ -77,6 +78,35 @@ if (!gotTheLock) {
|
||||
}
|
||||
|
||||
const projectStore = new ZipProjectStore();
|
||||
|
||||
/** Без меню Electron не вешает горячие клавиши DevTools (Ctrl+Shift+I / F12). */
|
||||
function wantsDevToolsMenu(): boolean {
|
||||
return (
|
||||
process.env.NODE_ENV === 'development' ||
|
||||
Boolean(process.env.VITE_DEV_SERVER_URL) ||
|
||||
process.env.DND_OPEN_DEVTOOLS === '1'
|
||||
);
|
||||
}
|
||||
|
||||
function installAppMenuForSession(): void {
|
||||
if (!wantsDevToolsMenu()) {
|
||||
Menu.setApplicationMenu(null);
|
||||
return;
|
||||
}
|
||||
const template: Electron.MenuItemConstructorOptions[] = [];
|
||||
if (process.platform === 'darwin') {
|
||||
template.push({
|
||||
label: app.name,
|
||||
submenu: [{ role: 'about' }, { type: 'separator' }, { role: 'quit' }],
|
||||
});
|
||||
}
|
||||
template.push({
|
||||
label: 'Вид',
|
||||
submenu: [{ role: 'reload' }, { role: 'forceReload' }, { type: 'separator' }, { role: 'toggleDevTools' }],
|
||||
});
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(template));
|
||||
}
|
||||
|
||||
const effectsStore = new EffectsStore();
|
||||
const videoStore = new VideoPlaybackStore();
|
||||
|
||||
@@ -211,7 +241,7 @@ async function main() {
|
||||
setLicenseAssert(() => {
|
||||
licenseService.assertForIpc();
|
||||
});
|
||||
Menu.setApplicationMenu(null);
|
||||
installAppMenuForSession();
|
||||
registerDndAssetProtocol(projectStore);
|
||||
registerHandler(ipcChannels.app.quit, () => {
|
||||
markAppQuitting();
|
||||
@@ -238,6 +268,9 @@ async function main() {
|
||||
const isFullScreen = togglePresentationFullscreen();
|
||||
return { ok: true, isFullScreen };
|
||||
});
|
||||
registerHandler(ipcChannels.windows.getMultiWindowState, () => {
|
||||
return { open: isMultiWindowOpen() };
|
||||
});
|
||||
|
||||
registerHandler(ipcChannels.project.list, async () => {
|
||||
const projects = await projectStore.listProjects();
|
||||
|
||||
Reference in New Issue
Block a user