131 lines
6.8 KiB
TypeScript
131 lines
6.8 KiB
TypeScript
import { useFlagsStatus, useUnleashClient, useVariant } from "@unleash/proxy-client-react";
|
||
import { useEffect, useMemo } from "react";
|
||
import { useSearchParams } from "react-router-dom";
|
||
|
||
export enum EUnleashFlags {
|
||
"genderPageType" = "genderPageType",
|
||
"zodiacImages" = "zodiacImages",
|
||
"dynamicHandsCompV2" = "dynamicHandsCompV2",
|
||
"dynamicHandsPalmistryV1" = "dynamicHandsPalmistryV1",
|
||
"welcomePageImagePalmistryV1" = "welcomePageImagePalmistryV1",
|
||
"cameraRequestModalPalmistryV1" = "cameraRequestModalPalmistryV1",
|
||
"cameraRequestModalCompatibilityV2" = "cameraRequestModalCompatibilityV2",
|
||
"darkThemePalmistryV1" = "darkThemePalmistryV1",
|
||
"darkThemeCompatibilityV2" = "darkThemeCompatibilityV2",
|
||
"paymentButtonLogic" = "paymentButtonLogic",
|
||
"pageAfterTrialPaymentCompatibilityV2" = "pageAfterTrialPaymentCompatibilityV2",
|
||
"pageAfterTrialPaymentCompatibilityV3" = "pageAfterTrialPaymentCompatibilityV3",
|
||
"pageAfterTrialPaymentCompatibilityV4" = "pageAfterTrialPaymentCompatibilityV4",
|
||
"pageAfterTrialPaymentPalmistryV1" = "pageAfterTrialPaymentPalmistryV1",
|
||
"paymentModalPage" = "paymentModalPage",
|
||
"headOrHeartResultPagePalmistryV1" = "headOrHeartResultPagePalmistryV1",
|
||
"headOrHeartResultPageCompatibilityV2" = "headOrHeartResultPageCompatibilityV2",
|
||
"headOrHeartResultPageCompatibilityV3" = "headOrHeartResultPageCompatibilityV3",
|
||
"headOrHeartResultPageCompatibilityV4" = "headOrHeartResultPageCompatibilityV4",
|
||
"compatibilityV1EmailEnter" = "compatibilityV1EmailEnter",
|
||
"compatibilityV2ScanHand" = "compatibilityV2ScanHand",
|
||
"preloadImages" = "preloadImages",
|
||
"scanHandTimeCompatibilityV2" = "scanHandTimeCompatibilityV2",
|
||
"compatibilityV2TimeForCameraInit" = "compatibilityV2TimeForCameraInit",
|
||
"compatibilityV2TrialTextPrice" = "v2-compatibility-trial-text-price",
|
||
"compatibilityV3TrialTextPrice" = "v3-compatibility-trial-text-price",
|
||
"compatibilityV4TrialTextPrice" = "v4-compatibility-trial-text-price",
|
||
"compatibilityV2TrialButton" = "v2-compatibility-trial-button",
|
||
"palmistryV1TrialTextPrice" = "v1-palmistry-trial-text-price",
|
||
"v2CompatibilityScanResultNumbers" = "v2-compatibility-scan-result-numbers",
|
||
"v2CompatibilityScanInstructionImage" = "v2-compatibility-scan-instruction-image",
|
||
"v2CompatibilityCameraTemplate" = "v2-compatibility-camera-template",
|
||
"v2CompatibilityRelationshipStatusPagePlacement" = "v2-compatibility-relationship-status-page-placement",
|
||
"v2CompatibilityReviewPage" = "v2-compatibility-review-page",
|
||
"v2CompatibilityPathToEnteringBirthdate" = "v2-compatibility-path-to-entering-birthdate",
|
||
}
|
||
|
||
interface IUseUnleashProps<T extends EUnleashFlags> {
|
||
flag: T;
|
||
}
|
||
|
||
interface IVariants {
|
||
[EUnleashFlags.genderPageType]: "v0" | "v1" | "v2";
|
||
[EUnleashFlags.zodiacImages]: "new" | "old";
|
||
[EUnleashFlags.dynamicHandsCompV2]: "show" | "hide";
|
||
[EUnleashFlags.dynamicHandsPalmistryV1]: "show" | "hide";
|
||
[EUnleashFlags.welcomePageImagePalmistryV1]: "v0" | "v1";
|
||
[EUnleashFlags.cameraRequestModalPalmistryV1]: "show" | "hide";
|
||
[EUnleashFlags.cameraRequestModalCompatibilityV2]: "show" | "hide";
|
||
[EUnleashFlags.darkThemePalmistryV1]: "enabled" | "disabled";
|
||
[EUnleashFlags.darkThemeCompatibilityV2]: "enabled" | "disabled";
|
||
[EUnleashFlags.paymentButtonLogic]: "old" | "new";
|
||
[EUnleashFlags.pageAfterTrialPaymentCompatibilityV2]: "paymentInformation" | "paymentForm";
|
||
[EUnleashFlags.pageAfterTrialPaymentCompatibilityV3]: "paymentInformation" | "paymentForm";
|
||
[EUnleashFlags.pageAfterTrialPaymentCompatibilityV4]: "paymentInformation" | "paymentForm";
|
||
[EUnleashFlags.pageAfterTrialPaymentPalmistryV1]: "paymentInformation" | "paymentForm";
|
||
[EUnleashFlags.paymentModalPage]: "v0" | "v1" | "v2";
|
||
[EUnleashFlags.headOrHeartResultPagePalmistryV1]: "v0" | "v1";
|
||
[EUnleashFlags.headOrHeartResultPageCompatibilityV2]: "v0" | "v1";
|
||
[EUnleashFlags.headOrHeartResultPageCompatibilityV3]: "v0" | "v1";
|
||
[EUnleashFlags.headOrHeartResultPageCompatibilityV4]: "v0" | "v1";
|
||
[EUnleashFlags.compatibilityV1EmailEnter]: "show" | "hide";
|
||
[EUnleashFlags.compatibilityV2ScanHand]: "show" | "hide";
|
||
[EUnleashFlags.preloadImages]: "yes" | "no";
|
||
[EUnleashFlags.scanHandTimeCompatibilityV2]: "v0" | "v1";
|
||
[EUnleashFlags.compatibilityV2TimeForCameraInit]: string;
|
||
[EUnleashFlags.compatibilityV2TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||
[EUnleashFlags.compatibilityV3TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||
[EUnleashFlags.compatibilityV4TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||
[EUnleashFlags.compatibilityV2TrialButton]: "v0" | "v1";
|
||
[EUnleashFlags.palmistryV1TrialTextPrice]: "v0" | "v1" | "v2" | "v3";
|
||
[EUnleashFlags.v2CompatibilityScanResultNumbers]: 'off' | 'on';
|
||
[EUnleashFlags.v2CompatibilityScanInstructionImage]: 'v0' | 'v1';
|
||
[EUnleashFlags.v2CompatibilityCameraTemplate]: 'v0' | 'v1' | 'v2' | 'v3' | 'v4';
|
||
[EUnleashFlags.v2CompatibilityRelationshipStatusPagePlacement]: 'v0' | 'v1' | 'v2';
|
||
[EUnleashFlags.v2CompatibilityReviewPage]: 'v0' | 'v1' | 'v2';
|
||
[EUnleashFlags.v2CompatibilityPathToEnteringBirthdate]: 'hide' | 'show';
|
||
}
|
||
|
||
/**
|
||
* Хук для получения значения A/B теста по флагу
|
||
* @template T - Тип флага из EUnleashFlags
|
||
* @returns Объект с информацией о готовности флага и его значении, типизированным в зависимости от переданного флага
|
||
*/
|
||
export const useUnleash = <T extends EUnleashFlags>({
|
||
flag
|
||
}: IUseUnleashProps<T>) => {
|
||
const { flagsReady } = useFlagsStatus();
|
||
const unleashClient = useUnleashClient();
|
||
const abVariant = useVariant(flag);
|
||
// const isEnabled = useFlag(flag);
|
||
const [searchParams] = useSearchParams();
|
||
const variantFromParams = searchParams.get(flag);
|
||
|
||
const isReady = useMemo(() => {
|
||
return flagsReady ?? true;
|
||
}, [flagsReady]);
|
||
|
||
const variant = useMemo(() => {
|
||
return variantFromParams || abVariant?.payload?.value || abVariant?.name;
|
||
}, [abVariant, variantFromParams]) as IVariants[T];
|
||
|
||
useEffect(() => {
|
||
unleashClient.on("impression", (impressionEvent: any) => {
|
||
if ("enabled" in impressionEvent && impressionEvent.enabled) {
|
||
window.gtag?.("event", "experiment_impression", {
|
||
app_name: impressionEvent.context.appName,
|
||
feature: impressionEvent.featureName,
|
||
treatment: impressionEvent.variant, // in case we use a variant for the control treatment
|
||
});
|
||
}
|
||
});
|
||
|
||
return () => {
|
||
unleashClient.off("impression");
|
||
}
|
||
}, [unleashClient]);
|
||
|
||
return useMemo(() => ({
|
||
isReady,
|
||
variant
|
||
}), [
|
||
isReady,
|
||
variant
|
||
]) as { isReady: boolean; variant: IVariants[T] };
|
||
}; |