github-actions[bot]
Sync to HuggingFace Spaces
f152ae2
import { Button, Group, Stack, Textarea } from "@mantine/core";
import { usePubSub } from "create-pubsub/react";
import {
type ChangeEvent,
type KeyboardEvent,
type ReactNode,
useCallback,
useEffect,
useRef,
useState,
} from "react";
import { Pattern, match } from "ts-pattern";
import { useLocation } from "wouter";
import { addLogEntry } from "../../../modules/logEntries";
import { postMessageToParentWindow } from "../../../modules/parentWindow";
import { settingsPubSub } from "../../../modules/pubSub";
import { getRandomQuerySuggestion } from "../../../modules/querySuggestions";
import { sleepUntilIdle } from "../../../modules/sleep";
import { searchAndRespond } from "../../../modules/textGeneration";
export default function SearchForm({
query,
updateQuery,
additionalButtons,
}: {
query: string;
updateQuery: (query: string) => void;
additionalButtons?: ReactNode;
}) {
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const [textAreaValue, setTextAreaValue] = useState(query);
const defaultSuggestedQuery = "Anything you need!";
const [suggestedQuery, setSuggestedQuery] = useState(defaultSuggestedQuery);
const [, navigate] = useLocation();
const [settings] = usePubSub(settingsPubSub);
useEffect(() => {
sleepUntilIdle().then(() => {
searchAndRespond();
});
}, []);
useEffect(() => {
getRandomQuerySuggestion().then((querySuggestion) => {
setSuggestedQuery(querySuggestion);
});
}, []);
const handleInputChange = async (event: ChangeEvent<HTMLTextAreaElement>) => {
const text = event.target.value;
setTextAreaValue(text);
if (text.length === 0) {
setSuggestedQuery(await getRandomQuerySuggestion());
}
};
const handleClearButtonClick = async () => {
setSuggestedQuery(await getRandomQuerySuggestion());
setTextAreaValue("");
textAreaRef.current?.focus();
addLogEntry("User cleaned the search query field");
};
const startSearching = useCallback(() => {
const queryToEncode = match(textAreaValue.trim())
.with(Pattern.string.minLength(1), () => textAreaValue)
.otherwise(() => suggestedQuery);
setTextAreaValue(queryToEncode);
const queryString = `q=${encodeURIComponent(queryToEncode)}`;
postMessageToParentWindow({ queryString, hash: "" });
navigate(`/?${queryString}`, { replace: true });
updateQuery(queryToEncode);
searchAndRespond();
addLogEntry(
`User submitted a search with ${queryToEncode.length} characters length`,
);
}, [textAreaValue, suggestedQuery, updateQuery, navigate]);
const handleSubmit = (event: { preventDefault: () => void }) => {
event.preventDefault();
startSearching();
};
const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
match([event, settings.enterToSubmit])
.with(
[{ code: "Enter", shiftKey: false }, true],
[{ code: "Enter", shiftKey: true }, false],
() => handleSubmit(event),
)
.otherwise(() => undefined);
};
return (
<form onSubmit={handleSubmit} style={{ width: "100%" }}>
<Stack gap="xs">
<Textarea
value={textAreaValue}
placeholder={suggestedQuery}
ref={textAreaRef}
onKeyDown={handleKeyDown}
onChange={handleInputChange}
autosize
minRows={1}
maxRows={8}
autoFocus
/>
<Group gap="xs">
{match(textAreaValue)
.with(Pattern.string.minLength(1), () => (
<Button
size="xs"
onClick={handleClearButtonClick}
variant="default"
>
Clear
</Button>
))
.otherwise(() => null)}
<Button size="xs" type="submit" variant="default" flex={1}>
Search
</Button>
{additionalButtons}
</Group>
</Stack>
</form>
);
}