* Adding base code for google re-captcha. * Removing recaptcha as well * Adding recaptchaToken on Button. * Fixing updateMetaProperty errors. * Handling recaptcha generation failed case. * Adding a message for recaptcha token gen fail * Rename setRecaptchaToken * Adding loading state for recaptcha button * Adding googleRecaptchaKey as a Btn prop * Adding the bound functions in widgets * Removing unused vars. * Handling google recaptcha key error. * Adding proper messages for
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
|
|
// Hook
|
|
export default function useScript(src: string) {
|
|
// Keep track of script status ("idle", "loading", "ready", "error")
|
|
const [status, setStatus] = useState(src ? "loading" : "idle");
|
|
|
|
useEffect(
|
|
() => {
|
|
// Allow falsy src value if waiting on other data needed for
|
|
// constructing the script URL passed to this hook.
|
|
if (!src) {
|
|
setStatus("idle");
|
|
return;
|
|
}
|
|
|
|
// Fetch existing script element by src
|
|
// It may have been added by another intance of this hook
|
|
let script = document.querySelector(`script[src="${src}"]`) as any;
|
|
|
|
if (!script) {
|
|
// Create script
|
|
script = document.createElement("script");
|
|
script.src = src;
|
|
script.async = true;
|
|
script.setAttribute("data-status", "loading");
|
|
// Add script to document body
|
|
document.body.appendChild(script);
|
|
|
|
// Store status in attribute on script
|
|
// This can be read by other instances of this hook
|
|
const setAttributeFromEvent = (event: any) => {
|
|
script.setAttribute(
|
|
"data-status",
|
|
event.type === "load" ? "ready" : "error",
|
|
);
|
|
};
|
|
|
|
script.addEventListener("load", setAttributeFromEvent);
|
|
script.addEventListener("error", setAttributeFromEvent);
|
|
} else {
|
|
// Grab existing script status from attribute and set to state.
|
|
setStatus(script.getAttribute("data-status"));
|
|
}
|
|
|
|
// Script event handler to update status in state
|
|
// Note: Even if the script already exists we still need to add
|
|
// event handlers to update the state for *this* hook instance.
|
|
const setStateFromEvent = (event: any) => {
|
|
setStatus(event.type === "load" ? "ready" : "error");
|
|
};
|
|
|
|
// Add event listeners
|
|
script.addEventListener("load", setStateFromEvent);
|
|
script.addEventListener("error", setStateFromEvent);
|
|
|
|
// Remove event listeners on cleanup
|
|
return () => {
|
|
if (script) {
|
|
script.removeEventListener("load", setStateFromEvent);
|
|
script.removeEventListener("error", setStateFromEvent);
|
|
}
|
|
};
|
|
},
|
|
[src], // Only re-run effect if script src changes
|
|
);
|
|
|
|
return status;
|
|
}
|