'use client'; import { useEffect, useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMastodon } from '@fortawesome/free-brands-svg-icons'; import { faArrowRight } from '@fortawesome/free-solid-svg-icons'; import { siteConfig } from '@/lib/config'; import { parseMastodonUrl, stripHtml, truncateText, formatRelativeTime, fetchAccountId, fetchStatuses, type MastodonStatus } from '@/lib/mastodon'; export function MastodonFeed() { const [statuses, setStatuses] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); useEffect(() => { const loadStatuses = async () => { const mastodonUrl = siteConfig.social.mastodon; if (!mastodonUrl) { setLoading(false); return; } try { // Parse the Mastodon URL const parsed = parseMastodonUrl(mastodonUrl); if (!parsed) { setError(true); setLoading(false); return; } const { instance, username } = parsed; // Fetch account ID const accountId = await fetchAccountId(instance, username); if (!accountId) { setError(true); setLoading(false); return; } // Fetch statuses (5 posts, exclude replies, include boosts) const fetchedStatuses = await fetchStatuses(instance, accountId, 5); setStatuses(fetchedStatuses); } catch (err) { console.error('Error loading Mastodon feed:', err); setError(true); } finally { setLoading(false); } }; loadStatuses(); }, []); // Don't render if no Mastodon URL is configured if (!siteConfig.social.mastodon) { return null; } // Don't render if there's an error (fail silently) if (error) { return null; } return (
{/* Header */}
微網誌
{/* Content */} {loading ? (
{[...Array(3)].map((_, i) => (
))}
) : statuses.length === 0 ? (

暫無動態

) : (
{statuses.map((status) => { // Handle boosts (reblogs) const displayStatus = status.reblog || status; const content = stripHtml(displayStatus.content); const truncated = truncateText(content, 180); const relativeTime = formatRelativeTime(status.created_at); const hasMedia = displayStatus.media_attachments.length > 0; return ( ); })}
)} {/* Footer link */} {!loading && statuses.length > 0 && ( 查看更多 )}
); }