vojo/src/app/hooks/useMemberEventParser.tsx

262 lines
7.4 KiB
TypeScript

import React, { ReactNode } from 'react';
import { IconSrc, Icons } from 'folds';
import { MatrixEvent } from 'matrix-js-sdk';
import { Trans } from 'react-i18next';
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;
const B = <b />;
export const useMemberEventParser = (): MemberEventParser => {
const parseMemberEvent: MemberEventParser = (mEvent) => {
const content = mEvent.getContent<IMemberContent>();
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: <Trans i18nKey="Room.member_broken" />,
};
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: (
<>
<Trans
i18nKey="Room.member_accepted_knock"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
return {
icon: Icons.ArrowGoRightPlus,
body: (
<>
<Trans
i18nKey="Room.member_invited"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
if (content.membership === Membership.Knock) {
return {
icon: Icons.ArrowGoRightPlus,
body: (
<>
<Trans
i18nKey="Room.member_knock"
values={{ user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
if (content.membership === Membership.Join) {
return {
icon: Icons.ArrowGoRight,
body: (
<Trans
i18nKey="Room.member_joined"
values={{ user: userName }}
components={{ bold: B }}
/>
),
};
}
if (content.membership === Membership.Leave) {
if (prevContent.membership === Membership.Invite) {
return {
icon: Icons.ArrowGoRightCross,
body:
senderId === userId ? (
<>
<Trans
i18nKey="Room.member_rejected_invite"
values={{ user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
) : (
<>
<Trans
i18nKey="Room.member_rejected_knock"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
if (prevContent.membership === Membership.Knock) {
return {
icon: Icons.ArrowGoRightCross,
body:
senderId === userId ? (
<>
<Trans
i18nKey="Room.member_revoked_knock"
values={{ user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
) : (
<>
<Trans
i18nKey="Room.member_revoked_invite"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
if (prevContent.membership === Membership.Ban) {
return {
icon: Icons.ArrowGoLeft,
body: (
<>
<Trans
i18nKey="Room.member_unbanned"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
return {
icon: Icons.ArrowGoLeft,
body:
senderId === userId ? (
<>
<Trans
i18nKey="Room.member_left"
values={{ user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
) : (
<>
<Trans
i18nKey="Room.member_kicked"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${reason}` : ''}
</>
),
};
}
if (content.membership === Membership.Ban) {
return {
icon: Icons.ArrowGoLeft,
body: (
<>
<Trans
i18nKey="Room.member_banned"
values={{ sender: senderName, user: userName }}
components={{ bold: B }}
/>
{reason ? ` ${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' ? (
<Trans
i18nKey="Room.member_name_changed"
values={{ oldName: prevUserName, newName: userName }}
components={{ bold: B }}
/>
) : (
<Trans
i18nKey="Room.member_name_removed"
values={{ user: prevUserName }}
components={{ bold: B }}
/>
),
};
}
if (content.avatar_url !== prevContent.avatar_url) {
return {
icon: Icons.User,
body:
content.avatar_url && typeof content.avatar_url === 'string' ? (
<Trans
i18nKey="Room.member_avatar_changed"
values={{ user: userName }}
components={{ bold: B }}
/>
) : (
<Trans
i18nKey="Room.member_avatar_removed"
values={{ user: userName }}
components={{ bold: B }}
/>
),
};
}
return {
icon: Icons.User,
body: <Trans i18nKey="Room.member_no_change" />,
};
};
return parseMemberEvent;
};