145 lines
4.6 KiB
TypeScript
145 lines
4.6 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import type { Track, Box, BoxType, Artist } from '~/../types/types'
|
|
|
|
export const FAVORITES_BOX_ID = 'FAV'
|
|
const STORAGE_KEY = 'evilspins:favorites:v2' // Version changée pour forcer la mise à jour
|
|
|
|
export const useFavoritesStore = defineStore('favorites', {
|
|
state: () => ({
|
|
favoritesPlaylist: {
|
|
id: FAVORITES_BOX_ID,
|
|
type: 'userPlaylist' as BoxType,
|
|
name: 'Favoris',
|
|
description: 'Vos titres favoris',
|
|
color1: '#FFD700',
|
|
color2: '#FFA500',
|
|
color3: '#FF8C00',
|
|
duration: 0,
|
|
state: 'box-hidden',
|
|
tracks: [] as Track[],
|
|
isPublic: false
|
|
} as Box,
|
|
version: 1
|
|
}),
|
|
getters: {
|
|
trackIds: (state) => state.favoritesPlaylist.tracks?.map((t) => t.id) || [],
|
|
tracks: (state) => state.favoritesPlaylist.tracks || [],
|
|
isFavorite: (state) => (trackId: number) =>
|
|
state.favoritesPlaylist.tracks?.some((t) => t.id === trackId) || false
|
|
},
|
|
|
|
actions: {
|
|
load() {
|
|
if (!process.client) return
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY)
|
|
if (raw) {
|
|
const data = JSON.parse(raw)
|
|
if (data.version === this.version && data.playlist) {
|
|
this.favoritesPlaylist = { ...this.favoritesPlaylist, ...data.playlist }
|
|
} else if (Array.isArray(data)) {
|
|
// Migration depuis l'ancienne version
|
|
this.favoritesPlaylist.tracks = data
|
|
.filter((x) => typeof x === 'number')
|
|
.map((id) => ({ id }) as unknown as Track) // On ne stocke que l'ID, les infos seront complétées par le dataStore
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading favorites:', error)
|
|
}
|
|
},
|
|
|
|
save() {
|
|
if (!process.client) return
|
|
try {
|
|
localStorage.setItem(
|
|
STORAGE_KEY,
|
|
JSON.stringify({
|
|
version: this.version,
|
|
playlist: this.favoritesPlaylist
|
|
})
|
|
)
|
|
} catch (error) {
|
|
console.error('Error saving favorites:', error)
|
|
}
|
|
},
|
|
|
|
// Crée une copie virtuelle d'une piste pour les favoris
|
|
createVirtualTrack(originalTrack: Track): Track {
|
|
// Crée une copie profonde de la piste
|
|
const virtualTrack = JSON.parse(JSON.stringify(originalTrack)) as Track
|
|
|
|
// Marque la piste comme provenant d'une playlist utilisateur
|
|
virtualTrack.source = 'userPlaylist'
|
|
virtualTrack.originalTrackId = originalTrack.id
|
|
virtualTrack.boxId = FAVORITES_BOX_ID
|
|
|
|
// Si la piste a un artiste sous forme d'objet, on le convertit en chaîne pour éviter les problèmes de référence
|
|
if (virtualTrack.artist && typeof virtualTrack.artist === 'object') {
|
|
virtualTrack.artist = (virtualTrack.artist as Artist).name
|
|
}
|
|
|
|
return virtualTrack
|
|
},
|
|
|
|
// Ajoute une piste aux favoris si elle n'y est pas déjà
|
|
add(track: Track) {
|
|
if (!this.isFavorite(track.id)) {
|
|
// Crée une copie virtuelle de la piste
|
|
const virtualTrack = this.createVirtualTrack(track)
|
|
|
|
if (!this.favoritesPlaylist.tracks) {
|
|
this.favoritesPlaylist.tracks = []
|
|
}
|
|
|
|
// Ajoute la piste virtuelle au début de la liste
|
|
this.favoritesPlaylist.tracks.unshift(virtualTrack)
|
|
this.updateDuration()
|
|
this.save()
|
|
}
|
|
},
|
|
|
|
// Supprime une piste des favoris
|
|
remove(trackId: number) {
|
|
if (this.favoritesPlaylist.tracks) {
|
|
const index = this.favoritesPlaylist.tracks.findIndex((t) => t.id === trackId)
|
|
if (index >= 0) {
|
|
this.favoritesPlaylist.tracks.splice(index, 1)
|
|
this.updateDuration()
|
|
this.save()
|
|
}
|
|
}
|
|
},
|
|
|
|
// Bascule l'état favori d'une piste
|
|
toggle(track: Track) {
|
|
if (this.isFavorite(track.id)) {
|
|
this.remove(track.id)
|
|
} else {
|
|
this.add(track)
|
|
}
|
|
},
|
|
|
|
// Met à jour la durée totale de la playlist
|
|
updateDuration() {
|
|
if (this.favoritesPlaylist.tracks) {
|
|
this.favoritesPlaylist.duration = this.favoritesPlaylist.tracks.reduce(
|
|
(total, track) => total + (track.duration || 0),
|
|
0
|
|
)
|
|
}
|
|
},
|
|
|
|
// Récupère la piste suivante dans les favoris
|
|
getNextTrack(currentTrackId: number): Track | null {
|
|
if (!this.favoritesPlaylist.tracks) return null
|
|
const currentIndex = this.favoritesPlaylist.tracks.findIndex((t) => t.id === currentTrackId)
|
|
if (currentIndex >= 0 && currentIndex < this.favoritesPlaylist.tracks.length - 1) {
|
|
const nextTrack = this.favoritesPlaylist.tracks[currentIndex + 1]
|
|
return nextTrack ? { ...nextTrack } : null
|
|
}
|
|
return null
|
|
}
|
|
}
|
|
})
|