Skip to content
Snippets Groups Projects
PlaylistModal.vue 6.21 KiB
Newer Older
Eliot Berriot's avatar
Eliot Berriot committed
  <modal @update:show="update" :show="$store.state.playlists.showModal">
Eliot Berriot's avatar
Eliot Berriot committed
    <div class="header">
      <translate translate-context="Popup/Playlist/Title/Verb">Manage playlists</translate>
Eliot Berriot's avatar
Eliot Berriot committed
    </div>
    <div class="scrolling content">
      <div class="description">
        <template v-if="track">
          <h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Current track</translate></h4>
            translate-context="Popup/Playlist/Paragraph"
Eliot Berriot's avatar
Eliot Berriot committed
            v-translate="{artist: track.artist.name, title: track.title}"
            :translate-params="{artist: track.artist.name, title: track.title}">
Eliot Berriot's avatar
Eliot Berriot committed
            "%{ title }", by %{ artist }
Eliot Berriot's avatar
Eliot Berriot committed
          <div class="ui divider"></div>
        </template>

        <playlist-form :key="formKey"></playlist-form>
Eliot Berriot's avatar
Eliot Berriot committed
        <div class="ui divider"></div>
        <div v-if="showDuplicateTrackAddConfirmation" class="ui warning message">
          <p translate-context="Popup/Playlist/Paragraph"
            v-translate="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"
            :translate-params="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"><strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>.</p>
          <button
            @click="update(false)"
            class="ui small cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
          </button>
          <button
            class="ui small green button"
            @click="addToPlaylist(lastSelectedPlaylist, true)">
              <translate translate-context="*/Playlist/Button.Label/Verb">Add anyways</translate></button>
        </div>
Eliot Berriot's avatar
Eliot Berriot committed
        <div v-if="errors.length > 0" class="ui negative message">
          <div class="header"><translate translate-context="Popup/Playlist/Error message.Title">The track can't be added to a playlist</translate></div>
Eliot Berriot's avatar
Eliot Berriot committed
          <ul class="list">
            <li v-for="error in errors">{{ error }}</li>
          </ul>
Eliot Berriot's avatar
Eliot Berriot committed
        </div>
        <h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Available playlists</translate></h4>
Eliot Berriot's avatar
Eliot Berriot committed
        <table class="ui unstackable very basic table">
          <thead>
            <tr>
              <th></th>
jovuit's avatar
jovuit committed
              <th><translate translate-context="*/*/*/Noun">Name</translate></th>
              <th class="sorted descending"><translate translate-context="Popup/Playlist/Table.Label/Short">Last modification</translate></th>
jovuit's avatar
jovuit committed
              <th><translate translate-context="*/*/*/Noun">Tracks</translate></th>
Eliot Berriot's avatar
Eliot Berriot committed
              <th></th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="playlist in sortedPlaylists">
              <td>
                <router-link
                  class="ui icon basic small button"
                  :to="{name: 'library.playlists.detail', params: {id: playlist.id }, query: {mode: 'edit'}}"><i class="ui pencil icon"></i></router-link>
              </td>
              <td :title="playlist.name">
                <router-link v-on:click.native="update(false)" :to="{name: 'library.playlists.detail', params: {id: playlist.id }}">{{ playlist.name }}</router-link></td>
Eliot Berriot's avatar
Eliot Berriot committed
              <td><human-date :date="playlist.modification_date"></human-date></td>
              <td>{{ playlist.tracks_count }}</td>
              <td>
                <div
                  v-if="track"
                  class="ui green icon basic small right floated button"
Eliot Berriot's avatar
Eliot Berriot committed
                  :title="labels.addToPlaylist"
                  @click="addToPlaylist(playlist.id, false)">
                  <i class="plus icon"></i> <translate translate-context="Popup/Playlist/Table.Button.Label/Verb">Add track</translate>
Eliot Berriot's avatar
Eliot Berriot committed
                </div>
              </td>
            </tr>
          </tbody>
        </table>
Eliot Berriot's avatar
Eliot Berriot committed
    </div>
    <div class="actions">
jovuit's avatar
jovuit committed
      <div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
Eliot Berriot's avatar
Eliot Berriot committed
    </div>
import _ from '@/lodash'
import axios from 'axios'
import {mapState} from 'vuex'

import logger from '@/logging'
import Modal from '@/components/semantic/Modal'
import PlaylistForm from '@/components/playlists/Form'

export default {
  components: {
    Modal,
    PlaylistForm
  },
  data () {
    return {
      formKey: String(new Date()),
      errors: [],
      duplicateTrackAddInfo: {},
      showDuplicateTrackAddConfirmation: false,
      lastSelectedPlaylist: -1,
Eliot Berriot's avatar
Eliot Berriot committed
      this.$store.commit('playlists/showModal', v)
    addToPlaylist (playlistId, allowDuplicate) {
      let self = this
      let payload = {
        track: this.track.id,
        playlist: playlistId,
        allow_duplicates: allowDuplicate

      self.lastSelectedPlaylist = playlistId

      return axios.post('playlist-tracks/', payload).then(response => {
        logger.default.info('Successfully added track to playlist')
Eliot Berriot's avatar
Eliot Berriot committed
        self.update(false)
        self.$store.dispatch('playlists/fetchOwn')
      }, error => {
        if (error.backendErrors.length == 1 && error.backendErrors[0].code == 'tracks_already_exist_in_playlist') {
          self.duplicateTrackAddInfo = error.backendErrors[0]
          self.showDuplicateTrackAddConfirmation = true
        } else {
          self.errors = error.backendErrors
          self.showDuplicateTrackAddConfirmation = false
        }
Eliot Berriot's avatar
Eliot Berriot committed
      playlists: state => state.playlists.playlists,
      track: state => state.playlists.modalTrack
Eliot Berriot's avatar
Eliot Berriot committed
    labels () {
      return {
Jo Vuit's avatar
Jo Vuit committed
        addToPlaylist: this.$pgettext('Popup/Playlist/Table.Button.Tooltip/Verb', 'Add to this playlist')
      let p = _.sortBy(this.playlists, [(e) => { return e.modification_date }])
      p.reverse()
      return p
Eliot Berriot's avatar
Eliot Berriot committed
  },
  watch: {
    '$store.state.route.path' () {
      this.$store.commit('playlists/showModal', false)
      this.showDuplicateTrackAddConfirmation = false
    },
    '$store.state.playlists.showModal' () {
      this.formKey = String(new Date())
      this.showDuplicateTrackAddConfirmation = false
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>