update cancel upload function
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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="Предпросмотр загруженного изображения"
|
||||
|
||||
Reference in New Issue
Block a user