mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Player queue for audiobooks #1077
This commit is contained in:
		
							parent
							
								
									3357ccfaf3
								
							
						
					
					
						commit
						78559520ab
					
				@ -477,6 +477,21 @@ export default {
 | 
			
		||||
          text: this.$strings.ButtonRemoveFromContinueListening
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      if (!this.isPodcast) {
 | 
			
		||||
        if (this.libraryItemIdStreaming && !this.isStreamingFromDifferentLibrary) {
 | 
			
		||||
          if (!this.isQueued) {
 | 
			
		||||
            items.push({
 | 
			
		||||
              func: 'addToQueue',
 | 
			
		||||
              text: this.$strings.ButtonQueueAddItem
 | 
			
		||||
            })
 | 
			
		||||
          } else if (!this.isStreaming) {
 | 
			
		||||
            items.push({
 | 
			
		||||
              func: 'removeFromQueue',
 | 
			
		||||
              text: this.$strings.ButtonQueueRemoveItem
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return items
 | 
			
		||||
    },
 | 
			
		||||
    _socket() {
 | 
			
		||||
@ -690,8 +705,9 @@ export default {
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    addToQueue() {
 | 
			
		||||
      var queueItem = {}
 | 
			
		||||
      if (this.recentEpisode) {
 | 
			
		||||
        const queueItem = {
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          libraryId: this.libraryId,
 | 
			
		||||
          episodeId: this.recentEpisode.id,
 | 
			
		||||
@ -701,8 +717,19 @@ export default {
 | 
			
		||||
          duration: this.recentEpisode.audioFile.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
        this.store.commit('addItemToQueue', queueItem)
 | 
			
		||||
      } else {
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          libraryId: this.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: this.title,
 | 
			
		||||
          subtitle: this.author,
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: this.media.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      this.store.commit('addItemToQueue', queueItem)
 | 
			
		||||
    },
 | 
			
		||||
    removeFromQueue() {
 | 
			
		||||
      const episodeId = this.recentEpisode ? this.recentEpisode.id : null
 | 
			
		||||
@ -815,6 +842,18 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        const queueItem = {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          libraryId: this.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: this.title,
 | 
			
		||||
          subtitle: this.author,
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: this.media.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
        queueItems.push(queueItem)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      eventBus.$emit('play-item', {
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
      <div v-show="showCoverBg" class="absolute top-0 left-0 w-full h-full overflow-hidden rounded-sm bg-primary">
 | 
			
		||||
        <div class="absolute cover-bg" ref="coverBg" />
 | 
			
		||||
      </div>
 | 
			
		||||
      <img ref="cover" :src="cover" @error="imageError" @load="imageLoaded" class="w-full h-full absolute top-0 left-0" :class="showCoverBg ? 'object-contain' : 'object-cover'" />
 | 
			
		||||
      <img ref="cover" :src="cover" @error="imageError" @load="imageLoaded" class="w-full h-full absolute top-0 left-0" :class="showCoverBg ? 'object-contain' : 'object-fill'" />
 | 
			
		||||
 | 
			
		||||
      <a v-if="!imageFailed && showOpenNewTab && isHovering" :href="cover" @click.stop target="_blank" class="absolute bg-primary flex items-center justify-center shadow-sm rounded-full hover:scale-110 transform duration-100" :style="{ top: sizeMultiplier * 0.5 + 'rem', right: sizeMultiplier * 0.5 + 'rem', width: 2.5 * sizeMultiplier + 'rem', height: 2.5 * sizeMultiplier + 'rem' }">
 | 
			
		||||
        <span class="material-icons" :style="{ fontSize: sizeMultiplier * 1.75 + 'rem' }">open_in_new</span>
 | 
			
		||||
@ -63,6 +63,9 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    resolution() {
 | 
			
		||||
      return `${this.naturalWidth}x${this.naturalHeight}px`
 | 
			
		||||
    },
 | 
			
		||||
    placeholderUrl() {
 | 
			
		||||
      return `${this.$config.routerBasePath}/book_placeholder.jpg`
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
@ -72,7 +75,7 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    imageLoaded() {
 | 
			
		||||
      if (this.$refs.cover) {
 | 
			
		||||
      if (this.$refs.cover && this.src !== this.placeholderUrl) {
 | 
			
		||||
        var { naturalWidth, naturalHeight } = this.$refs.cover
 | 
			
		||||
        this.naturalHeight = naturalHeight
 | 
			
		||||
        this.naturalWidth = naturalWidth
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
      <p v-if="caption" class="text-gray-400 text-xs">{{ caption }}</p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="w-28">
 | 
			
		||||
      <p v-if="isOpenInPlayer" class="text-sm text-right text-gray-400">Streaming</p>
 | 
			
		||||
      <p v-if="isOpenInPlayer" class="text-sm text-right text-gray-400">{{ $strings.ButtonPlaying }}</p>
 | 
			
		||||
      <div v-else-if="isHovering" class="flex items-center justify-end -mx-1">
 | 
			
		||||
        <button class="outline-none mx-1 flex items-center" @click.stop="playClick">
 | 
			
		||||
          <span class="material-icons text-success">play_arrow</span>
 | 
			
		||||
 | 
			
		||||
@ -2,13 +2,13 @@
 | 
			
		||||
  <modals-modal v-model="show" name="queue-items" :width="800" :height="'unset'">
 | 
			
		||||
    <template #outer>
 | 
			
		||||
      <div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden">
 | 
			
		||||
        <p class="font-book text-3xl text-white truncate">Player Queue</p>
 | 
			
		||||
        <p class="font-book text-3xl text-white truncate">{{ $strings.HeaderPlayerQueue }}</p>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <div ref="container" class="w-full rounded-lg bg-bg box-shadow-md overflow-y-auto overflow-x-hidden py-4" style="max-height: 80vh">
 | 
			
		||||
      <div v-if="show" class="w-full h-full">
 | 
			
		||||
        <div class="pb-4 px-4 flex items-center">
 | 
			
		||||
          <p class="text-base text-gray-200">Player Queue</p>
 | 
			
		||||
          <p class="text-base text-gray-200">{{ $strings.HeaderPlayerQueue }}</p>
 | 
			
		||||
          <p class="text-base text-gray-400 px-4">{{ playerQueueItems.length }} Items</p>
 | 
			
		||||
          <div class="flex-grow" />
 | 
			
		||||
          <ui-checkbox v-model="playerQueueAutoPlay" label="Auto Play" medium checkbox-bg="primary" border-color="gray-600" label-class="pl-2 mb-px" />
 | 
			
		||||
 | 
			
		||||
@ -22,15 +22,15 @@
 | 
			
		||||
          <span class="material-icons text-2xl sm:text-3xl">format_list_bulleted</span>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <button v-if="playerQueueItems.length" class="outline-none text-gray-300 mx-1 lg:mx-2 hover:text-white" @mousedown.prevent @mouseup.prevent @click.stop="$emit('showPlayerQueueItems')">
 | 
			
		||||
          <span class="material-icons text-2xl sm:text-3xl">queue_music</span>
 | 
			
		||||
        </button>
 | 
			
		||||
 | 
			
		||||
        <ui-tooltip v-if="chapters.length" direction="top" :text="useChapterTrack ? $strings.LabelUseFullTrack : $strings.LabelUseChapterTrack">
 | 
			
		||||
          <div class="cursor-pointer text-gray-300 mx-1 lg:mx-2 hover:text-white" @mousedown.prevent @mouseup.prevent @click.stop="setUseChapterTrack">
 | 
			
		||||
            <span class="material-icons text-2xl sm:text-3xl transform transition-transform" :class="useChapterTrack ? 'rotate-180' : ''">timelapse</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </ui-tooltip>
 | 
			
		||||
 | 
			
		||||
        <button v-if="playerQueueItems.length" class="outline-none text-gray-300 mx-1 lg:mx-2 hover:text-white" @mousedown.prevent @mouseup.prevent @click.stop="$emit('showPlayerQueueItems')">
 | 
			
		||||
          <span class="material-icons text-2xl sm:text-3xl">queue_music</span>
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate.sync="playbackRate" :paused="paused" :has-next-chapter="hasNextChapter" @prevChapter="prevChapter" @nextChapter="nextChapter" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setPlaybackRate="setPlaybackRate" @playPause="playPause" />
 | 
			
		||||
 | 
			
		||||
@ -72,11 +72,23 @@ export default {
 | 
			
		||||
      this.expanded = !this.expanded
 | 
			
		||||
    },
 | 
			
		||||
    goToTimestamp(time) {
 | 
			
		||||
      const queueItem = {
 | 
			
		||||
        libraryItemId: this.libraryItemId,
 | 
			
		||||
        libraryId: this.libraryItem.libraryId,
 | 
			
		||||
        episodeId: null,
 | 
			
		||||
        title: this.metadata.title,
 | 
			
		||||
        subtitle: this.metadata.authors.map((au) => au.name).join(', '),
 | 
			
		||||
        caption: '',
 | 
			
		||||
        duration: this.media.duration || null,
 | 
			
		||||
        coverPath: this.media.coverPath || null
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (this.$store.getters['getIsMediaStreaming'](this.libraryItemId)) {
 | 
			
		||||
        this.$eventBus.$emit('play-item', {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          startTime: time
 | 
			
		||||
          startTime: time,
 | 
			
		||||
          queueItems: [queueItem]
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        const payload = {
 | 
			
		||||
@ -86,7 +98,8 @@ export default {
 | 
			
		||||
              this.$eventBus.$emit('play-item', {
 | 
			
		||||
                libraryItemId: this.libraryItemId,
 | 
			
		||||
                episodeId: null,
 | 
			
		||||
                startTime: time
 | 
			
		||||
                startTime: time,
 | 
			
		||||
                queueItems: [queueItem]
 | 
			
		||||
              })
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
 | 
			
		||||
@ -137,8 +137,22 @@ export default {
 | 
			
		||||
      this.isHovering = false
 | 
			
		||||
    },
 | 
			
		||||
    playClick() {
 | 
			
		||||
      const queueItems = [
 | 
			
		||||
        {
 | 
			
		||||
          libraryItemId: this.book.id,
 | 
			
		||||
          libraryId: this.book.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: this.bookTitle,
 | 
			
		||||
          subtitle: this.bookAuthors.map((au) => au.name).join(', '),
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: this.media.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
 | 
			
		||||
      this.$eventBus.$emit('play-item', {
 | 
			
		||||
        libraryItemId: this.book.id
 | 
			
		||||
        libraryItemId: this.book.id,
 | 
			
		||||
        queueItems
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    clickEdit() {
 | 
			
		||||
 | 
			
		||||
@ -122,13 +122,42 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    clickPlay() {
 | 
			
		||||
      var nextBookNotRead = this.playableBooks.find((pb) => {
 | 
			
		||||
        var prog = this.$store.getters['user/getUserMediaProgress'](pb.id)
 | 
			
		||||
        return !prog || !prog.isFinished
 | 
			
		||||
      const queueItems = []
 | 
			
		||||
 | 
			
		||||
      // Collection queue will start at the first unfinished book
 | 
			
		||||
      //   if all books are finished then entire collection is queued
 | 
			
		||||
      const itemsWithProgress = this.playableBooks.map((item) => {
 | 
			
		||||
        return {
 | 
			
		||||
          ...item,
 | 
			
		||||
          progress: this.$store.getters['user/getUserMediaProgress'](item.id)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      if (nextBookNotRead) {
 | 
			
		||||
 | 
			
		||||
      const hasUnfinishedItems = itemsWithProgress.some((i) => !i.progress || !i.progress.isFinished)
 | 
			
		||||
      if (!hasUnfinishedItems) {
 | 
			
		||||
        console.warn('All items in collection are finished - starting at first item')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for (let i = 0; i < itemsWithProgress.length; i++) {
 | 
			
		||||
        const libraryItem = itemsWithProgress[i]
 | 
			
		||||
        if (!hasUnfinishedItems || !libraryItem.progress || !libraryItem.progress.isFinished) {
 | 
			
		||||
          queueItems.push({
 | 
			
		||||
            libraryItemId: libraryItem.id,
 | 
			
		||||
            libraryId: libraryItem.libraryId,
 | 
			
		||||
            episodeId: null,
 | 
			
		||||
            title: libraryItem.media.metadata.title,
 | 
			
		||||
            subtitle: libraryItem.media.metadata.authors.map((au) => au.name).join(', '),
 | 
			
		||||
            caption: '',
 | 
			
		||||
            duration: libraryItem.media.duration || null,
 | 
			
		||||
            coverPath: libraryItem.media.coverPath || null
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (queueItems.length >= 0) {
 | 
			
		||||
        this.$eventBus.$emit('play-item', {
 | 
			
		||||
          libraryItemId: nextBookNotRead.id
 | 
			
		||||
          libraryItemId: queueItems[0].libraryItemId,
 | 
			
		||||
          queueItems
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -127,12 +127,38 @@ export default {
 | 
			
		||||
        this.processingGoToTimestamp = false
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      if (session.episodeId && !libraryItem.media.episodes.find((ep) => ep.id === session.episodeId)) {
 | 
			
		||||
      if (session.episodeId && !libraryItem.media.episodes.some((ep) => ep.id === session.episodeId)) {
 | 
			
		||||
        this.$toast.error('Failed to get podcast episode')
 | 
			
		||||
        this.processingGoToTimestamp = false
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var queueItem = {}
 | 
			
		||||
      if (session.episodeId) {
 | 
			
		||||
        var episode = libraryItem.media.episodes.find((ep) => ep.id === session.episodeId)
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: libraryItem.id,
 | 
			
		||||
          libraryId: libraryItem.libraryId,
 | 
			
		||||
          episodeId: episode.id,
 | 
			
		||||
          title: episode.title,
 | 
			
		||||
          subtitle: libraryItem.media.metadata.title,
 | 
			
		||||
          caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, 'MMM do, yyyy')}` : 'Unknown publish date',
 | 
			
		||||
          duration: episode.audioFile.duration || null,
 | 
			
		||||
          coverPath: libraryItem.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: libraryItem.id,
 | 
			
		||||
          libraryId: libraryItem.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: libraryItem.media.metadata.title,
 | 
			
		||||
          subtitle: libraryItem.media.metadata.authors.map((au) => au.name).join(', '),
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: libraryItem.media.duration || null,
 | 
			
		||||
          coverPath: libraryItem.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const payload = {
 | 
			
		||||
        message: this.$getString('MessageStartPlaybackAtTime', [session.displayTitle, this.$secondsToTimestamp(session.currentTime)]),
 | 
			
		||||
        callback: (confirmed) => {
 | 
			
		||||
@ -140,7 +166,8 @@ export default {
 | 
			
		||||
            this.$eventBus.$emit('play-item', {
 | 
			
		||||
              libraryItemId: libraryItem.id,
 | 
			
		||||
              episodeId: session.episodeId || null,
 | 
			
		||||
              startTime: session.currentTime
 | 
			
		||||
              startTime: session.currentTime,
 | 
			
		||||
              queueItems: [queueItem]
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
          this.processingGoToTimestamp = false
 | 
			
		||||
 | 
			
		||||
@ -114,12 +114,38 @@ export default {
 | 
			
		||||
        this.processingGoToTimestamp = false
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      if (session.episodeId && !libraryItem.media.episodes.find((ep) => ep.id === session.episodeId)) {
 | 
			
		||||
      if (session.episodeId && !libraryItem.media.episodes.some((ep) => ep.id === session.episodeId)) {
 | 
			
		||||
        this.$toast.error('Failed to get podcast episode')
 | 
			
		||||
        this.processingGoToTimestamp = false
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var queueItem = {}
 | 
			
		||||
      if (session.episodeId) {
 | 
			
		||||
        var episode = libraryItem.media.episodes.find((ep) => ep.id === session.episodeId)
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: libraryItem.id,
 | 
			
		||||
          libraryId: libraryItem.libraryId,
 | 
			
		||||
          episodeId: episode.id,
 | 
			
		||||
          title: episode.title,
 | 
			
		||||
          subtitle: libraryItem.media.metadata.title,
 | 
			
		||||
          caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, 'MMM do, yyyy')}` : 'Unknown publish date',
 | 
			
		||||
          duration: episode.audioFile.duration || null,
 | 
			
		||||
          coverPath: libraryItem.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        queueItem = {
 | 
			
		||||
          libraryItemId: libraryItem.id,
 | 
			
		||||
          libraryId: libraryItem.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: libraryItem.media.metadata.title,
 | 
			
		||||
          subtitle: libraryItem.media.metadata.authors.map((au) => au.name).join(', '),
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: libraryItem.media.duration || null,
 | 
			
		||||
          coverPath: libraryItem.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const payload = {
 | 
			
		||||
        message: this.$getString('MessageStartPlaybackAtTime', [session.displayTitle, this.$secondsToTimestamp(session.currentTime)]),
 | 
			
		||||
        callback: (confirmed) => {
 | 
			
		||||
@ -127,7 +153,8 @@ export default {
 | 
			
		||||
            this.$eventBus.$emit('play-item', {
 | 
			
		||||
              libraryItemId: libraryItem.id,
 | 
			
		||||
              episodeId: session.episodeId || null,
 | 
			
		||||
              startTime: session.currentTime
 | 
			
		||||
              startTime: session.currentTime,
 | 
			
		||||
              queueItems: [queueItem]
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
          this.processingGoToTimestamp = false
 | 
			
		||||
 | 
			
		||||
@ -137,12 +137,16 @@
 | 
			
		||||
              {{ isMissing ? $strings.LabelMissing : $strings.LabelIncomplete }}
 | 
			
		||||
            </ui-btn>
 | 
			
		||||
 | 
			
		||||
            <ui-tooltip v-if="showQueueBtn" :text="isQueued ? $strings.ButtonQueueRemoveItem : $strings.ButtonQueueAddItem" direction="top">
 | 
			
		||||
              <ui-icon-btn :icon="isQueued ? 'playlist_add_check' : 'playlist_add'" class="mx-0.5" :class="isQueued ? 'text-success' : ''" @click="queueBtnClick" />
 | 
			
		||||
            </ui-tooltip>
 | 
			
		||||
 | 
			
		||||
            <ui-btn v-if="showReadButton" color="info" :padding-x="4" small class="flex items-center h-9 mr-2" @click="openEbook">
 | 
			
		||||
              <span class="material-icons -ml-2 pr-2 text-white">auto_stories</span>
 | 
			
		||||
              {{ $strings.ButtonRead }}
 | 
			
		||||
            </ui-btn>
 | 
			
		||||
 | 
			
		||||
            <ui-tooltip v-if="userCanUpdate" text="Edit" direction="top">
 | 
			
		||||
            <ui-tooltip v-if="userCanUpdate" :text="$strings.LabelEdit" direction="top">
 | 
			
		||||
              <ui-icon-btn icon="edit" class="mx-0.5" @click="editClick" />
 | 
			
		||||
            </ui-tooltip>
 | 
			
		||||
 | 
			
		||||
@ -398,6 +402,9 @@ export default {
 | 
			
		||||
    isStreaming() {
 | 
			
		||||
      return this.streamLibraryItem && this.streamLibraryItem.id === this.libraryItemId
 | 
			
		||||
    },
 | 
			
		||||
    isQueued() {
 | 
			
		||||
      return this.$store.getters['getIsMediaQueued'](this.libraryItemId)
 | 
			
		||||
    },
 | 
			
		||||
    userCanUpdate() {
 | 
			
		||||
      return this.$store.getters['user/getUserCanUpdate']
 | 
			
		||||
    },
 | 
			
		||||
@ -412,6 +419,10 @@ export default {
 | 
			
		||||
 | 
			
		||||
      // If rss feed is open then show feed url to users otherwise just show to admins
 | 
			
		||||
      return this.userIsAdminOrUp || this.rssFeedUrl
 | 
			
		||||
    },
 | 
			
		||||
    showQueueBtn() {
 | 
			
		||||
      if (this.isPodcast || this.isVideo) return false
 | 
			
		||||
      return !this.$store.getters['getIsStreamingFromDifferentLibrary'] && this.streamLibraryItem
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
@ -536,6 +547,7 @@ export default {
 | 
			
		||||
          if (!podcastProgress || !podcastProgress.isFinished) {
 | 
			
		||||
            queueItems.push({
 | 
			
		||||
              libraryItemId: this.libraryItemId,
 | 
			
		||||
              libraryId: this.libraryId,
 | 
			
		||||
              episodeId: episode.id,
 | 
			
		||||
              title: episode.title,
 | 
			
		||||
              subtitle: this.title,
 | 
			
		||||
@ -545,6 +557,18 @@ export default {
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        const queueItem = {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          libraryId: this.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: this.title,
 | 
			
		||||
          subtitle: this.authors.map((au) => au.name).join(', '),
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: this.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
        queueItems.push(queueItem)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$eventBus.$emit('play-item', {
 | 
			
		||||
@ -615,6 +639,26 @@ export default {
 | 
			
		||||
        console.log('RSS Feed Closed', data)
 | 
			
		||||
        this.rssFeedUrl = null
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    queueBtnClick() {
 | 
			
		||||
      if (this.isQueued) {
 | 
			
		||||
        // Remove from queue
 | 
			
		||||
        this.$store.commit('removeItemFromQueue', { libraryItemId: this.libraryItemId })
 | 
			
		||||
      } else {
 | 
			
		||||
        // Add to queue
 | 
			
		||||
 | 
			
		||||
        const queueItem = {
 | 
			
		||||
          libraryItemId: this.libraryItemId,
 | 
			
		||||
          libraryId: this.libraryId,
 | 
			
		||||
          episodeId: null,
 | 
			
		||||
          title: this.title,
 | 
			
		||||
          subtitle: this.authors.map((au) => au.name).join(', '),
 | 
			
		||||
          caption: '',
 | 
			
		||||
          duration: this.duration || null,
 | 
			
		||||
          coverPath: this.media.coverPath || null
 | 
			
		||||
        }
 | 
			
		||||
        this.$store.commit('addItemToQueue', queueItem)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
 | 
			
		||||
@ -107,6 +107,7 @@
 | 
			
		||||
  "HeaderOtherFiles": "Other Files",
 | 
			
		||||
  "HeaderOpenRSSFeed": "Open RSS Feed",
 | 
			
		||||
  "HeaderPermissions": "Permissions",
 | 
			
		||||
  "HeaderPlayerQueue": "Player Queue",
 | 
			
		||||
  "HeaderPodcastsToAdd": "Podcasts to Add",
 | 
			
		||||
  "HeaderPreviewCover": "Preview Cover",
 | 
			
		||||
  "HeaderRemoveEpisode": "Remove Episode",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user