chat / client /src /hooks /Messages /useProgress.ts
helloya20's picture
Upload 2345 files
f0743f4 verified
import { useState, useEffect, useMemo, useCallback } from 'react';
export default function useProgress(initialProgress = 0.01, increment = 0.007, fileSize?: number) {
const calculateIncrement = useCallback(
(size?: number) => {
const baseRate = 0.05;
const minRate = 0.002;
const sizeMB = size ? size / (1024 * 1024) : 0;
if (!size) {
return increment;
}
if (sizeMB <= 1) {
return baseRate * 2;
} else {
return Math.max(baseRate / Math.sqrt(sizeMB), minRate);
}
},
[increment],
);
const incrementValue = useMemo(
() => calculateIncrement(fileSize),
[fileSize, calculateIncrement],
);
const [progress, setProgress] = useState(initialProgress);
const getDynamicIncrement = useCallback(
(currentProgress: number) => {
if (!fileSize) {
return incrementValue;
}
if (currentProgress < 0.7) {
return incrementValue;
} else {
return Math.max(0.0005, incrementValue * (1 - currentProgress));
}
},
[incrementValue, fileSize],
);
useEffect(() => {
let timeout: ReturnType<typeof setTimeout>;
let timer: ReturnType<typeof setInterval>;
if (initialProgress >= 1 && progress >= 1) {
return;
} else if (initialProgress >= 1 && progress < 1) {
setProgress(0.99);
timeout = setTimeout(() => {
setProgress(1);
}, 200);
} else {
timer = setInterval(() => {
setProgress((prevProgress) => {
if (prevProgress >= 1) {
clearInterval(timer);
return 1;
}
const currentIncrement = getDynamicIncrement(prevProgress);
return Math.min(prevProgress + currentIncrement, 0.95);
});
}, 200);
}
return () => {
clearInterval(timer);
clearTimeout(timeout);
};
}, [progress, initialProgress, incrementValue, fileSize, getDynamicIncrement]);
return progress;
}