frontend: Finish interactivity

This commit is contained in:
2025-02-15 16:28:47 -08:00
parent 9c4981b9cb
commit 79f53bbffe
9 changed files with 247 additions and 35 deletions

View File

@@ -0,0 +1,82 @@
export interface NowPlayingResponse {
success: boolean;
nowPlaying: string;
isPaused: boolean;
volume: number;
isIdle: boolean;
currentFile: string;
}
export interface PlaylistItem {
filename: string;
title: string | null;
id: number;
playing: boolean | null;
}
export const API = {
async getPlaylist(): Promise<PlaylistItem[]> {
const response = await fetch('/api/playlist');
return response.json();
},
async addToPlaylist(url: string): Promise<void> {
await fetch('/api/playlist', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
},
async removeFromPlaylist(index: number): Promise<void> {
await fetch(`/api/playlist/${index}`, {
method: 'DELETE',
});
},
async play(): Promise<void> {
await fetch('/api/play', { method: 'POST' });
},
async pause(): Promise<void> {
await fetch('/api/pause', { method: 'POST' });
},
async skip(): Promise<void> {
await fetch('/api/skip', { method: 'POST' });
},
async skipTo(index: number): Promise<void> {
await fetch(`/api/skip/${index}`, { method: 'POST' });
},
async previous(): Promise<void> {
await fetch('/api/previous', { method: 'POST' });
},
async getNowPlaying(): Promise<NowPlayingResponse> {
const response = await fetch('/api/nowplaying');
return response.json();
},
async setVolume(volume: number): Promise<void> {
await fetch('/api/volume', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ volume }),
});
},
subscribeToEvents(onMessage: (event: any) => void): WebSocket {
const ws = new WebSocket(`ws://${window.location.host}/api/events`);
ws.onmessage = (event) => {
onMessage(JSON.parse(event.data));
};
return ws;
}
};