diff --git a/news.njk b/news.njk
index b0dbe83..39d78b1 100644
--- a/news.njk
+++ b/news.njk
@@ -161,7 +161,7 @@ withSidebar: true
-
+
@@ -387,12 +387,25 @@ function newsApp() {
this.error = null;
try {
- const [itemsRes, feedsRes, statusRes] = await Promise.all([
- fetch('/rssapi/api/items?limit=50').then(r => r.json()),
- fetch('/rssapi/api/feeds').then(r => r.json()),
- fetch('/rssapi/api/status').then(r => r.json())
+ const [itemsResult, feedsResult, statusResult] = await Promise.allSettled([
+ fetch('/rssapi/api/items?limit=50').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }),
+ fetch('/rssapi/api/feeds').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }),
+ fetch('/rssapi/api/status').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
]);
+ if (itemsResult.status === 'rejected') {
+ this.error = 'Failed to load news: ' + itemsResult.reason.message;
+ console.error('News items fetch error:', itemsResult.reason);
+ return;
+ }
+
+ const itemsRes = itemsResult.value;
+ const feedsRes = feedsResult.status === 'fulfilled' ? feedsResult.value : { feeds: [] };
+ const statusRes = statusResult.status === 'fulfilled' ? statusResult.value : null;
+
+ if (feedsResult.status === 'rejected') console.warn('News feeds fetch failed (non-critical):', feedsResult.reason);
+ if (statusResult.status === 'rejected') console.warn('News status fetch failed (non-critical):', statusResult.reason);
+
this.items = itemsRes.items || [];
this.pagination = itemsRes.pagination || null;
this.feeds = feedsRes.feeds || [];
@@ -429,8 +442,13 @@ function newsApp() {
},
get filteredItems() {
- if (this.filterFeed === 'all') return this.items;
- return this.items.filter(item => item.feedId === this.filterFeed);
+ const seen = new Set();
+ const base = this.filterFeed === 'all' ? this.items : this.items.filter(item => item.feedId === this.filterFeed);
+ return base.filter(item => {
+ if (seen.has(item.id)) return false;
+ seen.add(item.id);
+ return true;
+ });
},
getFeedUrl(feedId) {