Compare commits
7 Commits
a5fe876e3f
...
A-new-Comp
| Author | SHA1 | Date | |
|---|---|---|---|
| 9705257178 | |||
| 2f78442deb | |||
|
|
c586cc3932 | ||
|
|
11694d36dd | ||
|
|
3b05938162 | ||
|
|
f75a1481bd | ||
|
|
bb791e35d1 |
@@ -1,5 +1,6 @@
|
||||
# Builder
|
||||
FROM node:20-bookworm AS builder
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install --legacy-peer-deps
|
||||
@@ -8,9 +9,12 @@ COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Runtime
|
||||
FROM node:20-slim AS runner
|
||||
FROM node:20-alpine AS runner
|
||||
RUN apk add --no-cache python3 make g++ sqlite
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/.output ./.output
|
||||
COPY package*.json ./
|
||||
COPY ./server/database ./server/database
|
||||
EXPOSE 3000
|
||||
CMD ["node", ".output/server/index.mjs"]
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<template>
|
||||
<div class="platine pointer-events-none" :class="{ 'drag-over': isDragOver }" @dragenter.prevent="onDragEnter"
|
||||
@dragover.prevent="onDragOver" @dragleave="onDragLeave" @drop.prevent="onDrop">
|
||||
<div class="disc pointer-events-auto fixed" ref="discRef" :style="'background-image: url(/card-dock.svg)'"
|
||||
id="disc">
|
||||
<div
|
||||
class="bobine bg-slate-900 bg-opacity-50 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full"
|
||||
<div class="platine pointer-events-none" :class="{ 'loading': platineStore.isLoadingTrack, 'mounted': isMounted }"
|
||||
ref="platine">
|
||||
<img class="cover" :src="platineStore.currentTrack?.coverId" />
|
||||
<div class="disc pointer-events-auto fixed bg-transparent" ref="discRef" id="disc">
|
||||
<div class="bobine"
|
||||
:style="{ height: platineStore.progressPercentage + '%', width: platineStore.progressPercentage + '%' }"></div>
|
||||
<img class="absolute size-full rounded-full" :src="platineStore.currentTrack?.coverId"
|
||||
:alt="platineStore.currentTrack?.title">
|
||||
|
||||
|
||||
<div class="disc-label rounded-full bg-cover bg-center">
|
||||
<img src="/favicon.svg" class="size-1/3">
|
||||
<img src="/favicon.svg" class="size-1/2 bg-black rounded-full p-5">
|
||||
<div v-if="platineStore.isLoadingTrack" class="loading-indicator">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
@@ -18,11 +16,11 @@
|
||||
<div v-if="!platineStore.isLoadingTrack" class="absolute top-1/2 right-8 size-1/12 rounded-full bg-esyellow">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-1/5 text-base">
|
||||
<!-- <div class="w-full h-1/5 text-base">
|
||||
{{ platineStore.currentTrack?.title }}
|
||||
<br>
|
||||
{{ platineStore.currentTrack?.artist?.name }}
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -34,41 +32,12 @@ import type { Track } from '~~/types/types'
|
||||
const props = defineProps<{ track?: Track }>()
|
||||
const platineStore = usePlatineStore()
|
||||
const discRef = ref<HTMLElement>()
|
||||
const isDragOver = ref(false)
|
||||
|
||||
// Gestion du drag and drop
|
||||
const onDragEnter = (e: DragEvent) => {
|
||||
e.preventDefault()
|
||||
isDragOver.value = true
|
||||
}
|
||||
|
||||
const onDragOver = (e: DragEvent) => {
|
||||
e.preventDefault()
|
||||
isDragOver.value = true
|
||||
}
|
||||
|
||||
const onDragLeave = () => {
|
||||
isDragOver.value = false
|
||||
}
|
||||
|
||||
const onDrop = (e: DragEvent) => {
|
||||
isDragOver.value = false
|
||||
const cardData = e.dataTransfer?.getData('application/json')
|
||||
|
||||
if (cardData) {
|
||||
try {
|
||||
const newTrack = JSON.parse(cardData)
|
||||
if (newTrack && newTrack.url) {
|
||||
platineStore.loadTrack(newTrack)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du traitement de la carte déposée', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
const platine = ref<HTMLElement>()
|
||||
const isMounted = ref(false)
|
||||
|
||||
// Initialisation du lecteur
|
||||
onMounted(() => {
|
||||
isMounted.value = true
|
||||
if (discRef.value) {
|
||||
platineStore.initPlatine(discRef.value)
|
||||
}
|
||||
@@ -76,6 +45,7 @@ onMounted(() => {
|
||||
|
||||
// Nettoyage
|
||||
onUnmounted(() => {
|
||||
isMounted.value = false
|
||||
platineStore.cleanup()
|
||||
})
|
||||
|
||||
@@ -94,21 +64,34 @@ watch(() => props.track, (newTrack) => {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
|
||||
.card {
|
||||
position: absolute !important;
|
||||
z-index: 99;
|
||||
top: -20%;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
transform: translate(-50%, 50%);
|
||||
}
|
||||
|
||||
.cover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 100%;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: opacity 3s ease;
|
||||
|
||||
.loading & {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.disc {
|
||||
position: relative;
|
||||
background-color: white;
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@@ -116,10 +99,10 @@ watch(() => props.track, (newTrack) => {
|
||||
cursor: grab;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
|
||||
|
||||
.dragoOver & {
|
||||
background-color: #4CAF50;
|
||||
.loading & {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +175,6 @@ watch(() => props.track, (newTrack) => {
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
@@ -211,15 +193,6 @@ watch(() => props.track, (newTrack) => {
|
||||
}
|
||||
|
||||
.bobine {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
opacity: 0.7;
|
||||
}
|
||||
@apply bg-slate-900 bg-opacity-50 backdrop-blur absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<slot />
|
||||
<Bucket />
|
||||
<Platine />
|
||||
<Platine v-if="playerStore.currentTrack" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Track } from '~~/types/types'
|
||||
import { usePlayerStore } from '~/store/player'
|
||||
|
||||
const playerStore = usePlayerStore()
|
||||
const onCardDropped = (card: Track) => {
|
||||
console.log('Carte déposée dans le bucket:', card)
|
||||
}
|
||||
@@ -16,16 +18,17 @@ const onCardDropped = (card: Track) => {
|
||||
.bucket,
|
||||
.platine {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
bottom: -100%;
|
||||
right: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.bucket {
|
||||
z-index: 70;
|
||||
bottom: -260px;
|
||||
transition: bottom 0.3s ease;
|
||||
width: 100%;
|
||||
overflow-x: scroll;
|
||||
transition: bottom .3s ease;
|
||||
|
||||
&:hover,
|
||||
.card-dragging & {
|
||||
@@ -38,9 +41,15 @@ const onCardDropped = (card: Track) => {
|
||||
}
|
||||
|
||||
.platine {
|
||||
z-index: 60;
|
||||
bottom: -70%;
|
||||
transition: bottom 0.3s ease;
|
||||
/* width: 25%; */
|
||||
bottom: -100%;
|
||||
transition: bottom 2s ease;
|
||||
|
||||
&.mounted {
|
||||
z-index: 80;
|
||||
bottom: 0;
|
||||
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
3
env.sh
3
env.sh
@@ -1,3 +0,0 @@
|
||||
export DOMAIN="evilspins.com"
|
||||
export PORT="7901"
|
||||
export PORT_EXPOSED="3000"
|
||||
@@ -58,7 +58,7 @@ export default eventHandler(async (event) => {
|
||||
const date = new Date(year, month - 1, day, hour)
|
||||
const card = getCardFromDate(date)
|
||||
const url = `${urlPrefix}/${encodeURIComponent(file)}`
|
||||
const coverId = `${urlPrefix}/cover/${encodeURIComponent(file).replace(EXT_RE, '.jpg')}`
|
||||
const coverId = `${urlPrefix}/${encodeURIComponent(file).replace(EXT_RE, '.jpg')}`
|
||||
|
||||
return {
|
||||
id: Number(`${year}${index + 1}`),
|
||||
|
||||
Reference in New Issue
Block a user