feat: full HEIF/HEIC support, content-aware resize performance fix, UI improvements

- Add bidirectional HEIF support: decode (input) and encode (output) via system heif-convert/heif-enc
- Add server-side WebP preview generation for non-browser-previewable formats (HEIC, TIFF)
- Fix content-aware resize failing on HEIF input (decode before passing to caire)
- Fix content-aware resize timeout on large images by downscaling to max 1200px and using JPEG intermediate
- Add HEIF as target format in convert tool
- Add loading spinner for HEIF preview decode in file store
- Fix file picker not accepting HEIF files (explicit .heic,.heif,.hif extensions)
- Extend frontend timeout for medium tools to 180s with 45s progress animation
- Redesign rotate controls with preset buttons and compact flip section
- Remove misleading savings percentage from convert tool
This commit is contained in:
Siddharth Kumar Sah
2026-04-11 23:27:44 +08:00
parent e0869477d4
commit 6f5283019b
18 changed files with 425 additions and 86 deletions
+16 -2
View File
@@ -1,5 +1,6 @@
import { CATEGORIES, TOOLS } from "@stirling-image/shared";
import * as icons from "lucide-react";
import { Loader2 } from "lucide-react";
import { useCallback, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { ImageViewer } from "@/components/common/image-viewer";
@@ -12,8 +13,15 @@ import { useSettingsStore } from "@/stores/settings-store";
const QUICK_ACTION_IDS = ["resize", "compress", "convert", "remove-background"];
export function HomePage() {
const { setFiles, files, reset, originalBlobUrl, selectedFileName, selectedFileSize } =
useFileStore();
const {
setFiles,
files,
reset,
originalBlobUrl,
selectedFileName,
selectedFileSize,
currentEntry,
} = useFileStore();
const navigate = useNavigate();
const { fetch: fetchSettings } = useSettingsStore();
@@ -141,6 +149,12 @@ export function HomePage() {
<div className="flex-1 flex items-center justify-center p-6 min-h-0">
{files.length > 1 ? (
<MultiImageViewer />
) : currentEntry?.previewLoading ? (
<div className="flex flex-col items-center justify-center h-full gap-3 text-center">
<Loader2 className="h-8 w-8 text-muted-foreground animate-spin" />
<p className="text-sm text-muted-foreground">Generating preview...</p>
<p className="text-xs text-muted-foreground/60">{selectedFileName}</p>
</div>
) : originalBlobUrl ? (
<ImageViewer
src={originalBlobUrl}