feat: add playlists mvp for web and subsonic
This commit is contained in:
@@ -64,6 +64,21 @@ export type HomePayload = {
|
||||
artists: Artist[]
|
||||
}
|
||||
|
||||
export type PlaylistSummary = {
|
||||
id: string
|
||||
name: string
|
||||
comment: string
|
||||
public: boolean
|
||||
songCount: number
|
||||
durationSeconds: number
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export type PlaylistDetail = PlaylistSummary & {
|
||||
tracks: Track[]
|
||||
}
|
||||
|
||||
const API_BASE = import.meta.env.VITE_API_BASE ?? 'http://localhost:4040'
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
@@ -81,6 +96,10 @@ async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
throw new Error(`Request failed: ${response.status}`)
|
||||
}
|
||||
|
||||
if (response.status === 204) {
|
||||
return undefined as T
|
||||
}
|
||||
|
||||
return response.json() as Promise<T>
|
||||
}
|
||||
|
||||
@@ -131,6 +150,46 @@ export async function triggerScan() {
|
||||
return request<ScanStatus>('/api/admin/scan', { method: 'POST' })
|
||||
}
|
||||
|
||||
export async function fetchPlaylists() {
|
||||
return request<{ items: PlaylistSummary[] }>('/api/playlists')
|
||||
}
|
||||
|
||||
export async function fetchPlaylist(id: string) {
|
||||
return request<PlaylistDetail>(`/api/playlists/${id}`)
|
||||
}
|
||||
|
||||
export async function createPlaylist(input: {
|
||||
name: string
|
||||
comment?: string
|
||||
public?: boolean
|
||||
trackIds?: string[]
|
||||
}) {
|
||||
return request<PlaylistDetail>('/api/playlists', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(input),
|
||||
})
|
||||
}
|
||||
|
||||
export async function updatePlaylist(
|
||||
id: string,
|
||||
input: {
|
||||
name?: string
|
||||
comment?: string
|
||||
public?: boolean
|
||||
addTrackIds?: string[]
|
||||
removeTrackIds?: string[]
|
||||
},
|
||||
) {
|
||||
return request<PlaylistDetail>(`/api/playlists/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(input),
|
||||
})
|
||||
}
|
||||
|
||||
export async function deletePlaylist(id: string) {
|
||||
await request<void>(`/api/playlists/${id}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
export function coverArtUrl(id: string) {
|
||||
const token = useSessionStore.getState().token
|
||||
return `${API_BASE}/api/cover-art/${id}${token ? `?token=${encodeURIComponent(token)}` : ''}`
|
||||
|
||||
Reference in New Issue
Block a user