diff --git a/components/app/AudioPlayer.vue b/components/app/AudioPlayer.vue index bcc54262..d9fd1286 100644 --- a/components/app/AudioPlayer.vue +++ b/components/app/AudioPlayer.vue @@ -15,7 +15,7 @@

{{ isDirectPlayMethod ? 'Direct' : isLocalPlayMethod ? 'Local' : 'Transcode' }}

-
+

{{ currentTimePretty }}

@@ -80,18 +80,17 @@
-
-
+
+

0:00

{{ timeRemainingPretty }}

-
-
-
-
-
-
+
+
+
+
+
@@ -149,8 +148,10 @@ export default { useTotalTrack: true, lockUi: false, isLoading: false, - touchTrackStart: false, - dragPercent: 0, + isDraggingCursor: false, + draggingTouchStartX: 0, + draggingTouchStartTime: 0, + draggingCurrentTime: 0, syncStatus: 0, showMoreMenuDialog: false, coverRgb: 'rgb(55, 56, 56)', @@ -317,17 +318,20 @@ export default { return this.$secondsToTimestamp(this.totalDuration) }, currentTimePretty() { - return this.$secondsToTimestamp(this.currentTime / this.currentPlaybackRate) + let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime + return this.$secondsToTimestamp(currentTimeToUse / this.currentPlaybackRate) }, timeRemaining() { + let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime if (this.useChapterTrack && this.currentChapter) { - var currChapTime = this.currentTime - this.currentChapter.start + var currChapTime = currentTimeToUse - this.currentChapter.start return (this.currentChapterDuration - currChapTime) / this.currentPlaybackRate } return this.totalTimeRemaining }, totalTimeRemaining() { - return (this.totalDuration - this.currentTime) / this.currentPlaybackRate + let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime + return (this.totalDuration - currentTimeToUse) / this.currentPlaybackRate }, totalTimeRemainingPretty() { if (this.totalTimeRemaining < 0) { @@ -341,10 +345,6 @@ export default { } return '-' + this.$secondsToTimestamp(this.timeRemaining) }, - timeLeftInChapter() { - if (!this.currentChapter) return 0 - return this.currentChapter.end - this.currentTime - }, sleepTimeRemainingPretty() { if (!this.sleepTimeRemaining) return '0s' var secondsRemaining = Math.round(this.sleepTimeRemaining) @@ -391,11 +391,6 @@ export default { this.showFullscreen = false } }, - async touchstartTrack(e) { - await this.$hapticsImpact() - if (!e || !e.touches || !this.$refs.track || !this.showFullscreen || this.lockUi) return - this.touchTrackStart = true - }, async selectChapter(chapter) { await this.$hapticsImpact() this.seek(chapter.start) @@ -507,12 +502,13 @@ export default { console.error('No timestamp el') return } - let currentTime = this.currentTime / this.currentPlaybackRate + + let currentTime = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime if (this.useChapterTrack && this.currentChapter) { - const currChapTime = Math.max(0, this.currentTime - this.currentChapter.start) - currentTime = currChapTime / this.currentPlaybackRate + currentTime = Math.max(0, currentTime - this.currentChapter.start) } - ts.innerText = this.$secondsToTimestamp(currentTime) + + ts.innerText = this.$secondsToTimestamp(currentTime / this.currentPlaybackRate) }, timeupdate() { if (!this.$refs.playedTrack) { @@ -534,22 +530,25 @@ export default { }, updateTrack() { // Update progress track UI - let percentDone = this.currentTime / this.totalDuration + let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime + let percentDone = currentTimeToUse / this.totalDuration const totalPercentDone = percentDone let bufferedPercent = this.bufferedTime / this.totalDuration const totalBufferedPercent = bufferedPercent if (this.useChapterTrack && this.currentChapter) { - const currChapTime = this.currentTime - this.currentChapter.start + const currChapTime = currentTimeToUse - this.currentChapter.start percentDone = currChapTime / this.currentChapterDuration bufferedPercent = Math.max(0, Math.min(1, (this.bufferedTime - this.currentChapter.start) / this.currentChapterDuration)) } + const ptWidth = Math.round(percentDone * this.trackWidth) this.$refs.playedTrack.style.width = ptWidth + 'px' this.$refs.bufferedTrack.style.width = Math.round(bufferedPercent * this.trackWidth) + 'px' if (this.$refs.trackCursor) { - this.$refs.trackCursor.style.left = ptWidth - 8 + 'px' + const cursorShift = this.isDraggingCursor ? 7 : 6 + this.$refs.trackCursor.style.left = ptWidth - cursorShift + 'px' } if (this.useChapterTrack) { @@ -578,27 +577,14 @@ export default { this.$refs.playedTrack.classList.add('bg-yellow-300') } }, - clickTrack(e) { - if (this.isLoading || this.lockUi) return - if (!this.showFullscreen) { - // Track not clickable on mini-player - return - } - if (e) e.stopPropagation() - - var offsetX = e.offsetX - var perc = offsetX / this.trackWidth - var time = 0 - if (this.useChapterTrack && this.currentChapter) { - time = perc * this.currentChapterDuration + this.currentChapter.start - } else { - time = perc * this.totalDuration - } - if (isNaN(time) || time === null) { - console.error('Invalid time', perc, time) - return - } - this.seek(time) + async touchstartCursor(e) { + if (!e || !e.touches || !this.$refs.track || !this.showFullscreen || this.lockUi) return + await this.$hapticsImpact() + this.isDraggingCursor = true + this.draggingTouchStartX = e.touches[0].pageX + this.draggingTouchStartTime = this.currentTime + this.draggingCurrentTime = this.currentTime + this.updateTrack() }, async playPauseClick() { await this.$hapticsImpact() @@ -651,24 +637,11 @@ export default { touchend(e) { if (!e.changedTouches) return - if (this.touchTrackStart) { - var touch = e.changedTouches[0] - const touchOnTrackPos = touch.pageX - 12 - const dragPercent = Math.max(0, Math.min(1, touchOnTrackPos / this.trackWidth)) - - var seekToTime = 0 - if (this.useChapterTrack && this.currentChapter) { - const currChapTime = dragPercent * this.currentChapterDuration - seekToTime = this.currentChapter.start + currChapTime - } else { - seekToTime = dragPercent * this.totalDuration + if (this.isDraggingCursor) { + if (this.draggingCurrentTime !== this.currentTime) { + this.seek(this.draggingCurrentTime) } - this.seek(seekToTime) - - if (this.$refs.draggingTrack) { - this.$refs.draggingTrack.style.width = '0px' - } - this.touchTrackStart = false + this.isDraggingCursor = false } else if (this.showFullscreen) { this.touchEndY = e.changedTouches[0].screenY var touchDuration = Date.now() - this.touchStartTime @@ -680,29 +653,24 @@ export default { } }, touchmove(e) { - if (!this.touchTrackStart) return + if (!this.isDraggingCursor || !e.touches) return - var touch = e.touches[0] - const touchOnTrackPos = touch.pageX - 12 - const dragPercent = Math.max(0, Math.min(1, touchOnTrackPos / this.trackWidth)) - this.dragPercent = dragPercent - - if (this.$refs.draggingTrack) { - this.$refs.draggingTrack.style.width = this.dragPercent * this.trackWidth + 'px' + const distanceMoved = e.touches[0].pageX - this.draggingTouchStartX + let duration = this.totalDuration + let minTime = 0 + let maxTime = duration + if (this.useChapterTrack && this.currentChapter) { + duration = this.currentChapterDuration + minTime = this.currentChapter.start + maxTime = minTime + duration } - var ts = this.$refs.currentTimestamp - if (ts) { - var currTimeStr = '' - if (this.useChapterTrack && this.currentChapter) { - const currChapTime = dragPercent * this.currentChapterDuration - currTimeStr = this.$secondsToTimestamp(currChapTime) - } else { - const dragTime = dragPercent * this.totalDuration - currTimeStr = this.$secondsToTimestamp(dragTime) - } - ts.innerText = currTimeStr - } + const timePerPixel = duration / this.trackWidth + const newTime = this.draggingTouchStartTime + timePerPixel * distanceMoved + this.draggingCurrentTime = Math.min(maxTime, Math.max(minTime, newTime)) + + this.updateTimestamp() + this.updateTrack() }, async clickMenuAction(action) { await this.$hapticsImpact() @@ -848,7 +816,7 @@ export default { document.documentElement.style.setProperty('--cover-image-height', coverHeight + 'px') document.documentElement.style.setProperty('--cover-image-width-collapsed', coverImageWidthCollapsed + 'px') document.documentElement.style.setProperty('--cover-image-height-collapsed', 46 + 'px') - document.documentElement.style.setProperty('--title-author-left-offset-collapsed', 24 + coverImageWidthCollapsed + 'px') + document.documentElement.style.setProperty('--title-author-left-offset-collapsed', 30 + coverImageWidthCollapsed + 'px') }, minimizePlayerEvt() { this.collapseFullscreen() @@ -915,7 +883,7 @@ export default { --cover-image-height: 0px; --cover-image-width-collapsed: 46px; --cover-image-height-collapsed: 46px; - --title-author-left-offset-collapsed: 70px; + --title-author-left-offset-collapsed: 80px; } .playerContainer { @@ -942,7 +910,7 @@ export default { .cover-wrapper { bottom: 68px; - left: 12px; + left: 24px; height: var(--cover-image-height-collapsed); width: var(--cover-image-width-collapsed); transition: all 0.25s cubic-bezier(0.39, 0.575, 0.565, 1); @@ -999,9 +967,8 @@ export default { #playerControls { transition: all 0.15s cubic-bezier(0.39, 0.575, 0.565, 1); transition-property: width, bottom; - width: 140px; - padding-left: 12px; - padding-right: 12px; + width: 128px; + padding-right: 24px; bottom: 70px; } #playerControls .jump-icon { @@ -1019,7 +986,7 @@ export default { width: 40px; min-width: 40px; min-height: 40px; - margin: 0px 14px; + margin: 0px 7px; } #playerControls .play-btn .material-icons { transition: all 0.15s cubic-bezier(0.39, 0.575, 0.565, 1); diff --git a/tailwind.config.js b/tailwind.config.js index 714690d0..094947ac 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -50,6 +50,9 @@ module.exports = { }, minHeight: { '12': '3rem' + }, + spacing: { + '0.75': '0.1875rem' } } },