48af82777108 | atagen | 2026-10-26 10:41 UTC | 1 | import type { EventContext, MemberSummary, Sender, TimelineItem } from './types'; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 2 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 3 | export type RoomProfiles = Record<string, Record<string, MemberSummary>>; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 4 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 5 | export function lacksProfile(sender: Sender): boolean { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 6 | return !sender.display_name && !sender.avatar; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 7 | } |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 8 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 9 | /** Rooms holding a sender or reply sender that came back with no name and no avatar. */ |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 10 | export function roomsLackingProfiles(items: { roomId: string; item: TimelineItem }[]): Set<string> { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 11 | const rooms = new Set<string>(); |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 12 | for (const { roomId, item } of items) { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 13 | if (item.kind !== 'event') continue; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 14 | const reply = item.event.reply_to?.details; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 15 | if (lacksProfile(item.event.sender) || (reply?.kind === 'Ready' && lacksProfile(reply.sender))) rooms.add(roomId); |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 16 | } |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 17 | return rooms; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 18 | } |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 19 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 20 | function filled(sender: Sender, members: Record<string, MemberSummary> | undefined): Sender { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 21 | const member = members?.[sender.user_id]; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 22 | if (!member || !lacksProfile(sender) || (!member.display_name && !member.avatar)) return sender; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 23 | return { ...sender, display_name: member.display_name, avatar: member.avatar, name_ambiguous: member.name_ambiguous }; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 24 | } |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 25 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 26 | export function withProfiles(item: TimelineItem, members: Record<string, MemberSummary> | undefined): TimelineItem { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 27 | if (item.kind !== 'event' || !members) return item; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 28 | const { reply_to: reply } = item.event; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 29 | const details = reply?.details; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 30 | const sender = filled(item.event.sender, members); |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 31 | const replySender = details?.kind === 'Ready' ? filled(details.sender, members) : null; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 32 | if (sender === item.event.sender && (details?.kind !== 'Ready' || replySender === details.sender)) return item; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 33 | const reply_to = reply && details?.kind === 'Ready' && replySender ? { ...reply, details: { ...details, sender: replySender } } : reply; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 34 | return { ...item, event: { ...item.event, sender, reply_to } }; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 35 | } |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 36 | |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 37 | export function contextWithProfiles(context: EventContext, members: Record<string, MemberSummary> | undefined): EventContext { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 38 | if (!members) return context; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 39 | return { |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 40 | ...context, |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 41 | events_before: context.events_before.map((item) => withProfiles(item, members)), |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 42 | event: withProfiles(context.event, members), |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 43 | events_after: context.events_after.map((item) => withProfiles(item, members)) |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 44 | }; |
48af82777108 | atagen | 2026-10-26 10:41 UTC | 45 | } |