chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { AppTile } from '#/components/atoms/app-tile.jsx';
import { ListRow } from '#/components/molecules/list-row.jsx';
import { article, nsidDomain, recordNoun, timeAgo } from '#/lib/format.js';
const VERB = {
create: 'Added',
update: 'Updated',
delete: 'Removed',
};
/**
* A feed of record changes, newest first. Every row links to that change's
* point-in-time snapshot — deletes included, since the snapshot recovers what
* the record was.
*/
export function ActivityList({ events, recordHref, onNavigate }) {
return (
<div className="flex flex-col gap-1">
{events.map((event) => {
const label = VERB[event.action] || event.action;
// Read the record type in plain language ("a post"), not its NSID, and
// let the app show once below instead of repeating its domain here.
const noun = recordNoun(event.collection);
const href = recordHref?.(event.collection, event.rkey, event.seq);
return (
<ListRow
key={`${event.seq}-${event.collection}-${event.rkey}`}
variant="plain"
href={href}
onNavigate={onNavigate}
media={
<AppTile
domain={nsidDomain(event.collection)}
label={event.collection}
size={36}
/>
}
title={
<span className="font-normal text-foreground">
<span className="font-extrabold">{label}</span> {article(noun)}{' '}
{noun}
</span>
}
description={nsidDomain(event.collection)}
actions={
<span className="whitespace-nowrap text-[12px] text-faint">
{timeAgo(event.time)}
</span>
}
/>
);
})}
</div>
);
}