Skip to content

Commit d0d9546

Browse files
committed
更新RssFeed组件,修改RSS源为MIT科技新闻,并添加骨架屏组件以提升加载体验。同时,更新国际化文本以反映新的标题和分类,确保多语言支持的准确性和一致性。
1 parent a87308f commit d0d9546

3 files changed

Lines changed: 90 additions & 35 deletions

File tree

src/components/RssFeed.tsx

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,30 @@ interface RssItem {
1212
category?: string;
1313
pubDate: string;
1414
creator?: string;
15+
thumbnail?: string;
1516
}
1617

18+
// 添加骨架屏组件
19+
const SkeletonCard = () => (
20+
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
21+
<div className="p-4">
22+
<div className="flex justify-between items-start mb-3">
23+
<div className="h-6 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
24+
<div className="h-4 w-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
25+
</div>
26+
<div className="w-full h-40 bg-gray-200 dark:bg-gray-700 rounded mb-3 animate-pulse"></div>
27+
<div className="h-6 w-full bg-gray-200 dark:bg-gray-700 rounded mb-2 animate-pulse"></div>
28+
<div className="h-6 w-3/4 bg-gray-200 dark:bg-gray-700 rounded mb-3 animate-pulse"></div>
29+
<div className="h-4 w-full bg-gray-200 dark:bg-gray-700 rounded mb-2 animate-pulse"></div>
30+
<div className="h-4 w-3/4 bg-gray-200 dark:bg-gray-700 rounded mb-3 animate-pulse"></div>
31+
<div className="flex justify-between items-center">
32+
<div className="h-4 w-1/3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
33+
<div className="h-4 w-1/4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
34+
</div>
35+
</div>
36+
</div>
37+
);
38+
1739
export default function RssFeed() {
1840
const { t } = useTranslations();
1941
const [items, setItems] = useState<RssItem[]>([]);
@@ -24,36 +46,41 @@ export default function RssFeed() {
2446
const fetchRss = async () => {
2547
try {
2648
setLoading(true);
27-
const response = await fetch("https://linux.do/latest.rss", {
28-
cache: "no-store",
29-
});
49+
const rssToJsonUrl = "https://api.rss2json.com/v1/api.json?rss_url=";
50+
const techNewsRss = "https://news.mit.edu/rss/feed";
51+
const response = await fetch(
52+
`${rssToJsonUrl}${encodeURIComponent(techNewsRss)}`,
53+
{
54+
cache: "no-store",
55+
}
56+
);
3057

3158
if (!response.ok) {
3259
throw new Error(`获取RSS失败: ${response.status}`);
3360
}
3461

35-
const xmlText = await response.text();
36-
const result = await parseStringPromise(xmlText, {
37-
explicitArray: false,
38-
});
62+
const data = await response.json();
3963

40-
if (result?.rss?.channel?.item) {
41-
const rssItems = Array.isArray(result.rss.channel.item)
42-
? result.rss.channel.item
43-
: [result.rss.channel.item];
44-
45-
const parsedItems = rssItems
64+
// RSS2JSON 返回的是已解析好的JSON格式,不需要进一步解析XML
65+
if (data.status === "ok" && data.items && data.items.length > 0) {
66+
const parsedItems = data.items
4667
.map((item: any) => ({
4768
title: item.title,
4869
link: item.link,
49-
description: item.description,
50-
category: item.category,
70+
description: item.description || "",
71+
category:
72+
item.categories && item.categories.length > 0
73+
? item.categories[0]
74+
: "Technology",
5175
pubDate: item.pubDate,
52-
creator: item["dc:creator"],
76+
creator: item.author,
77+
thumbnail: item.thumbnail || "",
5378
}))
5479
.slice(0, 10); // 只显示前10条
5580

5681
setItems(parsedItems);
82+
} else {
83+
throw new Error("RSS 源返回数据格式不正确");
5784
}
5885
} catch (err) {
5986
console.error("获取RSS feed失败:", err);
@@ -106,11 +133,29 @@ export default function RssFeed() {
106133
if (loading) {
107134
return (
108135
<div className="w-full mt-6">
109-
<div className="text-center py-8">
110-
<div className="inline-block animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
111-
<p className="mt-2 text-gray-600 dark:text-gray-400">
112-
{t("rssFeed.loading")}
113-
</p>
136+
<h2 className="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200 flex items-center">
137+
<svg
138+
xmlns="http://www.w3.org/2000/svg"
139+
className="h-5 w-5 mr-2 text-red-600"
140+
fill="none"
141+
viewBox="0 0 24 24"
142+
stroke="currentColor"
143+
>
144+
<path
145+
strokeLinecap="round"
146+
strokeLinejoin="round"
147+
strokeWidth={2}
148+
d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
149+
/>
150+
</svg>
151+
MIT Technology News
152+
</h2>
153+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
154+
{Array(4)
155+
.fill(0)
156+
.map((_, index) => (
157+
<SkeletonCard key={index} />
158+
))}
114159
</div>
115160
</div>
116161
);
@@ -129,7 +174,7 @@ export default function RssFeed() {
129174
<h2 className="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200 flex items-center">
130175
<svg
131176
xmlns="http://www.w3.org/2000/svg"
132-
className="h-5 w-5 mr-2 text-blue-500"
177+
className="h-5 w-5 mr-2 text-red-600"
133178
fill="none"
134179
viewBox="0 0 24 24"
135180
stroke="currentColor"
@@ -138,13 +183,13 @@ export default function RssFeed() {
138183
strokeLinecap="round"
139184
strokeLinejoin="round"
140185
strokeWidth={2}
141-
d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-6 0a1 1 0 11-2 0 1 1 0 012 0z"
186+
d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
142187
/>
143188
</svg>
144-
{t("rssFeed.title")}
189+
MIT Technology News
145190
</h2>
146191

147-
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
192+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
148193
{items.map((item, index) => (
149194
<motion.div
150195
key={index}
@@ -154,25 +199,35 @@ export default function RssFeed() {
154199
className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-md transition-shadow duration-200"
155200
>
156201
<div className="p-4">
157-
<div className="flex justify-between items-start mb-2">
158-
<span className="inline-block px-2 py-1 text-xs font-medium bg-blue-100 dark:bg-blue-900/40 text-blue-800 dark:text-blue-300 rounded">
202+
<div className="flex justify-between items-start mb-3">
203+
<span className="inline-block px-2 py-1 text-xs font-medium bg-red-100 dark:bg-red-900/40 text-red-800 dark:text-red-300 rounded">
159204
{item.category || t("rssFeed.uncategorized")}
160205
</span>
161206
<span className="text-xs text-gray-500 dark:text-gray-400">
162207
{formatDate(item.pubDate)}
163208
</span>
164209
</div>
165210

166-
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2 line-clamp-2">
211+
{item.thumbnail && (
212+
<div className="mb-3 overflow-hidden rounded">
213+
<img
214+
src={item.thumbnail}
215+
alt={item.title}
216+
className="w-full h-48 object-cover transform hover:scale-105 transition-transform duration-300"
217+
/>
218+
</div>
219+
)}
220+
221+
<h3 className="text-base font-medium text-gray-900 dark:text-white mb-2 line-clamp-2">
167222
{extractCdata(item.title)}
168223
</h3>
169224

170-
<p className="text-sm text-gray-600 dark:text-gray-400 mb-3 line-clamp-2">
225+
<p className="text-sm text-gray-600 dark:text-gray-400 mb-3 line-clamp-3">
171226
{extractFirstParagraph(item.description)}
172227
</p>
173228

174229
<div className="flex justify-between items-center">
175-
<span className="text-xs text-gray-500 dark:text-gray-400">
230+
<span className="text-xs text-gray-500 dark:text-gray-400 truncate max-w-[50%]">
176231
{item.creator
177232
? `${t("rssFeed.author")}: ${extractCdata(item.creator)}`
178233
: ""}
@@ -181,7 +236,7 @@ export default function RssFeed() {
181236
href={item.link}
182237
target="_blank"
183238
rel="noopener noreferrer"
184-
className="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300"
239+
className="text-sm font-medium text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300"
185240
>
186241
{t("rssFeed.readMore")}
187242
</a>

src/messages/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,11 @@
395395
"generateFailed": "Generation failed: {message}"
396396
},
397397
"rssFeed": {
398-
"title": "Linux DO - Latest Topics",
398+
"title": "MIT Technology News",
399399
"loading": "Loading...",
400400
"readMore": "Read More",
401401
"author": "Author",
402-
"uncategorized": "Uncategorized",
402+
"uncategorized": "Technology",
403403
"error": "Failed to fetch RSS feed"
404404
}
405405
}

src/messages/zh.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@
398398
"generateFailed": "生成失败: {message}"
399399
},
400400
"rssFeed": {
401-
"title": "Linux DO - 最新话题",
401+
"title": "MIT科技新闻",
402402
"loading": "加载中...",
403403
"readMore": "阅读全文",
404404
"author": "作者",
405-
"uncategorized": "未分类",
405+
"uncategorized": "科技",
406406
"error": "获取RSS feed失败"
407407
}
408408
}

0 commit comments

Comments
 (0)