feat: add ICO size picker to the upload UI
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+37
-2
@@ -13,6 +13,8 @@ const DEFAULT_QUALITY = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QUALITY_FORMATS = ['jpg', 'jpeg', 'webp', 'avif', 'tiff'];
|
const QUALITY_FORMATS = ['jpg', 'jpeg', 'webp', 'avif', 'tiff'];
|
||||||
|
const ICON_SIZES = [16, 32, 48, 256, 512];
|
||||||
|
const DEFAULT_ICON_SIZE = 256;
|
||||||
|
|
||||||
function extensionOf(fileName) {
|
function extensionOf(fileName) {
|
||||||
return fileName.split('.').pop().toLowerCase();
|
return fileName.split('.').pop().toLowerCase();
|
||||||
@@ -32,7 +34,13 @@ export default function App() {
|
|||||||
files.map(async (file) => {
|
files.map(async (file) => {
|
||||||
const targets = await fetchFormats(extensionOf(file.name));
|
const targets = await fetchFormats(extensionOf(file.name));
|
||||||
const targetFormat = targets[0] ?? null;
|
const targetFormat = targets[0] ?? null;
|
||||||
return { file, targets, targetFormat, quality: defaultQualityFor(targetFormat) };
|
return {
|
||||||
|
file,
|
||||||
|
targets,
|
||||||
|
targetFormat,
|
||||||
|
quality: defaultQualityFor(targetFormat),
|
||||||
|
iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null,
|
||||||
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
setPendingFiles(withTargets);
|
setPendingFiles(withTargets);
|
||||||
@@ -41,7 +49,14 @@ export default function App() {
|
|||||||
function updateTargetFormat(index, targetFormat) {
|
function updateTargetFormat(index, targetFormat) {
|
||||||
setPendingFiles((current) =>
|
setPendingFiles((current) =>
|
||||||
current.map((item, i) =>
|
current.map((item, i) =>
|
||||||
i === index ? { ...item, targetFormat, quality: defaultQualityFor(targetFormat) } : item
|
i === index
|
||||||
|
? {
|
||||||
|
...item,
|
||||||
|
targetFormat,
|
||||||
|
quality: defaultQualityFor(targetFormat),
|
||||||
|
iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null,
|
||||||
|
}
|
||||||
|
: item
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -50,6 +65,10 @@ export default function App() {
|
|||||||
setPendingFiles((current) => current.map((item, i) => (i === index ? { ...item, quality } : item)));
|
setPendingFiles((current) => current.map((item, i) => (i === index ? { ...item, quality } : item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateIconSize(index, iconSize) {
|
||||||
|
setPendingFiles((current) => current.map((item, i) => (i === index ? { ...item, iconSize } : item)));
|
||||||
|
}
|
||||||
|
|
||||||
async function handleConvert() {
|
async function handleConvert() {
|
||||||
const validItems = pendingFiles.filter((item) => item.targetFormat);
|
const validItems = pendingFiles.filter((item) => item.targetFormat);
|
||||||
const jobs = await uploadFiles(validItems);
|
const jobs = await uploadFiles(validItems);
|
||||||
@@ -108,6 +127,22 @@ export default function App() {
|
|||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{item.targetFormat === 'ico' && (
|
||||||
|
<label>
|
||||||
|
Taille de l'icône
|
||||||
|
<select
|
||||||
|
value={item.iconSize ?? DEFAULT_ICON_SIZE}
|
||||||
|
onChange={(event) => updateIconSize(index, Number(event.target.value))}
|
||||||
|
>
|
||||||
|
{ICON_SIZES.map((size) => (
|
||||||
|
<option key={size} value={size}>
|
||||||
|
{size}px
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
|
||||||
{item.targetFormat === 'pdf' && (
|
{item.targetFormat === 'pdf' && (
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ export async function uploadFiles(items) {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
const targetFormats = [];
|
const targetFormats = [];
|
||||||
const qualities = [];
|
const qualities = [];
|
||||||
|
const iconSizes = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
formData.append('files', item.file);
|
formData.append('files', item.file);
|
||||||
targetFormats.push(item.targetFormat);
|
targetFormats.push(item.targetFormat);
|
||||||
qualities.push(item.quality ?? null);
|
qualities.push(item.quality ?? null);
|
||||||
|
iconSizes.push(item.iconSize ?? null);
|
||||||
}
|
}
|
||||||
formData.append('targetFormats', JSON.stringify(targetFormats));
|
formData.append('targetFormats', JSON.stringify(targetFormats));
|
||||||
formData.append('qualities', JSON.stringify(qualities));
|
formData.append('qualities', JSON.stringify(qualities));
|
||||||
|
formData.append('iconSizes', JSON.stringify(iconSizes));
|
||||||
|
|
||||||
const response = await fetch('/api/jobs', { method: 'POST', body: formData });
|
const response = await fetch('/api/jobs', { method: 'POST', body: formData });
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|||||||
Reference in New Issue
Block a user