2023-06-12 21:15:23 +10:00
|
|
|
import { MatrixClient } from 'matrix-js-sdk';
|
|
|
|
|
import { useMemo, useRef } from 'react';
|
2024-05-31 19:49:46 +05:30
|
|
|
import { TYPING_TIMEOUT_MS } from '../state/typingMembers';
|
2023-06-12 21:15:23 +10:00
|
|
|
|
|
|
|
|
type TypingStatusUpdater = (typing: boolean) => void;
|
|
|
|
|
|
|
|
|
|
export const useTypingStatusUpdater = (mx: MatrixClient, roomId: string): TypingStatusUpdater => {
|
|
|
|
|
const statusSentTsRef = useRef<number>(0);
|
2026-05-20 21:26:18 -04:00
|
|
|
const typingTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
2023-06-12 21:15:23 +10:00
|
|
|
|
|
|
|
|
const sendTypingStatus: TypingStatusUpdater = useMemo(() => {
|
|
|
|
|
statusSentTsRef.current = 0;
|
|
|
|
|
return (typing) => {
|
|
|
|
|
if (typing) {
|
|
|
|
|
if (Date.now() - statusSentTsRef.current < TYPING_TIMEOUT_MS) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mx.sendTyping(roomId, true, TYPING_TIMEOUT_MS);
|
|
|
|
|
const sentTs = Date.now();
|
|
|
|
|
statusSentTsRef.current = sentTs;
|
|
|
|
|
|
2026-05-20 21:26:18 -04:00
|
|
|
// Cancel any previous pending timeout before scheduling a new one
|
|
|
|
|
if (typingTimerRef.current !== undefined) clearTimeout(typingTimerRef.current);
|
|
|
|
|
typingTimerRef.current = setTimeout(() => {
|
|
|
|
|
typingTimerRef.current = undefined;
|
2023-06-12 21:15:23 +10:00
|
|
|
if (statusSentTsRef.current === sentTs) {
|
|
|
|
|
mx.sendTyping(roomId, false, TYPING_TIMEOUT_MS);
|
|
|
|
|
statusSentTsRef.current = 0;
|
|
|
|
|
}
|
|
|
|
|
}, TYPING_TIMEOUT_MS);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Date.now() - statusSentTsRef.current < TYPING_TIMEOUT_MS) {
|
|
|
|
|
mx.sendTyping(roomId, false, TYPING_TIMEOUT_MS);
|
|
|
|
|
}
|
|
|
|
|
statusSentTsRef.current = 0;
|
|
|
|
|
};
|
|
|
|
|
}, [mx, roomId]);
|
|
|
|
|
|
|
|
|
|
return sendTypingStatus;
|
|
|
|
|
};
|