mirror of
https://github.com/Tony0410/News-reader-pro.git
synced 2026-05-24 21:31:44 +08:00
## 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>
95 lines
2.5 KiB
TypeScript
95 lines
2.5 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
BarChart3,
|
|
Rss,
|
|
Bookmark,
|
|
Download,
|
|
Zap,
|
|
FileText
|
|
} from 'lucide-react';
|
|
|
|
interface FeatureToolbarProps {
|
|
onOpenStats: () => void;
|
|
onOpenRSS: () => void;
|
|
onOpenBookmarks: () => void;
|
|
onExportAudio: () => void;
|
|
smartSpeedEnabled: boolean;
|
|
onToggleSmartSpeed: () => void;
|
|
hasBookmark?: boolean;
|
|
canExport?: boolean;
|
|
isExporting?: boolean;
|
|
}
|
|
|
|
export const FeatureToolbar: React.FC<FeatureToolbarProps> = ({
|
|
onOpenStats,
|
|
onOpenRSS,
|
|
onOpenBookmarks,
|
|
onExportAudio,
|
|
smartSpeedEnabled,
|
|
onToggleSmartSpeed,
|
|
hasBookmark,
|
|
canExport,
|
|
isExporting
|
|
}) => {
|
|
const buttons = [
|
|
{
|
|
icon: BarChart3,
|
|
label: 'Stats',
|
|
onClick: onOpenStats,
|
|
color: 'text-blue-500',
|
|
bgColor: 'bg-blue-50 dark:bg-blue-900/30'
|
|
},
|
|
{
|
|
icon: Rss,
|
|
label: 'RSS Feeds',
|
|
onClick: onOpenRSS,
|
|
color: 'text-orange-500',
|
|
bgColor: 'bg-orange-50 dark:bg-orange-900/30'
|
|
},
|
|
{
|
|
icon: Bookmark,
|
|
label: 'Bookmarks',
|
|
onClick: onOpenBookmarks,
|
|
color: hasBookmark ? 'text-yellow-500' : 'text-slate-500',
|
|
bgColor: hasBookmark ? 'bg-yellow-50 dark:bg-yellow-900/30' : 'bg-slate-50 dark:bg-slate-800'
|
|
},
|
|
{
|
|
icon: Download,
|
|
label: isExporting ? 'Exporting...' : 'Export',
|
|
onClick: onExportAudio,
|
|
color: 'text-green-500',
|
|
bgColor: 'bg-green-50 dark:bg-green-900/30',
|
|
disabled: !canExport || isExporting
|
|
},
|
|
{
|
|
icon: Zap,
|
|
label: 'Smart Speed',
|
|
onClick: onToggleSmartSpeed,
|
|
color: smartSpeedEnabled ? 'text-purple-500' : 'text-slate-400',
|
|
bgColor: smartSpeedEnabled ? 'bg-purple-50 dark:bg-purple-900/30' : 'bg-slate-50 dark:bg-slate-800',
|
|
active: smartSpeedEnabled
|
|
}
|
|
];
|
|
|
|
return (
|
|
<div className="flex items-center gap-2 overflow-x-auto pb-2">
|
|
{buttons.map((btn, i) => (
|
|
<button
|
|
key={i}
|
|
onClick={btn.onClick}
|
|
disabled={btn.disabled}
|
|
className={`
|
|
flex items-center gap-2 px-3 py-2 rounded-xl text-sm font-medium transition-all whitespace-nowrap
|
|
${btn.bgColor} ${btn.color}
|
|
${btn.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:shadow-md active:scale-95'}
|
|
${btn.active ? 'ring-2 ring-purple-500 ring-offset-1' : ''}
|
|
`}
|
|
>
|
|
<btn.icon className="w-4 h-4" />
|
|
<span className="hidden sm:inline">{btn.label}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|