fix: Bug fixes Scrub lag Chapter track last chapter Mini bar stays over music Resume ABS doesn't stop music
This commit is contained in:
1 parent
eb4d6fcbf9
commit
0d8b8b6f5d
3 files changed
+31
-6
No files matched your search
+18
-4
@@ -253,7 +253,12 @@ export async function absPlayItem(item) {
|
|||||||
|
|
||||||
export function absTogglePlay() {
|
export function absTogglePlay() {
|
||||||
const audio = _getAudio();
|
const audio = _getAudio();
|
||||||
S.absPlayer.playing ? audio.pause() : audio.play().catch(() => {});
|
if (S.absPlayer.playing) {
|
||||||
|
audio.pause();
|
||||||
|
} else {
|
||||||
|
if (S.audio && !S.audio.paused) S.audio.pause();
|
||||||
|
audio.play().catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function absInterrupt() {
|
export function absInterrupt() {
|
||||||
@@ -261,6 +266,11 @@ export function absInterrupt() {
|
|||||||
_getAudio().pause(); // triggers the pause listener which calls _doSync()
|
_getAudio().pause(); // triggers the pause listener which calls _doSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function absOnMusicPause() {
|
||||||
|
// When music pauses, re-evaluate mini bar visibility (ABS bar should reappear)
|
||||||
|
if (S.absPlayer.item) _renderMiniBar();
|
||||||
|
}
|
||||||
|
|
||||||
export function absSeek(globalTime) {
|
export function absSeek(globalTime) {
|
||||||
const ap = S.absPlayer;
|
const ap = S.absPlayer;
|
||||||
globalTime = Math.max(0, Math.min(globalTime, ap.duration || Infinity));
|
globalTime = Math.max(0, Math.min(globalTime, ap.duration || Infinity));
|
||||||
@@ -373,8 +383,11 @@ function _chapterWindow() {
|
|||||||
const ap = S.absPlayer;
|
const ap = S.absPlayer;
|
||||||
if (!_chapterTrackMode || ap.chapterIdx < 0 || !ap.chapters.length) return null;
|
if (!_chapterTrackMode || ap.chapterIdx < 0 || !ap.chapters.length) return null;
|
||||||
const ch = ap.chapters[ap.chapterIdx];
|
const ch = ap.chapters[ap.chapterIdx];
|
||||||
|
if (!ch || ch.start == null) return null;
|
||||||
const nextCh = ap.chapters[ap.chapterIdx + 1];
|
const nextCh = ap.chapters[ap.chapterIdx + 1];
|
||||||
return { start: ch.start ?? 0, end: nextCh?.start ?? ap.duration };
|
const end = nextCh?.start ?? ch.end ?? ap.duration;
|
||||||
|
if (end <= ch.start) return null;
|
||||||
|
return { start: ch.start, end };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── PROGRESS SCRUB ───
|
// ─── PROGRESS SCRUB ───
|
||||||
@@ -396,7 +409,8 @@ function _renderMiniBar() {
|
|||||||
const ap = S.absPlayer;
|
const ap = S.absPlayer;
|
||||||
const bar = document.getElementById('abs-mini-bar');
|
const bar = document.getElementById('abs-mini-bar');
|
||||||
if (!bar) return;
|
if (!bar) return;
|
||||||
if (!ap.item) { bar.classList.remove('visible'); return; }
|
// Hide when no ABS item loaded, or when music is actively playing
|
||||||
|
if (!ap.item || (S.audio && !S.audio.paused)) { bar.classList.remove('visible'); return; }
|
||||||
bar.classList.add('visible');
|
bar.classList.add('visible');
|
||||||
const meta = ap.item?.media?.metadata || {};
|
const meta = ap.item?.media?.metadata || {};
|
||||||
const cover = absCoverUrl(ap.item?.id);
|
const cover = absCoverUrl(ap.item?.id);
|
||||||
@@ -452,7 +466,7 @@ function _renderPlayer() {
|
|||||||
function _renderProgress() {
|
function _renderProgress() {
|
||||||
const ap = S.absPlayer;
|
const ap = S.absPlayer;
|
||||||
const win = _chapterWindow();
|
const win = _chapterWindow();
|
||||||
const dispCur = win ? ap.currentTime - win.start : ap.currentTime;
|
const dispCur = win ? Math.max(0, ap.currentTime - win.start) : ap.currentTime;
|
||||||
const dispDur = win ? win.end - win.start : ap.duration;
|
const dispDur = win ? win.end - win.start : ap.duration;
|
||||||
const pct = dispDur > 0 ? Math.min(100, (dispCur / dispDur) * 100) : 0;
|
const pct = dispDur > 0 ? Math.min(100, (dispCur / dispDur) * 100) : 0;
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -24,7 +24,7 @@ import {
|
|||||||
absSetSpeed, absSleepIn, absOpenPlayer, absClosePlayer, absToggleChapters,
|
absSetSpeed, absSleepIn, absOpenPlayer, absClosePlayer, absToggleChapters,
|
||||||
absToggleSpeedPicker, absToggleSleepPicker, absSeekToChapter, absProgDown, absProgMove,
|
absToggleSpeedPicker, absToggleSleepPicker, absSeekToChapter, absProgDown, absProgMove,
|
||||||
absProgUp, loadAbsBooks, absOpenBook, loadAbsBookDetail, absPlayChapter,
|
absProgUp, loadAbsBooks, absOpenBook, loadAbsBookDetail, absPlayChapter,
|
||||||
absLoadSettingsLibraries, absToggleChapterTrack, absInterrupt,
|
absLoadSettingsLibraries, absToggleChapterTrack, absInterrupt, absOnMusicPause,
|
||||||
} from './abs.js';
|
} from './abs.js';
|
||||||
import {
|
import {
|
||||||
openNowPlaying, closeNowPlaying, switchNpTab, npGoArtist, npGoAlbum,
|
openNowPlaying, closeNowPlaying, switchNpTab, npGoArtist, npGoAlbum,
|
||||||
@@ -135,6 +135,7 @@ window.addEventListener('load', () => {
|
|||||||
setPlayIcon(false);
|
setPlayIcon(false);
|
||||||
document.getElementById('player-art').classList.remove('spinning');
|
document.getElementById('player-art').classList.remove('spinning');
|
||||||
if(navigator.mediaSession) navigator.mediaSession.playbackState = 'paused';
|
if(navigator.mediaSession) navigator.mediaSession.playbackState = 'paused';
|
||||||
|
absOnMusicPause();
|
||||||
});
|
});
|
||||||
S.previewAudio.addEventListener('timeupdate', updatePreviewProgress);
|
S.previewAudio.addEventListener('timeupdate', updatePreviewProgress);
|
||||||
S.previewAudio.addEventListener('ended', stopPreview);
|
S.previewAudio.addEventListener('ended', stopPreview);
|
||||||
|
|||||||
+11
-1
@@ -235,7 +235,17 @@ function _initBarScrub(bar, fill, onMove) {
|
|||||||
function getPos(clientX) { const r = bar.getBoundingClientRect(); return Math.max(0, Math.min(1, (clientX-r.left)/r.width)); }
|
function getPos(clientX) { const r = bar.getBoundingClientRect(); return Math.max(0, Math.min(1, (clientX-r.left)/r.width)); }
|
||||||
function startScrub(pos) { S._scrubbing=true; fill.style.transition='none'; fill.style.width=(pos*100)+'%'; onMove(pos); }
|
function startScrub(pos) { S._scrubbing=true; fill.style.transition='none'; fill.style.width=(pos*100)+'%'; onMove(pos); }
|
||||||
function moveScrub(pos) { fill.style.width=(pos*100)+'%'; onMove(pos); }
|
function moveScrub(pos) { fill.style.width=(pos*100)+'%'; onMove(pos); }
|
||||||
function endScrub(pos) { S._scrubbing=false; fill.style.transition=''; if(S.audio.duration) S.audio.currentTime=pos*S.audio.duration; }
|
function endScrub(pos) {
|
||||||
|
fill.style.transition='';
|
||||||
|
if(S.audio.duration) {
|
||||||
|
S.audio.currentTime = pos * S.audio.duration;
|
||||||
|
// Keep _scrubbing=true until seek completes so timeupdate can't snap bar back
|
||||||
|
S.audio.addEventListener('seeked', () => { S._scrubbing = false; }, { once: true });
|
||||||
|
setTimeout(() => { S._scrubbing = false; }, 1500); // fallback if seeked never fires
|
||||||
|
} else {
|
||||||
|
S._scrubbing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
bar.addEventListener('touchstart', e => { startScrub(getPos(e.touches[0].clientX)); e.stopPropagation(); }, {passive:true});
|
bar.addEventListener('touchstart', e => { startScrub(getPos(e.touches[0].clientX)); e.stopPropagation(); }, {passive:true});
|
||||||
bar.addEventListener('touchmove', e => { if(S._scrubbing) moveScrub(getPos(e.touches[0].clientX)); }, {passive:true});
|
bar.addEventListener('touchmove', e => { if(S._scrubbing) moveScrub(getPos(e.touches[0].clientX)); }, {passive:true});
|
||||||
bar.addEventListener('touchend', e => { if(S._scrubbing) endScrub(getPos(e.changedTouches[0].clientX)); }, {passive:true});
|
bar.addEventListener('touchend', e => { if(S._scrubbing) endScrub(getPos(e.changedTouches[0].clientX)); }, {passive:true});
|
||||||
|
|||||||
Reference in new issue
Block a user