update cancel upload function

This commit is contained in:
smanylov
2025-12-26 22:16:22 +07:00
parent a3bcccdf28
commit ab6e385984
2 changed files with 74 additions and 103 deletions
+1 -4
View File
@@ -102,17 +102,14 @@ export async function cancelUpload(udloadId: string) {
}
export async function chunkUpload(formData: FormData) {
console.log('chunkUpload');
try {
const response = await fetch(`${API_BASE_URL}/api/v1/files/chunk`, {
method: 'POST',
body: formData
});
console.log('chunkUpload fetch');
if (response.ok) {
let parsed = await response.json();
console.log('chunkUpload response.ok');
console.log(parsed);
if (parsed.message_desc === 'Upload cancelled successfully') {
return parsed.message_body;
+73 -99
View File
@@ -7,7 +7,7 @@ import { useTranslations } from 'next-intl';
import { useNavigationBlocker } from '@/app/hooks/useNavigationBlocker';
interface SelectedFile {
file: File;
preview: string;
preview: string | undefined;
name: string;
size: string;
dimensions?: {
@@ -39,6 +39,8 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile
const [isFileUploaded, setIsFileUploaded] = useState<boolean>(false);
const [uploadProgress, setUploadProgress] = useState<number>(0);
const isCancelledRef = useRef(false);
const t = useTranslations('Global');
let SUPPORTED_FORMATS: string[] = [];
@@ -150,55 +152,43 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile
setError(null);
return;
}
setUploadProgress(0);
setUploadId(null);
setError(null);
setIsFileUploaded(false)
setIsFileUploaded(false);
setUploadProgress(0);
const validation = validateFile(file);
if (!validation.isValid) {
setError(validation.errorMessage || t('unknown-validation-error'));
return;
}
try {
let dimensions = undefined;
if (fileType === "image") {
let dimensions = undefined;
if (fileType === "image") {
try {
dimensions = await getImageDimensions(file) as { width: number, height: number };
if (dimensions.width < 150 || dimensions.height < 150 ||
dimensions.width > 10000 || dimensions.height > 10000) {
setError(`${t('image-size')}: ${dimensions.width}x${dimensions.height}. ${t('acceptable-range')}: 150x150 - 10000x10000 ${t('pixels')}.`);
return;
}
} catch (err) {
setError(t('error-reading-image'));
return;
}
const objectUrl = URL.createObjectURL(file);
setSelectedFile({
file,
preview: objectUrl,
name: file.name,
size: `${(file.size / 1024 / 1024).toFixed(2)} MB`,
...(dimensions && { dimensions })
});
console.log('Файл обработан:', {
file: file,
name: file.name,
type: file.type,
size: file.size,
...(dimensions && { dimensions })
});
} catch (err) {
setError(t('error-processing-file'));
}
}, []);
setSelectedFile({
file,
name: file.name,
size: `${(file.size / 1024 / 1024).toFixed(2)} MB`,
dimensions,
preview: file.size < 10 * 1024 * 1024 ? URL.createObjectURL(file) : undefined
});
console.log('Файл выбран:', file.name, file.size);
}, [fileType, t]);
const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>): void => {
const file = event.target.files?.[0] || null;
@@ -233,7 +223,7 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile
};
const handleClearFile = async (): Promise<void> => {
if (selectedFile) {
if (selectedFile && selectedFile.preview) {
URL.revokeObjectURL(selectedFile.preview);
}
@@ -241,96 +231,80 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile
await cancelUpload(uploadId);
}
isCancelledRef.current = true;
setIsFileUploaded(false);
setSelectedFile(null);
setError(null);
setUploadProgress(0);
};
const handlerFileUpload = useCallback(async (file: SelectedFile): Promise<void> => {
if (uploadId) {
return;
};
const handlerFileUpload = useCallback(async (fileInfo: SelectedFile): Promise<void> => {
if (uploadId) return;
setError(null);
isCancelledRef.current = false;
const file = fileInfo.file;
try {
const extension = file.name.split('.').pop();
if (!extension) {
setError(t('file-has-no-extension'));
return;
}
const extension = file.name.split('.').pop() || '';
const initMessageBody = {
file_name: file.name,
file_type: fileType,
extension: extension,
file_size: file.file.size
file_size: file.size
};
const response = await fileUpload(initMessageBody) as FileUploadInitResponse;
if (response?.upload_id) {
setUploadId(response.upload_id);
const CHUNK_SIZE = response.chunk_size;
const totalChunks = response.total_chunks;
const fileSize = file.file.size;
let start = 0;
let chunkIndex = 0;
console.log('start upload');
console.log(`total chanks - ${totalChunks}`);
while (start < fileSize) {
console.log(`chank-${chunkIndex}`);
const end = Math.min(start + CHUNK_SIZE, fileSize);
const chunk = file.file.slice(start, end);
const formData = new FormData();
formData.append('upload_id', response.upload_id);
formData.append('chunk_number', chunkIndex.toString());
formData.append('chunk', chunk);
console.log(`init chunkUpload`);
const chunkResponse = await chunkUpload(formData);
console.log(`chunkResponse - ${chunkResponse}`);
if (chunkResponse.message_desc !== 'Chunk uploaded successfully') {
throw new Error('Er1: response error');
}
if (chunkIndex === totalChunks - 1) {
const chunkStatus = await checkChunkStatus(response.upload_id);
if (chunkStatus.message_body.missing_chunks === 0) {
setUploadId(null);
setIsFileUploaded(true);
} else {
throw new Error('Er2: not all chunks was uploaded');
}
}
start = end;
chunkIndex++;
setUploadProgress(Math.floor(chunkIndex / totalChunks * 100));
}
} else {
console.error(response);
if (!response?.upload_id) {
throw new Error('Failed to get upload_id');
}
} catch (error) {
setError(t('error-uploading-file'));
console.error('Chunk upload error:', error);
// Для дебага в production
if (error instanceof Error) {
console.error('Error name:', error.name);
console.error('Error message:', error.message);
if (error.cause) console.error('Error cause:', error.cause);
const CHUNK_SIZE = response.chunk_size;
const totalChunks = response.total_chunks;
setUploadId(response.upload_id);
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
if (isCancelledRef.current) {
return;
}
const start = chunkIndex * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('upload_id', response.upload_id);
formData.append('chunk_number', chunkIndex.toString());
formData.append('chunk', chunk);
const chunkResponse = await chunkUpload(formData);
if (chunkResponse.message_desc !== 'Chunk uploaded successfully') {
throw new Error(`Chunk ${chunkIndex} upload failed`);
}
setUploadProgress(Math.floor((chunkIndex + 1) / totalChunks * 100));
}
const chunkStatus = await checkChunkStatus(response.upload_id);
if (chunkStatus.message_body.missing_chunks === 0) {
setIsFileUploaded(true);
} else {
throw new Error('Not all chunks were uploaded');
}
} catch (error) {
if (!isCancelledRef.current) {
setError(t('error-uploading-file'));
console.error('Upload error:', error);
}
} finally {
setUploadId(null);
}
}, [uploadId, fileType]);
}, [uploadId, fileType, t]);
useEffect(() => {
// Обработка закрытия вкладки
@@ -462,7 +436,7 @@ export default function UploadSectionFile({ fileType, allowedExtensions, maxFile
</div>
</div>
{fileType === 'image' && (
{(fileType === 'image' && selectedFile.preview) && (
<img
src={selectedFile.preview}
alt="Предпросмотр загруженного изображения"