initiation librodrome

This commit is contained in:
Yvv
2026-02-20 12:55:10 +01:00
commit 35e2897a73
208 changed files with 18951 additions and 0 deletions

187
app/stores/player.ts Normal file
View File

@@ -0,0 +1,187 @@
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<Song | null>(null)
const currentTime = ref(0)
const duration = ref(0)
const volume = ref(0.8)
const mode = ref<PlayerMode>('guided')
const repeatMode = ref<RepeatMode>('none')
const isShuffled = ref(false)
const playlist = ref<Song[]>([])
const queue = ref<Song[]>([])
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')}`
}