vojo/src/app/features/room/RoomTimelineTyping.tsx

76 lines
2.1 KiB
TypeScript

import React from 'react';
import { Room } from 'matrix-js-sdk';
import { useTranslation } from 'react-i18next';
import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { getMemberDisplayName } from '../../utils/room';
import { getMxIdLocalPart } from '../../utils/matrix';
import * as css from './RoomTimelineTyping.css';
export type RoomTimelineTypingProps = {
room: Room;
};
export function RoomTimelineTyping({ room }: RoomTimelineTypingProps) {
const { t } = useTranslation();
const mx = useMatrixClient();
const typing = useRoomTypingMember(room.roomId);
const myUserId = mx.getUserId();
const names = typing
.filter((r) => r.userId !== myUserId)
.map((r) => getMemberDisplayName(room, r.userId) ?? getMxIdLocalPart(r.userId) ?? r.userId);
if (names.length === 0) return null;
let line: React.ReactNode;
if (names.length === 1) {
line = (
<>
<span className={css.TypingName}>{names[0]}</span>
{t('Room.is_typing')}
</>
);
} else if (names.length === 2) {
line = (
<>
<span className={css.TypingName}>{names[0]}</span>
{t('Room.and')}
<span className={css.TypingName}>{names[1]}</span>
{t('Room.are_typing')}
</>
);
} else if (names.length === 3) {
line = (
<>
<span className={css.TypingName}>{names[0]}</span>
{', '}
<span className={css.TypingName}>{names[1]}</span>
{t('Room.and')}
<span className={css.TypingName}>{names[2]}</span>
{t('Room.are_typing')}
</>
);
} else {
line = (
<>
<span className={css.TypingName}>{names[0]}</span>
{', '}
<span className={css.TypingName}>{names[1]}</span>
{', '}
<span className={css.TypingName}>{names[2]}</span>
{t('Room.and')}
<span className={css.TypingName}>
{t('Room.others_count', { count: names.length - 3 })}
</span>
{t('Room.are_typing')}
</>
);
}
return (
<div className={css.TypingRow} aria-live="polite">
{line}
</div>
);
}