Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input lag fix #708

Merged
merged 7 commits into from
Nov 3, 2024
Merged
38 changes: 17 additions & 21 deletions src/components/PromptForm/DesktopPromptForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ function DesktopPromptForm({
isLoading,
previousMessage,
}: DesktopPromptFormProps) {
const [prompt, setPrompt] = useState("");
// Has the user started typing?
const [isDirty, setIsDirty] = useState(false);
const [isPromptEmpty, setIsPromptEmpty] = useState(true);
const { error } = useAlert();
const { settings } = useSettings();
const [isRecording, setIsRecording] = useState(false);
Expand All @@ -91,13 +89,6 @@ function DesktopPromptForm({
const [selectedImageUrl, setSelectedImageUrl] = useState<string>("");
const location = useLocation();

// If the user clears the prompt, allow up-arrow again
useEffect(() => {
if (!prompt) {
setIsDirty(false);
}
}, [prompt, setIsDirty]);

// Focus the prompt form when the user navigates
useEffect(() => {
inputPromptRef.current?.focus();
Expand Down Expand Up @@ -150,8 +141,14 @@ function DesktopPromptForm({
// Handle prompt form submission
const handlePromptSubmit = (e: FormEvent) => {
e.preventDefault();
const textValue = prompt.trim();
setPrompt("");
const textValue = inputPromptRef.current?.value.trim() || "";
if (!textValue) {
return;
}
if (inputPromptRef.current) {
inputPromptRef.current.value = "";
}
setIsPromptEmpty(true);
setInputImageUrls([]);
onSendClick(textValue, inputImageUrls);
};
Expand All @@ -164,27 +161,25 @@ function DesktopPromptForm({
switch (e.key) {
// Allow the user to cursor-up to repeat last prompt
case "ArrowUp":
if (!isDirty && previousMessage) {
if (isPromptEmpty && previousMessage && inputPromptRef.current) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you get rid of the isPromptEmpty state completely and do:

if (inputPromptRef.current?.value === "" && previousMessage) {

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here either would work, this is just more consistent cos it does trim in state

e.preventDefault();
setPrompt(previousMessage);
setIsDirty(true);
inputPromptRef.current.value = previousMessage;
setIsPromptEmpty(false);
}
break;

// Prevent blank submissions and allow for multiline input.
case "Enter":
// Deal with Enter key based on user preference and state of prompt form
if (settings.enterBehaviour === "newline") {
handleMetaEnter(e);
} else if (settings.enterBehaviour === "send") {
if (!e.shiftKey && prompt.length) {
if (!e.shiftKey && !isPromptEmpty) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

handlePromptSubmit(e);
}
}
break;

default:
setIsDirty(true);
return;
}
};
Expand Down Expand Up @@ -386,8 +381,9 @@ function DesktopPromptForm({
onKeyDown={handleKeyDown}
isDisabled={isLoading}
autoFocus={true}
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
onChange={(e) => {
setIsPromptEmpty(e.target.value.trim().length === 0);
}}
bg="white"
_dark={{ bg: "gray.700" }}
placeholder={
Expand Down Expand Up @@ -422,7 +418,7 @@ function DesktopPromptForm({
/>

<Flex alignItems="center" gap={2}>
<KeyboardHint isVisible={!!prompt.length && !isLoading} />
<KeyboardHint isVisible={!isPromptEmpty && !isLoading} />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if doing inputPromptRef.current.value !== "" works here, but it might

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesnt cos you need to trigger a react rerender

<PromptSendButton isLoading={isLoading} />
</Flex>
</Flex>
Expand Down
Loading