=> {
isHuman: false,
captchaApi: undefined,
account: undefined,
- // don't handle timeout here, this should be handled by the state management
};
};
@@ -112,7 +111,6 @@ export function Manager(
}
await cryptoWaitReady();
- resetState();
// set the loading flag to true (allow UI to show some sort of loading / pending indicator while we get the captcha process going)
updateState({ loading: true });
updateState({
@@ -158,26 +156,12 @@ export function Manager(
throw new ProsopoDatasetError("DEVELOPER.PROVIDER_NO_CAPTCHA");
}
- // setup timeout, taking the timeout from the individual captcha or the global default
- const timeMillis: number = challenge.captchas
- .map(
- (captcha) =>
- captcha.timeLimitMs || config.captchas.image.challengeTimeout,
- )
- .reduce((a: number, b: number) => a + b);
- const timeout = setTimeout(() => {
- events.onChallengeExpired();
- // expired, disallow user's claim to be human
- updateState({ isHuman: false, showModal: false, loading: false });
- }, timeMillis);
-
// update state with new challenge
updateState({
index: 0,
solutions: challenge.captchas.map(() => []),
challenge,
showModal: true,
- timeout,
});
}
},
@@ -191,9 +175,6 @@ export function Manager(
const submit = async () => {
await providerRetry(
async () => {
- // disable the time limit, user has submitted their solution in time
- clearTimeout();
-
if (!state.challenge) {
throw new ProsopoError("CAPTCHA.NO_CAPTCHA", {
context: { error: "Cannot submit, no Captcha found in state" },
@@ -296,7 +277,6 @@ export function Manager(
},
}),
);
- setValidChallengeTimeout();
} else {
events.onFailed();
}
@@ -309,17 +289,15 @@ export function Manager(
};
const cancel = async () => {
- // disable the time limit
- clearTimeout();
// abandon the captcha process
resetState();
// trigger the onClose event
events.onClose();
+ // trigger full reset
+ callbacks?.onReset?.();
};
const reload = async () => {
- // disable the time limit
- clearTimeout();
// abandon the captcha process
resetState();
// trigger the onClose event
@@ -386,28 +364,7 @@ export function Manager(
return new ProviderApi(providerUrl, config.account.address);
};
- const clearTimeout = () => {
- // clear the timeout
- window.clearTimeout(Number(state.timeout));
- // then clear the timeout from the state
- updateState({ timeout: undefined });
- };
-
- const setValidChallengeTimeout = () => {
- const timeMillis: number = configOptional.captchas.image.solutionTimeout;
- const successfullChallengeTimeout = setTimeout(() => {
- // Human state expired, disallow user's claim to be human
- updateState({ isHuman: false });
-
- events.onExpired();
- }, timeMillis);
-
- updateState({ successfullChallengeTimeout });
- };
-
const resetState = () => {
- // clear timeout just in case a timer is still active (shouldn't be)
- clearTimeout();
updateState(defaultState());
events.onReset();
};
diff --git a/packages/types/src/config/config.ts b/packages/types/src/config/config.ts
index 6d9c4d3b72..e4b9168137 100644
--- a/packages/types/src/config/config.ts
+++ b/packages/types/src/config/config.ts
@@ -261,6 +261,7 @@ export const ProcaptchaConfigSchema = ProsopoClientConfigSchema.and(
theme: ThemeType.optional().default("light"),
captchas: CaptchaTimeoutSchema.optional().default(defaultCaptchaTimeouts),
language: LanguageSchema.optional(),
+ startOnRender: boolean().optional().default(false),
}),
);
diff --git a/packages/types/src/procaptcha/props.ts b/packages/types/src/procaptcha/props.ts
index 9128ef61ff..73ffc37c7c 100644
--- a/packages/types/src/procaptcha/props.ts
+++ b/packages/types/src/procaptcha/props.ts
@@ -32,3 +32,8 @@ export interface ProcaptchaProps {
callbacks?: Partial
;
frictionlessState?: FrictionlessState;
}
+
+export interface ProcaptchaPlaceholderProps extends ProcaptchaProps {
+ detectAndSetComponent: () => void;
+ frictionlessLoading: boolean;
+}
diff --git a/packages/web-components/package.json b/packages/web-components/package.json
index 37973c5329..1a7ddb5355 100644
--- a/packages/web-components/package.json
+++ b/packages/web-components/package.json
@@ -38,6 +38,8 @@
},
"devDependencies": {
"@prosopo/config": "2.1.14",
+ "@prosopo/locale-browser": "2.1.14",
+ "@prosopo/types": "2.1.14",
"@vitest/coverage-v8": "2.1.1",
"concurrently": "9.0.1",
"del-cli": "6.0.0",
diff --git a/packages/web-components/src/CaptchaPlaceholder.tsx b/packages/web-components/src/CaptchaPlaceholder.tsx
index 60e2b68bc7..25bca11430 100644
--- a/packages/web-components/src/CaptchaPlaceholder.tsx
+++ b/packages/web-components/src/CaptchaPlaceholder.tsx
@@ -13,7 +13,9 @@
// limitations under the License.
/** @jsxImportSource @emotion/react */
-import type { ProcaptchaProps } from "@prosopo/types";
+import { useTranslation } from "@prosopo/locale-browser";
+import type { ProcaptchaPlaceholderProps } from "@prosopo/types";
+import Checkbox from "./Checkbox.js";
import { ContainerDiv, WidthBasedStylesDiv } from "./Containers.js";
import { LoadingSpinner } from "./LoadingSpinner.js";
import Logo from "./Logo.js";
@@ -32,9 +34,12 @@ import { darkTheme, lightTheme } from "./theme.js";
export const ProcaptchaPlaceholder = ({
config,
callbacks,
-}: ProcaptchaProps) => {
+ frictionlessLoading,
+ detectAndSetComponent,
+}: ProcaptchaPlaceholderProps) => {
const themeColor = config.theme === "light" ? "light" : "dark";
const theme = config.theme === "light" ? lightTheme : darkTheme;
+ const { t } = useTranslation();
return (
-
+ {frictionlessLoading ? (
+
+ ) : (
+
+ )}