2fa20da94d
- Main: license service, IPC, router; закрытие окон; yauzl закрытие zip (EMFILE), zipRead тест - Editor: стабильный projectState без мигания, логотип и меню, строки UI, LayoutShell overlay - Control: ластик для всех типов эффектов, затухание/нарастание музыки при смене сцены - Сборка: vite, build/dev scripts, obfuscate-main и build-env скрипты с тестами; package.json Made-with: Cursor
248 lines
7.1 KiB
TypeScript
248 lines
7.1 KiB
TypeScript
import type { LicenseSnapshot } from '../license/licenseSnapshot';
|
|
import type {
|
|
AssetId,
|
|
EffectsEvent,
|
|
EffectsState,
|
|
GraphNodeId,
|
|
MediaAsset,
|
|
Project,
|
|
ProjectId,
|
|
Scene,
|
|
SceneId,
|
|
VideoPlaybackEvent,
|
|
VideoPlaybackState,
|
|
} from '../types';
|
|
|
|
export const ipcChannels = {
|
|
app: {
|
|
quit: 'app.quit',
|
|
getVersion: 'app.getVersion',
|
|
},
|
|
project: {
|
|
list: 'project.list',
|
|
create: 'project.create',
|
|
open: 'project.open',
|
|
saveNow: 'project.saveNow',
|
|
get: 'project.get',
|
|
updateScene: 'project.updateScene',
|
|
updateConnections: 'project.updateConnections',
|
|
setCurrentScene: 'project.setCurrentScene',
|
|
setCurrentGraphNode: 'project.setCurrentGraphNode',
|
|
importMedia: 'project.importMedia',
|
|
importScenePreview: 'project.importScenePreview',
|
|
clearScenePreview: 'project.clearScenePreview',
|
|
assetFileUrl: 'project.assetFileUrl',
|
|
updateSceneGraphNodePosition: 'project.updateSceneGraphNodePosition',
|
|
addSceneGraphNode: 'project.addSceneGraphNode',
|
|
removeSceneGraphNode: 'project.removeSceneGraphNode',
|
|
addSceneGraphEdge: 'project.addSceneGraphEdge',
|
|
removeSceneGraphEdge: 'project.removeSceneGraphEdge',
|
|
setSceneGraphNodeStart: 'project.setSceneGraphNodeStart',
|
|
deleteScene: 'project.deleteScene',
|
|
rename: 'project.rename',
|
|
importZip: 'project.importZip',
|
|
exportZip: 'project.exportZip',
|
|
deleteProject: 'project.deleteProject',
|
|
},
|
|
windows: {
|
|
openMultiWindow: 'windows.openMultiWindow',
|
|
closeMultiWindow: 'windows.closeMultiWindow',
|
|
togglePresentationFullscreen: 'windows.togglePresentationFullscreen',
|
|
},
|
|
session: {
|
|
stateChanged: 'session.stateChanged',
|
|
},
|
|
effects: {
|
|
getState: 'effects.getState',
|
|
dispatch: 'effects.dispatch',
|
|
stateChanged: 'effects.stateChanged',
|
|
},
|
|
video: {
|
|
getState: 'video.getState',
|
|
dispatch: 'video.dispatch',
|
|
stateChanged: 'video.stateChanged',
|
|
},
|
|
license: {
|
|
getStatus: 'license.getStatus',
|
|
setToken: 'license.setToken',
|
|
clearToken: 'license.clearToken',
|
|
acceptEula: 'license.acceptEula',
|
|
statusChanged: 'license.statusChanged',
|
|
},
|
|
} as const;
|
|
|
|
export type IpcInvokeMap = {
|
|
[ipcChannels.app.quit]: {
|
|
req: Record<string, never>;
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.app.getVersion]: {
|
|
req: Record<string, never>;
|
|
res: { version: string; buildNumber: string | null };
|
|
};
|
|
[ipcChannels.project.list]: {
|
|
req: Record<string, never>;
|
|
res: { projects: { id: ProjectId; name: string; updatedAt: string; fileName: string }[] };
|
|
};
|
|
[ipcChannels.project.create]: {
|
|
req: { name: string };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.open]: {
|
|
req: { projectId: ProjectId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.get]: {
|
|
req: Record<string, never>;
|
|
res: { project: Project | null };
|
|
};
|
|
[ipcChannels.project.saveNow]: {
|
|
req: Record<string, never>;
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.project.updateScene]: {
|
|
req: { sceneId: SceneId; patch: ScenePatch };
|
|
res: { scene: Scene };
|
|
};
|
|
[ipcChannels.project.updateConnections]: {
|
|
req: { sceneId: SceneId; connections: SceneId[] };
|
|
res: { scene: Scene };
|
|
};
|
|
[ipcChannels.project.setCurrentScene]: {
|
|
req: { sceneId: SceneId | null };
|
|
res: { currentSceneId: SceneId | null };
|
|
};
|
|
[ipcChannels.project.setCurrentGraphNode]: {
|
|
req: { graphNodeId: GraphNodeId | null };
|
|
res: { currentGraphNodeId: GraphNodeId | null; currentSceneId: SceneId | null };
|
|
};
|
|
[ipcChannels.project.importMedia]: {
|
|
req: { sceneId: SceneId };
|
|
res: { project: Project; imported: MediaAsset[] };
|
|
};
|
|
[ipcChannels.project.importScenePreview]: {
|
|
req: { sceneId: SceneId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.clearScenePreview]: {
|
|
req: { sceneId: SceneId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.assetFileUrl]: {
|
|
req: { assetId: AssetId };
|
|
res: { url: string | null };
|
|
};
|
|
[ipcChannels.project.updateSceneGraphNodePosition]: {
|
|
req: { nodeId: GraphNodeId; x: number; y: number };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.addSceneGraphNode]: {
|
|
req: { sceneId: SceneId; x: number; y: number };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.removeSceneGraphNode]: {
|
|
req: { nodeId: GraphNodeId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.addSceneGraphEdge]: {
|
|
req: { sourceGraphNodeId: GraphNodeId; targetGraphNodeId: GraphNodeId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.removeSceneGraphEdge]: {
|
|
req: { edgeId: string };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.setSceneGraphNodeStart]: {
|
|
req: { graphNodeId: GraphNodeId | null };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.deleteScene]: {
|
|
req: { sceneId: SceneId };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.rename]: {
|
|
req: { name: string; fileBaseName: string };
|
|
res: { project: Project };
|
|
};
|
|
[ipcChannels.project.importZip]: {
|
|
req: Record<string, never>;
|
|
res: { canceled: true } | { canceled: false; project: Project };
|
|
};
|
|
[ipcChannels.project.exportZip]: {
|
|
req: { projectId: ProjectId };
|
|
res: { canceled: true } | { canceled: false };
|
|
};
|
|
[ipcChannels.project.deleteProject]: {
|
|
req: { projectId: ProjectId };
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.windows.openMultiWindow]: {
|
|
req: Record<string, never>;
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.windows.closeMultiWindow]: {
|
|
req: Record<string, never>;
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.windows.togglePresentationFullscreen]: {
|
|
req: Record<string, never>;
|
|
res: { ok: true; isFullScreen: boolean };
|
|
};
|
|
[ipcChannels.effects.getState]: {
|
|
req: Record<string, never>;
|
|
res: { state: EffectsState };
|
|
};
|
|
[ipcChannels.effects.dispatch]: {
|
|
req: { event: EffectsEvent };
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.video.getState]: {
|
|
req: Record<string, never>;
|
|
res: { state: VideoPlaybackState };
|
|
};
|
|
[ipcChannels.video.dispatch]: {
|
|
req: { event: VideoPlaybackEvent };
|
|
res: { ok: true };
|
|
};
|
|
[ipcChannels.license.getStatus]: {
|
|
req: Record<string, never>;
|
|
res: LicenseSnapshot;
|
|
};
|
|
[ipcChannels.license.setToken]: {
|
|
req: { token: string };
|
|
res: LicenseSnapshot;
|
|
};
|
|
[ipcChannels.license.clearToken]: {
|
|
req: Record<string, never>;
|
|
res: LicenseSnapshot;
|
|
};
|
|
[ipcChannels.license.acceptEula]: {
|
|
req: { version: number };
|
|
res: { ok: true };
|
|
};
|
|
};
|
|
|
|
export type SessionState = {
|
|
project: Project | null;
|
|
currentSceneId: SceneId | null;
|
|
};
|
|
|
|
export type IpcEventMap = {
|
|
[ipcChannels.session.stateChanged]: { state: SessionState };
|
|
[ipcChannels.effects.stateChanged]: { state: EffectsState };
|
|
[ipcChannels.video.stateChanged]: { state: VideoPlaybackState };
|
|
[ipcChannels.license.statusChanged]: Record<string, never>;
|
|
};
|
|
|
|
export type ScenePatch = {
|
|
title?: string;
|
|
description?: string;
|
|
previewAssetId?: AssetId | null;
|
|
previewAssetType?: 'image' | 'video' | null;
|
|
previewVideoAutostart?: boolean;
|
|
previewRotationDeg?: 0 | 90 | 180 | 270;
|
|
settings?: Partial<Scene['settings']>;
|
|
media?: Partial<Scene['media']>;
|
|
layout?: Partial<Scene['layout']>;
|
|
};
|