Newer
Older
Eliot Berriot
committed
<template>
<main>
<div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
Eliot Berriot
committed
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="object">
<section :class="['ui', 'head', {'with-background': object.cover.original}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="object.title">
Eliot Berriot
committed
<div class="segment-content">
<h2 class="ui center aligned icon header">
<i class="circular inverted sound yellow icon"></i>
<div class="content">
<div v-html="subtitle"></div>
Eliot Berriot
committed
</h2>
<tags-list v-if="object.tags && object.tags.length > 0" :tags="object.tags"></tags-list>
Eliot Berriot
committed
<div class="ui hidden divider"></div>
Eliot Berriot
committed
<play-button class="orange" :tracks="object.tracks">
<translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
</play-button>
</div>
<modal v-if="publicLibraries.length > 0" :show.sync="showEmbedModal">
Eliot Berriot
committed
<div class="header">
<translate translate-context="Popup/Album/Title/Verb">Embed this album on your website</translate>
Eliot Berriot
committed
</div>
<div class="content">
<div class="description">
<embed-wizard type="album" :id="object.id" />
Eliot Berriot
committed
</div>
</div>
<div class="actions">
<div class="ui deny button">
<translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
Eliot Berriot
committed
</div>
</div>
</modal>
<div class="ui buttons">
<button class="ui button" @click="$refs.dropdown.click()">
<translate translate-context="*/*/Button.Label/Noun">More…</translate>
</button>
<div class="ui floating dropdown icon button" ref="dropdown" v-dropdown>
<i class="dropdown icon"></i>
<div class="menu">
<div
role="button"
v-if="publicLibraries.length > 0"
@click="showEmbedModal = !showEmbedModal"
class="basic item">
<i class="code icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">Embed</translate>
</div>
<a v-if="wikipediaUrl" :href="wikipediaUrl" target="_blank" rel="noreferrer noopener" class="basic item">
<i class="wikipedia w icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">View on Wikipedia</translate>
</a>
<a v-else :href="wikipediaSearchUrl" target="_blank" rel="noreferrer noopener" class="basic item">
<i class="wikipedia w icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">Search on Wikipedia</translate>
</a>
<a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" rel="noreferrer noopener" class="basic item">
<i class="external icon"></i>
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
</a>
<a v-if="discogsUrl" :href="discogsUrl" target="_blank" rel="noreferrer noopener" class="basic item">
<i class="external icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">View on Discogs</translate>
<a v-else :href="discogsSearchUrl" target="_blank" rel="noreferrer noopener" class="basic item">
<i class="external icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">Search on Discogs</translate>
</a>
<router-link
v-if="object.is_local"
:to="{name: 'library.albums.edit', params: {id: object.id }}"
class="basic item">
<i class="edit icon"></i>
<translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
</router-link>
<div
role="button"
class="basic item"
v-for="obj in getReportableObjs({album: object})"
:key="obj.target.type + obj.target.id"
@click.stop.prevent="$store.dispatch('moderation/report', obj.target)">
<i class="share icon" /> {{ obj.label }}
</div>
<div class="divider"></div>
<router-link class="basic item" v-if="$store.state.auth.availablePermissions['library']" :to="{name: 'manage.library.albums.detail', params: {id: object.id}}">
<i class="wrench icon"></i>
<translate translate-context="Content/Moderation/Link">Open in moderation interface</translate>
</router-link>
<a
v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
:href="$store.getters['instance/absoluteUrl'](`/api/admin/music/album/${object.id}`)"
target="_blank" rel="noopener noreferrer">
<i class="wrench icon"></i>
<translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>
</a>
</div>
</div>
</div>
</div>
Eliot Berriot
committed
</div>
</section>
<router-view v-if="object" :discs="discs" @libraries-loaded="libraries = $event" :object="object" object-type="album" :key="$route.fullPath"></router-view>
Eliot Berriot
committed
</template>
</main>
Eliot Berriot
committed
</template>
<script>
import axios from "axios"
import logger from "@/logging"
import backend from "@/audio/backend"
import PlayButton from "@/components/audio/PlayButton"
Eliot Berriot
committed
import EmbedWizard from "@/components/audio/EmbedWizard"
import Modal from '@/components/semantic/Modal'
import TagsList from "@/components/tags/List"
import ReportMixin from '@/components/mixins/Report'
Eliot Berriot
committed
const FETCH_URL = "albums/"
Eliot Berriot
committed
function groupByDisc(acc, track) {
var dn = track.disc_number - 1
if (dn < 0) dn = 0
if (acc[dn] == undefined) {
acc.push([track])
} else {
acc[dn].push(track)
}
return acc
}
Eliot Berriot
committed
export default {
props: ["id"],
Eliot Berriot
committed
components: {
PlayButton,
Eliot Berriot
committed
EmbedWizard,
Modal,
TagsList,
Eliot Berriot
committed
},
data() {
Eliot Berriot
committed
return {
isLoading: true,
Eliot Berriot
committed
discs: [],
libraries: [],
showEmbedModal: false,
wikipediaUrl: null,
discogsUrl: null
Eliot Berriot
committed
}
},
created() {
Eliot Berriot
committed
this.fetchData()
},
methods: {
fetchData() {
Eliot Berriot
committed
var self = this
this.isLoading = true
let url = FETCH_URL + this.id + "/"
Eliot Berriot
committed
logger.default.debug('Fetching album "' + this.id + '"')
Eliot Berriot
committed
axios.get(url, {params: {refresh: 'true'}}).then(response => {
self.object = backend.Album.clean(response.data)
self.discs = self.object.tracks.reduce(groupByDisc, [])
Eliot Berriot
committed
self.isLoading = false
Eliot Berriot
committed
})
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
},
fetchUrls () {
let self = this
this.discogsUrl = null
if (this.object.mbid) {
console.log('Getting URLS')
axios.get('https://musicbrainz.org/ws/2/release/' + this.object.mbid + '?inc=url-rels&fmt=json').then(response => {
response.data.relations.forEach(f => {
if (f.type == 'discogs') {
console.log('Found Discogs Link', f.url.resource)
return this.discogsUrl = f.url.resource
} if (f.type == 'wikidata') {
let foundUrl = f.url.resource
console.log('Found Wikidata Link')
console.log('Pasing', foundUrl, 'to getWiki')
this.getWiki(foundUrl)
}
}).catch(error => {
console.log("Couldn't reach Musicbrainz", error)
})
})
}
},
getWiki (url) {
let self = this
this.wikipediaUrl = null
let split = url.split('/')
let id = split[split.length - 1];
let getUrl = 'https://www.wikidata.org/w/api.php?action=wbgetentities&ids=' + id + '&props=sitelinks&sitefilter=' + this.shortLocale + 'wiki&format=json&origin=*'
console.log('Fetching Wikipedia Link for', id)
$.get(getUrl).done(function (data) {
$.each(data.entities, function (index, item) {
let wikilang = self.shortLocale + 'wiki'
if (item.sitelinks[wikilang]) {
console.log('Wikipedia language is', wikilang)
let wikiUrl = 'https://' + self.shortLocale + '.wikipedia.org/wiki/' + encodeURI(item.sitelinks[wikilang].title)
console.log('Wikipedia page found at', wikiUrl)
return self.wikipediaUrl = wikiUrl}
else {
console.log('No wiki entries for this language')
}
})
})
},
Eliot Berriot
committed
},
computed: {
shortLocale() {
return this.$store.state.ui.momentLocale.split('-')[0]
},
labels() {
Eliot Berriot
committed
publicLibraries () {
return this.libraries.filter(l => {
return l.privacy_level === 'everyone'
})
},
return (
"https://" + this.shortLocale + ".wikipedia.org/w/index.php?search=" +
encodeURI(this.object.title + " " + this.object.artist.name)
)
Eliot Berriot
committed
},
musicbrainzUrl() {
if (this.object.mbid) {
return "https://musicbrainz.org/release/" + this.object.mbid
}
Eliot Berriot
committed
},
return (
"https://discogs.com/search/?type=release&title=" +
encodeURI(this.object.title) + "&artist=" +
encodeURI(this.object.artist.name)
)
},
headerStyle() {
return ""
Eliot Berriot
committed
}
return (
"background-image: url(" +
this.$store.getters["instance/absoluteUrl"](this.object.cover.original) +
")"
)
},
subtitle () {
let route = this.$router.resolve({name: 'library.artists.detail', params: {id: this.object.artist.id }})
let msg = this.$npgettext('Content/Album/Header.Title', 'Album containing %{ count } track, by <a class="internal" href="%{ artistUrl }">%{ artist }</a>', 'Album containing %{ count } tracks, by <a class="internal" href="%{ artistUrl }">%{ artist }</a>', this.object.tracks.length)
return this.$gettextInterpolate(msg, {count: this.object.tracks.length, artist: this.object.artist.name, artistUrl: route.href})
Eliot Berriot
committed
}
},
watch: {
id() {
Eliot Berriot
committed
this.fetchData()
}
}
}
</script>