refactor: reference human id instead of email (#73)

* refactor: update api and client to reference humanIds

* fix: prevent deletion of network member

This may cause various side effects if there is data in other services
which reference this member
This commit was merged in pull request #73.
This commit is contained in:
Arjun Patel
2026-03-24 19:48:02 -07:00
committed by GitHub
parent 3bf3f16be7
commit bf0147d542
24 changed files with 666 additions and 416 deletions
+17 -16
View File
@@ -202,7 +202,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
</p>
<ControlsIndicator type="reply" />
<ComposeOverlay
networkId={networkId!}
networkId={networkId}
targetPath={path}
onActiveChange={setComposeActive}
/>
@@ -267,7 +267,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
</div>
<ComposeOverlay
networkId={networkId!}
networkId={networkId}
targetPath={path}
onActiveChange={setComposeActive}
onParticleCreated={onLocalParticleCreated}
@@ -333,7 +333,7 @@ function TopBar({ networkId, particle, streamParticle }: { networkId: string; pa
<>
<BreadcrumbSeparator />
<BreadcrumbItem className="text-xs">
<BreadcrumbPage><ParticleBreadcrumbContent particle={particle} /></BreadcrumbPage>
<BreadcrumbPage><ParticleBreadcrumbContent particle={particle} networkId={networkId} /></BreadcrumbPage>
</BreadcrumbItem>
</>
)}
@@ -370,10 +370,11 @@ function NetworkBreadcrumbContent({ networkId }: { networkId: string }) {
);
}
function ParticleBreadcrumbContent({ particle }: { particle: Particle }) {
const createdByEmail = particle.created_by_email;
const prefix = createdByEmail.split('@')[0];
const initials = createdByEmail.slice(0, 2).toUpperCase();
function ParticleBreadcrumbContent({ particle, networkId }: { particle: Particle; networkId: string }) {
const network = useNetwork(networkId);
const creator = network?.humans?.find((h) => h.id === particle.created_by_human_id);
const prefix = creator?.email_prefix ?? particle.created_by_human_id;
const initials = prefix.slice(0, 2).toUpperCase();
return (
<span className="flex
@@ -398,27 +399,27 @@ const SeenIndicator = ({ stream, currentParticle, networkId }: { stream: Particl
.filter(([userId, timestamp]) => timestamp.getTime() >= currentParticle.created_at.getTime() && userId !== authedUser?.id)
.map(([userId, _]) => userId);
const seenUserEmails = seenUserIds
.map((userId) => network?.humans?.find((h) => h.id === userId)?.email)
.filter((email): email is string => !!email && email !== currentParticle.created_by_email);
const seenHumans = seenUserIds
.map((userId) => network?.humans?.find((h) => h.id === userId))
.filter((h): h is NonNullable<typeof h> => !!h && h.id !== currentParticle.created_by_human_id);
if (seenUserIds.length === 0) return null;
if (seenHumans.length === 0) return null;
return (
<>
{seenUserEmails.length > 0 && "Seen by"}
{"Seen by"}
<AvatarGroup>
{seenUserEmails.map((email) => (
<Tooltip key={email}>
{seenHumans.map((human) => (
<Tooltip key={human.id}>
<TooltipTrigger asChild>
<Avatar size="sm">
<AvatarFallback>
{email.split("@")[0].slice(0, 2)}
{human.email_prefix.slice(0, 2)}
</AvatarFallback>
</Avatar>
</TooltipTrigger>
<TooltipContent>
<p>Seen by {email.split("@")[0]}</p>
<p>Seen by {human.email_prefix}</p>
</TooltipContent>
</Tooltip>
))}