♻️ refactor!: massive refactor

This commit is contained in:
2026-05-31 03:04:30 +07:00
parent c1f12c7201
commit df3c944547
86 changed files with 3691 additions and 1129 deletions
+99 -30
View File
@@ -1,5 +1,10 @@
import React from "react";
import type { FaceBlurMethod, Layer, LayerEffect } from "@pien-studio/types";
import {
getLayerRuntimeSource,
type FaceBlurMethod,
type Layer,
type LayerEffect,
} from "@pien-studio/types";
import type { FaceDetectionOverlay } from "./use-face-detection";
type FaceBlurPreview = {
@@ -21,15 +26,31 @@ type UseFaceBlurWorkflowOptions = {
};
export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
const { selectedLayer, faceDetectionsLayerId, faceDetections, setLayerEffect, removeLayerEffect } = options;
const [blurMethod, setBlurMethod] = React.useState<FaceBlurMethod>("gaussian");
const {
selectedLayer,
faceDetectionsLayerId,
faceDetections,
setLayerEffect,
removeLayerEffect,
} = options;
const [blurMethod, setBlurMethod] =
React.useState<FaceBlurMethod>("gaussian");
const [blurAmount, setBlurAmount] = React.useState(14);
const [censorColor, setCensorColor] = React.useState("#111111");
const [faceSelection, setFaceSelection] = React.useState<FaceSelectionState | null>(null);
const hasDetectableSelection = Boolean(selectedLayer && selectedLayer.type === "raster" && faceDetectionsLayerId === selectedLayer.id);
const [faceSelection, setFaceSelection] =
React.useState<FaceSelectionState | null>(null);
const hasDetectableSelection = Boolean(
selectedLayer &&
selectedLayer.type === "raster" &&
faceDetectionsLayerId === selectedLayer.id,
);
const faceBlurEffect = React.useMemo(
() => selectedLayer?.effects.find((e): e is Extract<LayerEffect, { kind: "face-blur" }> => e.kind === "face-blur") ?? null,
() =>
selectedLayer?.effects.find(
(e): e is Extract<LayerEffect, { kind: "face-blur" }> =>
e.kind === "face-blur",
) ?? null,
[selectedLayer?.effects],
);
@@ -40,18 +61,25 @@ export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
return faceDetections.map((_, index) => index);
}, [faceDetections, faceBlurEffect, hasDetectableSelection]);
const selectedFaceIndices = faceSelection?.key === selectionKey ? faceSelection.indices : defaultSelectedFaceIndices;
const selectedFaceIndices =
faceSelection?.key === selectionKey
? faceSelection.indices
: defaultSelectedFaceIndices;
const buildBlurRegions = React.useCallback(
(indices: number[]) => {
if (!selectedLayer || selectedLayer.type !== "raster") return [];
if (faceDetectionsLayerId !== selectedLayer.id || faceDetections.length === 0) return [];
if (
faceDetectionsLayerId !== selectedLayer.id ||
faceDetections.length === 0
)
return [];
const indexSet = new Set(indices);
return faceDetections
.filter((_, index) => indexSet.has(index))
.map((face) => {
const baseWidth = Math.max(1, selectedLayer.width ?? face.sourceWidth);
const baseHeight = Math.max(1, selectedLayer.height ?? face.sourceHeight);
const baseWidth = Math.max(1, selectedLayer.width);
const baseHeight = Math.max(1, selectedLayer.height);
const scaleX = face.sourceWidth / baseWidth;
const scaleY = face.sourceHeight / baseHeight;
return {
@@ -68,13 +96,21 @@ export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
[censorColor, faceDetections, faceDetectionsLayerId, selectedLayer],
);
const toggleFaceIndex = React.useCallback((index: number) => {
setFaceSelection((prev) => {
const current = prev?.key === selectionKey ? prev.indices : defaultSelectedFaceIndices;
const indices = current.includes(index) ? current.filter((item) => item !== index) : [...current, index];
return { key: selectionKey, indices };
});
}, [defaultSelectedFaceIndices, selectionKey]);
const toggleFaceIndex = React.useCallback(
(index: number) => {
setFaceSelection((prev) => {
const current =
prev?.key === selectionKey
? prev.indices
: defaultSelectedFaceIndices;
const indices = current.includes(index)
? current.filter((item) => item !== index)
: [...current, index];
return { key: selectionKey, indices };
});
},
[defaultSelectedFaceIndices, selectionKey],
);
const clearBlur = React.useCallback(() => {
if (!selectedLayer) return;
@@ -84,8 +120,17 @@ export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
const blurFaces = React.useCallback(
(indices: number[]) => {
if (!selectedLayer || selectedLayer.type !== "raster" || !selectedLayer.sourceUri) return;
if (faceDetectionsLayerId !== selectedLayer.id || faceDetections.length === 0) return;
if (
!selectedLayer ||
selectedLayer.type !== "raster" ||
!getLayerRuntimeSource(selectedLayer)
)
return;
if (
faceDetectionsLayerId !== selectedLayer.id ||
faceDetections.length === 0
)
return;
const regions = buildBlurRegions(indices);
setLayerEffect(selectedLayer.id, {
kind: "face-blur",
@@ -97,11 +142,25 @@ export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
});
setFaceSelection({ key: selectionKey, indices: [] });
},
[blurAmount, blurMethod, buildBlurRegions, censorColor, faceDetections.length, faceDetectionsLayerId, selectedLayer, selectionKey, setLayerEffect],
[
blurAmount,
blurMethod,
buildBlurRegions,
censorColor,
faceDetections.length,
faceDetectionsLayerId,
selectedLayer,
selectionKey,
setLayerEffect,
],
);
const faceBlurPreview = React.useMemo<FaceBlurPreview | null>(() => {
if (!hasDetectableSelection || !selectedLayer || selectedLayer.type !== "raster") {
if (
!hasDetectableSelection ||
!selectedLayer ||
selectedLayer.type !== "raster"
) {
return null;
}
@@ -111,16 +170,26 @@ export function useFaceBlurWorkflow(options: UseFaceBlurWorkflowOptions) {
return {
layerId: selectedLayer.id,
effects: [{
kind: "face-blur",
enabled: true,
method: blurMethod,
amount: blurAmount,
regions: buildBlurRegions(selectedFaceIndices),
censorColor,
}],
effects: [
{
kind: "face-blur",
enabled: true,
method: blurMethod,
amount: blurAmount,
regions: buildBlurRegions(selectedFaceIndices),
censorColor,
},
],
};
}, [blurAmount, blurMethod, buildBlurRegions, censorColor, hasDetectableSelection, selectedFaceIndices, selectedLayer]);
}, [
blurAmount,
blurMethod,
buildBlurRegions,
censorColor,
hasDetectableSelection,
selectedFaceIndices,
selectedLayer,
]);
return {
blurMethod,