()
| 14 | } |
| 15 | |
| 16 | function Home() { |
| 17 | const [convertedImages, setConvertedImages] = useState<ConvertedImage[]>([]); |
| 18 | const [isConverting, setIsConverting] = useState(false); |
| 19 | const [isDragging, setIsDragging] = useState(false); |
| 20 | const [isZipping, setIsZipping] = useState(false); |
| 21 | const [theme, setTheme] = useState<'light' | 'dark'>( |
| 22 | localStorage.getItem('theme') as 'light' | 'dark' || |
| 23 | (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') |
| 24 | ); |
| 25 | |
| 26 | useEffect(() => { |
| 27 | document.documentElement.classList.toggle('dark', theme === 'dark'); |
| 28 | localStorage.setItem('theme', theme); |
| 29 | }, [theme]); |
| 30 | |
| 31 | const toggleTheme = () => { |
| 32 | setTheme(prev => prev === 'light' ? 'dark' : 'light'); |
| 33 | }; |
| 34 | |
| 35 | const convertToWebP = useCallback(async (file: File): Promise<ConvertedImage> => { |
| 36 | const img = document.createElement('img'); |
| 37 | const imageUrl = URL.createObjectURL(file); |
| 38 | |
| 39 | return new Promise((resolve) => { |
| 40 | img.onload = () => { |
| 41 | const canvas = document.createElement('canvas'); |
| 42 | canvas.width = img.width; |
| 43 | canvas.height = img.height; |
| 44 | |
| 45 | const ctx = canvas.getContext('2d')!; |
| 46 | ctx.drawImage(img, 0, 0); |
| 47 | |
| 48 | const attemptConversion = (quality: number) => { |
| 49 | canvas.toBlob( |
| 50 | (blob) => { |
| 51 | if (blob) { |
| 52 | if(file.size > blob.size){ |
| 53 | resolve({ |
| 54 | originalName: file.name.replace(/\.[^/.]+$/, ''), |
| 55 | webpBlob: blob, |
| 56 | originalSize: file.size, |
| 57 | convertedSize: blob.size, |
| 58 | }); |
| 59 | }else{ |
| 60 | attemptConversion(quality - 0.1); |
| 61 | } |
| 62 | |
| 63 | } |
| 64 | URL.revokeObjectURL(imageUrl); |
| 65 | }, |
| 66 | 'image/webp', |
| 67 | quality |
| 68 | )}; |
| 69 | attemptConversion(0.8); |
| 70 | }; |
| 71 | |
| 72 | img.src = imageUrl; |
| 73 | }); |
nothing calls this directly
no test coverage detected