Implement audio player component and integrate with history and sample lists

- Added a new AudioPlayer component for audio playback functionality, utilizing WaveSurfer for waveform visualization.
- Integrated audio playback controls into the HistoryTable and SampleList components, allowing users to play audio directly from their history and samples.
- Updated player state management to handle audio URL, ID, title, and playback state.
- Introduced a custom Slider component for volume control and seek functionality.
- Enhanced UI to ensure the AudioPlayer is always visible except in settings, improving user experience.
This commit is contained in:
Jamie Pine
2026-01-25 13:12:50 -08:00
parent 6fa2966371
commit f80f870e93
8 changed files with 604 additions and 79 deletions
+38 -32
View File
@@ -7,6 +7,7 @@ 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 { isTauri, startServer, setupWindowCloseHandler } from '@/lib/tauri';
// Track if server is starting to prevent duplicate starts
@@ -83,40 +84,45 @@ function App() {
}
return (
<div className="min-h-screen bg-background flex">
<Sidebar activeTab={activeTab} onTabChange={setActiveTab} />
<div className="min-h-screen bg-background flex flex-col">
<div className="flex flex-1">
<Sidebar activeTab={activeTab} onTabChange={setActiveTab} />
<main className="flex-1 ml-20">
<div className="container mx-auto px-8 py-8 max-w-7xl">
{activeTab === 'profiles' && (
<div className="space-y-4">
<ProfileList />
</div>
)}
{activeTab === 'generate' && (
<div className="space-y-4">
<GenerationForm />
</div>
)}
{activeTab === 'history' && (
<div className="space-y-4">
<HistoryTable />
</div>
)}
{activeTab === 'settings' && (
<div className="space-y-4">
<div className="grid gap-4 md:grid-cols-2">
<ConnectionForm />
<ServerStatus />
<main className="flex-1 ml-20 pb-20">
<div className="container mx-auto px-8 py-8 max-w-7xl">
{activeTab === 'profiles' && (
<div className="space-y-4">
<ProfileList />
</div>
<ModelManagement />
</div>
)}
</div>
</main>
)}
{activeTab === 'generate' && (
<div className="space-y-4">
<GenerationForm />
</div>
)}
{activeTab === 'history' && (
<div className="space-y-4">
<HistoryTable />
</div>
)}
{activeTab === 'settings' && (
<div className="space-y-4">
<div className="grid gap-4 md:grid-cols-2">
<ConnectionForm />
<ServerStatus />
</div>
<ModelManagement />
</div>
)}
</div>
</main>
</div>
{/* Audio Player - always visible except on settings */}
{activeTab !== 'settings' && <AudioPlayer />}
<Toaster />
</div>