♠♣♦♥
This commit is contained in:
@@ -2,8 +2,18 @@
|
|||||||
<article @click="() => playerStore.playTrack(props.track).catch(err => console.error(err))"
|
<article @click="() => playerStore.playTrack(props.track).catch(err => console.error(err))"
|
||||||
class="card flip-card w-56 h-80" :class="isFaceUp ? 'face-up' : 'face-down'">
|
class="card flip-card w-56 h-80" :class="isFaceUp ? 'face-up' : 'face-down'">
|
||||||
<div class="flip-inner">
|
<div class="flip-inner">
|
||||||
|
<!-- Face-Up -->
|
||||||
<main
|
<main
|
||||||
class="flip-front backdrop-blur-sm border-2 -mt-12 z-10 card w-56 h-80 p-3 bg-opacity-40 hover:bg-opacity-80 hover:shadow-xl transition-all bg-white rounded-2xl shadow-lg flex flex-col overflow-hidden">
|
class="flip-front backdrop-blur-sm border-2 -mt-12 z-10 card w-56 h-80 p-3 bg-opacity-40 hover:bg-opacity-80 hover:shadow-xl transition-all bg-white rounded-2xl shadow-lg flex flex-col overflow-hidden">
|
||||||
|
<div class="flex items-center justify-center size-7 absolute top-7 right-7" v-if="isPlaylistTrack">
|
||||||
|
<div class="suit text-7xl absolute"
|
||||||
|
:class="[isRedCard ? 'text-red-600' : 'text-slate-800', props.track.card?.suit]">
|
||||||
|
{{ props.track.card?.suit }}
|
||||||
|
</div>
|
||||||
|
<div class="rank text-white font-bold absolute -mt-1">
|
||||||
|
{{ props.track.card?.rank }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Cover -->
|
<!-- Cover -->
|
||||||
<figure class="flex-1 overflow-hidden rounded-t-xl cursor-pointer">
|
<figure class="flex-1 overflow-hidden rounded-t-xl cursor-pointer">
|
||||||
<img :src="coverUrl" alt="Pochette de l'album" class="w-full h-full object-cover object-center" />
|
<img :src="coverUrl" alt="Pochette de l'album" class="w-full h-full object-cover object-center" />
|
||||||
@@ -14,22 +24,20 @@
|
|||||||
<div class="label" v-if="isOrder">
|
<div class="label" v-if="isOrder">
|
||||||
{{ props.track.order }}
|
{{ props.track.order }}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="text-base text-neutral-800 font-bold truncate">{{ props.track.title }}</h2>
|
<h2 class="text-base text-neutral-800 font-bold truncate">
|
||||||
|
{{ props.track.title }}
|
||||||
|
</h2>
|
||||||
<p class="text-sm text-neutral-500 truncate">
|
<p class="text-sm text-neutral-500 truncate">
|
||||||
<template v-if="isPlaylistTrack">
|
<template v-if="isPlaylistTrack">
|
||||||
{{ props.track.artist.name }}
|
{{ props.track.artist.name }}
|
||||||
</template>
|
</template>
|
||||||
<div class="order" v-if="isPlaylistTrack">
|
|
||||||
{{ props.track.card?.rank }}
|
|
||||||
{{ props.track.card?.suit }}
|
|
||||||
</div>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<!-- Face-Down -->
|
||||||
<footer
|
<footer
|
||||||
class="flip-back backdrop-blur-sm -mt-12 z-10 card w-56 h-80 p-3 bg-opacity-10 bg-white rounded-2xl shadow-lg flex flex-col overflow-hidden">
|
class="flip-back backdrop-blur-sm -mt-12 z-10 card w-56 h-80 p-3 bg-opacity-10 bg-white rounded-2xl shadow-lg flex flex-col overflow-hidden">
|
||||||
<!-- Back -->
|
|
||||||
<div class="h-full flex p-16 text-center bg-slate-800 rounded-xl">
|
<div class="h-full flex p-16 text-center bg-slate-800 rounded-xl">
|
||||||
<img src="/favicon.svg" />
|
<img src="/favicon.svg" />
|
||||||
<div class="label label--id" v-if="isOrder">
|
<div class="label label--id" v-if="isOrder">
|
||||||
@@ -53,6 +61,7 @@ const playerStore = usePlayerStore()
|
|||||||
const isManifesto = computed(() => props.track.compilationId.startsWith('ES00'))
|
const isManifesto = computed(() => props.track.compilationId.startsWith('ES00'))
|
||||||
const isOrder = computed(() => props.track.order && !isManifesto)
|
const isOrder = computed(() => props.track.order && !isManifesto)
|
||||||
const isPlaylistTrack = computed(() => props.track.compilationId.length === 6)
|
const isPlaylistTrack = computed(() => props.track.compilationId.length === 6)
|
||||||
|
const isRedCard = computed(() => props.track.card?.suit === '♥' || props.track.card?.suit === '♦')
|
||||||
const coverUrl = props.track.coverId.startsWith('http')
|
const coverUrl = props.track.coverId.startsWith('http')
|
||||||
? props.track.coverId
|
? props.track.coverId
|
||||||
: `https://f4.bcbits.com/img/${props.track.coverId}_4.jpg`;
|
: `https://f4.bcbits.com/img/${props.track.coverId}_4.jpg`;
|
||||||
@@ -101,5 +110,21 @@ const coverUrl = props.track.coverId.startsWith('http')
|
|||||||
.flip-back {
|
.flip-back {
|
||||||
transform: rotateY(180deg);
|
transform: rotateY(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.♠ {
|
||||||
|
@apply -mt-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.♣ {
|
||||||
|
@apply text-7xl -mt-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.♦ {
|
||||||
|
@apply -mt-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.♥ {
|
||||||
|
@apply text-5xl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
{{ Math.round(currentTime) }}
|
{{ Math.round(currentTime) }}
|
||||||
{{ Math.round(currentProgression) }}%
|
{{ Math.round(currentProgression) }}%
|
||||||
</p> -->
|
</p> -->
|
||||||
{{ playerStore.currentTrack?.url }}
|
|
||||||
<audio ref="audioRef" class="w-full" :src="playerStore.currentTrack?.url || ''" controls />
|
<audio ref="audioRef" class="w-full" :src="playerStore.currentTrack?.url || ''" controls />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.logo {
|
.logo {
|
||||||
filter: drop-shadow(2px 2px 0 rgb(0 0 0 / 0.8));
|
filter: drop-shadow(2px 2px 0 rgb(0 0 0 / 0.8));
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default eventHandler(async (event) => {
|
|||||||
const urlPrefix = `https://files.erudi.fr/music`
|
const urlPrefix = `https://files.erudi.fr/music`
|
||||||
|
|
||||||
let files = await fs.promises.readdir(dirPath)
|
let files = await fs.promises.readdir(dirPath)
|
||||||
files = files.filter((f) => !f.startsWith('.'))
|
files = files.filter((f) => !f.startsWith('.') && !f.endsWith('.jpg'))
|
||||||
|
|
||||||
const tracks = files.map((file, index) => {
|
const tracks = files.map((file, index) => {
|
||||||
const EXT_RE = /\.(mp3|flac|wav|opus)$/i
|
const EXT_RE = /\.(mp3|flac|wav|opus)$/i
|
||||||
@@ -43,7 +43,7 @@ export default eventHandler(async (event) => {
|
|||||||
const date = new Date(year, month - 1, day, hour)
|
const date = new Date(year, month - 1, day, hour)
|
||||||
const card = getCardFromDate(date)
|
const card = getCardFromDate(date)
|
||||||
const url = `${urlPrefix}/${encodeURIComponent(file)}`
|
const url = `${urlPrefix}/${encodeURIComponent(file)}`
|
||||||
const coverId = `${urlPrefix}/cover/${encodeURIComponent(file)}`
|
const coverId = `${urlPrefix}/${encodeURIComponent(file).replace(EXT_RE, '.jpg')}`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: Number(`${year}${index + 1}`),
|
id: Number(`${year}${index + 1}`),
|
||||||
|
|||||||
Reference in New Issue
Block a user