diff --git a/src/pages/VinesFeedPage.tsx b/src/pages/VinesFeedPage.tsx index 5f755f37..d3383813 100644 --- a/src/pages/VinesFeedPage.tsx +++ b/src/pages/VinesFeedPage.tsx @@ -286,6 +286,10 @@ export function VineCard({ event, isActive, isNearActive, onCommentClick }: Vine const [hasStarted, setHasStarted] = useState(false); const [isAttemptingPlay, setIsAttemptingPlay] = useState(isActive); const [isMuted, setIsMuted] = useState(globalMuted); + // true once the browser has decoded enough to render the first frame + const [isVideoReady, setIsVideoReady] = useState(false); + // true when the video is stalling / rebuffering mid-playback + const [isBuffering, setIsBuffering] = useState(false); const videoRef = useRef(null); @@ -295,6 +299,14 @@ export function VineCard({ event, isActive, isNearActive, onCommentClick }: Vine const { src, onError: onBlossomError } = useBlossomFallback(imeta.url ?? ''); + // Reset ready/buffering state when the active vine changes (new src loaded) + useEffect(() => { + setIsVideoReady(false); + setIsBuffering(false); + setHasStarted(false); + setIsPlaying(false); + }, [src]); + // Auto-play / auto-pause based on active state useEffect(() => { const video = videoRef.current; @@ -312,6 +324,7 @@ export function VineCard({ event, isActive, isNearActive, onCommentClick }: Vine video.pause(); video.currentTime = 0; setIsAttemptingPlay(false); + setIsBuffering(false); } }, [isActive, imeta.url]); @@ -344,20 +357,38 @@ export function VineCard({ event, isActive, isNearActive, onCommentClick }: Vine