import React, { ReactNode } from 'react'; import { IconSrc, Icons } from 'folds'; import { MatrixEvent } from 'matrix-js-sdk'; import { IMemberContent, Membership } from '../../types/matrix/room'; import { getMxIdLocalPart } from '../utils/matrix'; import { isMembershipChanged } from '../utils/room'; export type ParsedResult = { icon: IconSrc; body: ReactNode; }; export type MemberEventParser = (mEvent: MatrixEvent) => ParsedResult; export const useMemberEventParser = (): MemberEventParser => { const parseMemberEvent: MemberEventParser = (mEvent) => { const content = mEvent.getContent(); const prevContent = mEvent.getPrevContent() as IMemberContent; const senderId = mEvent.getSender(); const userId = mEvent.getStateKey(); const reason = typeof content.reason === 'string' ? content.reason : undefined; if (!senderId || !userId) return { icon: Icons.User, body: 'Broken membership event', }; const senderName = getMxIdLocalPart(senderId); const userName = typeof content.displayname === 'string' ? content.displayname || getMxIdLocalPart(userId) : getMxIdLocalPart(userId); if (isMembershipChanged(mEvent)) { if (content.membership === Membership.Invite) { if (prevContent.membership === Membership.Knock) { return { icon: Icons.ArrowGoRightPlus, body: ( <> {senderName} {' accepted '} {userName} {`'s join request `} {reason} ), }; } return { icon: Icons.ArrowGoRightPlus, body: ( <> {senderName} {' invited '} {userName} {reason} ), }; } if (content.membership === Membership.Knock) { return { icon: Icons.ArrowGoRightPlus, body: ( <> {userName} {' request to join room '} {reason} ), }; } if (content.membership === Membership.Join) { return { icon: Icons.ArrowGoRight, body: ( <> {userName} {' joined the room'} ), }; } if (content.membership === Membership.Leave) { if (prevContent.membership === Membership.Invite) { return { icon: Icons.ArrowGoRightCross, body: senderId === userId ? ( <> {userName} {' rejected the invitation '} {reason} ) : ( <> {senderName} {' rejected '} {userName} {`'s join request `} {reason} ), }; } if (prevContent.membership === Membership.Knock) { return { icon: Icons.ArrowGoRightCross, body: senderId === userId ? ( <> {userName} {' revoked joined request '} {reason} ) : ( <> {senderName} {' revoked '} {userName} {`'s invite `} {reason} ), }; } if (prevContent.membership === Membership.Ban) { return { icon: Icons.ArrowGoLeft, body: ( <> {senderName} {' unbanned '} {userName} {reason} ), }; } return { icon: Icons.ArrowGoLeft, body: senderId === userId ? ( <> {userName} {' left the room '} {reason} ) : ( <> {senderName} {' kicked '} {userName} {reason} ), }; } if (content.membership === Membership.Ban) { return { icon: Icons.ArrowGoLeft, body: ( <> {senderName} {' banned '} {userName} {reason} ), }; } } if (content.displayname !== prevContent.displayname) { const prevUserName = typeof prevContent.displayname === 'string' ? prevContent.displayname || getMxIdLocalPart(userId) : getMxIdLocalPart(userId); return { icon: Icons.Mention, body: typeof content.displayname === 'string' ? ( <> {prevUserName} {' changed display name to '} {userName} ) : ( <> {prevUserName} {' removed their display name '} ), }; } if (content.avatar_url !== prevContent.avatar_url) { return { icon: Icons.User, body: content.avatar_url && typeof content.avatar_url === 'string' ? ( <> {userName} {' changed their avatar'} ) : ( <> {userName} {' removed their avatar '} ), }; } return { icon: Icons.User, body: 'Membership event with no changes', }; }; return parseMemberEvent; };