Skip to content

Commit 24e7aa1

Browse files
authored
Merge pull request #8 from intellwe/feat/tts
FEAT: Implement Text-to-Speech with voice customization, speed adjustment, audio download
2 parents b5eb098 + 0b24188 commit 24e7aa1

File tree

4 files changed

+816
-15
lines changed

4 files changed

+816
-15
lines changed

src/App.tsx

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ import AudioUploader from './components/AudioUploader';
44
import TranscriptDisplay from './components/TranscriptDisplay';
55
import { TranscriptResponse } from './types';
66
import LiveRecording from './components/LiveRecording';
7+
import StandaloneTextToSpeech from './components/StandaloneTextToSpeech';
78

89
function App() {
910
const [transcript, setTranscript] = useState<TranscriptResponse | null>(null);
1011
const apiKey = import.meta.env.VITE_ELEVEN_LABS_API_KEY || "";
1112
const [currentYear] = useState(new Date().getFullYear());
13+
const [activeTab, setActiveTab] = useState<'transcribe' | 'tts'>('transcribe');
1214

1315
const handleTranscriptReceived = (data: TranscriptResponse) => {
1416
setTranscript(data);
17+
// Automatically switch to transcribe tab when transcript is received
18+
setActiveTab('transcribe');
1519
};
1620

1721
useEffect(() => {
@@ -42,22 +46,58 @@ function App() {
4246
</header>
4347

4448
<main className="animate-fade-in animation-delay-300">
45-
<div className="flex flex-col md:flex-row gap-6 mb-12">
46-
<div className="md:w-1/2">
47-
<AudioUploader
48-
onTranscriptReceived={handleTranscriptReceived}
49-
apiKey={apiKey}
50-
/>
51-
</div>
52-
<div className="md:w-1/2">
53-
<LiveRecording
54-
onTranscriptReceived={handleTranscriptReceived}
55-
apiKey={apiKey}
56-
/>
57-
</div>
49+
{/* Tab Navigation */}
50+
<div className="flex mb-8 border-b border-gray-700">
51+
<button
52+
onClick={() => setActiveTab('transcribe')}
53+
className={`px-6 py-3 font-medium text-sm transition-colors ${
54+
activeTab === 'transcribe'
55+
? 'text-blue-400 border-b-2 border-blue-400'
56+
: 'text-gray-400 hover:text-gray-200'
57+
}`}
58+
>
59+
Transcribe Audio
60+
</button>
61+
<button
62+
onClick={() => setActiveTab('tts')}
63+
className={`px-6 py-3 font-medium text-sm transition-colors ${
64+
activeTab === 'tts'
65+
? 'text-blue-400 border-b-2 border-blue-400'
66+
: 'text-gray-400 hover:text-gray-200'
67+
}`}
68+
>
69+
Text to Speech
70+
</button>
5871
</div>
72+
73+
{/* Transcribe Audio Tab */}
74+
{activeTab === 'transcribe' && (
75+
<>
76+
<div className="flex flex-col md:flex-row gap-6 mb-12">
77+
<div className="md:w-1/2">
78+
<AudioUploader
79+
onTranscriptReceived={handleTranscriptReceived}
80+
apiKey={apiKey}
81+
/>
82+
</div>
83+
<div className="md:w-1/2">
84+
<LiveRecording
85+
onTranscriptReceived={handleTranscriptReceived}
86+
apiKey={apiKey}
87+
/>
88+
</div>
89+
</div>
90+
91+
{transcript && <TranscriptDisplay transcript={transcript} apiKey={apiKey} />}
92+
</>
93+
)}
5994

60-
{transcript && <TranscriptDisplay transcript={transcript} />}
95+
{/* Text to Speech Tab */}
96+
{activeTab === 'tts' && (
97+
<div className="mb-12">
98+
<StandaloneTextToSpeech apiKey={apiKey} />
99+
</div>
100+
)}
61101
</main>
62102

63103
<footer className="mt-16 text-center text-gray-400 py-6 border-t border-gray-700 animate-fade-in animation-delay-700">

0 commit comments

Comments
 (0)