diff --git a/app/components/SearchModal.vue b/app/components/SearchModal.vue index ee3750b..5576650 100644 --- a/app/components/SearchModal.vue +++ b/app/components/SearchModal.vue @@ -31,7 +31,22 @@ r.type }} {{ r.label }} - {{ r.sublabel }} +
+ {{ r.sublabel }} + +
@@ -49,10 +64,12 @@ import { computed, nextTick, onMounted, ref, watch } from 'vue' import { useUiStore } from '~/store/ui' import { useDataStore } from '~/store/data' import { usePlayerStore } from '~/store/player' +import { useFavoritesStore } from '~/store/favorites' const ui = useUiStore() const data = useDataStore() const player = usePlayerStore() +const fav = useFavoritesStore() const inputRef = ref(null) const activeIndex = ref(0) diff --git a/app/plugins/favorites.client.ts b/app/plugins/favorites.client.ts new file mode 100644 index 0000000..0a41d10 --- /dev/null +++ b/app/plugins/favorites.client.ts @@ -0,0 +1,6 @@ +import { useFavoritesStore } from '~/store/favorites' + +export default defineNuxtPlugin(() => { + const fav = useFavoritesStore() + fav.load() +}) diff --git a/app/store/data.ts b/app/store/data.ts index 89c3cdb..cf25a92 100644 --- a/app/store/data.ts +++ b/app/store/data.ts @@ -1,4 +1,5 @@ import type { Box, Artist, Track } from '~/../types/types' +import { FAVORITES_BOX_ID, useFavoritesStore } from '~/store/favorites' // stores/data.ts import { defineStore } from 'pinia' @@ -44,6 +45,21 @@ export const useDataStore = defineStore('data', { artist: artistObj } }) + const favBox: Box = { + id: FAVORITES_BOX_ID, + type: 'playlist', + name: 'Favoris', + duration: 0, + tracks: [], + description: '', + color1: '#0f172a', + color2: '#1e293b', + color3: '#334155', + state: 'box-list' + } + if (!this.boxes.find((b) => b.id === FAVORITES_BOX_ID)) { + this.boxes = [favBox, ...this.boxes] + } this.isLoaded = true const uiStore = useUiStore() uiStore.closeBox() @@ -59,6 +75,12 @@ export const useDataStore = defineStore('data', { }, // Obtenir toutes les pistes d'une box donnée getTracksByboxId: (state) => (id: string) => { + if (id === FAVORITES_BOX_ID) { + const fav = useFavoritesStore() + return fav.trackIds + .map((tid) => state.tracks.find((t) => t.id === tid)) + .filter((t): t is Track => !!t) + } return state.tracks.filter((track) => track.boxId === id) }, // Filtrer les artistes selon certains critères diff --git a/app/store/favorites.ts b/app/store/favorites.ts new file mode 100644 index 0000000..c80b276 --- /dev/null +++ b/app/store/favorites.ts @@ -0,0 +1,52 @@ +import { defineStore } from 'pinia' +import type { Track } from '~/../types/types' + +export const FAVORITES_BOX_ID = 'FAV' +const STORAGE_KEY = 'evilspins:favorites:v1' + +export const useFavoritesStore = defineStore('favorites', { + state: () => ({ + trackIds: [] as number[] + }), + actions: { + load() { + if (!process.client) return + try { + const raw = localStorage.getItem(STORAGE_KEY) + if (raw) { + const arr = JSON.parse(raw) + if (Array.isArray(arr)) this.trackIds = arr.filter((x) => typeof x === 'number') + } + } catch {} + }, + save() { + if (!process.client) return + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify(this.trackIds)) + } catch {} + }, + toggle(track: Track) { + const id = track.id + const idx = this.trackIds.indexOf(id) + if (idx >= 0) this.trackIds.splice(idx, 1) + else this.trackIds.unshift(id) + this.save() + }, + add(track: Track) { + if (!this.trackIds.includes(track.id)) { + this.trackIds.unshift(track.id) + this.save() + } + }, + remove(trackId: number) { + const idx = this.trackIds.indexOf(trackId) + if (idx >= 0) { + this.trackIds.splice(idx, 1) + this.save() + } + }, + isFavorite(trackId: number) { + return this.trackIds.includes(trackId) + } + } +})