diff --git a/pages/item/_id/_episode/index.vue b/pages/item/_id/_episode/index.vue index d178dab1..c33ee6f4 100644 --- a/pages/item/_id/_episode/index.vue +++ b/pages/item/_id/_episode/index.vue @@ -41,7 +41,7 @@ -

+

@@ -116,6 +116,9 @@ export default { } }, computed: { + transformedDescription() { + return this.parseDescription(this.description) + }, bookCoverAspectRatio() { return this.$store.getters['libraries/getBookCoverAspectRatio'] }, @@ -310,6 +313,24 @@ export default { } }, methods: { + parseDescription(description) { + const timeMarkerLinkRegex = /(.*?)<\/a>/g + const timeMarkerRegex = /\b\d{1,2}:\d{1,2}(?::\d{1,2})?\b/g + + function convertToSeconds(time) { + const timeParts = time.split(':').map(Number) + return timeParts.reduce((acc, part, index) => acc * 60 + part, 0) + } + + return description.replace(timeMarkerLinkRegex, (match, href, displayTime) => { + const time = displayTime.match(timeMarkerRegex)[0] + const seekTimeInSeconds = convertToSeconds(time) + return `${displayTime}` + }).replace(timeMarkerRegex, (match) => { + const seekTimeInSeconds = convertToSeconds(match) + return `${match}` + }) + }, async deleteLocalEpisode() { await this.$hapticsImpact() @@ -351,23 +372,48 @@ export default { } else { this.$store.commit('setPlayerIsStartingPlayback', this.episode.id) - if (this.localEpisodeId && this.localLibraryItemId && !this.isLocal) { - console.log('Play local episode', this.localEpisodeId, this.localLibraryItemId) + const playbackData = this.generatePlaybackData() + this.emitPlayItemEvent(playbackData) + } + }, + async clickPlaybackTime(event) { + const startTime = event.target.getAttribute('data-time') + if (this.playerIsStartingPlayback) return - this.$eventBus.$emit('play-item', { - libraryItemId: this.localLibraryItemId, - episodeId: this.localEpisodeId, - serverLibraryItemId: this.serverLibraryItemId, - serverEpisodeId: this.serverEpisodeId - }) - } else { - this.$eventBus.$emit('play-item', { - libraryItemId: this.libraryItemId, - episodeId: this.episode.id, - serverLibraryItemId: this.serverLibraryItemId, - serverEpisodeId: this.serverEpisodeId - }) - } + await this.$hapticsImpact() + + this.$store.commit('setPlayerIsStartingPlayback', this.episode.id) + + const playbackData = this.generatePlaybackData(startTime) + this.emitPlayItemEvent(playbackData) + }, + generatePlaybackData(startTime) { + const playbackData = { + libraryItemId: this.libraryItemId, + episodeId: this.episode.id, + serverLibraryItemId: this.serverLibraryItemId, + serverEpisodeId: this.serverEpisodeId, + startTime + } + + if (this.localEpisodeId && this.localLibraryItemId && !this.isLocal) { + playbackData.libraryItemId = this.localLibraryItemId + playbackData.episodeId = this.localEpisodeId + } + + return playbackData + }, + emitPlayItemEvent(playbackData) { + this.$eventBus.$emit('play-item', playbackData) + }, + bindTimeMarkerEvents() { + const container = document.querySelector('.description-container') + if (container) { + container.addEventListener('click', (event) => { + if (event.target.classList.contains('time-marker')) { + this.clickPlaybackTime(event) + } + }) } }, async downloadClick() { @@ -557,9 +603,13 @@ export default { }, mounted() { this.$eventBus.$on('new-local-library-item', this.newLocalLibraryItem) + this.bindTimeMarkerEvents() }, beforeDestroy() { this.$eventBus.$off('new-local-library-item', this.newLocalLibraryItem) + document.querySelectorAll('.time-marker').forEach(marker => { + marker.removeEventListener('click', this.clickPlaybackTime) + }) } } - \ No newline at end of file +