Major feature update: Enhanced RSS, voice fixes, dark mode, and UI improvements
## New Features - Article Summary Mode: AI-generated 30-second summaries with complexity analysis - Reading Stats Dashboard: Track articles read, listening time, and streaks - Bookmark/Resume: Auto-save progress when pausing, resume from where you left off - Audio Export: Export articles as downloadable WAV files - RSS Feed Manager: Subscribe to feeds with real-time validation and 31+ recommendations - Smart Speed: Auto-adjust playback based on article complexity - Voice Moods: Quick presets for different listening scenarios ## RSS Enhancements - Expanded recommendations from 8 to 31 sources across 5 categories: * General News (9 sources) * Technology (8 sources) * Business & Finance (5 sources) * Science & Research (5 sources) * International News (4 sources) - Real-time URL validation with visual feedback - Detailed error messages for different failure scenarios - Always-visible categorized recommendations - Auto-loading articles when feeds are added ## Bug Fixes - Fixed voice selection: Selected voice now consistently applies to playback - Implemented voice generation counter to prevent voice mixing between paragraphs - Fixed speed control to snap to clean 0.5 increments (1.0, 1.5, 2.0, etc.) - Fixed dark mode toggle by configuring Tailwind CDN for class-based dark mode - Removed vibe visualizer animation ## UI/UX Improvements - Redesigned voice selector with prominent voice panel and preview functionality - Added voice cards with emojis and descriptions - Enhanced feature toolbar with quick access to all new features - Improved reader view with better typography and reading modes - Added ambient reading modes (clean, sepia, night light) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
45
components/VoiceMoodSelector.tsx
Normal file
45
components/VoiceMoodSelector.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import { VoiceMood, VoiceName } from '../types';
|
||||
import { VOICE_MOODS } from '../constants';
|
||||
|
||||
interface VoiceMoodSelectorProps {
|
||||
selectedMood: VoiceMood;
|
||||
onMoodChange: (mood: VoiceMood, voice: VoiceName, speed: number) => void;
|
||||
}
|
||||
|
||||
export const VoiceMoodSelector: React.FC<VoiceMoodSelectorProps> = ({
|
||||
selectedMood,
|
||||
onMoodChange
|
||||
}) => {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-sm font-semibold text-slate-700 dark:text-slate-300 px-1">
|
||||
Listening Mood
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{VOICE_MOODS.map((mood) => {
|
||||
const isSelected = selectedMood === mood.id;
|
||||
return (
|
||||
<button
|
||||
key={mood.id}
|
||||
onClick={() => onMoodChange(mood.id, mood.recommendedVoice, mood.recommendedSpeed)}
|
||||
className={`
|
||||
px-4 py-2 rounded-xl text-sm font-medium transition-all flex items-center gap-2
|
||||
${isSelected
|
||||
? 'bg-blue-500 text-white shadow-md'
|
||||
: 'bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-700'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<span>{mood.emoji}</span>
|
||||
<span>{mood.label}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400 px-1">
|
||||
{VOICE_MOODS.find(m => m.id === selectedMood)?.description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user