Skip to content
Snippets Groups Projects
AlbumBase.vue 10.1 KiB
Newer Older
  • Learn to ignore specific revisions
  •     <div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
    
          <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
        </div>
    
        <template v-if="object">
    
          <section class="ui vertical stripe segment channel-serie">
            <div class="ui stackable grid container">
              <div class="ui seven wide column">
                <div v-if="isSerie" class="padded basic segment">
                  <div class="ui two column grid" v-if="isSerie">
                    <div class="column">
                      <div class="large two-images">
    
                        <img alt="" class="channel-image" v-if="object.cover && object.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)">
    
                        <img alt="" class="channel-image" v-else src="../../assets/audio/default-cover.png">
    
                        <img alt="" class="channel-image" v-if="object.cover && object.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)">
    
                        <img alt="" class="channel-image" v-else src="../../assets/audio/default-cover.png">
    
                    <div class="ui column right aligned">
                      <tags-list v-if="object.tags && object.tags.length > 0" :tags="object.tags"></tags-list>
                      <div class="ui small hidden divider"></div>
                      <human-duration v-if="totalDuration > 0" :duration="totalDuration"></human-duration>
                      <template v-if="totalTracks > 0">
                        <div class="ui hidden very small divider"></div>
                        <translate key="1" v-if="isSerie" translate-context="Content/Channel/Paragraph"
                          translate-plural="%{ count } episodes"
                          :translate-n="totalTracks"
                          :translate-params="{count: totalTracks}">
                          %{ count } episode
                        </translate>
                        <translate v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate>
                      </template>
                      <div class="ui small hidden divider"></div>
    
    Agate's avatar
    Agate committed
                      <play-button class="vibrant" :tracks="object.tracks"></play-button>
    
                      <div class="ui hidden horizontal divider"></div>
                      <album-dropdown
                        :object="object"
                        :public-libraries="publicLibraries"
                        :is-loading="isLoading"
                        :is-album="isAlbum"
                        :is-serie="isSerie"
                        :is-channel="isChannel"
                        :artist="artist"></album-dropdown>
    
                  <div class="ui small hidden divider"></div>
                  <header>
                    <h2 class="ui header" :title="object.title">
                      {{ object.title }}
                    </h2>
                    <artist-label :artist="artist"></artist-label>
                  </header>
                </div>
                <div v-else class="ui center aligned text padded basic segment">
    
                  <img alt="" class="channel-image" v-if="object.cover && object.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](object.cover.urls.medium_square_crop)">
    
                  <img alt="" class="channel-image" v-else src="../../assets/audio/default-cover.png">
    
                  <div class="ui hidden divider"></div>
                  <header>
                    <h2 class="ui header" :title="object.title">
                      {{ object.title }}
                    </h2>
                    <artist-label class="rounded" :artist="artist"></artist-label>
                  </header>
                  <div class="ui small hidden divider"></div>
                  <template v-if="totalTracks > 0">
                    <div class="ui hidden very small divider"></div>
                    <translate key="1" v-if="isSerie" translate-context="Content/Channel/Paragraph"
                      translate-plural="%{ count } episodes"
                      :translate-n="totalTracks"
                      :translate-params="{count: totalTracks}">
                      %{ count } episode
                    </translate>
                    <translate v-else translate-context="*/*/*" :translate-params="{count: totalTracks}" :translate-n="totalTracks" translate-plural="%{ count } tracks">%{ count } track</translate> ·
                  </template>
                  <human-duration v-if="totalDuration > 0" :duration="totalDuration"></human-duration>
                  <div class="ui small hidden divider"></div>
    
                  <play-button class="vibrant" :album="object"></play-button>
    
                  <div class="ui horizontal hidden divider"></div>
                  <album-dropdown
                    :object="object"
                    :public-libraries="publicLibraries"
                    :is-loading="isLoading"
                    :is-album="isAlbum"
                    :is-serie="isSerie"
                    :is-channel="isChannel"
                    :artist="artist"></album-dropdown>
                  <div v-if="(object.tags && object.tags.length > 0) || object.description || $store.state.auth.authenticated && object.is_local">
                    <div class="ui small hidden divider"></div>
                    <div class="ui divider"></div>
                    <div class="ui small hidden divider"></div>
                    <template v-if="object.tags && object.tags.length > 0" >
                      <tags-list :tags="object.tags"></tags-list>
                      <div class="ui small hidden divider"></div>
                    </template>
                    <rendered-description
                      v-if="object.description"
                      :content="object.description"
                      :can-update="false"></rendered-description>
                    <router-link v-else-if="$store.state.auth.authenticated && object.is_local" :to="{name: 'library.albums.edit', params: {id: object.id }}">
                      <i class="pencil icon"></i>
                      <translate translate-context="Content/*/Button.Label/Verb">Add a description…</translate>
                    </router-link>
    
                <template v-if="isSerie">
                  <div class="ui hidden divider"></div>
                  <rendered-description
                    v-if="object.description"
                    :content="object.description"
                    :can-update="false"></rendered-description>
                  <router-link v-else-if="$store.state.auth.authenticated && object.is_local" :to="{name: 'library.albums.edit', params: {id: object.id }}">
                    <i class="pencil icon"></i>
                    <translate translate-context="Content/*/Button.Label/Verb">Add a description…</translate>
                  </router-link>
    
                </template>
    
              <div class="nine wide column">
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
                <router-view v-if="object" :paginate-by="paginateBy" :page="page" :total-tracks="totalTracks" :is-serie="isSerie" :artist="artist" :discs="discs" @libraries-loaded="libraries = $event" :object="object" object-type="album" :key="$route.fullPath" @page-changed="page = $event"></router-view>
    
    import lodash from "@/lodash"
    
    import backend from "@/audio/backend"
    import PlayButton from "@/components/audio/PlayButton"
    
    import TagsList from "@/components/tags/List"
    
    import ArtistLabel from '@/components/audio/ArtistLabel'
    import AlbumDropdown from './AlbumDropdown'
    
    function groupByDisc(initial) {
      function inner(acc, track) {
        var dn = track.disc_number - initial
        if (acc[dn] == undefined) {
          acc.push([track])
        } else {
          acc[dn].push(track)
        }
        return acc
    
      return inner
    
        ArtistLabel,
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
        AlbumDropdown
    
          object: null,
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
          page: 1,
          paginateBy: 50,
    
      async created() {
        await this.fetchData()
    
        async fetchData() {
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
          let tracksResponse = axios.get(`tracks/`, {params: {ordering: 'disc_number,position', album: this.id, page_size: this.paginateBy, page:this.page, include_channels: 'true'}})
    
          let albumResponse = await axios.get(`albums/${this.id}/`, {params: {refresh: 'true'}})
          let artistResponse = await axios.get(`artists/${albumResponse.data.artist.id}/`)
          this.artist = artistResponse.data
          if (this.artist.channel) {
            this.artist.channel.artist = this.artist
          }
    
          tracksResponse = await tracksResponse
          this.object = albumResponse.data
          this.object.tracks = tracksResponse.data.results
    
          this.discs = this.object.tracks.reduce(groupByDisc(this.object.tracks[0].disc_number), [])
    
          this.isLoading = false
    
        },
        remove () {
          let self = this
          self.isLoading = true
          axios.delete(`albums/${this.object.id}`).then((response) => {
            self.isLoading = false
            self.$emit('deleted')
            self.$router.push({name: 'library.artists.detail', params: {id: this.artist.id}})
          }, error => {
            self.isLoading = false
            self.errors = error.backendErrors
          })
    
        totalTracks () {
    
          return this.object.tracks_count
    
        },
        isChannel () {
          return this.object.artist.channel
        },
        isSerie () {
          return this.object.artist.content_category === 'podcast'
        },
        isAlbum () {
          return this.object.artist.content_category === 'music'
        },
        totalDuration () {
          let durations = [0]
          this.object.tracks.forEach((t) => {
            if (t.uploads[0] && t.uploads[0].duration) {
              durations.push(t.uploads[0].duration)
            }
          })
          return lodash.sum(durations)
        },
    
    Eliot Berriot's avatar
    Eliot Berriot committed
          return {
    
            title: this.$pgettext('*/*/*', 'Album'),
    
        publicLibraries () {
          return this.libraries.filter(l => {
            return l.privacy_level === 'everyone'
          })
        },
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
        },
        page() {
          this.fetchData()