mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-20 02:55:08 +08:00
- use stable sidebar list keys to avoid vnode reuse drift - sanitize persisted opened groups against current sidebar menu - guard non-array customization keys from localStorage Co-authored-by: Gargantua <22532097@zju.edu.cn>
This commit is contained in:
@@ -52,6 +52,21 @@ export function clearSidebarCustomization() {
|
||||
export function resolveSidebarItems(defaultItems, customization, options = {}) {
|
||||
const { cloneItems = false, assembleMoreGroup = false } = options;
|
||||
|
||||
const normalizeKeys = (keys = []) => {
|
||||
const list = Array.isArray(keys) ? keys : [];
|
||||
const deduped = [];
|
||||
const seen = new Set();
|
||||
|
||||
list.forEach((key) => {
|
||||
if (typeof key !== 'string') return;
|
||||
if (seen.has(key)) return;
|
||||
seen.add(key);
|
||||
deduped.push(key);
|
||||
});
|
||||
|
||||
return deduped;
|
||||
};
|
||||
|
||||
const all = new Map();
|
||||
const defaultMain = [];
|
||||
const defaultMore = [];
|
||||
@@ -70,9 +85,23 @@ export function resolveSidebarItems(defaultItems, customization, options = {}) {
|
||||
});
|
||||
|
||||
const hasCustomization = Boolean(customization);
|
||||
const mainKeys = hasCustomization ? customization.mainItems || [] : defaultMain;
|
||||
const moreKeys = hasCustomization ? customization.moreItems || [] : defaultMore;
|
||||
const used = hasCustomization ? new Set([...mainKeys, ...moreKeys]) : new Set(defaultMain.concat(defaultMore));
|
||||
let mainKeys = hasCustomization ? normalizeKeys(customization.mainItems || []) : [...defaultMain];
|
||||
let moreKeys = hasCustomization ? normalizeKeys(customization.moreItems || []) : [...defaultMore];
|
||||
|
||||
if (hasCustomization) {
|
||||
mainKeys = mainKeys.filter(title => all.has(title));
|
||||
moreKeys = moreKeys.filter(title => all.has(title));
|
||||
}
|
||||
|
||||
if (hasCustomization) {
|
||||
// 如果同一项同时出现在主区与更多区,主区优先。
|
||||
const mainSet = new Set(mainKeys);
|
||||
moreKeys = moreKeys.filter(title => !mainSet.has(title));
|
||||
}
|
||||
|
||||
const used = hasCustomization
|
||||
? new Set([...mainKeys, ...moreKeys])
|
||||
: new Set(defaultMain.concat(defaultMore));
|
||||
|
||||
const mainItems = mainKeys
|
||||
.map(title => all.get(title))
|
||||
@@ -119,7 +148,13 @@ export function resolveSidebarItems(defaultItems, customization, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
return { mainItems, moreItems, merged };
|
||||
return {
|
||||
mainItems,
|
||||
moreItems,
|
||||
merged,
|
||||
normalizedMainKeys: [...mainKeys],
|
||||
normalizedMoreKeys: [...moreKeys]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,9 +164,29 @@ export function resolveSidebarItems(defaultItems, customization, options = {}) {
|
||||
*/
|
||||
export function applySidebarCustomization(defaultItems) {
|
||||
const customization = getSidebarCustomization();
|
||||
const { merged } = resolveSidebarItems(defaultItems, customization, {
|
||||
const {
|
||||
merged,
|
||||
normalizedMainKeys,
|
||||
normalizedMoreKeys
|
||||
} = resolveSidebarItems(defaultItems, customization, {
|
||||
cloneItems: true,
|
||||
assembleMoreGroup: true
|
||||
});
|
||||
|
||||
if (customization) {
|
||||
const rawMainKeys = Array.isArray(customization.mainItems) ? customization.mainItems : [];
|
||||
const rawMoreKeys = Array.isArray(customization.moreItems) ? customization.moreItems : [];
|
||||
const hasChanged =
|
||||
JSON.stringify(rawMainKeys) !== JSON.stringify(normalizedMainKeys) ||
|
||||
JSON.stringify(rawMoreKeys) !== JSON.stringify(normalizedMoreKeys);
|
||||
|
||||
if (hasChanged) {
|
||||
setSidebarCustomization({
|
||||
mainItems: normalizedMainKeys,
|
||||
moreItems: normalizedMoreKeys
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return merged || defaultItems;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user