diff --git a/src/components/ChatForm/useInputValue.ts b/src/components/ChatForm/useInputValue.ts index ba2d670a..e55ad46b 100644 --- a/src/components/ChatForm/useInputValue.ts +++ b/src/components/ChatForm/useInputValue.ts @@ -34,7 +34,10 @@ export function useInputValue( (event: MessageEvent) => { if (addInputValue.match(event.data) || setInputValue.match(event.data)) { const { payload } = event.data; - debugRefact(`[DEBUG]: receiving event setInputValue/addInputValue`); + debugRefact( + `[DEBUG]: receiving event setInputValue/addInputValue with payload:`, + payload, + ); setUpIfNotReady(); if (payload.messages) { @@ -49,14 +52,19 @@ export function useInputValue( if (addInputValue.match(event.data)) { const { payload } = event.data; + debugRefact(`[DEBUG]: addInputValue triggered with:`, payload); const { send_immediately, value } = payload; - setValue((prev) => prev + value); + setValue((prev) => { + debugRefact(`[DEBUG]: Previous value: "${prev}", Adding: "${value}"`); + return prev + value; + }); setIsSendImmediately(send_immediately); return; } if (setInputValue.match(event.data)) { const { payload } = event.data; + debugRefact(`[DEBUG]: setInputValue triggered with:`, payload); const { send_immediately, value } = payload; uncheckCheckboxes(); setValue(value ?? ""); diff --git a/src/components/ComboBox/ComboBox.test.tsx b/src/components/ComboBox/ComboBox.test.tsx index 3f0edac5..2969885b 100644 --- a/src/components/ComboBox/ComboBox.test.tsx +++ b/src/components/ComboBox/ComboBox.test.tsx @@ -377,6 +377,8 @@ describe("ComboBox", () => { await user.keyboard("{z}"); expect(textarea.textContent).toEqual("@file "); + await pause(100); // required, because of cancelling on frequent paste + await user.keyboard("{z}{/Meta}{/Shift}"); expect(textarea.textContent).toEqual("@file /foo "); }); @@ -387,23 +389,29 @@ describe("ComboBox", () => { await user.type(textarea, "@"); await user.keyboard("{Enter}"); - await pause(50); + await pause(150); await user.keyboard("{Enter}"); expect(textarea.textContent).toEqual("@file /foo "); + await user.keyboard("{Control>}{z}"); expect(textarea.textContent).toEqual("@file "); + await user.keyboard("{z}"); expect(textarea.textContent).toEqual("@"); + await user.keyboard("{z}{/Control}"); expect(textarea.textContent).toEqual(""); - await user.keyboard("{Shift>}{Control>}{z}"); + await user.keyboard("{Shift>}{Control>}{Z}"); expect(textarea.textContent).toEqual("@"); - await user.keyboard("{z}"); + + await user.keyboard("{Z}"); expect(textarea.textContent).toEqual("@file "); - await user.keyboard("{z}{/Control}{/Shift}"); + await pause(100); // required, because of cancelling on frequent paste + + await user.keyboard("{z}{/Shift}{/Control}"); expect(textarea.textContent).toEqual("@file /foo "); }); diff --git a/src/components/ComboBox/ComboBox.tsx b/src/components/ComboBox/ComboBox.tsx index c4638bef..c26d013c 100644 --- a/src/components/ComboBox/ComboBox.tsx +++ b/src/components/ComboBox/ComboBox.tsx @@ -36,6 +36,7 @@ export const ComboBox: React.FC = ({ }) => { const ref = React.useRef(null); const [moveCursorTo, setMoveCursorTo] = React.useState(null); + const [lastPasteTimestamp, setLastPasteTimestamp] = React.useState(0); const shiftEnterToSubmit = useAppSelector(selectSubmitOption); const { escapeKeyPressed } = useEventsBusForIDE(); @@ -198,9 +199,30 @@ export const ComboBox: React.FC = ({ const handleChange = useCallback( (event: React.ChangeEvent) => { - onChange(event.target.value); + const newValue = event.target.value; + const nativeEvent = event.nativeEvent as InputEvent; + const currentEventTimestamp = nativeEvent.timeStamp; + + const inputType = nativeEvent.inputType; + const isPasteEvent = [ + "insertFromPaste", + "insertFromDrop", + "insertFromYank", + "insertReplacementText", + ].includes(inputType); + + const timeSinceLastChange = currentEventTimestamp - lastPasteTimestamp; + + if (isPasteEvent && timeSinceLastChange < 100) return; + + if (isPasteEvent) { + setLastPasteTimestamp(currentEventTimestamp); + closeCombobox(); + requestCommandsCompletion.cancel(); + } + onChange(newValue); }, - [onChange], + [onChange, closeCombobox, requestCommandsCompletion, lastPasteTimestamp], ); const onItemClick = useCallback( @@ -240,7 +262,7 @@ export const ComboBox: React.FC = ({ showOnChange={false} showOnKeyDown={false} showOnMouseDown={false} - setValueOnChange={true} + setValueOnChange={false} render={render({ ref, placeholder, diff --git a/src/components/TextArea/TextArea.tsx b/src/components/TextArea/TextArea.tsx index e51dda08..939d76eb 100644 --- a/src/components/TextArea/TextArea.tsx +++ b/src/components/TextArea/TextArea.tsx @@ -28,13 +28,15 @@ export const TextArea = React.forwardRef( const handleKeyDown = useCallback( (event: React.KeyboardEvent) => { const isMod = event.metaKey || event.ctrlKey; - if (isMod && event.key === "z" && !event.shiftKey) { + const eventKey = event.key.toLowerCase(); + + if (isMod && eventKey === "z" && !event.shiftKey) { event.preventDefault(); undoRedo.undo(); setCallChange(true); } - if (isMod && event.key === "z" && event.shiftKey) { + if (isMod && eventKey === "z" && event.shiftKey) { event.preventDefault(); undoRedo.redo(); setCallChange(true);