Skip to content
Snippets Groups Projects
Card.vue 8.92 KiB
Newer Older
    <div class="content">
      <div class="header">
        {{ library.name }}
        <span
          v-if="library.privacy_level === 'me'"
          class="right floated"
          :data-tooltip="labels.tooltips.me">
          <i class="small lock icon"></i>
        </span>
        <span
          v-else-if="library.privacy_level === 'everyone'"
          class="right floated"
          :data-tooltip="labels.tooltips.everyone">
          <i class="small globe icon"></i>
        </span>
      </div>
      <div class="meta">
        <span>
          <i class="small outline clock icon" />
          <human-date :date="library.creation_date" />
        </span>
      </div>
      <div class="description">
        {{ library.description }}
        <div class="ui hidden divider"></div>
      </div>
Eliot Berriot's avatar
Eliot Berriot committed
      <div class="meta">
        <i class="music icon"></i>
jovuit's avatar
jovuit committed
        <translate translate-context="*/*/*" :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
      <div v-if="displayScan && latestScan" class="meta">
Eliot Berriot's avatar
Eliot Berriot committed
        <template v-if="latestScan.status === 'pending'">
          <i class="hourglass icon"></i>
          <translate translate-context="Content/Library/Card.List item">Scan pending</translate>
Eliot Berriot's avatar
Eliot Berriot committed
        </template>
        <template v-if="latestScan.status === 'scanning'">
          <i class="loading spinner icon"></i>
          <translate translate-context="Content/Library/Card.List item" :translate-params="{progress: scanProgress}">Scanning… (%{ progress }%)</translate>
Eliot Berriot's avatar
Eliot Berriot committed
        </template>
        <template v-else-if="latestScan.status === 'errored'">
          <i class="red download icon"></i>
          <translate translate-context="Content/Library/Card.List item">Problem during scanning</translate>
Eliot Berriot's avatar
Eliot Berriot committed
        </template>
        <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files === 0">
          <i class="green download icon"></i>
          <translate translate-context="Content/Library/Card.List item">Scanned</translate>
Eliot Berriot's avatar
Eliot Berriot committed
        </template>
        <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files > 0">
          <i class="yellow download icon"></i>
          <translate translate-context="Content/Library/Card.List item">Scanned with errors</translate>
Eliot Berriot's avatar
Eliot Berriot committed
        </template>
        <span class="link right floated" @click="showScan = !showScan">
jovuit's avatar
jovuit committed
          <translate translate-context="Content/Library/Card.Button.Label/Noun">Details</translate>
Eliot Berriot's avatar
Eliot Berriot committed
          <i v-if="showScan" class="angle down icon" />
          <i v-else class="angle right icon" />
        </span>
        <div v-if="showScan">
          <template v-if="latestScan.modification_date">
            <translate translate-context="Content/Library/Card.List item/Noun">Last update:</translate><human-date :date="latestScan.modification_date" /><br />
Eliot Berriot's avatar
Eliot Berriot committed
          </template>
          <translate translate-context="Content/Library/Card.List item/Noun">Failed tracks:</translate> {{ latestScan.errored_files }}
Eliot Berriot's avatar
Eliot Berriot committed
        </div>
      </div>
      <div v-if="displayScan && canLaunchScan" class="clearfix">
Eliot Berriot's avatar
Eliot Berriot committed
        <span class="right floated link" @click="launchScan">
          <translate translate-context="Content/Library/Card.Button.Label/Verb">Scan now</translate> <i class="paper plane icon" />
Eliot Berriot's avatar
Eliot Berriot committed
        </span>
      </div>
    </div>
    <div class="extra content">
      <actor-link :actor="library.actor" />
    </div>
    <div v-if="displayCopyFid" class="extra content">
      <div class="ui form">
        <div class="field">
          <label><translate translate-context="Content/Library/Title">Sharing link</translate></label>
          <copy-input :button-classes="'basic'" :value="library.fid" />
        </div>
      </div>
    </div>
    <div v-if="displayFollow" :class="['ui', 'bottom', {two: library.follow}, 'attached', 'buttons']">
      <button
        v-if="!library.follow"
        @click="follow()"
        :class="['ui', 'green', {'loading': isLoadingFollow}, 'button']">
        <translate translate-context="Content/Library/Card.Button.Label/Verb">Follow</translate>
      <template v-else-if="!library.follow.approved">
        <button
          class="ui disabled button"><i class="hourglass icon"></i>
          <translate translate-context="Content/Library/Card.Paragraph">Follow request pending approval</translate>
        </button>
        <button
          @click="unfollow"
          class="ui button">
          <translate translate-context="Content/Library/Card.Paragraph">Cancel follow request</translate>
        </button>
      </template>
      <template v-else-if="library.follow.approved">
        <button
          class="ui disabled button"><i class="check icon"></i>
          <translate translate-context="Content/Library/Card.Paragraph">Following</translate>
        </button>
        <dangerous-button
          color=""
          :class="['ui', 'button']"
          :action="unfollow">
          <translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate>
          <p slot="modal-header"><translate translate-context="Popup/Library/Title">Unfollow this library?</translate></p>
          <div slot="modal-content">
            <p><translate translate-context="Popup/Library/Paragraph">By unfollowing this library, you loose access to its content.</translate></p>
          </div>
          <div slot="modal-confirm"><translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate></div>
        </dangerous-button>
      </template>
    </div>
  </div>
</template>
<script>
import axios from 'axios'

export default {
  props: {
    library: {type: Object, required: true},
    displayFollow: {type: Boolean, default: true},
    displayScan: {type: Boolean, default: true},
    displayCopyFid: {type: Boolean, default: false},
  },
Eliot Berriot's avatar
Eliot Berriot committed
      isLoadingFollow: false,
      showScan: false,
      scanTimeout: null,
      latestScan: this.library.latest_scan,
      let me = this.$pgettext('Content/Library/Card.Help text', 'This library is private and your approval from its owner is needed to access its content')
      let everyone = this.$pgettext('Content/Library/Card.Help text', 'This library is public and you can access its content freely')
Eliot Berriot's avatar
Eliot Berriot committed
    },
    scanProgress () {
      let scan = this.latestScan
      let progress = scan.processed_files * 100 / scan.total_files
      return Math.min(parseInt(progress), 100)
    },
    scanStatus () {
      if (this.latestScan) {
        return this.latestScan.status
      }
      return 'unknown'
    },
    canLaunchScan () {
      if (this.scanStatus === 'pending') {
        return false
      }
      if (this.scanStatus === 'scanning') {
        return false
      }
      return true
Eliot Berriot's avatar
Eliot Berriot committed
    launchScan () {
      let self = this
      let successMsg = this.$pgettext('Content/Library/Message', 'Scan launched')
      let skippedMsg = this.$pgettext('Content/Library/Message', 'Scan skipped (previous scan is too recent)')
Eliot Berriot's avatar
Eliot Berriot committed
      axios.post(`federation/libraries/${this.library.uuid}/scan/`).then((response) => {
        let msg
        if (response.data.status == 'skipped') {
          msg = skippedMsg
        } else {
          self.latestScan = response.data.scan
          msg = successMsg
        }
        self.$store.commit('ui/addMessage', {
          content: msg,
          date: new Date()
        })
      })
    },
    follow () {
      let self = this
      this.isLoadingFollow = true
      axios.post('federation/follows/library/', {target: this.library.uuid}).then((response) => {
        self.library.follow = response.data
        self.isLoadingFollow = false
Eliot Berriot's avatar
Eliot Berriot committed
        self.$emit('followed')

      }, error => {
        self.isLoadingFollow = false
      })
    },
    unfollow () {
      let self = this
      this.isLoadingFollow = true
      axios.delete(`federation/follows/library/${this.library.follow.uuid}/`).then((response) => {
        self.$emit('deleted')
Eliot Berriot's avatar
Eliot Berriot committed
        self.isLoadingFollow = false
      }, error => {
        self.isLoadingFollow = false
      })
Eliot Berriot's avatar
Eliot Berriot committed
    },
    fetchScanStatus () {
      let self = this
      axios.get(`federation/follows/library/${this.library.follow.uuid}/`).then((response) => {
        self.latestScan = response.data.target.latest_scan
        if (self.scanStatus === 'pending' || self.scanStatus === 'scanning') {
          self.scanTimeout = setTimeout(self.fetchScanStatus(), 5000)
        } else {
          clearTimeout(self.scanTimeout)
        }
      })
    }
  },
  watch: {
    showScan (newValue, oldValue) {
      if (newValue) {
        if (this.scanStatus === 'pending' || this.scanStatus === 'scanning') {
          this.fetchScanStatus()
        }
      } else {
        if (this.scanTimeout) {
          clearTimeout(this.scanTimeout)
        }
      }