terry-staging #12

Merged
terry merged 13 commits from terry-staging into main 2026-05-30 10:45:30 +00:00
Showing only changes of commit 07f040a549 - Show all commits

View File

@@ -120,13 +120,22 @@ export function MessageInlineVideo({
const [currentTime, setCurrentTime] = useState(initialTime); const [currentTime, setCurrentTime] = useState(initialTime);
const [duration, setDuration] = useState(attachment.durationSec ?? 0); const [duration, setDuration] = useState(attachment.durationSec ?? 0);
const [isScrubbing, setIsScrubbing] = useState(false); const [isScrubbing, setIsScrubbing] = useState(false);
// When we programmatically seek (e.g. syncing the playhead back from the
// fullscreen overlay) the progress fill should jump straight to the watched
// position instead of sweeping up from its old width via the CSS transition.
// Cleared as soon as real playback resumes so live progress stays smooth.
const [snapProgress, setSnapProgress] = useState(false);
const t = TOKENS[size]; const t = TOKENS[size];
useEffect(() => { useEffect(() => {
const v = videoRef.current; const v = videoRef.current;
if (!v) return; if (!v) return;
const onPlay = () => setIsPlaying(true); const onPlay = () => {
setIsPlaying(true);
// Real playback advances the fill smoothly again; re-enable transitions.
setSnapProgress(false);
};
const onPause = () => setIsPlaying(false); const onPause = () => setIsPlaying(false);
const onTime = () => { const onTime = () => {
setCurrentTime(v.currentTime); setCurrentTime(v.currentTime);
@@ -232,7 +241,9 @@ export function MessageInlineVideo({
// Update React state synchronously so the progress bar paints the // Update React state synchronously so the progress bar paints the
// new playhead in the next frame, before the <video> seek round- // new playhead in the next frame, before the <video> seek round-
// trip emits its own events (paused videos don't fire timeupdate // trip emits its own events (paused videos don't fire timeupdate
// and `seeked` can lag ~hundreds of ms). // and `seeked` can lag ~hundreds of ms). Snap the fill to the new
// position so it doesn't sweep up from its pre-fullscreen width.
setSnapProgress(true);
setCurrentTime(finalTime); setCurrentTime(finalTime);
onTimeUpdate?.(finalTime); onTimeUpdate?.(finalTime);
const apply = () => { const apply = () => {
@@ -334,7 +345,9 @@ export function MessageInlineVideo({
> >
<div <div
className={`h-full bg-white ${ className={`h-full bg-white ${
isScrubbing ? "" : "transition-[width] duration-150 ease-out" isScrubbing || snapProgress
? ""
: "transition-[width] duration-150 ease-out"
}`} }`}
style={{ width: `${progressPct}%` }} style={{ width: `${progressPct}%` }}
/> />