feat: кубики/таймер/кисть/спонсоры и задел игровых систем

Показ анимации кубиков игрокам, закрытие оверлеев с окнами, ручной ввод количества, меньший радиус кисти, блок спонсоров в «О программе»; плюс черновик game systems / character sheet.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-09-13 15:37:44 +08:00
parent 3d0474fe97
commit 712086ddca
32 changed files with 1712 additions and 34 deletions
+47
View File
@@ -76,11 +76,22 @@ import type {
StorylineListItem,
StorylineSelection,
} from '../graph/storylineExportImport';
import type { SystemDefinition } from '../characterSheet/types';
/** Catalog row for imported TTRPG systems (userData/game-systems). */
export type GameSystemListItem = {
id: string;
name: string;
edition?: string;
schemaVersion: number;
revision: number;
};
export const ipcChannels = {
app: {
quit: 'app.quit',
getVersion: 'app.getVersion',
openExternal: 'app.openExternal',
},
updater: {
check: 'updater.check',
@@ -284,6 +295,14 @@ export const ipcChannels = {
upsertProgress: 'players.upsertProgress',
stateChanged: 'players.stateChanged',
},
gameSystems: {
list: 'gameSystems.list',
importFromFile: 'gameSystems.importFromFile',
delete: 'gameSystems.delete',
get: 'gameSystems.get',
bindSnapshot: 'gameSystems.bindSnapshot',
getSnapshot: 'gameSystems.getSnapshot',
},
playlists: {
getState: 'playlists.getState',
create: 'playlists.create',
@@ -427,6 +446,10 @@ export type IpcInvokeMap = {
req: Record<string, never>;
res: { version: string; buildNumber: string | null; packaged: boolean };
};
[ipcChannels.app.openExternal]: {
req: { url: string };
res: { ok: true } | { ok: false; error: string };
};
[ipcChannels.updater.check]: {
req: Record<string, never>;
res: UpdaterCheckResponse;
@@ -1052,6 +1075,30 @@ export type IpcInvokeMap = {
req: { id: PlayerId };
res: { url: string | null };
};
[ipcChannels.gameSystems.list]: {
req: Record<string, never>;
res: { systems: GameSystemListItem[] };
};
[ipcChannels.gameSystems.importFromFile]: {
req: Record<string, never>;
res: { canceled: true } | { canceled: false; system: GameSystemListItem };
};
[ipcChannels.gameSystems.delete]: {
req: { id: string };
res: { ok: true };
};
[ipcChannels.gameSystems.get]: {
req: { id: string };
res: { system: SystemDefinition | null };
};
[ipcChannels.gameSystems.bindSnapshot]: {
req: { systemId: string };
res: { systemId: string; snapshotHash: string; system: SystemDefinition };
};
[ipcChannels.gameSystems.getSnapshot]: {
req: { hash: string };
res: { system: SystemDefinition | null };
};
[ipcChannels.playlists.getState]: {
req: Record<string, never>;
res: PlaylistsState;