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.
This commit is contained in:
@@ -4,13 +4,57 @@ import type { Track } from '@/lib/api'
|
||||
type PlayerState = {
|
||||
currentTrack: Track | null
|
||||
queue: Track[]
|
||||
setQueue: (tracks: Track[]) => void
|
||||
playTrack: (track: Track) => void
|
||||
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) => ({
|
||||
export const usePlayerStore = create<PlayerState>((set, get) => ({
|
||||
currentTrack: null,
|
||||
queue: [],
|
||||
setQueue: (queue) => set({ queue, currentTrack: queue[0] ?? null }),
|
||||
playTrack: (currentTrack) => set({ currentTrack }),
|
||||
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 }),
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user