89 lines
2.3 KiB
TypeScript
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]
|
|
);
|
|
};
|