w-funnel/src/hooks/lottie/useLottie.ts
gofnnp fba0acaf0b payment
add payment
2025-10-06 22:51:32 +04:00

89 lines
2.3 KiB
TypeScript

"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Data } from "@lottiefiles/dotlottie-react";
import indexedDB, { EObjectStores } from "@/shared/utils/indexedDB";
import { ELottieKeys, lottieUrls } from "@/shared/constants/lottie";
interface IUseLottieProps {
preloadKey?: ELottieKeys;
loadKey?: ELottieKeys;
}
export const useLottie = ({ preloadKey, loadKey }: IUseLottieProps) => {
const [animationData, setAnimationData] = useState<Data>();
const [isError, setIsError] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const getAnimationDataFromLottie = async (key: ELottieKeys) => {
try {
const animation = await fetch(lottieUrls[key]);
if (!animation.ok) {
throw new Error(`HTTP error! status: ${animation.status}`);
}
const arrayBuffer = await animation.arrayBuffer();
return arrayBuffer;
} catch (error) {
console.error("Error loading animation:", error);
setIsError(true);
return null;
}
};
const preload = useCallback(async (key: ELottieKeys) => {
console.log("preload", key);
const arrayBuffer = await getAnimationDataFromLottie(key);
indexedDB.set(EObjectStores.Lottie, key, arrayBuffer);
}, []);
const load = useCallback(async (key: ELottieKeys) => {
setIsLoading(true);
setIsError(false);
try {
const animationFromDB = await indexedDB.get<ArrayBuffer>(
EObjectStores.Lottie,
key
);
if (animationFromDB) {
setAnimationData(animationFromDB);
setIsLoading(false);
return;
}
const arrayBuffer = await getAnimationDataFromLottie(key);
if (!arrayBuffer) {
setIsLoading(false);
return;
}
setAnimationData(arrayBuffer);
await indexedDB.set<ArrayBuffer>(EObjectStores.Lottie, key, arrayBuffer);
} catch (error) {
console.error("Error in load process:", error);
setIsError(true);
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
if (preloadKey) {
preload(preloadKey);
}
if (loadKey) {
load(loadKey);
}
}, [load, loadKey, preload, preloadKey]);
return useMemo(
() => ({
animationData,
isError,
isLoading,
}),
[animationData, isError, isLoading]
);
};