Files
chopin-frontend/src/components/UI/VideoQueue.vue
T
2026-10-08 10:06:45 +02:00

147 lines
3.2 KiB
Vue

<template>
<div :data-theme="mobile ? 'dark' : null" :class="'video'" >
<div :class="mobile ? 'mobile-thumbnail-container' : 'thumbnail-container'">
<div v-if="playerOffline" :class="mobile ? 'mobile-thumbnail-placeholder' : 'thumbnail-placeholder'"></div>
<img v-else-if="video && video.thumbnail" :class="mobile ? 'mobile-thumbnail' : 'thumbnail'" :src="video.thumbnail" alt="" />
<div v-else :class="mobile ? 'mobile-thumbnail-placeholder' : 'thumbnail-placeholder'"></div>
</div>
<div class="info">
<p v-if="playerOffline" class="title secondary">Subsonics est hors-ligne</p>
<Marquee v-else-if="video" :class="{'title': true}">
<span :style="{ color: mobile ? 'var(--text)' : '' }">{{ video.title }}</span>
</Marquee>
<p v-else class="title">Aucun titre joué</p>
<p v-if="playerOffline" class="author">Connectez-vous d'abord à un salon vocal pour lancer un titre</p>
<p v-else-if="video" class="author">{{ video.author }}</p>
<p v-else class="author">Aucun auteur</p>
</div>
</div>
</template>
<script setup>
/**
* Ligne « titre » compacte : miniature, titre (défilant s'il est long) et auteur.
* Props : video ({ title, author, thumbnail } ou null), playerOffline (message hors ligne), mobile (miniature carrée, thème sombre).
*/
import Marquee from "./Marquee.vue";
const props = defineProps({
video: {
required: true,
default: null
},
playerOffline: {
type: Boolean,
default: false
},
mobile: {
type: Boolean,
default: false
}
});
</script>
<style scoped>
.thumbnail {
width: 100%;
height: auto;
border-radius: 10px;
user-select: none;
aspect-ratio: 16/9;
object-fit: cover;
background-color: var(--tertiary);
}
.mobile-thumbnail {
width: 100%;
height: auto;
border-radius: 10px;
user-select: none;
aspect-ratio: 1/1;
object-fit: cover;
background-color: var(--tertiary);
}
.thumbnail-placeholder {
width: 100%;
height: 100%;
background-color: var(--tertiary);
border-radius: 10px;
aspect-ratio: 16/9;
}
.thumbnail-container {
position: relative;
width: 10%;
min-width: 70px;
}
.mobile-thumbnail-container {
position: relative;
width: 12%;
min-width: 40px;
}
.mobile-thumbnail-placeholder {
width: 100%;
height: 100%;
background-color: var(--tertiary);
border-radius: 10px;
aspect-ratio: 1/1;
}
.duration {
position: absolute;
bottom: 0px;
right: 0px;
background-color: rgba(0, 0, 0, 0.5);
color: var(--on-media);
padding: 2px 5px;
border-radius: 15px;
font-size: 0.8em;
margin: 3% 0.5% 3% 3%;
}
.info {
display: flex;
flex-direction: column;
flex: 1;
gap: 5px;
overflow-wrap: break-word;
word-break: break-word;
white-space: normal;
width: 1px;
font-size: 0.8em !important;
}
.info p {
margin: 0;
}
.title {
font-weight: bold;
}
.secondary {
opacity: 0.8;
}
.author {
color: var(--text-secondary);
font-size: 0.8em !important;
}
.video {
display: flex;
align-items: center;
cursor: pointer;
justify-content: space-between;
gap: 10px;
width: 100%;
}
</style>