Files
DndGamePlayer/app/renderer/presentation/PresentationApp.tsx
T
Ivan Fontosh f270812219 feat(tokens): app-local non-player tokens with session moves and UI polish
Add token library/placements, keep play-time moves for the session, lock presentation interactions, and fix export/import modal layout plus freeform trap label.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:04:12 +08:00

50 lines
1.7 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { ipcChannels, type SessionState } from '../../shared/ipc/contracts';
import { getDndApi } from '../shared/dndApi';
import { PresentationView } from '../shared/PresentationView';
import styles from './PresentationApp.module.css';
export function PresentationApp() {
const [session, setSession] = useState<SessionState | null>(null);
const api = getDndApi();
useEffect(() => {
void api.invoke(ipcChannels.project.get, {}).then((res) => {
setSession({
project: res.project,
currentSceneId: res.project?.currentSceneId ?? null,
});
});
return api.on(ipcChannels.session.stateChanged, ({ state }) => setSession(state));
}, [api]);
useEffect(() => {
const onKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
void api.invoke(ipcChannels.windows.closeMultiWindow, {});
return;
}
if (e.altKey && (e.key === 'Enter' || e.code === 'Enter' || e.code === 'NumpadEnter')) {
e.preventDefault();
void api.invoke(ipcChannels.windows.togglePresentationFullscreen, {});
}
};
window.addEventListener('keydown', onKeyDown);
return () => window.removeEventListener('keydown', onKeyDown);
}, [api]);
return (
<div
className={styles.root}
onDoubleClick={() => void api.invoke(ipcChannels.windows.togglePresentationFullscreen, {})}
>
{/* Презентация только для просмотра: никаких кликов/drag по сцене и оверлеям. */}
<div className={styles.viewPassthrough}>
<PresentationView session={session} showTitle={false} />
</div>
</div>
);
}