fix(POSTV1-07): 自动关闭编辑器操作提示
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run

This commit is contained in:
suyx
2026-08-05 18:01:03 +08:00
parent 9d2aa879e9
commit 468bb5579d
2 changed files with 51 additions and 29 deletions
+43 -29
View File
@@ -160,6 +160,20 @@ export function EditorPage({ projectId }: { projectId: string }) {
const conflictExportGuardRef = useRef(new ConflictExportGuard());
const candidateMenuRef = useRef<HTMLDivElement | null>(null);
const candidateTriggerRef = useRef<HTMLButtonElement | null>(null);
const noticeTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
function showNotice(message: string) {
if (noticeTimerRef.current) clearTimeout(noticeTimerRef.current);
setNotice(message);
noticeTimerRef.current = setTimeout(() => {
setNotice("");
noticeTimerRef.current = undefined;
}, 3_000);
}
useEffect(() => () => {
if (noticeTimerRef.current) clearTimeout(noticeTimerRef.current);
}, []);
useEffect(() => {
let active = true;
@@ -175,7 +189,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
setDraftAdjustments(initial.background.adjustments);
historyRef.current = new CanvasEditHistory(initial);
elementControllerRef.current = new CanvasElementController(initial);
}).catch(() => { if (active) setNotice("编辑器暂时无法读取项目"); });
}).catch(() => { if (active) showNotice("编辑器暂时无法读取项目"); });
return () => { active = false; };
}, [projectId]);
@@ -291,7 +305,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
function applyPreview() {
if (!canvasState) return;
commitCanvas(updateBackgroundAdjustments(canvasState, draftAdjustments));
setNotice("底图调整已提交");
showNotice("底图调整已提交");
}
function undo() {
@@ -334,9 +348,9 @@ export function EditorPage({ projectId }: { projectId: string }) {
const palette = await paletteForAsset(pendingBackground);
commitCanvas(switchBackground(canvasState, pendingBackground, palette));
setPendingBackground(undefined);
setNotice("已更换底图,覆盖元素保留,底图处理已重置");
showNotice("已更换底图,覆盖元素保留,底图处理已重置");
} catch {
setNotice("新底图无法读取,未更换底图或刷新色卡");
showNotice("新底图无法读取,未更换底图或刷新色卡");
}
}
@@ -353,7 +367,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
commitCanvas(next);
setGuides([]);
setCandidateMenu(undefined);
setNotice(message);
showNotice(message);
}
function addSticker(sticker: StaticStickerCatalogItem) {
@@ -369,8 +383,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
}));
commitElementOperation(controller, "贴纸已加入画布");
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
else setNotice("贴纸未能加入画布");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
else showNotice("贴纸未能加入画布");
}
}
@@ -383,8 +397,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
controller.add(createColorCardElement(definition, palette, newElementIdentity(), canvasState.elements.length));
commitElementOperation(controller, "色卡已按原始底图加入画布");
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
else setNotice("无法从原始底图稳定提取五色,色卡未加入画布");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
else showNotice("无法从原始底图稳定提取五色,色卡未加入画布");
}
}
@@ -394,7 +408,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
if (templateId === "DYN012") {
const font = fontOption("FONT081");
if (!font || await ensureFont(font.fontId, font.url) !== "ready") {
setNotice("DYN012 的 FONT081 替代字体不可用,未使用系统字体替代。");
showNotice("DYN012 的 FONT081 替代字体不可用,未使用系统字体替代。");
return;
}
}
@@ -407,8 +421,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
commitElementOperation(controller, "动态值已确认并加入画布");
setLocationDialog(undefined);
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
else setNotice("动态贴纸未能加入画布");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
else showNotice("动态贴纸未能加入画布");
}
}
@@ -456,7 +470,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
controller.replaceElement(overrideDynamicStickerValue(element, value));
commitElementOperation(controller, "动态贴纸显示文字已更新");
} catch {
setNotice("动态贴纸显示文字不能为空");
showNotice("动态贴纸显示文字不能为空");
}
}
@@ -480,7 +494,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
if (!template.fontUrl || !canvasState) return;
const status = await ensureFont(template.defaultFontId, template.fontUrl);
if (status !== "ready") {
setNotice("素材暂不可用,未使用系统字体替代。");
showNotice("素材暂不可用,未使用系统字体替代。");
return;
}
const controller = controllerForCurrent();
@@ -490,8 +504,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
commitElementOperation(controller, "文字模板已加入画布");
void recordRecentTextTemplate(template.templateId, template.resourceVersion);
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
else setNotice("文字模板未能加入画布");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
else showNotice("文字模板未能加入画布");
}
}
@@ -503,7 +517,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
action(edit);
return { ...current, draft: edit.value };
} catch {
setNotice("文字参数不在允许范围内");
showNotice("文字参数不在允许范围内");
return current;
}
});
@@ -514,7 +528,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
if (!template?.fontUrl) return;
const status = await ensureFont(template.defaultFontId, template.fontUrl);
if (status !== "ready") {
setNotice("素材暂不可用,未使用系统字体替代。");
showNotice("素材暂不可用,未使用系统字体替代。");
return;
}
updateTextDraft((edit) => edit.switchTemplate(templateId));
@@ -527,7 +541,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
}
const option = fontOption(fontId);
if (!option || await ensureFont(option.fontId, option.url) !== "ready") {
setNotice("字体素材暂不可用,未使用系统字体替代。");
showNotice("字体素材暂不可用,未使用系统字体替代。");
return;
}
updateTextDraft((edit) => edit.setStyle({ fontOverride: fontId }));
@@ -546,8 +560,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
void recordRecentTextTemplate(complete.template_or_asset_id, complete.resource_version);
}
} catch (error) {
if (error instanceof Error && error.message === "text_content_required") setNotice("请输入文字内容或删除该元素。");
else setNotice("文字编辑未能完成");
if (error instanceof Error && error.message === "text_content_required") showNotice("请输入文字内容或删除该元素。");
else showNotice("文字编辑未能完成");
}
}
@@ -556,7 +570,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
const current = canvasState.elements.find((element) => element.element_id === textEdit.elementId);
if (current) setTextEdit({ draft: structuredClone(current), elementId: current.element_id, originalTemplateId: current.template_or_asset_id });
}
setNotice("已取消未提交的文字修改");
showNotice("已取消未提交的文字修改");
}
function pendingTextDraft() {
@@ -624,7 +638,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
return;
}
const ran = await conflictExportGuardRef.current.run(() => executeExport(options));
if (!ran) setNotice("版本冲突时仅允许导出本页版本一次");
if (!ran) showNotice("版本冲突时仅允许导出本页版本一次");
}
async function retryExportDownload() {
@@ -639,8 +653,8 @@ export function EditorPage({ projectId }: { projectId: string }) {
action(controller);
commitElementOperation(controller, message);
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
else setNotice("对象操作未完成");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
else showNotice("对象操作未完成");
}
}
@@ -668,7 +682,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
opacityGestureRef.current = undefined;
if (gesture.last === gesture.base) return;
commitCanvas(gesture.last);
setNotice("贴纸透明度已提交");
showNotice("贴纸透明度已提交");
}
function duplicateSelection() {
@@ -688,7 +702,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
const controller = controllerForCurrent();
if (!controller || selectedIds.length === 0) return;
clipboardRef.current = controller.copySelected();
setNotice("已复制到画布剪贴板");
showNotice("已复制到画布剪贴板");
}
function pasteSelection() {
@@ -698,7 +712,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
controller.pasteElements(clipboardRef.current, () => newElementIdentity());
commitElementOperation(controller, "已粘贴画布对象");
} catch (error) {
if (error instanceof Error && error.message === "canvas_element_limit_reached") setNotice("画布最多 50 个元素,请先删除现有元素。");
if (error instanceof Error && error.message === "canvas_element_limit_reached") showNotice("画布最多 50 个元素,请先删除现有元素。");
}
}
@@ -728,7 +742,7 @@ export function EditorPage({ projectId }: { projectId: string }) {
const drag = dragRef.current;
if (!drag) return;
commitCanvas(drag.last);
setNotice("对象位置已提交");
showNotice("对象位置已提交");
setGuides([]);
dragRef.current = undefined;
}