Files
evilspins/app/store/player.ts
valere 96ffb4b10a
All checks were successful
Deploy App / build (push) Successful in 1m20s
Deploy App / deploy (push) Successful in 16s
add working player
2025-10-04 00:49:12 +02:00

114 lines
3.0 KiB
TypeScript

// ~/store/player.ts
import { defineStore } from 'pinia'
import type { Track } from '~/../types/types'
import { useDataStore } from '~/store/data'
export const usePlayerStore = defineStore('player', {
state: () => ({
currentTrack: null as Track | null,
position: 0,
audio: null as HTMLAudioElement | null,
}),
actions: {
async playTrack(track: Track) {
this.currentTrack = track
// toggle si on reclique sur la même
if (this.isPlayingTrack(track)) {
this.togglePlay()
return
}
if (!this.audio) {
this.audio = new Audio()
}
// définir la source (fichier de la compilation entière)
this.audio.src = this.getCompilationUrlFromTrack(track)
this.audio.load()
// attendre que le player soit prêt avant de lire
await new Promise<void>((resolve, reject) => {
const onCanPlay = () => {
this.audio!.removeEventListener("canplay", onCanPlay)
resolve()
}
const onError = (e: Event) => {
this.audio!.removeEventListener("error", onError)
reject(e)
}
this.audio!.addEventListener("canplay", onCanPlay, { once: true })
this.audio!.addEventListener("error", onError, { once: true })
})
// positionner le début
this.audio.currentTime = track.start ?? 0
// lancer la lecture
try {
await this.audio.play()
} catch (err) {
console.error("Impossible de lire la piste :", err)
}
},
togglePlay() {
if (!this.audio) return
if (this.audio.paused) {
this.audio.play().catch(err => console.error(err))
} else {
this.audio.pause()
}
},
},
getters: {
isCurrentCompilation: (state) => {
return (compilationId: string) =>
compilationId === state.currentTrack?.compilationId
},
isPlayingTrack: (state) => {
return (track: Track) => {
if (!state.audio || !state.currentTrack) return false
const currentTime = state.audio.currentTime
if (!currentTime || isNaN(currentTime)) return false
const from = track.start ?? 0
const to = state.getTrackStop(track)
if (!to || isNaN(to)) return false
return currentTime >= from && currentTime < to
}
},
getCurrentTrack: (state) => state.currentTrack,
getCompilationUrlFromTrack: () => {
return (track: Track) =>
`https://files.erudi.fr/evilspins/${track.compilationId}.mp3`
},
getCurrentCompilation: (state) => {
return state.currentTrack
? state.getCompilationUrlFromTrack(state.currentTrack)
: null
},
getTrackStop: (state) => {
return (track: Track) => {
if (!state.audio) return 0
if (track.order === 0) {
return Math.round(state.audio.duration)
} else {
const dataStore = useDataStore()
const nextTrack = dataStore.getNextTrack(track)
return nextTrack ? nextTrack.start : Math.round(state.audio.duration)
}
}
}
},
})