A small web app for watching movies and shows easily
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

81 lines
1.9 KiB

import Turnstile, { BoundTurnstileObject } from "react-turnstile";
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
import { conf } from "@/setup/config";
export interface TurnstileStore {
turnstile: BoundTurnstileObject | null;
cbs: ((token: string | null) => void)[];
setTurnstile(v: BoundTurnstileObject | null): void;
getToken(): Promise<string>;
processToken(token: string | null): void;
}
export const useTurnstileStore = create(
immer<TurnstileStore>((set, get) => ({
turnstile: null,
cbs: [],
processToken(token) {
const cbs = get().cbs;
cbs.forEach((fn) => fn(token));
set((s) => {
s.cbs = [];
});
},
getToken() {
return new Promise((resolve, reject) => {
set((s) => {
s.cbs = [
...s.cbs,
(token) => {
if (!token) reject(new Error("Failed to get token"));
else resolve(token);
},
];
});
});
},
setTurnstile(v) {
set((s) => {
s.turnstile = v;
});
},
}))
);
export function getTurnstile() {
return useTurnstileStore.getState().turnstile;
}
export function isTurnstileInitialized() {
return !!getTurnstile();
}
export function getTurnstileToken() {
const turnstile = getTurnstile();
turnstile?.reset();
turnstile?.execute();
return useTurnstileStore.getState().getToken();
}
export function TurnstileProvider() {
const siteKey = conf().TURNSTILE_KEY;
const setTurnstile = useTurnstileStore((s) => s.setTurnstile);
const processToken = useTurnstileStore((s) => s.processToken);
if (!siteKey) return null;
return (
<Turnstile
sitekey={siteKey}
onLoad={(_widgetId, bound) => {
setTurnstile(bound);
}}
onError={() => {
processToken(null);
}}
onVerify={(token) => {
processToken(token);
}}
/>
);
}