136 lines
3.6 KiB
TypeScript
136 lines
3.6 KiB
TypeScript
import { apiClient } from '../client'
|
|
|
|
export interface TTSRequest {
|
|
text: string
|
|
provider?: string
|
|
options?: Record<string, any>
|
|
}
|
|
|
|
export interface TTSResponse {
|
|
id: number
|
|
text: string
|
|
provider: string
|
|
options: Record<string, any>
|
|
status: string
|
|
error: string | null
|
|
sound_id: number | null
|
|
user_id: number
|
|
created_at: string
|
|
}
|
|
|
|
export interface TTSGenerateResponse {
|
|
message: string
|
|
tts: TTSResponse
|
|
}
|
|
|
|
export interface TTSProvider {
|
|
name: string
|
|
file_extension: string
|
|
supported_languages: string[]
|
|
option_schema: Record<string, any>
|
|
}
|
|
|
|
export interface TTSProvidersResponse {
|
|
[key: string]: TTSProvider
|
|
}
|
|
|
|
export type TTSSortField = 'created_at' | 'text' | 'provider'
|
|
export type TTSSortOrder = 'asc' | 'desc'
|
|
|
|
export interface GetTTSHistoryParams {
|
|
search?: string
|
|
sort_by?: TTSSortField
|
|
sort_order?: TTSSortOrder
|
|
page?: number
|
|
limit?: number
|
|
}
|
|
|
|
export interface GetTTSHistoryResponse {
|
|
tts: TTSResponse[]
|
|
total: number
|
|
total_pages: number
|
|
current_page: number
|
|
}
|
|
|
|
export const ttsService = {
|
|
async generateTTS(request: TTSRequest): Promise<TTSGenerateResponse> {
|
|
return await apiClient.post('/api/v1/tts', request)
|
|
},
|
|
|
|
async getTTSHistory(params?: GetTTSHistoryParams): Promise<GetTTSHistoryResponse> {
|
|
const searchParams = new URLSearchParams()
|
|
|
|
// Backend currently only supports limit and offset, not page-based pagination
|
|
if (params?.limit) {
|
|
searchParams.append('limit', params.limit.toString())
|
|
}
|
|
if (params?.page && params?.limit) {
|
|
// Convert page to offset
|
|
const offset = (params.page - 1) * params.limit
|
|
searchParams.append('offset', offset.toString())
|
|
}
|
|
|
|
const url = searchParams.toString()
|
|
? `/api/v1/tts?${searchParams.toString()}`
|
|
: '/api/v1/tts'
|
|
|
|
const ttsArray: TTSResponse[] = await apiClient.get(url)
|
|
|
|
// Apply client-side filtering and sorting since backend doesn't support them yet
|
|
let filteredTTS = ttsArray
|
|
|
|
if (params?.search) {
|
|
const search = params.search.toLowerCase()
|
|
filteredTTS = filteredTTS.filter(tts =>
|
|
tts.text.toLowerCase().includes(search) ||
|
|
tts.provider.toLowerCase().includes(search)
|
|
)
|
|
}
|
|
|
|
if (params?.sort_by && params?.sort_order) {
|
|
filteredTTS.sort((a, b) => {
|
|
let aValue = a[params.sort_by as keyof TTSResponse]
|
|
let bValue = b[params.sort_by as keyof TTSResponse]
|
|
|
|
// Convert dates to timestamps for comparison
|
|
if (params.sort_by === 'created_at') {
|
|
aValue = new Date(aValue as string).getTime()
|
|
bValue = new Date(bValue as string).getTime()
|
|
}
|
|
|
|
// Handle null values
|
|
if (aValue === null && bValue === null) return 0
|
|
if (aValue === null) return 1
|
|
if (bValue === null) return -1
|
|
|
|
const comparison = aValue > bValue ? 1 : -1
|
|
return params.sort_order === 'asc' ? comparison : -comparison
|
|
})
|
|
}
|
|
|
|
// Calculate pagination info
|
|
const limit = params?.limit || 50
|
|
const currentPage = params?.page || 1
|
|
const total = filteredTTS.length
|
|
const totalPages = Math.ceil(total / limit)
|
|
|
|
return {
|
|
tts: filteredTTS,
|
|
total,
|
|
total_pages: totalPages,
|
|
current_page: currentPage,
|
|
}
|
|
},
|
|
|
|
async getProviders(): Promise<TTSProvidersResponse> {
|
|
return await apiClient.get('/api/v1/tts/providers')
|
|
},
|
|
|
|
async getProvider(name: string): Promise<TTSProvider> {
|
|
return await apiClient.get(`/api/v1/tts/providers/${name}`)
|
|
},
|
|
|
|
async deleteTTS(ttsId: number): Promise<{ message: string }> {
|
|
return await apiClient.delete(`/api/v1/tts/${ttsId}`)
|
|
},
|
|
} |