This commit is contained in:
2026-04-18 23:11:35 +02:00
commit f7cfd2a86e
196 changed files with 35538 additions and 0 deletions
@@ -0,0 +1,40 @@
import type { ConversationMember } from '@chat-app/shared/chat';
import { useTranslation } from 'react-i18next';
interface Props {
typingUserIds: string[];
members: ConversationMember[];
}
export function TypingIndicator({ typingUserIds, members }: Props) {
const { t } = useTranslation(['app']);
if (typingUserIds.length === 0) return null;
const names = typingUserIds
.map((id) => members.find((m) => m.userId === id)?.profile?.displayName)
.filter((n): n is string => typeof n === 'string' && n.length > 0);
const text =
names.length === 1
? t('app:chats.typing_one', { name: names[0] })
: t('app:chats.typing_many', { count: typingUserIds.length });
return (
<div className="px-6 pb-1 pt-0 text-xs text-neutral-400">
<span className="inline-flex items-center gap-2">
<TypingDots />
<span>{text}</span>
</span>
</div>
);
}
function TypingDots() {
return (
<span aria-hidden="true" className="inline-flex items-center gap-0.5">
<span className="h-1 w-1 rounded-full bg-neutral-500 [animation:pulse_1.2s_ease-in-out_infinite]" />
<span className="h-1 w-1 rounded-full bg-neutral-500 [animation:pulse_1.2s_ease-in-out_infinite] [animation-delay:0.15s]" />
<span className="h-1 w-1 rounded-full bg-neutral-500 [animation:pulse_1.2s_ease-in-out_infinite] [animation-delay:0.3s]" />
</span>
);
}