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[] = [
|
||||
{
|
||||
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',
|
||||
date: 'August 2026',
|
||||
|
|
|
|||
|
|
@ -741,6 +741,11 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
|||
);
|
||||
|
||||
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(
|
||||
() =>
|
||||
|
|
@ -818,10 +823,16 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
|||
})
|
||||
.onEnd((e) => {
|
||||
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));
|
||||
try {
|
||||
player.currentTime = ratio * knownDuration;
|
||||
player.currentTime = ratio * total;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
|
@ -830,7 +841,7 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) {
|
|||
scheduleHide();
|
||||
})
|
||||
.runOnJS(true),
|
||||
[player, knownDuration, cancelHide, scheduleHide],
|
||||
[player, cancelHide, scheduleHide],
|
||||
);
|
||||
|
||||
// ----- fullscreen toggle ----------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue