Various improvements & Epub support

This commit is contained in:
Stefan Hardegger
2025-08-08 14:09:14 +02:00
parent 090b858a54
commit 379c8c170f
37 changed files with 4069 additions and 298 deletions

View File

@@ -32,7 +32,8 @@ export default function ImageUpload({
if (rejection.errors?.[0]?.code === 'file-too-large') {
setError(`File is too large. Maximum size is ${maxSizeMB}MB.`);
} else if (rejection.errors?.[0]?.code === 'file-invalid-type') {
setError('Invalid file type. Please select an image file.');
const allowedTypes = accept.split(',').map(type => type.trim()).join(', ');
setError(`Invalid file type. Supported formats: ${allowedTypes.replace(/image\//g, '').toUpperCase()}.`);
} else {
setError('File rejected. Please try another file.');
}
@@ -41,18 +42,31 @@ export default function ImageUpload({
const file = acceptedFiles[0];
if (file) {
// Additional client-side validation for file type
const allowedTypes = accept.split(',').map(type => type.trim());
if (!allowedTypes.includes(file.type)) {
const supportedFormats = allowedTypes.map(type => type.replace('image/', '').toUpperCase()).join(', ');
setError(`Invalid file type. Your file is ${file.type}. Supported formats: ${supportedFormats}.`);
return;
}
// Create preview
const previewUrl = URL.createObjectURL(file);
setPreview(previewUrl);
onImageSelect(file);
}
}, [onImageSelect, maxSizeMB]);
}, [onImageSelect, maxSizeMB, accept]);
// Build proper accept object for dropzone based on specific MIME types
const acceptTypes = accept.split(',').map(type => type.trim());
const dropzoneAccept = acceptTypes.reduce((acc, type) => {
acc[type] = []; // Empty array means accept files with this MIME type
return acc;
}, {} as Record<string, string[]>);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
'image/*': accept.split(',').map(type => type.trim()),
},
accept: dropzoneAccept,
maxFiles: 1,
maxSize: maxSizeMB * 1024 * 1024, // Convert MB to bytes
});
@@ -123,7 +137,7 @@ export default function ImageUpload({
)}
</div>
<p className="text-sm text-gray-500">
Supports JPEG, PNG, WebP up to {maxSizeMB}MB
Supports {acceptTypes.map(type => type.replace('image/', '').toUpperCase()).join(', ')} up to {maxSizeMB}MB
</p>
</div>
)}