feat: implement ThemeProvider and SoundCard components; add utility functions for formatting duration and size

This commit is contained in:
JSC
2025-08-02 18:21:26 +02:00
parent e66ab7b7f8
commit b42b802c37
9 changed files with 424 additions and 29 deletions

View File

@@ -0,0 +1,83 @@
import { apiClient } from '../client'
export interface Sound {
id: number
name: string
filename: string
duration: number
size: number
hash: string
type: 'SDB' | 'TTS' | 'EXT'
play_count: number
is_normalized: boolean
normalized_filename?: string
normalized_duration?: number
normalized_size?: number
normalized_hash?: string
thumbnail?: string
is_music: boolean
is_deletable: boolean
created_at: string
updated_at: string
}
export interface GetSoundsParams {
types?: string[]
}
export interface GetSoundsResponse {
sounds: Sound[]
}
export class SoundsService {
/**
* Get all sounds with optional type filtering
*/
async getSounds(params?: GetSoundsParams): Promise<Sound[]> {
const queryParams: Record<string, string | number | boolean | undefined> = {}
if (params?.types) {
// Handle multiple types by building query string manually
const searchParams = new URLSearchParams()
params.types.forEach(type => {
searchParams.append('types', type)
})
const response = await apiClient.get<GetSoundsResponse>(`/api/v1/sounds/?${searchParams.toString()}`)
return response.sounds || []
}
const response = await apiClient.get<GetSoundsResponse>('/api/v1/sounds/', { params: queryParams })
return response.sounds || []
}
/**
* Get sounds of a specific type
*/
async getSoundsByType(type: string): Promise<Sound[]> {
return this.getSounds({ types: [type] })
}
/**
* Get SDB type sounds
*/
async getSDBSounds(): Promise<Sound[]> {
return this.getSoundsByType('SDB')
}
/**
* Play a sound by ID
*/
async playSound(soundId: number): Promise<void> {
await apiClient.post(`/api/v1/sounds/play/${soundId}`)
}
/**
* Stop all playing sounds
*/
async stopSounds(): Promise<void> {
await apiClient.post('/api/v1/sounds/stop')
}
}
export const soundsService = new SoundsService()