♻️ 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
+50 -12
View File
@@ -2,9 +2,17 @@
import type { Layer } from "@pien-studio/types";
import Image from "next/image";
import type { FaceDetectionOverlay, FacePreview } from "../../hooks/use-face-detection";
import type {
FaceDetectionOverlay,
FacePreview,
} from "../../hooks/use-face-detection";
import { useTranslations } from "../../hooks/use-translations";
import { panelClass, panelCounterClass, panelInsetClass, panelTitleClass } from "../../lib/theme";
import {
panelClass,
panelCounterClass,
panelInsetClass,
panelTitleClass,
} from "../../lib/theme";
type Props = {
isDark: boolean;
@@ -49,10 +57,20 @@ export function FacePanel({
return (
<div className={panelClass(isDark)}>
<div className="flex items-center justify-between">
<h2 className={`text-xs font-semibold uppercase tracking-wide ${panelTitleClass(isDark)}`}>{t("editor.faceTool")}</h2>
<span className={`rounded-full px-2 py-0.5 text-[10px] font-semibold ${panelCounterClass(isDark)}`}>{faceDetections.length}</span>
<h2
className={`text-xs font-semibold uppercase tracking-wide ${panelTitleClass(isDark)}`}
>
{t("editor.faceTool")}
</h2>
<span
className={`rounded-full px-2 py-0.5 text-[10px] font-semibold ${panelCounterClass(isDark)}`}
>
{faceDetections.length}
</span>
</div>
<p className={`mt-2 text-[11px] ${isDark ? "text-[#9aa1ad]" : "text-[#6b7280]"}`}>
<p
className={`mt-2 text-[11px] ${isDark ? "text-[#9aa1ad]" : "text-[#6b7280]"}`}
>
{faceStatus === "unsupported"
? t("editor.faceMlFailed")
: faceStatus === "detecting"
@@ -64,7 +82,9 @@ export function FacePanel({
: t("editor.facesDetected")}
</p>
{hasFaces ? (
<div className={`mt-3 max-h-[180px] space-y-1 overflow-auto rounded-md border p-1 ${panelInsetClass(isDark)}`}>
<div
className={`mt-3 max-h-[180px] space-y-1 overflow-auto rounded-md border p-1 ${panelInsetClass(isDark)}`}
>
{faceDetections.map((face, index) => (
<button
key={`face-result-${index}`}
@@ -79,12 +99,24 @@ export function FacePanel({
onClick={() => onToggleFaceIndex(index)}
>
{facePreviews[index]?.src ? (
<Image src={facePreviews[index].src} alt={`Face preview ${index + 1}`} width={40} height={40} unoptimized className="h-10 w-10 rounded object-cover" draggable={false} />
<Image
src={facePreviews[index].src}
alt={`Face preview ${index + 1}`}
width={40}
height={40}
unoptimized
className="h-10 w-10 rounded object-cover"
draggable={false}
/>
) : (
<div className={`h-10 w-10 rounded ${isDark ? "bg-white/10" : "bg-black/10"}`} />
<div
className={`h-10 w-10 rounded ${isDark ? "bg-white/10" : "bg-black/10"}`}
/>
)}
<div>
<p className="font-semibold">{t("editor.person")} {index + 1}</p>
<p className="font-semibold">
{t("editor.person")} {index + 1}
</p>
<p>{`${face.gender ?? t("editor.unknown")}${face.genderScore != null ? ` ${Math.round(face.genderScore * 100)}%` : ""}`}</p>
</div>
</button>
@@ -92,8 +124,12 @@ export function FacePanel({
</div>
) : null}
<div className={`mt-3 space-y-2 rounded-md border p-2 ${panelInsetClass(isDark)}`}>
<label className="block text-[11px] font-semibold">{t("editor.blurMethod")}</label>
<div
className={`mt-3 space-y-2 rounded-md border p-2 ${panelInsetClass(isDark)}`}
>
<label className="block text-[11px] font-semibold">
{t("editor.blurMethod")}
</label>
<div className="grid grid-cols-3 gap-1">
{[
{ id: "gaussian", label: t("editor.soft") },
@@ -110,7 +146,9 @@ export function FacePanel({
? "bg-white/10 text-[#d7dae0]"
: "bg-white text-[#1f2430]"
}`}
onClick={() => onSetBlurMethod(option.id as "gaussian" | "pixelate" | "censor")}
onClick={() =>
onSetBlurMethod(option.id as "gaussian" | "pixelate" | "censor")
}
>
{option.label}
</button>