feat(control): таймер сессии поверх сцены

Отдельное окно countdown с «Показать игрокам»; на превью — move/resize/rotate, на презентации тот же layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-09-03 16:51:56 +08:00
parent a4d7ab77e7
commit db1168a46c
23 changed files with 1313 additions and 3 deletions
+27
View File
@@ -55,6 +55,8 @@ import type {
SceneTrapsState,
SceneViewEvent,
SceneViewState,
SessionTimerEvent,
SessionTimerState,
TokenId,
TokenPathSessionEvent,
TokenPathSessionState,
@@ -163,6 +165,8 @@ export const ipcChannels = {
closeMaterials: 'windows.closeMaterials',
openPlaylists: 'windows.openPlaylists',
closePlaylists: 'windows.closePlaylists',
openTimer: 'windows.openTimer',
closeTimer: 'windows.closeTimer',
openNpcsEditor: 'windows.openNpcsEditor',
closeNpcsEditor: 'windows.closeNpcsEditor',
openNpcs: 'windows.openNpcs',
@@ -200,6 +204,11 @@ export const ipcChannels = {
dispatch: 'npcsOverlay.dispatch',
stateChanged: 'npcsOverlay.stateChanged',
},
sessionTimer: {
getState: 'sessionTimer.getState',
dispatch: 'sessionTimer.dispatch',
stateChanged: 'sessionTimer.stateChanged',
},
sceneDarkness: {
getState: 'sceneDarkness.getState',
dispatch: 'sceneDarkness.dispatch',
@@ -357,6 +366,7 @@ export type IpcEventMap = {
[ipcChannels.effects.stateChanged]: { state: EffectsState };
[ipcChannels.materialsOverlay.stateChanged]: { state: MaterialsOverlayState };
[ipcChannels.npcsOverlay.stateChanged]: { state: NpcsOverlayState };
[ipcChannels.sessionTimer.stateChanged]: { state: SessionTimerState };
[ipcChannels.sceneDarkness.stateChanged]: { state: SceneDarknessState };
[ipcChannels.sceneMarker.stateChanged]: { state: SceneMarkerState };
[ipcChannels.sceneTraps.stateChanged]: { state: SceneTrapsState };
@@ -786,6 +796,14 @@ export type IpcInvokeMap = {
req: Record<string, never>;
res: { ok: true };
};
[ipcChannels.windows.openTimer]: {
req: Record<string, never>;
res: { ok: true };
};
[ipcChannels.windows.closeTimer]: {
req: Record<string, never>;
res: { ok: true };
};
[ipcChannels.windows.openNpcsEditor]: {
req: Record<string, never>;
res: { ok: true };
@@ -842,6 +860,14 @@ export type IpcInvokeMap = {
req: { event: NpcsOverlayEvent };
res: { ok: true };
};
[ipcChannels.sessionTimer.getState]: {
req: Record<string, never>;
res: { state: SessionTimerState };
};
[ipcChannels.sessionTimer.dispatch]: {
req: { event: SessionTimerEvent };
res: { state: SessionTimerState };
};
[ipcChannels.effects.getState]: {
req: Record<string, never>;
res: { state: EffectsState };
@@ -1094,6 +1120,7 @@ export type LegacyIpcEventMap = {
[ipcChannels.effects.stateChanged]: { state: EffectsState };
[ipcChannels.materialsOverlay.stateChanged]: { state: MaterialsOverlayState };
[ipcChannels.npcsOverlay.stateChanged]: { state: NpcsOverlayState };
[ipcChannels.sessionTimer.stateChanged]: { state: SessionTimerState };
[ipcChannels.sceneDarkness.stateChanged]: { state: SceneDarknessState };
[ipcChannels.sceneMarker.stateChanged]: { state: SceneMarkerState };
[ipcChannels.sceneTraps.stateChanged]: { state: SceneTrapsState };