282 lines
No EOL
11 KiB
Text
282 lines
No EOL
11 KiB
Text
<main class="layout-maxed ma-collection-details" id="app" v-cloak @keyup="changeImage">
|
|
|
|
<h1>{{item.artists_sort}} - {{item.title}}</h1>
|
|
<div class="grid sm:grid-cols-3 gap-16">
|
|
<div class="text-center">
|
|
<img :src="item.thumb %>" :alt="`Miniature pour l'album ${item.title}`" />
|
|
</div>
|
|
<div class="sm:col-span-2 text-center galerie">
|
|
<div v-for="(image, index) in item.images" :data-index="index" @click.stop.prevent="showGallery">
|
|
<img :src="image.uri150" :alt="`Miniature de type ${image.type}`" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="grid md:grid-cols-3 gap-16">
|
|
<div>
|
|
<template v-for="album in tracklist">
|
|
<strong v-if="album.title">{{album.title}}</strong>
|
|
<ol class="ml-4">
|
|
<li v-for="track in album.tracks">
|
|
{{ track.title }} <template v-if="track.duration">({{track.duration}})</template>
|
|
<ul v-if="track.extraartists && track.extraartists.length > 0" class="sm-hidden ml-4">
|
|
<li v-for="extra in track.extraartists">
|
|
<small>{{extra.role}} : {{extra.name}}</small>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
</template>
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<div class="grid grid-cols-2 gap-10">
|
|
<div>
|
|
<strong>Genres</strong>
|
|
<br />
|
|
<template v-for="(genre, index) in item.genres">
|
|
{{genre}}<template v-if="index < item.genres.length - 1">, </template>
|
|
</template>
|
|
</div>
|
|
<div>
|
|
<strong>Styles</strong>
|
|
<br />
|
|
<span v-for="(style, index) in item.styles">
|
|
{{style}}<template v-if="index < item.styles.length - 1">, </template>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="grid grid-cols-3 gap-10">
|
|
<div>
|
|
<strong>Pays</strong>
|
|
<br />
|
|
<span>{{item.country}}</span>
|
|
</div>
|
|
<div>
|
|
<strong>Année</strong>
|
|
<br />
|
|
<span>{{item.year}}</span>
|
|
</div>
|
|
<div>
|
|
<strong>Date de sortie</strong>
|
|
<br />
|
|
<span>{{item.released}}</span>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="grid gap-10">
|
|
<div>
|
|
<strong>Format</strong>
|
|
<ul class="ml-4">
|
|
<li v-for="(format) in item.formats">
|
|
{{format.name}}
|
|
<template v-if="format.descriptions && format.descriptions.length > 0">
|
|
(<span v-for="(description, index) in format.descriptions">
|
|
{{description}}<template v-if="index < format.descriptions.length - 1">, </template>
|
|
</span>)
|
|
</template>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class="grid grid-cols-2 gap-10">
|
|
<div>
|
|
<strong id="identifiers">Codes barres</strong>
|
|
<ol class="ml-4">
|
|
<li v-for="identifier in identifiers">
|
|
{{identifier.value}} ({{identifier.type}})
|
|
</li>
|
|
</ol>
|
|
<template v-if="item.identifiers.length > identifiersPreviewLength">
|
|
<button type="button" class="button is-link" v-if="identifiersMode === 'preview'" @click="showAllIdentifiers">
|
|
Voir la suite
|
|
</button>
|
|
<button type="button" class="button is-link" v-if="identifiersMode === 'all'" @click="showLessIdentifiers">
|
|
Voir moins
|
|
</button>
|
|
</template>
|
|
</div>
|
|
<div>
|
|
<strong>Label</strong>
|
|
<br />
|
|
<template v-for="label in item.labels">
|
|
{{label.name}} {{label.catno}}
|
|
<br />
|
|
</template>
|
|
<hr />
|
|
<strong>Sociétés</strong>
|
|
<br />
|
|
<template v-for="company in item.companies">
|
|
<strong>{{company.entity_type_name}}</strong> : {{company.name}}
|
|
<br />
|
|
</template>
|
|
</div>
|
|
</div>
|
|
<!-- <hr />
|
|
<div class="grid gap-10">
|
|
<div>
|
|
<strong>Note</strong>
|
|
<br />
|
|
<span>{{item.notes}}</span>
|
|
</div>
|
|
</div> -->
|
|
<hr />
|
|
<div class="grid gap-10">
|
|
<div>
|
|
<strong>Vidéos</strong>
|
|
<dl>
|
|
<template v-for="video in item.videos">
|
|
<dt>
|
|
<a :href="video.uri" target="_blank" rel="noopener noreferrer">{{video.title}}</a>
|
|
</dt>
|
|
<dd>
|
|
{{video.description}}
|
|
</dd>
|
|
</template>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal" :class="{'is-visible': modalIsVisible}">
|
|
<div class="modal-background"></div>
|
|
<button type="button" aria-label="Fermer" class="close" @click="toggleModal"></button>
|
|
<button type="button" aria-label="Image précédente" class="navigation previous" @click="previous" v-if="index > 0">
|
|
<i class="icon-left-open"></i>
|
|
</button>
|
|
<button type="button" aria-label="Image suivante" class="navigation next" @click="next" v-if="index + 1 < item.images.length">
|
|
<i class="icon-right-open"></i>
|
|
</button>
|
|
<div class="modal-card">
|
|
<img :src="preview" />
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script>
|
|
Vue.createApp({
|
|
data() {
|
|
return {
|
|
item: <%- JSON.stringify(page.item) %>,
|
|
tracklist: [],
|
|
identifiers: [],
|
|
modalIsVisible: false,
|
|
identifiersMode: 'preview',
|
|
identifiersPreviewLength: 16,
|
|
preview: null,
|
|
index: null,
|
|
}
|
|
},
|
|
created() {
|
|
this.setTrackList();
|
|
this.setIdentifiers();
|
|
|
|
window.addEventListener("keydown", this.changeImage);
|
|
},
|
|
destroyed() {
|
|
window.removeEventListener('keydown', this.changeImage);
|
|
},
|
|
methods: {
|
|
setIdentifiers() {
|
|
this.identifiers = [];
|
|
|
|
let max = this.identifiersMode == 'preview' && this.item.identifiers.length > this.identifiersPreviewLength ? this.identifiersPreviewLength : this.item.identifiers.length;
|
|
|
|
for ( let i = 0 ; i < max ; i += 1 ) {
|
|
this.identifiers.push(this.item.identifiers[i]);
|
|
}
|
|
},
|
|
setTrackList() {
|
|
let subTrack = {
|
|
type: null,
|
|
title: null,
|
|
tracks: [],
|
|
};
|
|
for (let i = 0 ; i < this.item.tracklist.length ; i += 1 ) {
|
|
const {
|
|
type_,
|
|
title,
|
|
position,
|
|
duration,
|
|
extraartists,
|
|
} = this.item.tracklist[i];
|
|
|
|
if ( type_ === 'heading' ) {
|
|
if ( subTrack.type ) {
|
|
this.tracklist.push(subTrack);
|
|
subTrack = {
|
|
type: null,
|
|
title: null,
|
|
tracks: [],
|
|
};
|
|
}
|
|
|
|
subTrack.type = type_;
|
|
subTrack.title = title;
|
|
} else {
|
|
subTrack.tracks.push({
|
|
title,
|
|
position,
|
|
duration,
|
|
extraartists
|
|
});
|
|
}
|
|
}
|
|
this.tracklist.push(subTrack);
|
|
},
|
|
setImage() {
|
|
this.preview = this.item.images[this.index].uri;
|
|
},
|
|
showGallery(event) {
|
|
const item = event.target.tagName === 'IMG' ? event.target.parentElement : event.target;
|
|
|
|
const {
|
|
index,
|
|
} = item.dataset;
|
|
|
|
this.index = Number(index);
|
|
this.modalIsVisible = true;
|
|
|
|
this.setImage();
|
|
},
|
|
toggleModal() {
|
|
this.modalIsVisible = !this.modalIsVisible;
|
|
},
|
|
previous() {
|
|
this.index = this.index > 0 ? this.index - 1 : this.item.images.length -1;
|
|
this.setImage();
|
|
},
|
|
next() {
|
|
this.index = (this.index +1) === this.item.images.length ? 0 : this.index + 1;
|
|
this.setImage();
|
|
},
|
|
changeImage(event) {
|
|
const direction = event.code;
|
|
|
|
if ( this.modalIsVisible && ['ArrowRight', 'ArrowLeft', 'Escape'].indexOf(direction) !== -1 ) {
|
|
switch (direction) {
|
|
case 'ArrowRight':
|
|
return this.next();
|
|
case 'ArrowLeft':
|
|
return this.previous();
|
|
default:
|
|
this.modalIsVisible = false;
|
|
return true;
|
|
}
|
|
}
|
|
},
|
|
showAllIdentifiers() {
|
|
this.identifiersMode = 'all';
|
|
this.setIdentifiers();
|
|
},
|
|
showLessIdentifiers() {
|
|
this.identifiersMode = 'preview';
|
|
this.setIdentifiers();
|
|
|
|
document.querySelector('#identifiers').scrollIntoView({ behavior: 'smooth' });
|
|
},
|
|
},
|
|
}).mount('#app');
|
|
</script> |