114 lines
3.0 KiB
TypeScript
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)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
})
|