diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7cdf312..5937be3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -30,6 +30,7 @@ function App() { const [openMenuVisible, setOpenMenuVisible] = useState(false); const [exportMenuVisible, setExportMenuVisible] = useState(false); const canvasRef = useRef(null); + const [exportProgress, setExportProgress] = useState({ current: 0, total: 0 }); useBackgroundProcessor(); const { updateState, dismissUpdateError, triggerUpdate, restartApp } = useUpdater(); @@ -79,7 +80,8 @@ function App() { showToast, profile: settings.profile, visibility: settings.visibility, - globalJpegQuality: settings.globalJpegQuality + globalJpegQuality: settings.globalJpegQuality, + onProgress: (current, total) => setExportProgress({ current, total }) }); useEffect(() => { @@ -218,7 +220,12 @@ function App() { }}>

ExifFrame

- {updateState.stage !== 'idle' && (() => { + {exportProgress.total > 0 ? ( + + ) : updateState.stage !== 'idle' && (() => { const { stage, version, downloadPct, errorMessage, releaseNotes } = updateState; if (stage === 'checking') { return ( diff --git a/frontend/src/hooks/useExport.ts b/frontend/src/hooks/useExport.ts index a723e6b..904b909 100644 --- a/frontend/src/hooks/useExport.ts +++ b/frontend/src/hooks/useExport.ts @@ -17,6 +17,8 @@ export interface UseExportProps { profile: string; visibility: MetadataVisibility; globalJpegQuality: string; + + onProgress?: (current: number, total: number) => void; } const uploadCanvasBlob = async ( @@ -59,7 +61,7 @@ const uploadCanvasBlob = async ( export function useExport({ canvasRef, imageObj, currentImage, importedImages, isSelectingRef, setIsSelecting, showToast, - profile, visibility, globalJpegQuality + profile, visibility, globalJpegQuality, onProgress }: UseExportProps) { const downloadImage = async () => { @@ -117,8 +119,19 @@ export function useExport({ let successCount = 0; let failCount = 0; + const safeOnProgress = (current: number, total: number) => { + if (onProgress) { + try { + onProgress(current, total); + } catch (e) { + console.error("onProgress failed:", e); + } + } + }; + try { showToast("Exporting images..."); + safeOnProgress(0, importedImages.length); for (let i = 0; i < importedImages.length; i++) { const imgState = importedImages[i]; @@ -186,6 +199,7 @@ export function useExport({ if (imgToDraw && !imgState.imageObj) { imgToDraw.src = ""; } + safeOnProgress(i + 1, importedImages.length); } } @@ -201,6 +215,7 @@ export function useExport({ } finally { setIsSelecting(false); isSelectingRef.current = false; + safeOnProgress(0, 0); // Reset progress } };