Skip to content
Snippets Groups Projects
PlaylistSelector.vue 6.59 KiB
Newer Older
  • Learn to ignore specific revisions
  •       title="Edit playlist for this timeslot"
          size="lg"
        >
    
            <span v-if="timeslot === null || timeslot.playlist_id === null">
    
              <i><small>(none set)</small></i>
            </span>
            <span v-else>
    
              <span v-if="currentPlaylistDescription">
                , Description: <b>{{ currentPlaylistDescription }}</b>
              </span>
            </span>
          </p>
    
          <p>Available playlists:</p>
    
            <b-table
              ref="playlistsTable"
              striped
              :fields="playlistsTableFields"
              :items="playlists"
            >
              <!-- Column: Entries
              This column displays the number of entries of the playlist.
              -->
    
              <template v-slot:cell(entries)="data">
    
                  v-b-tooltip.html="playlistToolTip(data.value)"
    
                  class="tw-underline hover:tw-no-underline tw-cursor-help"
    
                  {{ data.value.length }} items
                </span>
    
    
              <!-- Column: Duration
              This column displays the number of entries of the playlist.
              -->
              <template v-slot:cell(duration)="data">
                <span
                  :class="{'is-mismatched': isMismatchedLength(data) }"
                >
    
                  {{ playlistDuration(data) }}
    
    
                  <abbr
                    v-if="isMismatchedLength(data)"
                    :title="title(data)"
                  >
                    (?)
                  </abbr>
                </span>
              </template>
    
    
              <!-- Column: Actions
              This column displays the available buttons for actions the user can
              take on this playlist (e.g. editing and deleting).
              -->
    
              <template v-slot:cell(actions)="data">
    
                <b-button-group size="sm">
                  <b-button
    
                    v-if="data.item.id !== timeslot.playlist_id"
    
                  <b-button
                    v-else
                    variant="danger"
                    @click="choose(null)"
                  >
                    Unset
                  </b-button>
    
                </b-button-group>
              </template>
            </b-table>
          </div>
          <div v-else>
            <img
    
    
          <div align="center">
            <b-button :to="'files'">
              Go to FileManager
            </b-button>
          </div>
    
    import prettyDate from '../../mixins/prettyDate'
    
    
    export default {
      mixins: [ prettyDate ],
    
      data () {
        return {
    
          timeslot: null,
    
          playlistsTableFields: [
            { key: 'id', label: 'Index' },
            { key: 'description', label: 'Description' },
            { key: 'entries', label: 'Entries' },
    
            { key: 'duration', label: 'Duration' },
    
            { key: 'actions', label: 'Actions', class: 'text-right' },
          ],
        }
      },
    
      computed: {
    
        loaded () { return this.$store.state.playlists.loaded.playlists },
    
    
        timeslotDurationInNs() {
          const mm = this.timeslotDuration % 60;
          const hh = (this.timeslotDuration - mm) / 60;
    
          return this.hmsToNanoseconds(
                  `${this.leadingZero(hh)}:${this.leadingZero(mm)}:00`
          );
        },
    
    
        timeslotDuration() {
          const { start, end } = this.timeslot
    
          return parseInt(
            this.prettyDuration(start, end),
            10
          )
        },
    
    
        currentPlaylistDescription () {
          let description = false
    
          if (this.timeslot && this.timeslot.playlist_id !== null) {
            let choosenList = this.playlists.find(list => list.id === this.timeslot.playlist_id)
    
            if (choosenList && choosenList.description.length > 0) {
              description = choosenList.description
            }
          }
          return description
    
        },
    
        ...mapGetters({
          selectedShow: 'shows/selectedShow',
          timeslots: 'shows/timeslots',
          notes: 'shows/notes',
          playlists: 'playlists/playlists',
          getTimeslotById: 'shows/getTimeslotById',
        })
    
        open (scheduleId, timeslotId) {
          this.scheduleId = scheduleId
          this.timeslot = this.getTimeslotById(timeslotId)
          this.$refs.modalPlaylistSelector.show()
    
        choose (data) {
          const { item } = data || {}
          const { id } = item || {}
          let confirmed = true
    
          if (data && this.isMismatchedLength(data)) {
            confirmed = confirm("The playlist you have selected has a different length than the timeslot. Proceed?")
          }
    
          if (confirmed) {
            let ts = {...this.timeslot}
            ts.playlist_id = id
            this.$store.dispatch('shows/updateTimeslot', {
              show: this.selectedShow.id,
              schedule: this.scheduleId,
              timeslot: ts,
              callback: () => { this.timeslot = this.getTimeslotById(ts.id) }
            })
          }
        },
    
        title(data) {
          if (this.isMismatchedLength(data)) {
            return "Playlist is not the same length as the timeslot"
          }
    
          return ""
    
        },
    
        playlistToolTip (entries) {
          let text = '<div style="white-space: nowrap;" align="left">'
          for (let i in entries) {
            text += i + ': ' + entries[i].uri + '<br>'
          }
          text += '</div>'
          return text
        },
    
          if (!item.entries) {
            return 0;
          }
    
          let delta = 0;
          const totalDuration = item.entries.reduce((acc, entry) => {
    
            const newDuration = acc + this.durationInSeconds(entry.duration);
    
    
            if (Number.isNaN(newDuration)) {
              return acc;
            }
    
            return newDuration
    
    
          const unknowns = item.entries.filter(entry => !entry.duration);
          if (unknowns.length === 1) {
    
            delta = this.durationInSeconds(this.timeslotDurationInNs) - totalDuration;
    
          const totalDurationInNanoseconds = (totalDuration + delta) * 1000 * 1000 * 1000
          return this.prettyNanoseconds(totalDurationInNanoseconds)
    
        isMismatchedLength(playlist) {
          const totalDuration = this.playlistDuration(playlist);
          let delta = 0;
    
          const unknowns = playlist.item.entries.filter(entry => !entry.duration);
          if (unknowns.length === 1) {
            delta = this.timeslotDurationInNs - totalDuration;
          }
    
          return this.timeslotDurationInNs !== totalDuration + delta;
        },