/** * A link alone on its line: one 36px row for every kind. Hovering it shows its * card; a tap opens it. Loading draws the row in bars; not available says so * in one line of the same height. */ import { Avatar } from './Avatar' import { AvatarGroup } from './AvatarGroup' import { Card } from './Card' import { Link } from './Link' import { chosenOf, type LinkedKind, type LinkState } from './linked' import { CommentCount, LinkedIcon, LinkKey, ProgressRing, StatusMark } from './LinkParts' import { LinkPreview } from './LinkPreview' import { SkeletonBar } from './Skeleton' export interface LinkUnavailableProps { kind: LinkedKind /** What it is, in a word: "Item". Drawn as "Item — not available.". */ noun: string /** Where it may still open, for someone who can: its app and address. */ openIn?: { app: string; href: string } } /** * Not available: deleted, or not this reader's to see, which read the same. * One line at a row's height, whether a row or a card was to draw. The way * out stays, since the app it lives in may still open it for you. */ export function LinkUnavailable({ kind, noun, openIn }: LinkUnavailableProps) { return ( {noun} — not available. {openIn && ( Open in {openIn.app} ↗ )} ) } export interface LinkRowProps { link: LinkState /** Hovering shows its card. */ preview?: boolean } export function LinkRow({ link, preview = true }: LinkRowProps) { if (link.state === 'loading') { return (
) } if (link.state === 'unavailable') return const { linked } = link const status = chosenOf(linked.status) const owner = chosenOf(linked.owner) const said = linked.kind === 'message' && linked.author const row = ( {said ? : } {said ? ( {said.name} {linked.body ?? linked.title} ) : ( <> {linked.key && {linked.key}} {linked.title} )} {linked.updated && {linked.updated}} {/* A row keeps to one line: the count shows only when there is something unread in it, except where conversations are what it holds. */} {linked.conversation && (linked.conversation.unread || linked.kind === 'topic') && } {/* A ring already says how far along it is. */} {status?.colour && !linked.done && } {linked.done && } {owner && } {linked.members && } {linked.authors && } ) return preview ? ( {row} ) : ( row ) }