From be3c0c9d03c8257237121bfd89acf25dec36ff48 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 17 Jul 2021 22:04:46 -0300 Subject: make next/previous buttons pay heed to timestamps! --- ui.js | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 6 deletions(-) (limited to 'ui.js') diff --git a/ui.js b/ui.js index b67fc8d..bc7f68d 100644 --- a/ui.js +++ b/ui.js @@ -1117,6 +1117,27 @@ class AppElement extends FocusElement { return this.timestampDictionary.get(item) || null } + getTimestampAtSec(item, sec) { + const timestampData = this.getTimestampData(item) + if (!timestampData) { + return null + } + + // Just like, start from the end, man. + // Why doesn't JavaScript have a findIndexFromEnd function??? + for (let i = timestampData.length - 1; i >= 0; i--) { + const ts = timestampData[i]; + if ( + ts.timestamp <= sec && + ts.timestampEnd >= sec + ) { + return ts + } + } + + return null + } + async readTimestampData(item) { const file = this.getTimestampsFile(item) @@ -1217,19 +1238,86 @@ class AppElement extends FocusElement { // all are before this position, skip to previous. let maxCurSec = 0 - this.forEachQueuePlayerToActOn(({ timeData }) => { - if (timeData) { - maxCurSec = Math.max(maxCurSec, timeData.curSecTotal) + this.forEachQueuePlayerToActOn(qp => { + if (qp.timeData) { + let effectiveCurSec = qp.timeData.curSecTotal + + const ts = this.getTimestampAtSec(qp.playingTrack, qp.timeData.curSecTotal) + if (ts) { + effectiveCurSec -= ts.timestamp + } + + maxCurSec = Math.max(maxCurSec, effectiveCurSec) } }) if (Math.floor(maxCurSec) < this.config.seekToStartThreshold) { - this.actOnQueuePlayers(qp => qp.playPrevious(qp.playingTrack, true)) + this.skipBack() } else { - this.actOnQueuePlayers(qp => qp.seekToStart()) + this.seekToStart() } } + seekToStart() { + this.actOnQueuePlayers(qp => qp.seekToStart()) + this.actOnQueuePlayers(qp => { + if (!qp.playingTrack) { + return + } + + const ts = this.getTimestampAtSec(qp.playingTrack, qp.timeData.curSecTotal) + if (ts) { + qp.seekTo(ts.timestamp) + return + } + + qp.seekToStart() + }) + } + + skipBack() { + this.actOnQueuePlayers(qp => { + if (!qp.playingTrack) { + return + } + + const ts = this.getTimestampAtSec(qp.playingTrack, qp.timeData.curSecTotal) + if (ts) { + const timestampData = this.getTimestampData(qp.playingTrack) + const playingTimestampIndex = timestampData.indexOf(ts) + const previous = timestampData[playingTimestampIndex - 1] + if (previous) { + qp.seekTo(previous.timestamp) + return + } + } + + qp.playPrevious(qp.playingTrack, true) + }) + } + + skipAhead() { + this.actOnQueuePlayers(qp => { + if (!qp.playingTrack) { + return + } + + const ts = this.getTimestampAtSec(qp.playingTrack, qp.timeData.curSecTotal) + + if (ts) { + const timestampData = this.getTimestampData(qp.playingTrack) + const playingTimestampIndex = timestampData.indexOf(ts) + const next = timestampData[playingTimestampIndex + 1] + if (next) { + qp.seekTo(next.timestamp) + return + } + } + + qp.playNext(qp.playingTrack, true) + }) + } + actOnQueuePlayers(fn) { this.forEachQueuePlayerToActOn(queuePlayer => { fn(queuePlayer) @@ -1610,7 +1698,7 @@ class AppElement extends FocusElement { } else if (input.isSkipBack(keyBuf)) { this.skipBackOrSeekToStart() } else if (input.isSkipAhead(keyBuf)) { - this.actOnQueuePlayers(qp => qp.playNext(qp.playingTrack, true)) + this.skipAhead() } } -- cgit 1.3.0-6-gf8a5