"use client";
import { useState, useEffect, useSyncExternalStore } from "react";
import { useEditor } from "@/editor/use-editor";
import { formatTimecode } from "opencut-wasm";
import { invokeAction } from "@/actions";
import { EditableTimecode } from "@/components/editable-timecode";
import { Button } from "@/components/ui/button";
import {
ArrowExpandDiagonal01Icon,
FullScreenIcon,
Minimize01Icon,
PauseIcon,
PlayIcon,
} from "@hugeicons/core-free-icons";
import { HugeiconsIcon } from "@hugeicons/react";
import { Separator } from "@/components/ui/separator";
import {
Select,
SelectTrigger,
SelectContent,
SelectItem,
SelectSeparator,
} from "@/components/ui/select";
import { PREVIEW_ZOOM_PRESETS } from "@/preview/zoom";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { usePreviewPopoutStore } from "@/preview/popout-store";
import { usePreviewViewport } from "./preview-viewport";
import { GridPopover } from "./guide-popover";
import { usePreviewStore } from "@/preview/preview-store";
import type { MediaTime } from "@/wasm";
export function PreviewToolbar({
onToggleFullscreen,
}: {
onToggleFullscreen: () => void;
}) {
return (
{/* v0.4.0 */}
{/*
*/}
);
}
function PopoutButton() {
const isPoppedOut = usePreviewPopoutStore(
(state) => state.container !== null,
);
const openPopout = usePreviewPopoutStore((state) => state.openPopout);
const dockPopout = usePreviewPopoutStore((state) => state.dockPopout);
const isSupported = useSyncExternalStore(
() => () => {},
() => "documentPictureInPicture" in window,
() => false,
);
if (!isSupported) {
return null;
}
const togglePopout = () => {
if (isPoppedOut) {
dockPopout();
} else {
openPopout();
}
};
return (
{isPoppedOut ? "Dock preview" : "Pop out preview"}
);
}
function TimecodeDisplay() {
const editor = useEditor();
const totalDuration = useEditor((e) => e.timeline.getTotalDuration());
const fps = useEditor((e) => e.project.getActive().settings.fps);
const [currentTime, setCurrentTime] = useState(() =>
editor.playback.getCurrentTime(),
);
useEffect(() => {
const unsubscribeUpdate = editor.playback.onUpdate(setCurrentTime);
const unsubscribeSeek = editor.playback.onSeek(setCurrentTime);
return () => {
unsubscribeUpdate();
unsubscribeSeek();
};
}, [editor.playback]);
return (
editor.playback.seek({ time })}
className="text-center"
/>
/
{formatTimecode({
time: totalDuration,
format: "HH:MM:SS:FF",
rate: fps,
})}
);
}
function ZoomSelect() {
const { isAtFit, zoomPercent, fitToScreen, setViewportPercent } =
usePreviewViewport();
const displayLabel = isAtFit ? "Fit" : `${zoomPercent}%`;
const onValueChange = (value: string) => {
if (value === "fit") {
fitToScreen();
} else {
setViewportPercent({ percent: Number(value) });
}
};
return (
);
}
function PlayPauseButton() {
const isPlaying = useEditor((e) => e.playback.getIsPlaying());
return (
);
}