262 lines
7.4 KiB
TypeScript
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;
|
|
};
|