feat(v5): add user friendly error toasts

This commit is contained in:
2026-07-09 19:53:55 +08:00
parent 30e1d250ef
commit da390b8bd9
4 changed files with 45 additions and 7 deletions

View File

@@ -1,9 +1,18 @@
import { useEffect, useMemo, useState } from "react";
import { Toaster, toast } from "sonner";
import CanvasPane, { CanvasThumbnail } from "./components/CanvasPane.jsx";
import Controls from "./components/Controls.jsx";
import HistogramPanel from "./components/HistogramPanel.jsx";
import { applyStateOperation, combineStates, deleteState, getOperations, listStates, uploadImage } from "./lib/api.js";
function showErrorToast(error, fallback = "Something went wrong.") {
const message = error?.message || fallback;
toast.error(message, {
description: "Please check the selected image, operation, and parameters."
});
return message;
}
export default function App() {
const [session, setSession] = useState(null);
const [states, setStates] = useState([]);
@@ -26,7 +35,7 @@ export default function App() {
setParams({ _repeat: 1, ...Object.fromEntries(Object.entries(first.params || {}).map(([key, schema]) => [key, schema.default])) });
}
})
.catch((error) => setStatus(error.message));
.catch((error) => setStatus(showErrorToast(error, "Unable to load operations.")));
}, []);
async function refreshStates(sessionId, nextActiveId = null) {
@@ -51,7 +60,7 @@ export default function App() {
setTransform({ x: 0, y: 0, scale: 1 });
setStatus(`${payload.width} x ${payload.height} ${payload.color_mode} image loaded as S0.`);
} catch (error) {
setStatus(error.message);
setStatus(showErrorToast(error, "Unable to upload image."));
} finally {
setBusy(false);
}
@@ -76,7 +85,7 @@ export default function App() {
setSelectedStateIds([state.state_id]);
setStatus(`${state.label} created.`);
} catch (error) {
setStatus(error.message);
setStatus(showErrorToast(error, "Unable to apply operation."));
} finally {
setBusy(false);
}
@@ -92,7 +101,7 @@ export default function App() {
setSelectedStateIds([state.state_id]);
setStatus(`${state.label} created.`);
} catch (error) {
setStatus(error.message);
setStatus(showErrorToast(error, "Unable to combine states."));
} finally {
setBusy(false);
}
@@ -117,7 +126,7 @@ export default function App() {
setSelectedStateIds((current) => current.filter((id) => id !== state.state_id));
setStatus(`${state.label} deleted.`);
} catch (error) {
setStatus(error.message);
setStatus(showErrorToast(error, "Unable to delete state."));
} finally {
setBusy(false);
}
@@ -131,6 +140,7 @@ export default function App() {
return (
<div className="flex h-screen overflow-hidden bg-zinc-950 text-zinc-100">
<Toaster richColors theme="dark" position="top-right" closeButton />
<Controls
operations={operations}
selectedOperation={selectedOperation}