import type { Song } from '~/types/song' import type { PlayerMode, RepeatMode } from '~/types/player' export const usePlayerStore = defineStore('player', () => { // State const isPlaying = ref(false) const currentSong = ref(null) const currentTime = ref(0) const duration = ref(0) const volume = ref(0.8) const mode = ref('guided') const repeatMode = ref('none') const isShuffled = ref(false) const playlist = ref([]) const queue = ref([]) const isExpanded = ref(false) // Computed const progress = computed(() => { if (duration.value === 0) return 0 return (currentTime.value / duration.value) * 100 }) const formattedCurrentTime = computed(() => formatTime(currentTime.value)) const formattedDuration = computed(() => formatTime(duration.value)) const isGuidedMode = computed(() => mode.value === 'guided') const currentIndex = computed(() => { if (!currentSong.value) return -1 return playlist.value.findIndex(s => s.id === currentSong.value!.id) }) const hasNext = computed(() => { if (repeatMode.value === 'all') return playlist.value.length > 0 return currentIndex.value < playlist.value.length - 1 }) const hasPrev = computed(() => { return currentIndex.value > 0 }) // Actions function setSong(song: Song) { currentSong.value = song currentTime.value = 0 duration.value = song.duration } function setPlaylist(songs: Song[]) { playlist.value = songs } function setMode(newMode: PlayerMode) { mode.value = newMode } function togglePlay() { isPlaying.value = !isPlaying.value } function play() { isPlaying.value = true } function pause() { isPlaying.value = false } function setCurrentTime(time: number) { currentTime.value = time } function setDuration(dur: number) { duration.value = dur } function setVolume(vol: number) { volume.value = Math.max(0, Math.min(1, vol)) } function toggleRepeat() { const modes: RepeatMode[] = ['none', 'all', 'one'] const idx = modes.indexOf(repeatMode.value) repeatMode.value = modes[(idx + 1) % modes.length] } function toggleShuffle() { isShuffled.value = !isShuffled.value } function toggleExpanded() { isExpanded.value = !isExpanded.value } function nextSong(): Song | null { if (playlist.value.length === 0) return null if (repeatMode.value === 'one') { currentTime.value = 0 return currentSong.value } let nextIdx = currentIndex.value + 1 if (nextIdx >= playlist.value.length) { if (repeatMode.value === 'all') { nextIdx = 0 } else { pause() return null } } const song = playlist.value[nextIdx] setSong(song) return song } function prevSong(): Song | null { if (playlist.value.length === 0) return null // If more than 3 seconds in, restart current song if (currentTime.value > 3) { currentTime.value = 0 return currentSong.value } let prevIdx = currentIndex.value - 1 if (prevIdx < 0) { if (repeatMode.value === 'all') { prevIdx = playlist.value.length - 1 } else { currentTime.value = 0 return currentSong.value } } const song = playlist.value[prevIdx] setSong(song) return song } return { // State isPlaying, currentSong, currentTime, duration, volume, mode, repeatMode, isShuffled, playlist, queue, isExpanded, // Computed progress, formattedCurrentTime, formattedDuration, isGuidedMode, currentIndex, hasNext, hasPrev, // Actions setSong, setPlaylist, setMode, togglePlay, play, pause, setCurrentTime, setDuration, setVolume, toggleRepeat, toggleShuffle, toggleExpanded, nextSong, prevSong, } }) function formatTime(seconds: number): string { const mins = Math.floor(seconds / 60) const secs = Math.floor(seconds % 60) return `${mins}:${secs.toString().padStart(2, '0')}` }