fix: restore psd text layer inline editing
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-29 09:47:21 +08:00
parent 6d281e950a
commit a8e5252241

View File

@ -200,6 +200,7 @@ export function AgentPsdTemplateEditorDialog({
const previewViewportRef = useRef<HTMLDivElement | null>(null);
const uploadInputRef = useRef<HTMLInputElement | null>(null);
const inlineTextEditorRef = useRef<HTMLTextAreaElement | null>(null);
const selectedTemplate = useMemo(
() => templates.find((template) => template.id === selectedTemplateId) || null,
@ -234,6 +235,20 @@ export function AgentPsdTemplateEditorDialog({
() => orderedPreviewLayers.filter((layer) => layer.isEditable),
[orderedPreviewLayers]
);
const orderedEditableImageLayers = useMemo(
() =>
orderedEditableLayers.filter(
(layer): layer is AgentPsdTemplateImageLayerSlot => isAgentPsdImageLayerSlot(layer)
),
[orderedEditableLayers]
);
const orderedEditableTextLayers = useMemo(
() =>
orderedEditableLayers.filter(
(layer): layer is AgentPsdTemplateTextLayerSlot => isAgentPsdTextLayerSlot(layer)
),
[orderedEditableLayers]
);
const shouldShowCompositeFallback = useMemo(
() => orderedPreviewLayers.some((layer) => !String(layer.sourceUrl || "").trim()),
[orderedPreviewLayers]
@ -329,6 +344,23 @@ export function AgentPsdTemplateEditorDialog({
};
}, [selectedTemplate]);
useEffect(() => {
if (!selectedTextLayer) {
return;
}
const textarea = inlineTextEditorRef.current;
if (!textarea) {
return;
}
requestAnimationFrame(() => {
textarea.focus();
const valueLength = textarea.value.length;
textarea.setSelectionRange(valueLength, valueLength);
});
}, [selectedTextLayer?.id]);
async function handleSlotUpload(slotId: string, event: ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0];
if (!file) return;
@ -628,11 +660,45 @@ export function AgentPsdTemplateEditorDialog({
</div>
<div className="absolute inset-0">
{orderedEditableLayers.map((layer) => {
{orderedEditableImageLayers.map((layer) => {
const isSelected = selectedLayerId === layer.id;
const frameStyle = getLayerFrameStyle(layer, isSelected);
const hasAssignedImage = Boolean(
String(effectiveImageAssignments[layer.id] || "").trim()
);
return (
<button
key={layer.id}
type="button"
onClick={() => setSelectedLayerId(layer.id)}
className="absolute overflow-hidden rounded-lg transition-all"
style={{
...frameStyle,
zIndex: isSelected ? 20 : 10,
background: isSelected ? "rgba(249,115,22,0.08)" : "transparent",
}}
aria-label={`${getLayerLabel(layer)} ${layer.layerName}`}
title={`${getLayerLabel(layer)}:${layer.layerName}`}
>
<div className="absolute left-2 top-2 rounded-full bg-black/70 px-2 py-1 text-[11px] text-white">
{layer.layerName}
</div>
{!hasAssignedImage ? (
<div className="pointer-events-none absolute bottom-2 right-2 rounded-full bg-orange-500/85 px-2 py-1 text-[11px] text-white">
点击替换图片
</div>
) : null}
</button>
);
})}
{orderedEditableTextLayers.map((layer) => {
const isSelected = selectedLayerId === layer.id;
const frameStyle = getLayerFrameStyle(layer, isSelected);
if (isAgentPsdTextLayerSlot(layer) && isSelected) {
if (isSelected) {
return (
<div
key={layer.id}
@ -644,6 +710,7 @@ export function AgentPsdTemplateEditorDialog({
}}
>
<textarea
ref={inlineTextEditorRef}
value={effectiveTextAssignments[layer.id] || ""}
onChange={(event) =>
setTextAssignments((current) => ({
@ -661,24 +728,17 @@ export function AgentPsdTemplateEditorDialog({
);
}
const hasAssignedImage =
isAgentPsdImageLayerSlot(layer) &&
Boolean(String(effectiveImageAssignments[layer.id] || "").trim());
return (
<button
key={layer.id}
type="button"
onClick={() => setSelectedLayerId(layer.id)}
onDoubleClick={() => setSelectedLayerId(layer.id)}
className="absolute overflow-hidden rounded-lg transition-all"
style={{
...frameStyle,
zIndex: isSelected ? 35 : 30,
background: isSelected
? isAgentPsdImageLayerSlot(layer)
? "rgba(249,115,22,0.08)"
: "rgba(56,189,248,0.05)"
: "transparent",
zIndex: isSelected ? 40 : 30,
background: isSelected ? "rgba(56,189,248,0.05)" : "transparent",
}}
aria-label={`${getLayerLabel(layer)} ${layer.layerName}`}
title={`${getLayerLabel(layer)}:${layer.layerName}`}
@ -687,17 +747,9 @@ export function AgentPsdTemplateEditorDialog({
{layer.layerName}
</div>
{isAgentPsdImageLayerSlot(layer) ? (
!hasAssignedImage ? (
<div className="pointer-events-none absolute bottom-2 right-2 rounded-full bg-orange-500/85 px-2 py-1 text-[11px] text-white">
点击替换图片
</div>
) : null
) : (
<div className="pointer-events-none absolute bottom-2 right-2 rounded-full bg-sky-500/85 px-2 py-1 text-[11px] text-white">
点击编辑文字
</div>
)}
<div className="pointer-events-none absolute bottom-2 right-2 rounded-full bg-sky-500/85 px-2 py-1 text-[11px] text-white">
点击编辑文字
</div>
</button>
);
})}