feat: modernize UI with gradient design, glass morphism, and enhanced visual appeal

- Add purple/indigo gradient background throughout app
- Implement glass morphism effects on all cards
- Add gradient buttons with smooth hover animations
- Integrate emoji icons for better visual communication
- Enhance typography with improved font stack
- Add loading spinners and smooth transitions
- Improve color scheme with modern purple/indigo palette
- Add glowing shadows and depth effects
- Maintain responsive design and touch-friendly interactions
This commit is contained in:
2025-12-09 12:29:40 +00:00
parent 63bdf57593
commit 706ada866c
17 changed files with 731 additions and 93 deletions

View File

@@ -4,10 +4,11 @@
The Text to Audiobook system is a full-stack application that converts long-form text into multi-voice audiobooks using Kokoro TTS. The architecture follows a client-server model with a React TypeScript frontend and a Python FastAPI backend running in Docker. The system automatically detects speaker roles in text, allows voice assignment per role, and generates high-quality audio using the Kokoro-82M model.
The application workflow consists of three main phases:
The application workflow consists of four main phases:
1. **Text Input & Role Detection**: User provides text, system identifies distinct speakers
2. **Voice Assignment**: User maps each detected role to a specific Kokoro voice
3. **Audio Generation & Playback**: System synthesizes multi-voice audio and provides playback/download
3. **Script Review & Editing**: User reviews and edits AI-generated speaker assignments for each text segment
4. **Audio Generation & Playback**: System synthesizes multi-voice audio and provides playback/download
## Architecture
@@ -93,10 +94,12 @@ Main application container managing the overall workflow state.
- `text: string` - User input text
- `roles: Role[]` - Detected roles from backend
- `voiceAssignments: Map<string, string>` - Role ID to Voice ID mapping
- `scriptSegments: ScriptSegment[]` - AI-generated script segments
- `selectedLanguage: string` - Language code (default: 'a')
- `speed: number` - Playback speed (default: 1.0)
- `audioUrl: string | null` - Generated audio blob URL
- `isDetectingRoles: boolean` - Loading state for role detection
- `isGeneratingScript: boolean` - Loading state for script generation
- `isGenerating: boolean` - Loading state for audio generation
- `error: string | null` - Error message if any
@@ -104,7 +107,10 @@ Main application container managing the overall workflow state.
- `handleTextChange(text: string)` - Updates text state
- `handleDetectRoles()` - Calls API to detect roles
- `handleVoiceAssignment(roleId: string, voiceId: string)` - Updates voice mapping
- `handleGenerate()` - Calls API to generate audiobook
- `handleGenerateScript()` - Calls API to generate script preview
- `handleSkipReview()` - Skips script review and proceeds to generation
- `handleSegmentChange(segmentId: string, newSpeaker: string)` - Updates speaker for a segment
- `handleGenerate()` - Calls API to generate audiobook with edited script
- `handleDownload()` - Triggers download of generated audio
#### 2. TextInputSection Component
@@ -132,14 +138,25 @@ Displays role-to-voice mapping interface with language and speed controls.
- `isGenerating: boolean`
- `allRolesAssigned: boolean`
#### 4. AudioPlayerSection Component
#### 4. ScriptReviewSection Component
Displays AI-generated script with editable speaker assignments.
**Props:**
- `segments: ScriptSegment[]`
- `roles: Role[]`
- `onSegmentChange: (segmentId: string, newSpeaker: string) => void`
- `onGenerate: () => void`
- `onSkipReview: () => void`
- `isGenerating: boolean`
#### 5. AudioPlayerSection Component
Displays audio player and download button after generation.
**Props:**
- `audioUrl: string`
- `onDownload: () => void`
#### 5. API Client (`src/api/tts.ts`)
#### 6. API Client (`src/api/tts.ts`)
**Interfaces:**
```typescript
@@ -156,8 +173,24 @@ export interface RolesResponse {
roles: Role[];
}
export interface GenerateRequest {
export interface ScriptSegment {
id: string;
speaker: string;
text: string;
}
export interface ScriptRequest {
text: string;
roles: string[];
}
export interface ScriptResponse {
segments: ScriptSegment[];
}
export interface GenerateRequest {
segments?: ScriptSegment[];
text?: string;
lang: string;
roles: { id: string; voice: string }[];
speed?: number;
@@ -167,6 +200,7 @@ export interface GenerateRequest {
**Functions:**
```typescript
export async function detectRoles(text: string): Promise<RolesResponse>
export async function generateScript(request: ScriptRequest): Promise<ScriptResponse>
export async function generateAudiobook(payload: GenerateRequest): Promise<Blob>
export async function checkHealth(): Promise<{ status: string }>
```
@@ -188,6 +222,11 @@ async def detect_roles(request: RoleDetectionRequest) -> RolesResponse:
"""Analyzes text and returns detected roles"""
pass
@app.post("/api/tts/script")
async def generate_script(request: ScriptRequest) -> ScriptResponse:
"""Generates script preview with AI-segmented text and speaker assignments"""
pass
@app.post("/api/tts")
async def generate_audiobook(request: TTSRequest) -> StreamingResponse:
"""Generates multi-voice audiobook and streams audio"""
@@ -206,12 +245,25 @@ class RoleInfo(BaseModel):
class RolesResponse(BaseModel):
roles: List[RoleInfo]
class ScriptRequest(BaseModel):
text: str
roles: List[str] # List of detected role IDs
class ScriptSegment(BaseModel):
id: str # Unique segment identifier
speaker: str # Assigned speaker/role
text: str # Text content for this segment
class ScriptResponse(BaseModel):
segments: List[ScriptSegment]
class RoleVoiceMapping(BaseModel):
id: str
voice: str
class TTSRequest(BaseModel):
text: str
segments: Optional[List[ScriptSegment]] = None # If provided, use edited script
text: Optional[str] = None # Fallback if no script provided
lang: str
roles: List[RoleVoiceMapping]
speed: Optional[float] = 1.0
@@ -384,10 +436,11 @@ interface LanguageOption {
**Application State:**
```typescript
interface AppState {
phase: 'input' | 'assignment' | 'generated';
phase: 'input' | 'assignment' | 'review' | 'generated';
text: string;
roles: Role[];
voiceAssignments: Map<string, string>;
scriptSegments: ScriptSegment[];
language: string;
speed: number;
audioUrl: string | null;
@@ -578,6 +631,22 @@ ROLE_PATTERNS = {
*For any* text where both AI detection and pattern detection find roles, the backend should merge results and return each unique role exactly once.
**Validates: Requirements 14.5**
### Property 32: Script generation completeness
*For any* text and list of roles, the script generation should return segments that cover the entire input text without gaps or overlaps.
**Validates: Requirements 15.2**
### Property 33: Script segment structure
*For any* generated script, each segment should contain an id, speaker, and text field.
**Validates: Requirements 15.4**
### Property 34: Script segment editability
*For any* script segment, the user should be able to change the speaker assignment to any detected role.
**Validates: Requirements 15.5**
### Property 35: Edited script persistence
*For any* edited script segment, the changes should be preserved when generating the audiobook.
**Validates: Requirements 15.7**
## Error Handling
### Frontend Error Handling