From 293855fda4ff8466eef8a52da983e9e1146549fd Mon Sep 17 00:00:00 2001 From: Mykhailo Mohyliuk Date: Thu, 5 Oct 2023 18:37:15 +0300 Subject: [PATCH] added throttle on composing --- client-web/src/pages/ChatInRoom/Chat.tsx | 19 ++++++++++------ client-web/src/utils/throttle.ts | 29 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 client-web/src/utils/throttle.ts diff --git a/client-web/src/pages/ChatInRoom/Chat.tsx b/client-web/src/pages/ChatInRoom/Chat.tsx index 9246eceb..6210b218 100644 --- a/client-web/src/pages/ChatInRoom/Chat.tsx +++ b/client-web/src/pages/ChatInRoom/Chat.tsx @@ -60,6 +60,7 @@ import { useSnackbar } from "../../context/SnackbarContext"; import { createMainMessageForThread } from "../../utils/createMessage"; import Dompurify from "dompurify"; import { LeaveRoomButton } from "../../components/Chat/LeaveRoomButton"; +import { throttle } from "../../utils/throttle"; export type IMessagePosition = { position: MessageModel["position"]; @@ -401,14 +402,19 @@ export function ChatInRoom() { } setFileUploading(false); }; + const sendThrottledComposing = useRef( + throttle(() => { + xmpp.isComposing( + user.walletAddress, + roomData.jid, + user.firstName + " " + user.lastName + ); + }, 500) + ); - const setMessage = (value) => { + const setMessage = (value: string) => { setMyMessage(value); - xmpp.isComposing( - user.walletAddress, - roomData.jid, - user.firstName + " " + user.lastName - ); + sendThrottledComposing.current(); }; const handlePaste = (event: any) => { @@ -423,7 +429,6 @@ export function ChatInRoom() { }; useEffect(() => { - const timeoutId = setTimeout(() => { xmpp.pausedComposing(user.walletAddress, roomData?.jid); }, 1000); diff --git a/client-web/src/utils/throttle.ts b/client-web/src/utils/throttle.ts new file mode 100644 index 00000000..ed3c60ca --- /dev/null +++ b/client-web/src/utils/throttle.ts @@ -0,0 +1,29 @@ +export const throttle = void>( + func: T, + delay: number +): T => { + let lastInvokeTime = 0; + let timeoutId: NodeJS.Timeout | null = null; + + return ((...args: any[]) => { + const now = Date.now(); + const timeSinceLastInvoke = now - lastInvokeTime; + + const invoke = () => { + lastInvokeTime = Date.now(); + func(...args); + }; + + if (timeSinceLastInvoke >= delay) { + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + invoke(); + } else if (!timeoutId) { + timeoutId = setTimeout(() => { + invoke(); + }, delay - timeSinceLastInvoke); + } + }) as T; +};