From e7e3a0a4401522d5a6a53549319a27191931ad91 Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Sun, 25 Jan 2026 16:38:25 -0800 Subject: [PATCH] Update dependencies and enhance UI components for better functionality - Added new Tauri plugins: @tauri-apps/plugin-process and @tauri-apps/plugin-updater to improve application capabilities. - Introduced UpdateStatus component to display update information in the UI. - Enhanced GenerationForm to include an optional instruct field for additional input. - Refactored various components for improved styling and responsiveness, including Sidebar, AudioPlayer, and ProfileCard. - Updated API models and schemas to accommodate new instruct parameter in generation requests and responses. - Improved documentation for autoupdater setup and usage. --- app/package.json | 2 + app/src/App.tsx | 7 +- .../components/AudioPlayer/AudioPlayer.tsx | 14 +- .../components/Generation/GenerationForm.tsx | 27 +- .../ServerSettings/ConnectionForm.tsx | 8 +- .../ServerSettings/ModelManagement.tsx | 27 +- .../ServerSettings/ModelProgress.tsx | 11 +- .../ServerSettings/ServerStatus.tsx | 4 +- .../ServerSettings/UpdateStatus.tsx | 101 ++ app/src/components/Sidebar.tsx | 10 +- .../components/VoiceProfiles/ProfileCard.tsx | 14 +- .../components/VoiceProfiles/ProfileForm.tsx | 590 ++++++++++-- .../components/VoiceProfiles/SampleList.tsx | 4 +- .../components/VoiceProfiles/SampleUpload.tsx | 10 +- app/src/components/ui/circle-button.tsx | 7 +- app/src/components/ui/slider.tsx | 5 +- app/src/hooks/useAutoUpdater.ts | 12 +- app/src/lib/api/client.ts | 27 +- app/src/lib/api/core/ApiError.ts | 28 +- app/src/lib/api/core/ApiRequestOptions.ts | 22 +- app/src/lib/api/core/ApiResult.ts | 10 +- app/src/lib/api/core/CancelablePromise.ts | 221 +++-- app/src/lib/api/core/OpenAPI.ts | 36 +- app/src/lib/api/core/request.ts | 475 +++++----- ...mple_profiles__profile_id__samples_post.ts | 5 +- .../Body_transcribe_audio_transcribe_post.ts | 5 +- app/src/lib/api/models/GenerationRequest.ts | 12 +- app/src/lib/api/models/GenerationResponse.ts | 18 +- app/src/lib/api/models/HTTPValidationError.ts | 3 +- app/src/lib/api/models/HealthResponse.ts | 13 +- app/src/lib/api/models/HistoryListResponse.ts | 5 +- app/src/lib/api/models/HistoryResponse.ts | 20 +- .../lib/api/models/ModelDownloadRequest.ts | 3 +- app/src/lib/api/models/ModelStatus.ts | 11 +- .../lib/api/models/ModelStatusListResponse.ts | 3 +- .../lib/api/models/ProfileSampleResponse.ts | 9 +- .../lib/api/models/TranscriptionResponse.ts | 5 +- app/src/lib/api/models/ValidationError.ts | 7 +- app/src/lib/api/models/VoiceProfileCreate.ts | 7 +- .../lib/api/models/VoiceProfileResponse.ts | 13 +- ...mple_profiles__profile_id__samples_post.ts | 20 +- .../$Body_transcribe_audio_transcribe_post.ts | 31 +- app/src/lib/api/schemas/$GenerationRequest.ts | 72 +- .../lib/api/schemas/$GenerationResponse.ts | 83 +- .../lib/api/schemas/$HTTPValidationError.ts | 14 +- app/src/lib/api/schemas/$HealthResponse.ts | 85 +- .../lib/api/schemas/$HistoryListResponse.ts | 26 +- app/src/lib/api/schemas/$HistoryResponse.ts | 91 +- .../lib/api/schemas/$ModelDownloadRequest.ts | 12 +- app/src/lib/api/schemas/$ModelStatus.ts | 53 +- .../api/schemas/$ModelStatusListResponse.ts | 18 +- .../lib/api/schemas/$ProfileSampleResponse.ts | 36 +- .../lib/api/schemas/$TranscriptionResponse.ts | 20 +- app/src/lib/api/schemas/$ValidationError.ts | 43 +- .../lib/api/schemas/$VoiceProfileCreate.ts | 45 +- .../lib/api/schemas/$VoiceProfileResponse.ts | 69 +- app/src/lib/api/services/DefaultService.ts | 874 +++++++++--------- app/src/lib/hooks/useAudioRecording.ts | 9 +- app/src/stores/serverStore.ts | 3 +- backend/database.py | 3 +- backend/history.py | 12 +- backend/main.py | 11 +- backend/migrate_add_instruct.py | 48 + backend/models.py | 3 + backend/tts.py | 15 +- bun.lock | 6 + docs/AUTOUPDATER.md | 53 +- docs/AUTOUPDATER_QUICKSTART.md | 116 +++ landing/src/app/globals.css | 2 +- landing/src/app/layout.tsx | 9 +- landing/src/app/page.tsx | 44 +- landing/src/components/DownloadSection.tsx | 11 +- landing/src/components/Footer.tsx | 31 +- landing/src/components/Header.tsx | 19 +- landing/src/components/PlatformIcons.tsx | 6 +- landing/src/components/ui/button.tsx | 16 +- landing/src/components/ui/card.tsx | 94 +- landing/src/components/ui/feature-card.tsx | 11 +- landing/src/components/ui/hero.tsx | 6 +- landing/src/components/ui/section.tsx | 7 +- landing/src/components/ui/separator.tsx | 31 +- landing/src/lib/constants.ts | 12 +- landing/tsconfig.json | 14 +- tauri/assets/voicebox.icon/icon.json | 41 +- tauri/src-tauri/gen/Assets.car | Bin 3847048 -> 3847048 bytes tauri/src-tauri/tauri.conf.json | 4 +- tauri/vite.config.ts | 9 +- 87 files changed, 2421 insertions(+), 1628 deletions(-) create mode 100644 app/src/components/ServerSettings/UpdateStatus.tsx create mode 100644 backend/migrate_add_instruct.py create mode 100644 docs/AUTOUPDATER_QUICKSTART.md diff --git a/app/package.json b/app/package.json index 78b15c71..c07776a0 100644 --- a/app/package.json +++ b/app/package.json @@ -31,6 +31,8 @@ "@tanstack/react-query": "^5.0.0", "@tanstack/react-query-devtools": "^5.0.0", "@tauri-apps/api": "^2.0.0", + "@tauri-apps/plugin-process": "^2.3.1", + "@tauri-apps/plugin-updater": "^2.9.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^3.6.0", diff --git a/app/src/App.tsx b/app/src/App.tsx index 5f70cf08..7fc4411e 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -3,11 +3,13 @@ import { GenerationForm } from '@/components/Generation/GenerationForm'; import { HistoryTable } from '@/components/History/HistoryTable'; import { ConnectionForm } from '@/components/ServerSettings/ConnectionForm'; import { ServerStatus } from '@/components/ServerSettings/ServerStatus'; +import { UpdateStatus } from '@/components/ServerSettings/UpdateStatus'; import { ModelManagement } from '@/components/ServerSettings/ModelManagement'; import { Toaster } from '@/components/ui/toaster'; import { ProfileList } from '@/components/VoiceProfiles/ProfileList'; import { Sidebar } from '@/components/Sidebar'; import { AudioPlayer } from '@/components/AudioPlayer/AudioPlayer'; +import { UpdateNotification } from '@/components/UpdateNotification'; import { isTauri, startServer, setupWindowCloseHandler } from '@/lib/tauri'; // Track if server is starting to prevent duplicate starts @@ -90,12 +92,15 @@ function App() {
+ + {activeTab === 'settings' ? (
+ {isTauri() && }
) : ( @@ -107,7 +112,7 @@ function App() {
- + {/* Generator - Bottom Left */}
diff --git a/app/src/components/AudioPlayer/AudioPlayer.tsx b/app/src/components/AudioPlayer/AudioPlayer.tsx index 1f51c87c..bf6c09fb 100644 --- a/app/src/components/AudioPlayer/AudioPlayer.tsx +++ b/app/src/components/AudioPlayer/AudioPlayer.tsx @@ -34,12 +34,12 @@ export function AudioPlayer() { if (!audioUrl) { return; } - + if (wavesurferRef.current) { console.log('WaveSurfer already initialized, skipping'); return; } - + console.log('Creating NEW WaveSurfer instance'); // Wait for container to be properly rendered @@ -241,7 +241,7 @@ export function AudioPlayer() { // Load audio when URL changes (only if WaveSurfer is already initialized) useEffect(() => { const wavesurfer = wavesurferRef.current; - + if (!audioUrl || !wavesurfer) { // Reset state when no audio or WaveSurfer not ready if (!audioUrl && wavesurfer) { @@ -259,7 +259,7 @@ export function AudioPlayer() { // CRITICAL: Force stop any current playback and cancel any pending loads // This must happen BEFORE any early returns console.log('Audio URL changed to:', audioUrl); - + // COMPLETELY stop and destroy the current audio try { // First pause if playing @@ -267,7 +267,7 @@ export function AudioPlayer() { console.log('Pausing current playback'); wavesurfer.pause(); } - + // Stop the media element explicitly const mediaElement = wavesurfer.getMediaElement(); if (mediaElement) { @@ -276,7 +276,7 @@ export function AudioPlayer() { mediaElement.currentTime = 0; mediaElement.src = ''; } - + // Use empty() to completely destroy the waveform and media element console.log('Calling wavesurfer.empty() to destroy audio'); wavesurfer.empty(); @@ -284,7 +284,7 @@ export function AudioPlayer() { console.error('Error stopping previous audio:', error); // Continue anyway to load new audio } - + // Reset loading state to allow new load (cancel any pending loads) loadingRef.current = false; diff --git a/app/src/components/Generation/GenerationForm.tsx b/app/src/components/Generation/GenerationForm.tsx index 06502c89..ffff041b 100644 --- a/app/src/components/Generation/GenerationForm.tsx +++ b/app/src/components/Generation/GenerationForm.tsx @@ -33,6 +33,7 @@ const generationSchema = z.object({ language: z.enum(['en', 'zh']), seed: z.number().int().optional(), modelSize: z.enum(['1.7B', '0.6B']).optional(), + instruct: z.string().max(500).optional(), }); type GenerationFormValues = z.infer; @@ -50,6 +51,7 @@ export function GenerationForm() { language: 'en', seed: undefined, modelSize: '1.7B', + instruct: '', }, }); @@ -70,6 +72,7 @@ export function GenerationForm() { language: data.language, seed: data.seed, model_size: data.modelSize, + instruct: data.instruct || undefined, }); toast({ @@ -119,7 +122,7 @@ export function GenerationForm() {