import { useState } from 'react'; import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { fetchFormats, uploadFiles } from '../api.js'; import { FileCard } from '../FileCard.jsx'; import { Dropzone } from '../components/Dropzone.jsx'; import { FileConfigCard } from '../components/FileConfigCard.jsx'; import { ReassuranceStrip } from '../components/ReassuranceStrip.jsx'; import { FormatsGrid } from '../components/FormatsGrid.jsx'; import { FormatMarquee } from '../components/FormatMarquee.jsx'; import { SeoHead } from '../components/SeoHead.jsx'; import { extensionOf } from '../utils/archiveExtensions.js'; import '../styles/home.css'; import '../styles/sections.css'; const DEFAULT_QUALITY = { jpg: 80, jpeg: 80, webp: 80, avif: 50, tiff: 80, png: 6, zip: 6, 'tar.gz': 6, 'tar.bz2': 9, '7z': 5, 'tar.7z': 5, mp3: 192, ogg: 192, aac: 192, m4a: 192, }; const DEFAULT_ICON_SIZE = 256; function defaultQualityFor(targetFormat) { return DEFAULT_QUALITY[targetFormat] ?? null; } export function HomePage() { const { lang } = useParams(); const { t } = useTranslation(); const [pendingFiles, setPendingFiles] = useState([]); const [submittedJobs, setSubmittedJobs] = useState([]); async function handleFilesSelected(fileList) { const files = Array.from(fileList); const withTargets = await Promise.all( files.map(async (file) => { const targets = await fetchFormats(extensionOf(file.name)); const targetFormat = targets[0] ?? null; return { file, targets, targetFormat, quality: defaultQualityFor(targetFormat), iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null, }; }) ); setPendingFiles((current) => [...current, ...withTargets]); } function updateTargetFormat(index, targetFormat) { setPendingFiles((current) => current.map((item, i) => i === index ? { ...item, targetFormat, quality: defaultQualityFor(targetFormat), iconSize: targetFormat === 'ico' ? DEFAULT_ICON_SIZE : null, } : item ) ); } function updateQuality(index, quality) { 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))); } function removePendingFile(index) { setPendingFiles((current) => current.filter((_, i) => i !== index)); } function removeSubmittedJob(index) { setSubmittedJobs((current) => current.filter((_, i) => i !== index)); } async function handleConvert() { const validItems = pendingFiles.filter((item) => item.targetFormat); const jobs = await uploadFiles(validItems); const jobsWithSize = jobs.map((job, i) => ({ ...job, size: validItems[i].file.size, targetFormat: validItems[i].targetFormat, })); setSubmittedJobs((current) => [...current, ...jobsWithSize]); setPendingFiles([]); } return ( <> {t('hero.kicker')} {t('hero.title')} {t('hero.subtitle')} {pendingFiles.length > 0 && ( {pendingFiles.map((item, index) => ( ))} {t('hero.convert')} )} {submittedJobs.map((job, index) => job.id ? ( removeSubmittedJob(index)} /> ) : ( removeSubmittedJob(index)} /> ) )} > ); }
{t('hero.subtitle')}