Files
TermorServer/apps/web/src/stores/player-store.ts
benya 2e7283baad feat: redesign web interface to match aonsoku layout
Replace the early prototype UI with a darker Aonsoku-inspired shell featuring a compact top bar, library sidebar, command palette, settings overlay, dense track list, artists table, albums grid, and a bottom player bar. Add a supporting albums browse endpoint so the frontend can render the same navigation shape without faking data.
2026-04-02 22:53:13 +03:00

61 lines
1.7 KiB
TypeScript

import { create } from 'zustand'
import type { Track } from '@/lib/api'
type PlayerState = {
currentTrack: Track | null
queue: Track[]
isPlaying: boolean
volume: number
setQueue: (tracks: Track[], startIndex?: number) => void
playTrack: (track: Track, queue?: Track[]) => void
togglePlayback: () => void
playNext: () => void
playPrevious: () => void
setVolume: (volume: number) => void
}
export const usePlayerStore = create<PlayerState>((set, get) => ({
currentTrack: null,
queue: [],
isPlaying: false,
volume: 0.7,
setQueue: (queue, startIndex = 0) =>
set({
queue,
currentTrack: queue[startIndex] ?? null,
isPlaying: queue.length > 0,
}),
playTrack: (currentTrack, queue) =>
set((state) => ({
currentTrack,
queue: queue ?? state.queue,
isPlaying: true,
})),
togglePlayback: () => set((state) => ({ isPlaying: !state.isPlaying })),
playNext: () =>
set((state) => {
if (!state.currentTrack || state.queue.length === 0) {
return state
}
const index = state.queue.findIndex((track) => track.id === state.currentTrack?.id)
const nextTrack = state.queue[index + 1] ?? state.queue[0] ?? null
return {
currentTrack: nextTrack,
isPlaying: !!nextTrack,
}
}),
playPrevious: () =>
set((state) => {
if (!state.currentTrack || state.queue.length === 0) {
return state
}
const index = state.queue.findIndex((track) => track.id === state.currentTrack?.id)
const previousTrack = state.queue[index - 1] ?? state.queue[state.queue.length - 1] ?? null
return {
currentTrack: previousTrack,
isPlaying: !!previousTrack,
}
}),
setVolume: (volume) => set({ volume }),
}))