feat: Update dependencies and add new voice
- Updates project dependencies to latest versions for improved performance and security. - Adds a new voice option, 'Aoede', to the available voices. - Modifies the voice change handler to force re-generation of future audio segments for the selected article. - Updates Vite configuration to align with newer Vite versions and load environment variables correctly. - Adjusts TypeScript configuration for a more modern setup. - Removes unnecessary configuration from Nginx file.
This commit is contained in:
38
App.tsx
38
App.tsx
@@ -91,6 +91,8 @@ export default function App() {
|
||||
const segmentsToBuffer = article.segments.slice(currentIndex, currentIndex + 5);
|
||||
|
||||
for (const seg of segmentsToBuffer) {
|
||||
// Only process if we don't have audio URL, and it's not currently loading.
|
||||
// This handles cases where we cleared the URL to force regeneration.
|
||||
if (!seg.audioUrl && !seg.isLoading && !seg.hasError) {
|
||||
processSegmentAudio(article.id, seg.id, seg.text, playerState.selectedVoice);
|
||||
}
|
||||
@@ -99,6 +101,38 @@ export default function App() {
|
||||
|
||||
// -- Handlers --
|
||||
|
||||
const handleVoiceChange = useCallback((newVoice: VoiceName) => {
|
||||
setPlayerState(prev => ({ ...prev, selectedVoice: newVoice }));
|
||||
|
||||
// Force flush future buffer so new voice is applied immediately
|
||||
setQueue(prevQueue => prevQueue.map(article => {
|
||||
// If this is the currently active article
|
||||
if (article.id === playerState.currentArticleId) {
|
||||
return {
|
||||
...article,
|
||||
segments: article.segments.map((seg, idx) => {
|
||||
// Keep the current segment (and past ones) to avoid cutting off mid-speech abruptly
|
||||
if (idx <= article.currentSegmentIndex) {
|
||||
return seg;
|
||||
}
|
||||
// Invalidate all future segments
|
||||
return { ...seg, audioUrl: undefined, isLoading: false, hasError: false };
|
||||
})
|
||||
};
|
||||
}
|
||||
// For inactive articles, invalidate everything
|
||||
return {
|
||||
...article,
|
||||
segments: article.segments.map(seg => ({
|
||||
...seg,
|
||||
audioUrl: undefined,
|
||||
isLoading: false,
|
||||
hasError: false
|
||||
}))
|
||||
};
|
||||
}));
|
||||
}, [playerState.currentArticleId]);
|
||||
|
||||
const handleAddUrl = async () => {
|
||||
if (!inputUrl.trim()) return;
|
||||
|
||||
@@ -373,8 +407,8 @@ export default function App() {
|
||||
<div className="flex items-center gap-4">
|
||||
<VoiceSelector
|
||||
selectedVoice={playerState.selectedVoice}
|
||||
onVoiceChange={(v) => setPlayerState(prev => ({ ...prev, selectedVoice: v }))}
|
||||
disabled={playerState.isPlaying}
|
||||
onVoiceChange={handleVoiceChange}
|
||||
// Removed disabled prop to allow switching while playing
|
||||
/>
|
||||
<button
|
||||
onClick={() => setShowSettings(!showSettings)}
|
||||
|
||||
Reference in New Issue
Block a user