172 lines
4.5 KiB
TypeScript
172 lines
4.5 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import type { Track } from '~~/types'
|
|
|
|
export const useCardStore = defineStore('card', {
|
|
state: () => ({
|
|
// Stocke les IDs des cartes déjà révélées
|
|
revealedCards: new Set<number>(),
|
|
// Stocke les pistes dans le panier
|
|
bucket: [] as Track[],
|
|
// Stocke l'état d'ouverture du panier
|
|
isBucketOpen: false
|
|
}),
|
|
|
|
actions: {
|
|
// Mettre à jour l'ordre des pistes dans le panier
|
|
updateBucketOrder(newOrder: Track[]) {
|
|
this.bucket = [...newOrder]
|
|
this.saveBucketToLocalStorage()
|
|
},
|
|
|
|
// Marquer une carte comme révélée
|
|
revealCard(trackId: number) {
|
|
this.revealedCards.add(trackId)
|
|
this.saveToLocalStorage()
|
|
},
|
|
|
|
hideCard(trackId: number) {
|
|
this.revealedCards.delete(trackId)
|
|
this.saveToLocalStorage()
|
|
},
|
|
|
|
flipCard(track: any) {
|
|
if (this.isRevealed(track.id)) {
|
|
this.hideCard(track.id)
|
|
} else {
|
|
this.revealCard(track.id)
|
|
}
|
|
},
|
|
|
|
// Basculer l'état de révélation de toutes les cartes
|
|
revealAllCards(tracks: Track[]) {
|
|
tracks.forEach((track) => {
|
|
this.revealCard(track.id)
|
|
})
|
|
this.saveToLocalStorage()
|
|
},
|
|
|
|
hideAllCards(tracks: Track[]) {
|
|
tracks.forEach((track) => {
|
|
this.hideCard(track.id)
|
|
})
|
|
this.saveToLocalStorage()
|
|
},
|
|
|
|
// Sauvegarder l'état dans le localStorage
|
|
saveToLocalStorage() {
|
|
if (typeof window !== 'undefined') {
|
|
try {
|
|
localStorage.setItem(
|
|
'cardStore',
|
|
JSON.stringify({
|
|
revealedCards: Array.from(this.revealedCards)
|
|
})
|
|
)
|
|
} catch (e) {
|
|
console.error('Failed to save card store to localStorage', e)
|
|
}
|
|
}
|
|
},
|
|
|
|
// Charger l'état depuis le localStorage
|
|
loadFromLocalStorage() {
|
|
if (typeof window !== 'undefined') {
|
|
try {
|
|
const saved = localStorage.getItem('cardStore')
|
|
if (saved) {
|
|
const { revealedCards } = JSON.parse(saved)
|
|
if (Array.isArray(revealedCards)) {
|
|
this.revealedCards = new Set(
|
|
revealedCards.filter((id): id is number => typeof id === 'number')
|
|
)
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to load card store from localStorage', e)
|
|
}
|
|
}
|
|
},
|
|
|
|
// Initialiser le store
|
|
initialize() {
|
|
this.loadFromLocalStorage()
|
|
},
|
|
|
|
// Gestion du panier
|
|
addToBucket(track: Track) {
|
|
// Vérifie si la piste n'est pas déjà dans le panier
|
|
if (!this.bucket.some((item) => item.id === track.id)) {
|
|
this.bucket.push(track)
|
|
this.saveBucketToLocalStorage()
|
|
}
|
|
},
|
|
|
|
removeFromBucket(trackId: number) {
|
|
const index = this.bucket.findIndex((item) => item.id === trackId)
|
|
if (index !== -1) {
|
|
this.bucket.splice(index, 1)
|
|
this.saveBucketToLocalStorage()
|
|
}
|
|
},
|
|
|
|
clearBucket() {
|
|
this.bucket = []
|
|
this.saveBucketToLocalStorage()
|
|
},
|
|
|
|
toggleBucket() {
|
|
this.isBucketOpen = !this.isBucketOpen
|
|
},
|
|
|
|
// Sauvegarder le panier dans le localStorage
|
|
saveBucketToLocalStorage() {
|
|
if (typeof window !== 'undefined') {
|
|
try {
|
|
localStorage.setItem('cardStoreBucket', JSON.stringify(this.bucket))
|
|
} catch (e) {
|
|
console.error('Failed to save bucket to localStorage', e)
|
|
}
|
|
}
|
|
},
|
|
|
|
// Charger le panier depuis le localStorage
|
|
loadBucketFromLocalStorage() {
|
|
if (typeof window !== 'undefined') {
|
|
try {
|
|
const saved = localStorage.getItem('cardStoreBucket')
|
|
if (saved) {
|
|
const bucket = JSON.parse(saved)
|
|
if (Array.isArray(bucket)) {
|
|
this.bucket = bucket
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to load bucket from localStorage', e)
|
|
}
|
|
}
|
|
},
|
|
// Vérifier si une carte est révélée
|
|
isCardRevealed(trackId: number): boolean {
|
|
return this.revealedCards.has(trackId)
|
|
}
|
|
},
|
|
|
|
getters: {
|
|
// Getter pour la réactivité dans les templates
|
|
isRevealed: (state) => (trackId: number) => {
|
|
return state.revealedCards.has(trackId)
|
|
},
|
|
|
|
// Getters pour le panier
|
|
bucketCount: (state) => state.bucket.length,
|
|
|
|
isInBucket: (state) => (trackId: number) => {
|
|
return state.bucket.some((track) => track.id === trackId)
|
|
},
|
|
|
|
bucketTotalDuration: (state) => {
|
|
return state.bucket.reduce((total, track) => total + ((track as any).duration || 0), 0)
|
|
}
|
|
}
|
|
})
|