DNDGamePlayer: Electron редактор сцен, презентация, упаковка electron-builder

Made-with: Cursor
This commit is contained in:
Ivan Fontosh
2026-04-19 14:16:54 +08:00
commit a6cbcc273e
82 changed files with 22195 additions and 0 deletions
@@ -0,0 +1,43 @@
import { useEffect, useState } from 'react';
import { ipcChannels } from '../../../shared/ipc/contracts';
import type { VideoPlaybackEvent, VideoPlaybackState } from '../../../shared/types';
import { getDndApi } from '../dndApi';
export function useVideoPlaybackState(): readonly [
VideoPlaybackState | null,
{ dispatch: (event: VideoPlaybackEvent) => Promise<void> },
] {
const api = getDndApi();
const [state, setState] = useState<VideoPlaybackState | null>(null);
const [timeOffsetMs, setTimeOffsetMs] = useState(0);
const [clientNowMs, setClientNowMs] = useState(() => Date.now());
useEffect(() => {
if (!state) return;
const id = window.setInterval(() => {
setClientNowMs(Date.now());
}, 250);
return () => window.clearInterval(id);
}, [state]);
useEffect(() => {
void api.invoke(ipcChannels.video.getState, {}).then((r) => {
setState(r.state);
setTimeOffsetMs(r.state.serverNowMs - Date.now());
});
return api.on(ipcChannels.video.stateChanged, ({ state: next }) => {
setState(next);
setTimeOffsetMs(next.serverNowMs - Date.now());
});
}, [api]);
return [
state ? { ...state, serverNowMs: clientNowMs + timeOffsetMs } : null,
{
dispatch: async (event) => {
await api.invoke(ipcChannels.video.dispatch, { event });
},
},
] as const;
}