mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Audio player next/prev chapter buttons
This commit is contained in:
		
							parent
							
								
									3171ce5aba
								
							
						
					
					
						commit
						2d5e4ebcf0
					
				| @ -38,6 +38,12 @@ export default { | ||||
|     userIsAdminOrUp() { | ||||
|       return this.$store.getters['user/getIsAdminOrUp'] | ||||
|     }, | ||||
|     user() { | ||||
|       return this.$store.state.user.user || {} | ||||
|     }, | ||||
|     userId() { | ||||
|       return this.user.id | ||||
|     }, | ||||
|     configRoutes() { | ||||
|       if (!this.userIsAdminOrUp) { | ||||
|         return [ | ||||
| @ -87,6 +93,11 @@ export default { | ||||
|           title: 'Your Stats', | ||||
|           path: '/config/stats' | ||||
|         }) | ||||
|         configRoutes.push({ | ||||
|           id: 'config-users-id-sessions', | ||||
|           title: 'Your Sessions', | ||||
|           path: `/config/users/${this.userId}/sessions` | ||||
|         }) | ||||
|       } | ||||
| 
 | ||||
|       return configRoutes | ||||
|  | ||||
| @ -2,18 +2,21 @@ | ||||
|   <div class="flex pt-4 pb-2 md:pt-0 md:pb-2"> | ||||
|     <div class="flex-grow" /> | ||||
|     <template v-if="!loading"> | ||||
|       <div class="cursor-pointer flex items-center justify-center text-gray-300 mr-8" @mousedown.prevent @mouseup.prevent @click.stop="restart"> | ||||
|       <div class="cursor-pointer flex items-center justify-center text-gray-300 mr-4 md:mr-8" @mousedown.prevent @mouseup.prevent @click.stop="prevChapter"> | ||||
|         <span class="material-icons text-3xl">first_page</span> | ||||
|       </div> | ||||
|       <div class="cursor-pointer flex items-center justify-center text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward"> | ||||
|         <span class="material-icons text-3xl">replay_10</span> | ||||
|       </div> | ||||
|       <div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause"> | ||||
|       <div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-4 md:mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause"> | ||||
|         <span class="material-icons">{{ seekLoading ? 'autorenew' : paused ? 'play_arrow' : 'pause' }}</span> | ||||
|       </div> | ||||
|       <div class="cursor-pointer flex items-center justify-center text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpForward"> | ||||
|         <span class="material-icons text-3xl">forward_10</span> | ||||
|       </div> | ||||
|       <div class="flex items-center justify-center ml-4 md:ml-8" :class="hasNextChapter ? 'text-gray-300 cursor-pointer' : 'text-gray-500'" @mousedown.prevent @mouseup.prevent @click.stop="nextChapter"> | ||||
|         <span class="material-icons text-3xl">last_page</span> | ||||
|       </div> | ||||
|       <controls-playback-speed-control v-model="playbackRate" @input="playbackRateUpdated" @change="playbackRateChanged" /> | ||||
|     </template> | ||||
|     <template v-else> | ||||
| @ -31,7 +34,8 @@ export default { | ||||
|     loading: Boolean, | ||||
|     seekLoading: Boolean, | ||||
|     playbackRate: Number, | ||||
|     paused: Boolean | ||||
|     paused: Boolean, | ||||
|     hasNextChapter: Boolean | ||||
|   }, | ||||
|   data() { | ||||
|     return {} | ||||
| @ -41,8 +45,12 @@ export default { | ||||
|     playPause() { | ||||
|       this.$emit('playPause') | ||||
|     }, | ||||
|     restart() { | ||||
|       this.$emit('restart') | ||||
|     prevChapter() { | ||||
|       this.$emit('prevChapter') | ||||
|     }, | ||||
|     nextChapter() { | ||||
|       if (!this.hasNextChapter) return | ||||
|       this.$emit('nextChapter') | ||||
|     }, | ||||
|     jumpBackward() { | ||||
|       this.$emit('jumpBackward') | ||||
|  | ||||
| @ -23,7 +23,7 @@ | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|       <player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate="playbackRate" :paused="paused" @restart="restart" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setPlaybackRate="setPlaybackRate" @playPause="playPause" /> | ||||
|       <player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate="playbackRate" :paused="paused" :has-next-chapter="hasNextChapter" @prevChapter="prevChapter" @nextChapter="nextChapter" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setPlaybackRate="setPlaybackRate" @playPause="playPause" /> | ||||
|     </div> | ||||
| 
 | ||||
|     <player-track-bar ref="trackbar" :loading="loading" :chapters="chapters" :duration="duration" @seek="seek" /> | ||||
| @ -106,6 +106,14 @@ export default { | ||||
|     }, | ||||
|     isFullscreen() { | ||||
|       return this.$store.state.playerIsFullscreen | ||||
|     }, | ||||
|     currentChapterIndex() { | ||||
|       if (!this.currentChapter) return 0 | ||||
|       return this.chapters.findIndex((ch) => ch.id === this.currentChapter.id) | ||||
|     }, | ||||
|     hasNextChapter() { | ||||
|       if (!this.chapters.length) return false | ||||
|       return this.currentChapterIndex < this.chapters.length - 1 | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
| @ -190,6 +198,23 @@ export default { | ||||
|     restart() { | ||||
|       this.seek(0) | ||||
|     }, | ||||
|     prevChapter() { | ||||
|       if (!this.currentChapter || this.currentChapterIndex === 0) { | ||||
|         return this.restart() | ||||
|       } | ||||
|       var timeInCurrentChapter = this.currentTime - this.currentChapter.start | ||||
|       if (timeInCurrentChapter <= 3 && this.chapters[this.currentChapterIndex - 1]) { | ||||
|         var prevChapter = this.chapters[this.currentChapterIndex - 1] | ||||
|         this.seek(prevChapter.start) | ||||
|       } else { | ||||
|         this.seek(this.currentChapter.start) | ||||
|       } | ||||
|     }, | ||||
|     nextChapter() { | ||||
|       if (!this.currentChapter || !this.hasNextChapter) return | ||||
|       var nextChapter = this.chapters[this.currentChapterIndex + 1] | ||||
|       this.seek(nextChapter.start) | ||||
|     }, | ||||
|     setStreamReady() { | ||||
|       if (this.$refs.trackbar) this.$refs.trackbar.setPercentageReady(1) | ||||
|     }, | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| <template> | ||||
|   <div id="page-wrapper" class="bg-bg page overflow-y-auto p-8" :class="streamLibraryItem ? 'streaming' : ''"> | ||||
|   <div id="page-wrapper" class="bg-bg page overflow-y-auto p-4 md:p-8" :class="streamLibraryItem ? 'streaming' : ''"> | ||||
|     <div class="max-w-6xl mx-auto"> | ||||
|       <div class="flex mb-6"> | ||||
|       <div class="flex flex-wrap sm:flex-nowrap justify-center mb-6"> | ||||
|         <div class="w-48 min-w-48"> | ||||
|           <div class="w-full h-52"> | ||||
|             <covers-author-image :author="author" rounded="0" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="flex-grow px-8"> | ||||
|         <div class="flex-grow py-4 sm:py-0 px-4 md:px-8"> | ||||
|           <div class="flex items-center mb-8"> | ||||
|             <h1 class="text-2xl">{{ author.name }}</h1> | ||||
| 
 | ||||
|  | ||||
| @ -124,6 +124,8 @@ export default class CastPlayer extends EventEmitter { | ||||
| 
 | ||||
|   async seek(time, playWhenReady) { | ||||
|     if (!this.player) return | ||||
| 
 | ||||
|     this.playWhenReady = playWhenReady | ||||
|     if (time < this.currentTrack.startOffset || time > this.currentTrack.startOffset + this.currentTrack.duration) { | ||||
|       // Change Track
 | ||||
|       var request = buildCastLoadRequest(this.libraryItem, this.coverUrl, this.audioTracks, time, playWhenReady, this.defaultPlaybackRate) | ||||
|  | ||||
| @ -71,7 +71,7 @@ export default class LocalAudioPlayer extends EventEmitter { | ||||
|       console.log(`[LocalPlayer] Track ended - loading next track ${this.currentTrackIndex + 1}`) | ||||
|       // Has next track
 | ||||
|       this.currentTrackIndex++ | ||||
|       this.playWhenReady = true | ||||
|       this.playWhenReady = !this.player.paused | ||||
|       this.startTime = this.currentTrack.startOffset | ||||
|       this.loadCurrentTrack() | ||||
|     } else { | ||||
| @ -89,6 +89,7 @@ export default class LocalAudioPlayer extends EventEmitter { | ||||
|     } | ||||
| 
 | ||||
|     this.emit('stateChange', 'LOADED') | ||||
| 
 | ||||
|     if (this.playWhenReady) { | ||||
|       this.playWhenReady = false | ||||
|       this.play() | ||||
| @ -229,8 +230,11 @@ export default class LocalAudioPlayer extends EventEmitter { | ||||
|     this.player.playbackRate = playbackRate | ||||
|   } | ||||
| 
 | ||||
|   seek(time) { | ||||
|   seek(time, playWhenReady) { | ||||
|     if (!this.player) return | ||||
| 
 | ||||
|     this.playWhenReady = playWhenReady | ||||
| 
 | ||||
|     if (this.isHlsTranscode) { | ||||
|       // Seeking HLS stream
 | ||||
|       var offsetTime = time - (this.currentTrack.startOffset || 0) | ||||
| @ -255,7 +259,6 @@ export default class LocalAudioPlayer extends EventEmitter { | ||||
|         this.player.currentTime = Math.max(0, offsetTime) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
|   setVolume(volume) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user