fix(player): scrubber seekuje takze gdy dlugosc zna tylko scena, nie player
SPROSTOWANIE: paska postepu NIE trzeba bylo budowac, on juz istnial (track + fill + thumb + gest + czasy, 48px hit-box). Moja wczesniejsza diagnoza "player nie ma czym przewijac" byla bledna: szukalem po nazwach Slider/progressBar/seekBar, a implementacja nazywa sie scrub*. Zamiast dublowac funkcje, zostal realny blad, ktory przy okazji wyszedl. Blad: UI paska liczy sie z `dur = knownDuration || durationSec || 0`, czyli z fallbackiem na dlugosc z metadanych sceny, ale seek w `onEnd` byl strzezony warunkiem na samym `knownDuration` (to, co zglosil player). Dla zrodla, ktore nie poda dlugosci playerowi, a ma ja w metadanych, uchwyt i czas jechaly za palcem, a po puszczeniu nie dzialo sie nic. Teraz seek uzywa tej samej wartosci co rysowanie, przez `durRef` (gest powstaje raz w useMemo, wiec domykalby stara wartosc). Zweryfikowane na emulatorze na realnym odtwarzaniu: przeciagniecie paska przenioslo pozycje z 1:36 na 18:03, wypelnienie i uchwyt zgodne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
068a65dd8c
commit
20c04698b1
2 changed files with 21 additions and 3 deletions
|
|
@ -16,6 +16,13 @@ export type ChangelogEntry = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CHANGELOG: ChangelogEntry[] = [
|
export const CHANGELOG: ChangelogEntry[] = [
|
||||||
|
{
|
||||||
|
id: '2026-08-18i',
|
||||||
|
date: 'August 2026',
|
||||||
|
items: [
|
||||||
|
'Dragging the progress bar now works on videos whose length the player has not reported yet. The handle and the time moved with your finger, but letting go did nothing; it seeks properly now.',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: '2026-08-18h',
|
id: '2026-08-18h',
|
||||||
date: 'August 2026',
|
date: 'August 2026',
|
||||||
|
|
|
||||||
|
|
@ -741,6 +741,11 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
||||||
);
|
);
|
||||||
|
|
||||||
const dur = knownDuration || durationSec || 0;
|
const dur = knownDuration || durationSec || 0;
|
||||||
|
// Gest scrubbera powstaje raz (useMemo), więc czyta długość przez ref, nie z domknięcia.
|
||||||
|
const durRef = React.useRef(dur);
|
||||||
|
React.useEffect(() => {
|
||||||
|
durRef.current = dur;
|
||||||
|
}, [dur]);
|
||||||
|
|
||||||
const panSeek = React.useMemo(
|
const panSeek = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|
@ -818,10 +823,16 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
||||||
})
|
})
|
||||||
.onEnd((e) => {
|
.onEnd((e) => {
|
||||||
const w = scrubBarWidthRef.current;
|
const w = scrubBarWidthRef.current;
|
||||||
if (w > 0 && knownDuration > 0) {
|
// `durRef`, NIE `knownDuration`: pasek RYSUJE się z `dur`, czyli z fallbackiem
|
||||||
|
// na długość z metadanych sceny, gdy player jeszcze nie zgłosił swojej. Warunek
|
||||||
|
// na samym `knownDuration` powodował, że przy takim źródle uchwyt i czas jechały
|
||||||
|
// za palcem, a po puszczeniu nie działo się nic. Ref, bo gest jest zbudowany raz
|
||||||
|
// i domykałby starą wartość.
|
||||||
|
const total = durRef.current;
|
||||||
|
if (w > 0 && total > 0) {
|
||||||
const ratio = Math.max(0, Math.min(1, e.x / w));
|
const ratio = Math.max(0, Math.min(1, e.x / w));
|
||||||
try {
|
try {
|
||||||
player.currentTime = ratio * knownDuration;
|
player.currentTime = ratio * total;
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
@ -830,7 +841,7 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
||||||
scheduleHide();
|
scheduleHide();
|
||||||
})
|
})
|
||||||
.runOnJS(true),
|
.runOnJS(true),
|
||||||
[player, knownDuration, cancelHide, scheduleHide],
|
[player, cancelHide, scheduleHide],
|
||||||
);
|
);
|
||||||
|
|
||||||
// ----- fullscreen toggle ----------------------------------------------------
|
// ----- fullscreen toggle ----------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue