Newer
Older
<div class="ui card">
<div class="content">
<div class="header">
{{ library.name }}
<div class="ui right floated dropdown">
<i class="ellipsis vertical grey large icon nomargin"></i>
<div class="menu">
<div
role="button"
v-for="obj in getReportableObjs({library, account: library.actor})"
:key="obj.target.type + obj.target.id"
class="item basic"
@click.stop.prevent="$store.dispatch('moderation/report', obj.target)">
<i class="share icon" /> {{ obj.label }}
</div>
</div>
</div>
<span
v-if="library.privacy_level === 'me'"
class="right floated"
:data-tooltip="labels.tooltips.me">
<i class="small lock grey icon"></i>
</span>
<span
v-else-if="library.privacy_level === 'everyone'"
class="right floated"
:data-tooltip="labels.tooltips.everyone">
<i class="small globe grey 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>
<i class="music icon"></i>
<translate translate-context="*/*/*" :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
Eliot Berriot
committed
<div v-if="displayScan && latestScan" class="meta">
<template v-if="latestScan.status === 'pending'">
<i class="hourglass icon"></i>
<translate translate-context="Content/Library/Card.List item">Scan pending</translate>
</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>
</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>
</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>
</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>
</template>
<span class="link right floated" @click="showScan = !showScan">
<translate translate-context="Content/Library/Card.Button.Label/Noun">Details</translate>
<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 />
<translate translate-context="Content/Library/Card.List item/Noun">Failed tracks:</translate> {{ latestScan.errored_files }}
Eliot Berriot
committed
<div v-if="displayScan && canLaunchScan" class="clearfix">
<span class="right floated link" @click="launchScan">
<translate translate-context="Content/Library/Card.Button.Label/Verb">Scan now</translate> <i class="paper plane icon" />
</div>
<div class="extra content">
<actor-link :actor="library.actor" />
</div>
Eliot Berriot
committed
<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>
Eliot Berriot
committed
<copy-input :button-classes="'basic'" :value="library.fid" />
</div>
</div>
</div>
Eliot Berriot
committed
<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>
Eliot Berriot
committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<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'
import ReportMixin from '@/components/mixins/Report'
import jQuery from 'jquery'
Eliot Berriot
committed
props: {
library: {type: Object, required: true},
displayFollow: {type: Boolean, default: true},
displayScan: {type: Boolean, default: true},
displayCopyFid: {type: Boolean, default: true},
Eliot Berriot
committed
},
isLoadingFollow: false,
showScan: false,
scanTimeout: null,
latestScan: this.library.latest_scan,
mounted () {
let self = this
jQuery(this.$el).find('.ui.dropdown').dropdown({
selectOnKeydown: false,
action: function (text, value, $el) {
// used ton ensure focusing the dropdown and clicking via keyboard
// works as expected
self.$refs[$el.data('ref')].click()
jQuery(self.$el).find('.ui.dropdown').dropdown('hide')
}
})
},
computed: {
labels () {
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')
return {
tooltips: {
me,
everyone
}
}
},
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
let successMsg = this.$pgettext('Content/Library/Message', 'Scan launched')
let skippedMsg = this.$pgettext('Content/Library/Message', 'Scan skipped (previous scan is too recent)')
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
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
committed
self.library.follow = null
}, error => {
self.isLoadingFollow = false
})
},
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)
}
}
}
}
}
</script>