TuringToken/web/src/components/distributor/useSmoothUploadProgress.js

69 lines
2.4 KiB
JavaScript

/*
Copyright (C) 2025 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
*/
import { useEffect, useRef, useState } from 'react';
/** 代理申请上传:平滑展示 axios 进度,避免 0→99 无过渡 */
export function useSmoothUploadProgress(uploadPct) {
const [uploadDisplayPct, setUploadDisplayPct] = useState(null);
const uploadTargetRef = useRef(null);
const uploadDisplayRef = useRef(0);
const uploadSmoothRafRef = useRef(null);
uploadTargetRef.current = uploadPct;
useEffect(() => {
if (uploadPct == null) {
if (uploadSmoothRafRef.current != null) {
cancelAnimationFrame(uploadSmoothRafRef.current);
uploadSmoothRafRef.current = null;
}
uploadDisplayRef.current = 0;
setUploadDisplayPct(null);
return;
}
let cancelled = false;
const tick = () => {
if (cancelled) return;
const target = uploadTargetRef.current;
if (target == null) return;
const cur = uploadDisplayRef.current;
if (cur < target - 0.01) {
const next = Math.min(
target,
cur + Math.max(0.55, (target - cur) * 0.2),
);
uploadDisplayRef.current = next;
setUploadDisplayPct(Math.round(next));
uploadSmoothRafRef.current = requestAnimationFrame(tick);
} else if (cur > target + 0.01) {
uploadDisplayRef.current = target;
setUploadDisplayPct(Math.round(target));
uploadSmoothRafRef.current = requestAnimationFrame(tick);
} else {
uploadDisplayRef.current = target;
setUploadDisplayPct(Math.round(target));
uploadSmoothRafRef.current = null;
}
};
uploadSmoothRafRef.current = requestAnimationFrame(tick);
return () => {
cancelled = true;
if (uploadSmoothRafRef.current != null) {
cancelAnimationFrame(uploadSmoothRafRef.current);
uploadSmoothRafRef.current = null;
}
};
}, [uploadPct]);
return uploadDisplayPct;
}