import type { Human } from '@/api/types'; import { getInitials } from '@/lib/utils'; export const REMOVED_MEMBER_LABEL = 'Removed member'; export const REMOVED_MEMBER_INITIALS = '–'; export interface HumanDisplay { /** True when the human was found in the provided list. */ exists: boolean; /** Short name for inline text (e.g. message sender). */ displayName: string; /** Full email or fallback label for tooltips. */ email: string; /** Initials for avatar fallback. */ initials: string; } /** * Resolve a human's display info by id, falling back consistently when the * human has been removed from the network. Member content (particles, reactions, * etc.) is retained after removal, so every render path needs a graceful fallback * instead of leaking raw ids into the UI. */ export function resolveHumanDisplay( humanId: string | null | undefined, humans: Human[] | undefined, ): HumanDisplay { const human = humanId ? humans?.find((h) => h.id === humanId) : undefined; if (!human) { return { exists: false, displayName: REMOVED_MEMBER_LABEL, email: REMOVED_MEMBER_LABEL, initials: REMOVED_MEMBER_INITIALS, }; } return { exists: true, displayName: human.email_prefix, email: human.email, initials: getInitials(human.email), }; }