/** * Renders the "journal" tab of the index page, which lays the feed out as a * mosaic of tiles of several sizes. * * @module */ import { Fragment, useMemo } from "react"; import { Trans } from "@lingui/react/macro"; import { ListState } from "../shared/ListState.tsx"; import { JournalCard } from "../dump/JournalCard.tsx"; import { useAuth } from "../../hooks/auth/useAuth.ts"; import { useWS } from "../../hooks/ws/useWS.ts"; import { FeedFooter } from "./FeedFooter.tsx"; import { composeJournal } from "../../utils/feed/journalLayout.ts"; import type { MainFeedProps } from "./DumpFeed.tsx"; /** * Renders the feed `Index` passes as blocks of {@link JournalCard}, laid out * by `composeJournal`, followed by the infinite-scroll sentinel, or the * loading, error or empty state. The votes come from `WSContext`. */ export function JournalFeed( { state, dumps, sentinelRef }: MainFeedProps, ): React.JSX.Element { const { user } = useAuth(); const { voteCounts, myVotes, castVote, removeVote } = useWS(); const blocks = useMemo(() => composeJournal(dumps), [dumps]); return ( blocks.length === 0} empty={

No dumps yet. Be the first!

} > {({ data: { hasMore, loadingMore } }) => ( <> { /* Each block is its own grid, with a themable
between them. Inside a grid the
would be stretched to a 9rem row, while out here a theme can shrink it to nothing. */ }
{blocks.map((block, index) => ( {index > 0 &&
}
    {block.entries.map(({ dump, shape }) => ( ))}
))}
)}
); }