Newer
Older
<template>
ref="modalPlaylistSelector"
:title="$t('playlistSelector.title')"
:cancel-title="$t('cancel')"
size="lg"
{{ $t('playlistSelector.currentPlaylistLabel') }}:
<span v-if="timeslot === null || timeslot.playlist_id === null">
<i><small>{{ $t('noneSetFeminine') }}</small></i>
{{ timeslot.playlist_id }}<br>
<span v-if="currentPlaylistDescription"> {{ $t('showMeta.description') }}: <b>{{ currentPlaylistDescription }}</b></span>
<div v-if="playlists.length">
<b-table
ref="playlistsTable"
striped
:fields="playlistsTableFields"
:items="playlists"
>
<!-- Column: Entries
This column displays the number of entries of the playlist.
-->
v-b-tooltip.html="playlistToolTip(data.value)"
class="tw-underline hover:tw-no-underline tw-cursor-help"
{{ $t('playlistTable.items', { smart_count: data.value.length }) }}
</span>
</template>
<!-- Column: Duration
This column displays the number of entries of the playlist.
-->
:class="{'is-mismatched': isMismatchedLength(data) }"
>
{{ playlistDuration(data.item) }}
<abbr
v-if="isMismatchedLength(data)"
:title="title(data)"
</template>
<!-- Column: Actions
This column displays the available buttons for actions the user can
take on this playlist (e.g. editing and deleting).
-->
<b-button-group size="sm">
<b-button
v-if="data.item.id !== timeslot.playlist_id"
variant="info"
@click="choose(data)"
</b-button>
<b-button
v-else
variant="danger"
@click="choose(null)"
</b-button>
</b-button-group>
</template>
</b-table>
</div>
<!-- If no playlists are available -->
<div
>
{{ $t('playlistSelector.noPlaylistsAvailable') }}
</div>
src="/assets/radio.gif"
:alt="$t('loading')"
<div>
<div class="tw-space-x-2">
<b-button :to="'files'">
{{ $t('playlistSelector.goToFiles') }}
</b-button>
<b-button
v-if="!audioUpload"
v-model="audioFile"
@click="toggleAudioUpload"
>
{{ $t('playlistSelector.uploadAudio') }}
</b-button>
</div>
<div
v-if="audioUpload"
class="tw-mt-4 tw-space-x-2 tw-flex"
>
<b-form-file
/>
<b-button
>
{{ $t('playlistSelector.upload') }}
</b-button>
</div>
</template>
<script>
import prettyDate from '@/mixins/prettyDate'
import playlist from '@/mixins/playlist'
data() {
return {
scheduleId: null,
timeslot: null,
audioFile: null,
audioUpload: false,
audioUploadError: '',
}
},
computed: {
loaded() {
return this.$store.state.playlists.loaded.playlists
},
playlistsTableFields() {
return [
{key: 'id', label: this.$t('playlistTable.index') },
{key: 'description', label: this.$t('playlistTable.description') },
{key: 'entries', label: this.$t('playlistTable.entries') },
{key: 'duration', label: this.$t('playlistTable.duration') },
{key: 'actions', label: this.$t('playlistTable.actions'), class: 'text-right'},
]
},
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).minutes,
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',
})
},
methods: {
event.preventDefault()
event.stopPropagation()
if (!this.audioFile) {
this.audioUploadError = this.$t('playlistSelector.missingFile')
this.$store.dispatch('files/addFile', {
show: this.selectedShow.slug,
uploadSourceFile: this.audioFile,
callback: this.handleUploadedFile,
})
},
handleUploadedFile() {
this.$store.dispatch('files/fetchFiles', {
slug: this.selectedShow.slug,
callback: this.createPlaylistForUploadedFile
})
},
createPlaylistForUploadedFile(files) {
const file = files.slice(-1)[0]
const playlist = {
description: 'Automatisch erstellt durch Dateiupload',
}
this.$store.dispatch('playlists/add', {
slug,
playlist,
})
},
toggleAudioUpload() {
this.audioUpload = !this.audioUpload
},
this.audioFile = null
this.audioUpload = false
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(this.$t('playlistSelector.mismatchedLengthConfirmation'))
}
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 this.$t('playlistSelector.mismatchedLength')
}
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
},
isMismatchedLength(playlist) {
const totalDuration = this.playlistDuration(playlist.item)
let delta = 0
const unknowns = playlist.item.entries.filter(entry => !entry.duration)
delta = this.timeslotDurationInNs - totalDuration
return this.timeslotDurationInNs !== totalDuration + delta
</script>