feat: more tests, refactored

This commit is contained in:
2026-05-24 21:05:21 +07:00
parent e7dd9420e7
commit c1f12c7201
33 changed files with 1403 additions and 334 deletions
+17 -21
View File
@@ -14,7 +14,7 @@ import { ToolRail } from "../../../components/editor/tool-rail";
import { exportProjectAsPng } from "../../../lib/export-png";
import { floodFillDataUrl } from "../../../lib/flood-fill";
import { commitStroke, type BrushStroke } from "../../../lib/brush-painter";
import { createEditorToolControllers } from "../../../lib/editor-tool-controller";
import type { EditorToolController } from "../../../lib/editor-tool-controller";
import { useFaceDetection } from "../../../hooks/use-face-detection";
import { useFaceBlurWorkflow } from "../../../hooks/use-face-blur-workflow";
import { useEditorAutosave } from "../../../hooks/use-editor-autosave";
@@ -111,7 +111,7 @@ export default function EditorPage() {
width: selectedLayer.width,
height: selectedLayer.height,
};
}, [selectedLayer?.id, selectedLayer?.type, selectedLayer?.sourceUri, selectedLayer?.width, selectedLayer?.height]);
}, [selectedLayer]);
const isLayerStillSelected = React.useCallback((layerId: string) => {
const state = useEditorStore.getState();
@@ -120,7 +120,6 @@ export default function EditorPage() {
const { faceDetections, faceDetectionsLayerId, facePreviews, faceStatus } = useFaceDetection({
tool,
selectedLayerId,
selectedImageLayer,
activeLayerStillSelected: isLayerStillSelected,
});
@@ -173,7 +172,7 @@ export default function EditorPage() {
const handleExportPng = React.useCallback(async () => {
await exportProjectAsPng(project, { isDark });
}, [isDark, project, exportProjectAsPng]);
}, [isDark, project]);
const handleExportProjectFile = React.useCallback(() => {
const json = exportProjectToJson();
@@ -219,6 +218,7 @@ export default function EditorPage() {
}
function handleCanvasApply(width: number, height: number, aspect: AspectRatio) {
void aspect;
setCanvasSize(width, height);
}
@@ -271,23 +271,19 @@ export default function EditorPage() {
addCanvasSizedLayer(canvas.toDataURL("image/png"), "Layer");
}, [cw, ch, addCanvasSizedLayer]);
const toolControllers = React.useMemo(
() =>
createEditorToolControllers({
onAddTextLayer: () => addLayerByType("text"),
onImportImage: () => imageInputRef.current?.click(),
labels: {
pointer: t("editor.toolPointer"),
pan: t("editor.toolPan"),
face: t("editor.toolFace"),
fill: t("editor.toolFill"),
brush: t("editor.toolBrush"),
text: t("editor.toolText"),
image: t("editor.toolImage"),
},
}),
[addLayerByType, t],
);
const handleImportImageClick = React.useCallback(() => {
imageInputRef.current?.click();
}, []);
const toolControllers = React.useMemo<EditorToolController[]>(() => [
{ kind: "mode", id: "pointer", label: t("editor.toolPointer") },
{ kind: "mode", id: "hand", label: t("editor.toolPan") },
{ kind: "mode", id: "face", label: t("editor.toolFace") },
{ kind: "mode", id: "fill", label: t("editor.toolFill") },
{ kind: "mode", id: "brush", label: t("editor.toolBrush") },
{ kind: "action", id: "add-text", label: t("editor.toolText"), run: () => addLayerByType("text") },
{ kind: "action", id: "import-image", label: t("editor.toolImage"), run: handleImportImageClick },
], [addLayerByType, handleImportImageClick, t]);
const canvasBindings = {
onMoveLayer: (_id: string, x: number, y: number) => setSelectedLayerPositionDraft(x, y),
+8 -2
View File
@@ -30,9 +30,15 @@ export default function HomePage() {
}, []);
React.useEffect(() => {
let canceled = false;
hydrate();
void refreshProjects();
}, [hydrate, refreshProjects]);
loadProjects().then((loadedProjects) => {
if (!canceled) setProjects(loadedProjects);
});
return () => {
canceled = true;
};
}, [hydrate]);
function openProject(project: Project) {
setProject(project);