import { useState, useRef, useEffect, useCallback } from "react"; import { compressImage } from "../utils/compressImage"; import { API_URL } from "../config/authConstants"; const MAX_SIZE_MB = 5; export const ACCEPT = "image/jpeg,image/png,image/webp"; let idCounter = 0; const nextId = () => `img-${++idCounter}-${Date.now()}`; export function useImageUpload(existingUrls = []) { const [images, setImages] = useState([]); const [imgError, setImgError] = useState(""); const [compressing, setCompressing] = useState(false); const fileInputRef = useRef(null); const existingUrlList = Array.isArray(existingUrls) ? existingUrls : []; useEffect(() => { if (existingUrlList.length > 0) { setImages(existingUrlList.map((url, i) => ({ id: `existing-${i}`, file: null, preview: `${API_URL}${url}`, isExisting: true, serverUrl: url, }))); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleFileChange = useCallback(async (e) => { const files = Array.from(e.target.files || []); if (!files.length) return; setImgError(""); for (const file of files) { if (!file.type.startsWith("image/")) { setImgError("Только изображения (JPEG, PNG, WebP)"); return; } if (file.size > MAX_SIZE_MB * 1024 * 1024) { setImgError(`Файл слишком большой — максимум ${MAX_SIZE_MB} МБ`); return; } } setCompressing(true); try { const compressedFiles = await Promise.all(files.map(f => compressImage(f))); const newImages = compressedFiles.map(file => ({ id: nextId(), file, preview: URL.createObjectURL(file), isExisting: false, serverUrl: null, })); setImages(prev => [...prev, ...newImages]); } catch { setImgError("Не удалось обработать изображение"); } finally { setCompressing(false); if (fileInputRef.current) fileInputRef.current.value = ""; } }, []); const removeImage = useCallback((id) => { setImages(prev => { const img = prev.find(i => i.id === id); if (img && !img.isExisting && img.preview) { URL.revokeObjectURL(img.preview); } return prev.filter(i => i.id !== id); }); }, []); const getFilesForUpload = useCallback(() => { return images.filter(i => !i.isExisting).map(i => i.file); }, [images]); const getExistingUrlsToKeep = useCallback(() => { return images.filter(i => i.isExisting).map(i => i.serverUrl); }, [images]); useEffect(() => { return () => { images.forEach(img => { if (!img.isExisting && img.preview) { URL.revokeObjectURL(img.preview); } }); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { images, imgError, compressing, fileInputRef, handleFileChange, removeImage, getFilesForUpload, getExistingUrlsToKeep, }; }