Files
evilspins/app/store/player.ts
valere e2c5693948
All checks were successful
Deploy App / build (push) Successful in 4m19s
Deploy App / deploy (push) Successful in 16s
playlists support v1
2025-10-09 22:47:30 +02:00

106 lines
2.8 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) {
const oldTrack = this.currentTrack
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.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,
getCurrentCompilation: (state) => {
return state.currentTrack ? state.currentTrack.url : 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)
}
}
}
}
})