This commit is contained in:
@@ -72,7 +72,7 @@ export function PlaybackControls({
|
||||
const timecode = frameToTimecode(currentFrame, fps);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2 bg-black/90 px-3 py-2 border-t border-white/5">
|
||||
<div className="flex items-center gap-2 bg-black/90 px-3 py-2 border-t border-white/5" style={{ touchAction: "manipulation" }}>
|
||||
{/* Frame info */}
|
||||
<div className="flex items-center gap-3 font-mono text-xs text-zinc-300 min-w-0">
|
||||
<span className="hidden sm:block text-zinc-500">
|
||||
@@ -91,38 +91,41 @@ export function PlaybackControls({
|
||||
|
||||
{/* Transport Controls */}
|
||||
<div className="flex items-center gap-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-zinc-400 hover:text-white"
|
||||
onClick={() => {
|
||||
if (videoRef.current) videoRef.current.currentTime = 0;
|
||||
}}
|
||||
>
|
||||
<ChevronFirst className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Go to start</TooltipContent>
|
||||
</Tooltip>
|
||||
{/* Go to start + Reverse — hidden on mobile */}
|
||||
<div className="hidden sm:contents">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-zinc-400 hover:text-white"
|
||||
onClick={() => {
|
||||
if (videoRef.current) videoRef.current.currentTime = 0;
|
||||
}}
|
||||
>
|
||||
<ChevronFirst className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Go to start</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className={cn(
|
||||
"text-zinc-400 hover:text-white",
|
||||
isReversing && "text-amber-400 bg-amber-400/10"
|
||||
)}
|
||||
onClick={onReverse}
|
||||
>
|
||||
<SkipBack className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Reverse (J)</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className={cn(
|
||||
"text-zinc-400 hover:text-white",
|
||||
isReversing && "text-amber-400 bg-amber-400/10"
|
||||
)}
|
||||
onClick={onReverse}
|
||||
>
|
||||
<SkipBack className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Reverse (J)</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
@@ -171,22 +174,25 @@ export function PlaybackControls({
|
||||
<TooltipContent>Step forward (→)</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-zinc-400 hover:text-white"
|
||||
onClick={() => {
|
||||
if (videoRef.current)
|
||||
videoRef.current.currentTime = videoRef.current.duration;
|
||||
}}
|
||||
>
|
||||
<ChevronLast className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Go to end</TooltipContent>
|
||||
</Tooltip>
|
||||
{/* Go to end — hidden on mobile */}
|
||||
<div className="hidden sm:contents">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="text-zinc-400 hover:text-white"
|
||||
onClick={() => {
|
||||
if (videoRef.current)
|
||||
videoRef.current.currentTime = videoRef.current.duration;
|
||||
}}
|
||||
>
|
||||
<ChevronLast className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Go to end</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Spacer */}
|
||||
@@ -194,19 +200,21 @@ export function PlaybackControls({
|
||||
|
||||
{/* Right Controls */}
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Playback speed */}
|
||||
<Select value={String(playbackRate)} onValueChange={handleRateChange}>
|
||||
<SelectTrigger className="h-7 w-16 text-xs border-0 bg-white/5 text-zinc-300 px-2">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{PLAYBACK_RATES.map((r) => (
|
||||
<SelectItem key={r} value={String(r)} className="text-xs">
|
||||
{r}x
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{/* Playback speed — hidden on mobile */}
|
||||
<div className="hidden sm:contents">
|
||||
<Select value={String(playbackRate)} onValueChange={handleRateChange}>
|
||||
<SelectTrigger className="h-7 w-16 text-xs border-0 bg-white/5 text-zinc-300 px-2">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{PLAYBACK_RATES.map((r) => (
|
||||
<SelectItem key={r} value={String(r)} className="text-xs">
|
||||
{r}x
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Annotation toggle */}
|
||||
<Tooltip>
|
||||
|
||||
Reference in New Issue
Block a user