@@ -6,7 +6,7 @@ import type { Particle } from "@/api/types";
|
||||
import { parseParticlePath, particlePath, toFirestoreDocPath, type ParticlePath } from "@/lib/particle-path";
|
||||
import { ComposeOverlay } from "@/features/compose/compose-overlay";
|
||||
import { PlaybackPageIndicator } from "@/features/particles/playback-page-indicator";
|
||||
import { MediaParticleView } from "@/features/particles/media-particle-view";
|
||||
import { MediaParticleView, type MediaParticleHandle } from "@/features/particles/media-particle-view";
|
||||
import { TextParticleView } from "@/features/particles/text-particle-view";
|
||||
import { FallbackParticleView } from "@/features/particles/fallback-particle-view";
|
||||
import { Avatar, AvatarFallback, AvatarGroup } from "@/components/ui/avatar";
|
||||
@@ -140,8 +140,11 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
authedUser?.id,
|
||||
);
|
||||
|
||||
const mediaRef = useRef<MediaParticleHandle>(null);
|
||||
|
||||
const [composeActive, setComposeActive] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [fastPlayback, setFastPlayback] = useState(false);
|
||||
|
||||
// Show/hide chrome on mouse activity (YouTube-style)
|
||||
const [showControls, setShowControls] = useState(true);
|
||||
@@ -196,17 +199,23 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
case "ArrowRight":
|
||||
case "ArrowDown":
|
||||
e.preventDefault();
|
||||
next();
|
||||
if (!mediaRef.current?.seek(10)) next();
|
||||
break;
|
||||
case "ArrowLeft":
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
prev();
|
||||
if (!mediaRef.current?.seek(-10)) prev();
|
||||
break;
|
||||
case " ":
|
||||
e.preventDefault();
|
||||
if (!e.repeat) pause();
|
||||
break;
|
||||
case "Shift":
|
||||
if (!e.repeat) {
|
||||
mediaRef.current?.setPlaybackRate(1.5);
|
||||
setFastPlayback(true);
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
e.preventDefault();
|
||||
navigate(`/${networkId}`);
|
||||
@@ -230,6 +239,10 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
e.preventDefault();
|
||||
resume();
|
||||
}
|
||||
if (e.key === "Shift") {
|
||||
mediaRef.current?.setPlaybackRate(1);
|
||||
setFastPlayback(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
@@ -287,6 +300,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
case "media":
|
||||
return (
|
||||
<MediaParticleView
|
||||
ref={mediaRef}
|
||||
key={particle.id}
|
||||
particle={particle}
|
||||
streamPath={path}
|
||||
@@ -333,6 +347,12 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
||||
onClick={handlePlaybackClick}
|
||||
>
|
||||
{renderParticle(currentParticle)}
|
||||
|
||||
{fastPlayback && (
|
||||
<div className="pointer-events-none absolute right-4 top-14 z-20 rounded-full bg-black/50 px-2.5 py-1 text-xs font-medium text-white backdrop-blur-sm">
|
||||
1.5x
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user