76 lines
2.1 KiB
TypeScript
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>
|
|
);
|
|
}
|