+ {{ item.title }} +
+ + {% if item.description %} ++ {{ item.description }} +
+ {% endif %} + +diff --git a/_data/newsActivity.js b/_data/newsActivity.js new file mode 100644 index 0000000..47499b8 --- /dev/null +++ b/_data/newsActivity.js @@ -0,0 +1,99 @@ +/** + * News/RSS Activity Data + * Fetches from Indiekit's endpoint-rss public API + */ + +import EleventyFetch from "@11ty/eleventy-fetch"; + +const INDIEKIT_URL = process.env.SITE_URL || "https://example.com"; + +/** + * Fetch from Indiekit's public RSS API endpoint + */ +async function fetchFromIndiekit(endpoint) { + try { + const url = `${INDIEKIT_URL}/rssapi/api/${endpoint}`; + console.log(`[newsActivity] Fetching from Indiekit: ${url}`); + const data = await EleventyFetch(url, { + duration: "15m", + type: "json", + }); + console.log(`[newsActivity] Indiekit ${endpoint} success`); + return data; + } catch (error) { + console.log( + `[newsActivity] Indiekit API unavailable for ${endpoint}: ${error.message}` + ); + return null; + } +} + +export default async function () { + try { + console.log("[newsActivity] Fetching RSS feed data..."); + + // Fetch all data from Indiekit API + const [itemsRes, feedsRes, statusRes] = await Promise.all([ + fetchFromIndiekit("items?limit=50"), + fetchFromIndiekit("feeds"), + fetchFromIndiekit("status"), + ]); + + // Check if we got data + const hasData = itemsRes?.items?.length || feedsRes?.feeds?.length; + + if (!hasData) { + console.log("[newsActivity] No data available from Indiekit"); + return { + items: [], + feeds: [], + status: null, + lastUpdated: null, + source: "unavailable", + }; + } + + console.log( + `[newsActivity] Got ${itemsRes?.items?.length || 0} items from ${feedsRes?.feeds?.length || 0} feeds` + ); + + // Create a map of feed IDs to feed info for quick lookup + const feedMap = new Map(); + for (const feed of feedsRes?.feeds || []) { + feedMap.set(feed.id, feed); + } + + // Enhance items with additional feed info + const items = (itemsRes?.items || []).map((item) => { + const feed = feedMap.get(item.feedId); + return { + ...item, + feedInfo: feed + ? { + title: feed.title, + siteUrl: feed.siteUrl, + imageUrl: feed.imageUrl, + } + : null, + }; + }); + + return { + items, + feeds: feedsRes?.feeds || [], + pagination: itemsRes?.pagination || null, + status: statusRes || null, + lastUpdated: statusRes?.lastSync || new Date().toISOString(), + source: "indiekit", + }; + } catch (error) { + console.error("[newsActivity] Error:", error.message); + return { + items: [], + feeds: [], + status: null, + lastUpdated: null, + source: "error", + }; + } +} diff --git a/news.njk b/news.njk new file mode 100644 index 0000000..af26274 --- /dev/null +++ b/news.njk @@ -0,0 +1,312 @@ +--- +layout: layouts/base.njk +title: News Feed +permalink: /news/ +withSidebar: true +--- +
+ Aggregated content from my favorite feeds +
+ {% if newsActivity.lastUpdated %} ++ Last updated: {{ newsActivity.lastUpdated | date("PPpp") }} +
+ {% endif %} ++ {{ item.description }} +
+ {% endif %} + ++ {{ item.description }} +
+ {% endif %} + ++ {{ item.description }} +
+ {% endif %} + +No news items yet.
+Add some RSS feeds to get started.
+