import React, { useEffect, useRef } from 'react'; import { computeTimeSec } from '../../main/video/videoPlaybackStore'; import type { SessionState } from '../../shared/ipc/contracts'; import { PixiEffectsOverlay } from './effects/PxiEffectsOverlay'; import { useEffectsState } from './effects/useEffectsState'; import styles from './PresentationView.module.css'; import { RotatedImage } from './RotatedImage'; import { useAssetUrl } from './useAssetImageUrl'; import { useVideoPlaybackState } from './video/useVideoPlaybackState'; export type PresentationViewProps = { session: SessionState | null; /** Если true — показываем укороченный заголовок/оверлей для предпросмотра. */ compact?: boolean; showTitle?: boolean; showEffects?: boolean; }; export function PresentationView({ session, compact = false, showTitle = true, showEffects = true, }: PresentationViewProps) { const [fxState] = useEffectsState(); const [vp] = useVideoPlaybackState(); const videoElRef = useRef(null); const [contentRect, setContentRect] = React.useState<{ x: number; y: number; w: number; h: number } | null>( null, ); const scene = session?.project && session.currentSceneId ? session.project.scenes[session.currentSceneId] : undefined; const previewUrl = useAssetUrl(scene?.previewAssetId ?? null); const rot = scene?.previewRotationDeg ?? 0; useEffect(() => { const el = videoElRef.current; if (!el) return; if (!vp) return; if (!scene?.previewAssetId) return; if (scene.previewAssetType !== 'video') return; if (vp.targetAssetId !== scene.previewAssetId) return; el.playbackRate = vp.playbackRate; const desired = computeTimeSec(vp, vp.serverNowMs); if (Number.isFinite(desired) && Math.abs(el.currentTime - desired) > 0.35) { el.currentTime = Math.max(0, desired); } if (vp.playing) { void el.play().catch(() => undefined); } else { el.pause(); } }, [scene?.previewAssetId, scene?.previewAssetType, vp]); return (
{previewUrl && scene?.previewAssetType === 'image' ? (
) : previewUrl && scene?.previewAssetType === 'video' ? (