From a7178e1434abf1221e1b3101c61f09fc167fc174 Mon Sep 17 00:00:00 2001 From: arpitnath Date: Tue, 3 Oct 2023 19:42:36 +0530 Subject: [PATCH] reduce outbound calls when widget re-positioned with keyboard --- frontend/src/Editor/EditorFunc.jsx | 25 ++++++++++++- .../src/_hooks/useDebouncedArrowKeyPress.js | 37 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 frontend/src/_hooks/useDebouncedArrowKeyPress.js diff --git a/frontend/src/Editor/EditorFunc.jsx b/frontend/src/Editor/EditorFunc.jsx index acd59cf6ef..327f228668 100644 --- a/frontend/src/Editor/EditorFunc.jsx +++ b/frontend/src/Editor/EditorFunc.jsx @@ -64,6 +64,8 @@ import { useMounted } from '@/_hooks/use-mount'; // eslint-disable-next-line import/no-unresolved import { diff } from 'deep-object-diff'; +import useDebouncedArrowKeyPress from '@/_hooks/useDebouncedArrowKeyPress'; + setAutoFreeze(false); enablePatches(); @@ -199,6 +201,7 @@ const EditorComponent = (props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const lastKeyPressTimestamp = useDebouncedArrowKeyPress(500); // 500 milliseconds delay // Handle appDefinition updates useEffect(() => { const didAppDefinitionChanged = !_.isEqual(appDefinition, prevAppDefinition.current); @@ -219,6 +222,19 @@ const EditorComponent = (props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify({ appDefinition, currentPageId, dataQueries })]); + useEffect(() => { + // This effect runs when lastKeyPressTimestamp changes + // You can place your database update logic here + // Ensure that you only update the database if the timestamp is recent + if (Date.now() - lastKeyPressTimestamp < 500) { + updateEditorState({ + isUpdatingEditorStateInProcess: true, + }); + autoSave(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify({ appDefinition, lastKeyPressTimestamp })]); + const handleMessage = (event) => { const { data } = event; @@ -774,8 +790,15 @@ const EditorComponent = (props) => { updateState({ appDiffOptions: opts, }); + + let updatingEditorStateInProcess = true; + + if (opts?.widgetMovedWithKeyboard === true) { + updatingEditorStateInProcess = false; + } + updateEditorState({ - isUpdatingEditorStateInProcess: true, + isUpdatingEditorStateInProcess: updatingEditorStateInProcess, appDefinition: updatedAppDefinition, }); diff --git a/frontend/src/_hooks/useDebouncedArrowKeyPress.js b/frontend/src/_hooks/useDebouncedArrowKeyPress.js new file mode 100644 index 0000000000..0e041f5eeb --- /dev/null +++ b/frontend/src/_hooks/useDebouncedArrowKeyPress.js @@ -0,0 +1,37 @@ +// useDebouncedArrowKeyPress.js +import { useEffect, useState } from 'react'; + +function useDebouncedArrowKeyPress(delay) { + const [lastKeyPressTimestamp, setLastKeyPressTimestamp] = useState(0); + + useEffect(() => { + let timer; + + function handleKeyPress(event) { + if ( + event.key === 'ArrowUp' || + event.key === 'ArrowDown' || + event.key === 'ArrowLeft' || + event.key === 'ArrowRight' + ) { + // Arrow key was pressed; debounce the update + clearTimeout(timer); + + timer = setTimeout(() => { + // Trigger the update only after the specified delay + setLastKeyPressTimestamp(Date.now()); + }, delay); + } + } + + document.addEventListener('keydown', handleKeyPress); + + return () => { + document.removeEventListener('keydown', handleKeyPress); + }; + }, [delay]); + + return lastKeyPressTimestamp; +} + +export default useDebouncedArrowKeyPress;