Files
News-reader-pro/components/ReaderView.tsx
Anthony 0775104b69 feat: Initialize project with basic structure and dependencies
Sets up the foundational elements for the NewsCaster AI application. This includes:
- Initializing the project with Vite and React.
- Defining core types for articles and player state.
- Configuring build tools and TypeScript.
- Adding essential dependencies like React, Vite, and Google's Gemini API client.
- Providing initial README instructions for running locally.
- Setting up basic styling and structure in index.html.
- Defining available voices and playback constants.
- Implementing utility functions for audio handling.
2025-11-19 19:33:34 +08:00

60 lines
2.1 KiB
TypeScript

import React from 'react';
import { Article } from '../types';
import { FileText } from 'lucide-react';
interface ReaderViewProps {
article?: Article | null;
}
export const ReaderView: React.FC<ReaderViewProps> = ({ article }) => {
if (!article) {
return (
<div className="h-full flex flex-col items-center justify-center text-slate-400 p-12 border-2 border-dashed border-slate-200 rounded-2xl bg-slate-50/50">
<FileText className="w-12 h-12 mb-4 opacity-50" />
<p className="text-lg font-medium">Select an article to read along</p>
<p className="text-sm">The text will appear here while you listen.</p>
</div>
);
}
// Split text by newlines to create paragraphs
const paragraphs = article.text
? article.text.split('\n').filter(p => p.trim().length > 0)
: [];
return (
<div className="bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden h-[calc(100vh-12rem)] flex flex-col">
<div className="p-6 border-b border-slate-100 bg-white sticky top-0 z-10">
<h2 className="text-2xl font-bold text-slate-900 leading-tight">
{article.title}
</h2>
<a
href={article.url}
target="_blank"
rel="noopener noreferrer"
className="text-sm text-blue-600 hover:underline mt-2 inline-block"
>
{new URL(article.url).hostname}
</a>
</div>
<div className="flex-grow overflow-y-auto p-6 sm:p-8 space-y-6 custom-scrollbar bg-white">
{paragraphs.length > 0 ? (
paragraphs.map((paragraph, idx) => (
<p key={idx} className="text-lg text-slate-700 leading-relaxed font-serif">
{paragraph}
</p>
))
) : (
<div className="space-y-4 animate-pulse">
<div className="h-4 bg-slate-100 rounded w-3/4"></div>
<div className="h-4 bg-slate-100 rounded w-full"></div>
<div className="h-4 bg-slate-100 rounded w-5/6"></div>
<p className="text-slate-400 italic mt-4">Extracting article content...</p>
</div>
)}
</div>
</div>
);
};