feat: add Text to Speech (TTS) functionality with provider selection, generation, and history management
- Implemented CreateTTSDialog for generating TTS from user input. - Added TTSHeader for search, sorting, and creation controls. - Created TTSList to display TTS history with filtering and sorting capabilities. - Developed TTSLoadingStates for handling loading and error states. - Introduced TTSRow for individual TTS entries with play and delete options. - Built TTSTable for structured display of TTS history. - Integrated TTS service API for generating and managing TTS data. - Added TTSPage to encapsulate the TTS feature with pagination and state management.
This commit is contained in:
129
src/lib/api/services/tts.ts
Normal file
129
src/lib/api/services/tts.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
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>
|
||||
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/generate', 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/history?${searchParams.toString()}`
|
||||
: '/api/v1/tts/history'
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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}`)
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user