atagen

malice

public
Star0
Watch0
0f306a02ef992c8a7d2252fafe6f2548d710e0dd
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git

Blame: web/src/lib/mention-profiles.ts

48af82777108atagen2026-10-26 10:41 UTC1
import type { EventContext, MemberSummary, Sender, TimelineItem } from './types';
48af82777108atagen2026-10-26 10:41 UTC2
48af82777108atagen2026-10-26 10:41 UTC3
export type RoomProfiles = Record<string, Record<string, MemberSummary>>;
48af82777108atagen2026-10-26 10:41 UTC4
48af82777108atagen2026-10-26 10:41 UTC5
export function lacksProfile(sender: Sender): boolean {
48af82777108atagen2026-10-26 10:41 UTC6
  return !sender.display_name && !sender.avatar;
48af82777108atagen2026-10-26 10:41 UTC7
}
48af82777108atagen2026-10-26 10:41 UTC8
48af82777108atagen2026-10-26 10:41 UTC9
/** Rooms holding a sender or reply sender that came back with no name and no avatar. */
48af82777108atagen2026-10-26 10:41 UTC10
export function roomsLackingProfiles(items: { roomId: string; item: TimelineItem }[]): Set<string> {
48af82777108atagen2026-10-26 10:41 UTC11
  const rooms = new Set<string>();
48af82777108atagen2026-10-26 10:41 UTC12
  for (const { roomId, item } of items) {
48af82777108atagen2026-10-26 10:41 UTC13
    if (item.kind !== 'event') continue;
48af82777108atagen2026-10-26 10:41 UTC14
    const reply = item.event.reply_to?.details;
48af82777108atagen2026-10-26 10:41 UTC15
    if (lacksProfile(item.event.sender) || (reply?.kind === 'Ready' && lacksProfile(reply.sender))) rooms.add(roomId);
48af82777108atagen2026-10-26 10:41 UTC16
  }
48af82777108atagen2026-10-26 10:41 UTC17
  return rooms;
48af82777108atagen2026-10-26 10:41 UTC18
}
48af82777108atagen2026-10-26 10:41 UTC19
48af82777108atagen2026-10-26 10:41 UTC20
function filled(sender: Sender, members: Record<string, MemberSummary> | undefined): Sender {
48af82777108atagen2026-10-26 10:41 UTC21
  const member = members?.[sender.user_id];
48af82777108atagen2026-10-26 10:41 UTC22
  if (!member || !lacksProfile(sender) || (!member.display_name && !member.avatar)) return sender;
48af82777108atagen2026-10-26 10:41 UTC23
  return { ...sender, display_name: member.display_name, avatar: member.avatar, name_ambiguous: member.name_ambiguous };
48af82777108atagen2026-10-26 10:41 UTC24
}
48af82777108atagen2026-10-26 10:41 UTC25
48af82777108atagen2026-10-26 10:41 UTC26
export function withProfiles(item: TimelineItem, members: Record<string, MemberSummary> | undefined): TimelineItem {
48af82777108atagen2026-10-26 10:41 UTC27
  if (item.kind !== 'event' || !members) return item;
48af82777108atagen2026-10-26 10:41 UTC28
  const { reply_to: reply } = item.event;
48af82777108atagen2026-10-26 10:41 UTC29
  const details = reply?.details;
48af82777108atagen2026-10-26 10:41 UTC30
  const sender = filled(item.event.sender, members);
48af82777108atagen2026-10-26 10:41 UTC31
  const replySender = details?.kind === 'Ready' ? filled(details.sender, members) : null;
48af82777108atagen2026-10-26 10:41 UTC32
  if (sender === item.event.sender && (details?.kind !== 'Ready' || replySender === details.sender)) return item;
48af82777108atagen2026-10-26 10:41 UTC33
  const reply_to = reply && details?.kind === 'Ready' && replySender ? { ...reply, details: { ...details, sender: replySender } } : reply;
48af82777108atagen2026-10-26 10:41 UTC34
  return { ...item, event: { ...item.event, sender, reply_to } };
48af82777108atagen2026-10-26 10:41 UTC35
}
48af82777108atagen2026-10-26 10:41 UTC36
48af82777108atagen2026-10-26 10:41 UTC37
export function contextWithProfiles(context: EventContext, members: Record<string, MemberSummary> | undefined): EventContext {
48af82777108atagen2026-10-26 10:41 UTC38
  if (!members) return context;
48af82777108atagen2026-10-26 10:41 UTC39
  return {
48af82777108atagen2026-10-26 10:41 UTC40
    ...context,
48af82777108atagen2026-10-26 10:41 UTC41
    events_before: context.events_before.map((item) => withProfiles(item, members)),
48af82777108atagen2026-10-26 10:41 UTC42
    event: withProfiles(context.event, members),
48af82777108atagen2026-10-26 10:41 UTC43
    events_after: context.events_after.map((item) => withProfiles(item, members))
48af82777108atagen2026-10-26 10:41 UTC44
  };
48af82777108atagen2026-10-26 10:41 UTC45
}