Compare commits
No commits in common. "9d82ed43d9e95520ba99934035d4ad274342cdf2" and "ec2475a323a78ef493ea73b1088fc97644b823f4" have entirely different histories.
9d82ed43d9
...
ec2475a323
|
|
@ -49,12 +49,6 @@ function parseStoredSkills(raw: string | null): SkillData[] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSkillsByIdsFromList(skills: SkillData[], skillIds: string[]): SkillData[] {
|
|
||||||
if (skillIds.length === 0) return skills;
|
|
||||||
const idSet = new Set(skillIds.map((id) => String(id)));
|
|
||||||
return skills.filter((skill) => !idSet.has(String(skill.skill_id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook 返回类型
|
// Hook 返回类型
|
||||||
interface UseIframeSkillReturn {
|
interface UseIframeSkillReturn {
|
||||||
selectedSkill: SkillData | null;
|
selectedSkill: SkillData | null;
|
||||||
|
|
@ -87,45 +81,6 @@ export function useIframeSkill(
|
||||||
const [selectedSkills, setSelectedSkills] = useState<SkillData[]>([]);
|
const [selectedSkills, setSelectedSkills] = useState<SkillData[]>([]);
|
||||||
const [isBootstrapping, setIsBootstrapping] = useState(false);
|
const [isBootstrapping, setIsBootstrapping] = useState(false);
|
||||||
|
|
||||||
const removeFailedSkills = useCallback(
|
|
||||||
(skillIds: string[]) => {
|
|
||||||
if (skillIds.length === 0) return;
|
|
||||||
|
|
||||||
// 1) 回滚内存状态:移除失败 skill,避免展示错误 tag
|
|
||||||
setSelectedSkills((prev) => {
|
|
||||||
const next = removeSkillsByIdsFromList(prev, skillIds);
|
|
||||||
setSelectedSkill(next[0] ?? null);
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2) 回滚 localStorage(latest + thread)
|
|
||||||
const latestSkills = parseStoredSkills(
|
|
||||||
window.localStorage.getItem(STORAGE_KEYS.latest),
|
|
||||||
);
|
|
||||||
const nextLatestSkills = removeSkillsByIdsFromList(latestSkills, skillIds);
|
|
||||||
if (nextLatestSkills.length > 0) {
|
|
||||||
window.localStorage.setItem(
|
|
||||||
STORAGE_KEYS.latest,
|
|
||||||
JSON.stringify(nextLatestSkills),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
window.localStorage.removeItem(STORAGE_KEYS.latest);
|
|
||||||
}
|
|
||||||
|
|
||||||
const threadKey = getThreadStorageKey(threadId);
|
|
||||||
if (threadKey) {
|
|
||||||
const threadSkills = parseStoredSkills(window.localStorage.getItem(threadKey));
|
|
||||||
const nextThreadSkills = removeSkillsByIdsFromList(threadSkills, skillIds);
|
|
||||||
if (nextThreadSkills.length > 0) {
|
|
||||||
window.localStorage.setItem(threadKey, JSON.stringify(nextThreadSkills));
|
|
||||||
} else {
|
|
||||||
window.localStorage.removeItem(threadKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[threadId],
|
|
||||||
);
|
|
||||||
|
|
||||||
// 1. 监听 query 参数变化(临时禁用)
|
// 1. 监听 query 参数变化(临时禁用)
|
||||||
// TODO: 当前 skill 仅通过 iframe postMessage 传递,暂不从 URL 读取 skill_id/title。
|
// TODO: 当前 skill 仅通过 iframe postMessage 传递,暂不从 URL 读取 skill_id/title。
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|
@ -268,8 +223,6 @@ export function useIframeSkill(
|
||||||
toast.dismiss("suggest-skill-bootstrap");
|
toast.dismiss("suggest-skill-bootstrap");
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
const failedIds = selectedSkills.map((item) => String(item.id).trim());
|
|
||||||
removeFailedSkills(failedIds);
|
|
||||||
toast.error(`技能「${title}」加载失败`, {
|
toast.error(`技能「${title}」加载失败`, {
|
||||||
description: result.message || "未知错误",
|
description: result.message || "未知错误",
|
||||||
});
|
});
|
||||||
|
|
@ -290,8 +243,6 @@ export function useIframeSkill(
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const failedIds = selectedSkills.map((item) => String(item.id).trim());
|
|
||||||
removeFailedSkills(failedIds);
|
|
||||||
toast.dismiss("suggest-skill-bootstrap");
|
toast.dismiss("suggest-skill-bootstrap");
|
||||||
const message =
|
const message =
|
||||||
error instanceof Error ? error.message : "网络请求失败";
|
error instanceof Error ? error.message : "网络请求失败";
|
||||||
|
|
@ -303,7 +254,7 @@ export function useIframeSkill(
|
||||||
setIsBootstrapping(false);
|
setIsBootstrapping(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[removeFailedSkills, searchParams, sendSelectSkill, threadId],
|
[searchParams, sendSelectSkill, threadId],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 打开 skill 选择对话框
|
// 打开 skill 选择对话框
|
||||||
|
|
|
||||||
|
|
@ -411,12 +411,6 @@
|
||||||
--container-width-lg: calc(var(--spacing) * 256);
|
--container-width-lg: calc(var(--spacing) * 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", ui-sans-serif,
|
|
||||||
system-ui, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
Streamdown Markdown Styles
|
Streamdown Markdown Styles
|
||||||
使用 data-streamdown 属性选择器统一定义
|
使用 data-streamdown 属性选择器统一定义
|
||||||
|
|
@ -458,9 +452,9 @@ pre {
|
||||||
font-size: calc(16px * var(--zoom-scale));
|
font-size: calc(16px * var(--zoom-scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 代码块 - 14px */
|
/* 二三级标题 - 16px */
|
||||||
[data-streamdown="code-block"] pre {
|
[data-streamdown="code-block"] pre {
|
||||||
font-size: calc(14px * var(--zoom-scale));
|
font-size: calc(16px * var(--zoom-scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-line {
|
.cm-line {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue