docs: handle recaptcha loading before submitting AI assistant queries (#13065)
This commit is contained in:
1 parent
7a07319a69
commit
5d79dc8c41
2 files changed
+34
-12
No files matched your search
@@ -12,7 +12,8 @@ type AiAssistantChatWindowInputProps = {
|
|||||||
export const AiAssistantChatWindowInput = ({
|
export const AiAssistantChatWindowInput = ({
|
||||||
chatWindowRef,
|
chatWindowRef,
|
||||||
}: AiAssistantChatWindowInputProps) => {
|
}: AiAssistantChatWindowInputProps) => {
|
||||||
const { chatOpened, inputRef, loading, setChatOpened } = useAiAssistant()
|
const { chatOpened, inputRef, loading, setChatOpened, isCaptchaLoaded } =
|
||||||
|
useAiAssistant()
|
||||||
const { submitQuery, conversation } = useChat()
|
const { submitQuery, conversation } = useChat()
|
||||||
const { isBrowser } = useIsBrowser()
|
const { isBrowser } = useIsBrowser()
|
||||||
const { searchQuery, searchQueryType } = useMemo(() => {
|
const { searchQuery, searchQueryType } = useMemo(() => {
|
||||||
@@ -29,9 +30,12 @@ export const AiAssistantChatWindowInput = ({
|
|||||||
const [question, setQuestion] = React.useState("")
|
const [question, setQuestion] = React.useState("")
|
||||||
const formRef = useRef<HTMLFormElement | null>(null)
|
const formRef = useRef<HTMLFormElement | null>(null)
|
||||||
|
|
||||||
const onSubmit = (e?: React.FormEvent<HTMLFormElement>) => {
|
const onSubmit = (
|
||||||
|
e?: React.FormEvent<HTMLFormElement>,
|
||||||
|
overrideQuestion?: string
|
||||||
|
) => {
|
||||||
e?.preventDefault()
|
e?.preventDefault()
|
||||||
submitQuery(question)
|
submitQuery(overrideQuestion || question)
|
||||||
setQuestion("")
|
setQuestion("")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,19 +114,17 @@ export const AiAssistantChatWindowInput = ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (searchQueryType === "submit") {
|
if (!searchQuery || !isCaptchaLoaded) {
|
||||||
onSubmit()
|
|
||||||
}
|
|
||||||
}, [searchQueryType])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!searchQuery) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setQuestion(searchQuery)
|
setQuestion(searchQuery)
|
||||||
setChatOpened(true)
|
setChatOpened(true)
|
||||||
}, [searchQuery])
|
if (searchQueryType !== "submit") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
onSubmit(undefined, searchQuery)
|
||||||
|
}, [searchQuery, searchQueryType, isCaptchaLoaded])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -158,7 +160,7 @@ export const AiAssistantChatWindowInput = ({
|
|||||||
"appearance-none p-0 text-medusa-fg-base disabled:text-medusa-fg-disabled",
|
"appearance-none p-0 text-medusa-fg-base disabled:text-medusa-fg-disabled",
|
||||||
"transition-colors"
|
"transition-colors"
|
||||||
)}
|
)}
|
||||||
disabled={!question || loading}
|
disabled={!question || loading || !isCaptchaLoaded}
|
||||||
>
|
>
|
||||||
<ArrowUpCircleSolid />
|
<ArrowUpCircleSolid />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export type AiAssistantContextType = {
|
|||||||
inputRef: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>
|
inputRef: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>
|
||||||
contentRef: React.RefObject<HTMLDivElement | null>
|
contentRef: React.RefObject<HTMLDivElement | null>
|
||||||
loading: boolean
|
loading: boolean
|
||||||
|
isCaptchaLoaded: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AiAssistantThreadItem = {
|
export type AiAssistantThreadItem = {
|
||||||
@@ -59,6 +60,7 @@ const AiAssistantInnerProvider = ({
|
|||||||
setOnCompleteAction,
|
setOnCompleteAction,
|
||||||
type,
|
type,
|
||||||
}: AiAssistantInnerProviderProps) => {
|
}: AiAssistantInnerProviderProps) => {
|
||||||
|
const [isCaptchaLoaded, setIsCaptchaLoaded] = useState(false)
|
||||||
const [chatOpened, setChatOpened] = useState(false)
|
const [chatOpened, setChatOpened] = useState(false)
|
||||||
const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null)
|
const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null)
|
||||||
const contentRef = useRef<HTMLDivElement>(null)
|
const contentRef = useRef<HTMLDivElement>(null)
|
||||||
@@ -146,6 +148,23 @@ const AiAssistantInnerProvider = ({
|
|||||||
|
|
||||||
const recaptchaElm = document.querySelector(".grecaptcha-badge")
|
const recaptchaElm = document.querySelector(".grecaptcha-badge")
|
||||||
recaptchaElm?.parentElement?.classList.add("absolute")
|
recaptchaElm?.parentElement?.classList.add("absolute")
|
||||||
|
const maxRetry = 10
|
||||||
|
let retries = 0
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (window.grecaptcha) {
|
||||||
|
setIsCaptchaLoaded(true)
|
||||||
|
clearInterval(interval)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
retries++
|
||||||
|
if (retries > maxRetry) {
|
||||||
|
clearInterval(interval)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval)
|
||||||
|
}
|
||||||
}, [isBrowser])
|
}, [isBrowser])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -157,6 +176,7 @@ const AiAssistantInnerProvider = ({
|
|||||||
inputRef,
|
inputRef,
|
||||||
contentRef,
|
contentRef,
|
||||||
loading,
|
loading,
|
||||||
|
isCaptchaLoaded,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
Reference in new issue
Block a user