feat(layout): add two-pane layout and content fetching pipeline

- Left: bookmark list; Right: content panel
- Selection triggers readability fetch via readerService
- ContentPanel renders title and HTML
- Wires selection from BookmarkItem -> BookmarkList -> Bookmarks
This commit is contained in:
Gigi
2025-10-02 23:34:21 +02:00
parent 1d10c10a44
commit 96d93d0e17

View File

@@ -6,6 +6,8 @@ import { RelayPool } from 'applesauce-relay'
import { Bookmark } from '../types/bookmarks'
import { BookmarkList } from './BookmarkList'
import { fetchBookmarks } from '../services/bookmarkService'
import ContentPanel from './ContentPanel'
import { fetchReadableContent, ReadableContent } from '../services/readerService'
interface BookmarksProps {
relayPool: RelayPool | null
@@ -15,6 +17,9 @@ interface BookmarksProps {
const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
const [bookmarks, setBookmarks] = useState<Bookmark[]>([])
const [loading, setLoading] = useState(true)
const [selectedUrl, setSelectedUrl] = useState<string | undefined>(undefined)
const [readerLoading, setReaderLoading] = useState(false)
const [readerContent, setReaderContent] = useState<ReadableContent | undefined>(undefined)
const activeAccount = Hooks.useActiveAccount()
const accountManager = Hooks.useAccountManager()
@@ -51,6 +56,20 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
await fetchBookmarks(relayPool, fullAccount || activeAccount, setBookmarks, setLoading, timeoutId)
}
const handleSelectUrl = async (url: string) => {
setSelectedUrl(url)
setReaderLoading(true)
setReaderContent(undefined)
try {
const content = await fetchReadableContent(url)
setReaderContent(content)
} catch (err) {
console.warn('Failed to fetch readable content:', err)
} finally {
setReaderLoading(false)
}
}
const formatUserDisplay = () => {
@@ -91,12 +110,25 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
}
return (
<BookmarkList
bookmarks={bookmarks}
activeAccount={activeAccount || null}
onLogout={onLogout}
formatUserDisplay={formatUserDisplay}
/>
<div className="two-pane">
<div className="pane sidebar">
<BookmarkList
bookmarks={bookmarks}
activeAccount={activeAccount || null}
onLogout={onLogout}
formatUserDisplay={formatUserDisplay}
onSelectUrl={handleSelectUrl}
/>
</div>
<div className="pane main">
<ContentPanel
loading={readerLoading}
title={readerContent?.title}
html={readerContent?.html}
selectedUrl={selectedUrl}
/>
</div>
</div>
)
}