// FeedPane — the right pane. A two-column split: scrollable post list // on the left (~430px), thread/post detail on the right. import React, { useCallback, useEffect, useState } from 'react'; import { useStore, type FeedTab } from '@/lib/store'; import { fetchForYou, fetchTrending, fetchTimeline, fetchHashtag, fetchAuthorPosts, type FeedPostItem, } from '@/lib/feed'; import { PostList } from './PostList'; import { PostDetail } from './PostDetail'; import { ComposeModal } from './ComposeModal'; export function FeedPane(): React.ReactElement { const tab = useStore(s => s.feedTab); const selected = useStore(s => s.feedSelectedPost); const keyFile = useStore(s => s.keyFile); const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [composing, setComposing] = useState(false); const load = useCallback(async () => { setLoading(true); try { const list = await fetchByTab(tab, keyFile?.pub_key); setPosts(list); } catch { setPosts([]); } finally { setLoading(false); } }, [tab, keyFile]); useEffect(() => { load(); }, [load]); // Ctrl/Cmd+N → compose (scoped to Feed being active). useEffect(() => { const onKey = (e: KeyboardEvent) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'n') { e.preventDefault(); setComposing(true); } }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, []); return (
{/* Header strip — tab label + compose CTA */}
{titleFor(tab)}
{loading ? (
Loading…
) : posts.length === 0 ? (
No posts in this feed yet.
) : ( )}
{composing && keyFile && ( setComposing(false)} onPublished={() => { setComposing(false); // Re-pull so the new post shows up immediately. setTimeout(load, 800); }} /> )}
); } function titleFor(tab: FeedTab): string { switch (tab.kind) { case 'foryou': return 'For You'; case 'timeline': return 'Following'; case 'trending': return 'Trending 24h'; case 'hashtag': return `#${tab.tag}`; case 'author': return 'Author wall'; } } async function fetchByTab(tab: FeedTab, selfPub: string | undefined): Promise { switch (tab.kind) { case 'foryou': if (!selfPub) return fetchTrending(24, 30); return fetchForYou(selfPub, 30); case 'timeline': if (!selfPub) return []; return fetchTimeline(selfPub, { limit: 30 }); case 'trending': return fetchTrending(24, 30); case 'hashtag': return fetchHashtag(tab.tag, 30); case 'author': return fetchAuthorPosts(tab.pub, { limit: 30 }); } }