mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-09-20 21:50:11 +08:00
fix: PR 审查真实缺陷修复(图标错位/定时器清理/并发/统计同步)
- AppDetailModal: iconPath 改用 viewingOrigin 动态计算,修复合并源切换时图标与数据错位 - App.vue: onUnmounted 清理 saveBoundsTimer 防抖定时器,避免组件销毁后悬空 IPC 调用 - App.vue: loadHomeListEntries 串行 for-of 改 Promise.all 并发拉取,缩短首页入口加载 - InstalledAppsModal: 顶部统计徽章基于搜索过滤结果实时计算,修复搜索时数字不同步 (审查误报项已核实未改: fetchAppFromStore 已有 encodeURIComponent + AbortSignal)
This commit is contained in:
+15
-11
@@ -1467,13 +1467,15 @@ const loadHomeListEntries = async () => {
|
|||||||
{ name: string; urls: { spark?: string; apm?: string } }
|
{ name: string; urls: { spark?: string; apm?: string } }
|
||||||
>();
|
>();
|
||||||
|
|
||||||
for (const mode of modes) {
|
// 并发拉取各来源的 homelist.json(spark/apm),缩短首页入口加载耗时;
|
||||||
const finalArch = mode === "spark" ? `${arch}-store` : `${arch}-apm`;
|
// 各来源独立解析后合并到局部 byName,不逐个触发响应式更新。
|
||||||
const base = `${APM_STORE_BASE_URL}/${finalArch}/home`;
|
await Promise.all(
|
||||||
|
modes.map(async (mode) => {
|
||||||
try {
|
const finalArch = mode === "spark" ? `${arch}-store` : `${arch}-apm`;
|
||||||
const res = await fetch(`${base}/homelist.json`);
|
const base = `${APM_STORE_BASE_URL}/${finalArch}/home`;
|
||||||
if (res.ok) {
|
try {
|
||||||
|
const res = await fetch(`${base}/homelist.json`);
|
||||||
|
if (!res.ok) return;
|
||||||
const lists = await res.json();
|
const lists = await res.json();
|
||||||
lists.forEach(
|
lists.forEach(
|
||||||
(item: { name?: string; type?: string; jsonUrl?: string }) => {
|
(item: { name?: string; type?: string; jsonUrl?: string }) => {
|
||||||
@@ -1494,11 +1496,11 @@ const loadHomeListEntries = async () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Failed to load ${mode} homelist.json`, e);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}),
|
||||||
console.warn(`Failed to load ${mode} homelist.json`, e);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const entries: SidebarEntry[] = [];
|
const entries: SidebarEntry[] = [];
|
||||||
const urlsMap: Record<string, { spark?: string; apm?: string }> = {};
|
const urlsMap: Record<string, { spark?: string; apm?: string }> = {};
|
||||||
@@ -3486,6 +3488,8 @@ onMounted(async () => {
|
|||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
rootAbortController.abort();
|
rootAbortController.abort();
|
||||||
updateCenterStore.unbind();
|
updateCenterStore.unbind();
|
||||||
|
// 清理窗口尺寸防抖定时器,防止组件销毁后仍触发 IPC 保存调用
|
||||||
|
if (saveBoundsTimer) clearTimeout(saveBoundsTimer);
|
||||||
// 停止仍挂起的"等待 loading 完成后执行一次"的 watcher,避免泄漏
|
// 停止仍挂起的"等待 loading 完成后执行一次"的 watcher,避免泄漏
|
||||||
for (const stop of pendingWatchers.splice(0)) stop();
|
for (const stop of pendingWatchers.splice(0)) stop();
|
||||||
// 移除 window / document 监听
|
// 移除 window / document 监听
|
||||||
|
|||||||
@@ -783,8 +783,10 @@ const installBtnText = computed(() => {
|
|||||||
const iconPath = computed(() => {
|
const iconPath = computed(() => {
|
||||||
if (!displayApp.value) return "";
|
if (!displayApp.value) return "";
|
||||||
const arch = window.apm_store.arch || "amd64";
|
const arch = window.apm_store.arch || "amd64";
|
||||||
|
// 切换来源标签时(viewingOrigin)需动态重算架构路径,确保图标/资源跟随当前查看来源,
|
||||||
|
// 而非固定使用合并应用原始 origin,避免切换源时图标与数据错位。
|
||||||
const finalArch =
|
const finalArch =
|
||||||
displayApp.value.origin === "spark" ? `${arch}-store` : `${arch}-apm`;
|
viewingOrigin.value === "spark" ? `${arch}-store` : `${arch}-apm`;
|
||||||
return `${APM_STORE_BASE_URL}/${finalArch}/${displayApp.value.category}/${displayApp.value.pkgname}/icon.png`;
|
return `${APM_STORE_BASE_URL}/${finalArch}/${displayApp.value.category}/${displayApp.value.pkgname}/icon.png`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -450,11 +450,22 @@ const hasOrigin = (app: App, origin: "spark" | "apm"): boolean =>
|
|||||||
app.origins?.includes(origin) ?? app.origin === origin;
|
app.origins?.includes(origin) ?? app.origin === origin;
|
||||||
|
|
||||||
// APM / Spark 分别统计实际安装的包数量(同一 pkgname 同时装两种来源时各计一次)
|
// APM / Spark 分别统计实际安装的包数量(同一 pkgname 同时装两种来源时各计一次)
|
||||||
|
// 搜索过滤后的全量(不叠加来源筛选),用于顶部统计徽章实时同步搜索结果,
|
||||||
|
// 避免搜索时列表缩减而徽章数字仍显示全量造成误导。
|
||||||
|
const searchFilteredApps = computed(() => {
|
||||||
|
const q = searchQuery.value.trim().toLowerCase();
|
||||||
|
if (!q) return props.apps;
|
||||||
|
return props.apps.filter(
|
||||||
|
(a) =>
|
||||||
|
a.name.toLowerCase().includes(q) || a.pkgname.toLowerCase().includes(q),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const apmCount = computed(
|
const apmCount = computed(
|
||||||
() => props.apps.filter((a) => hasOrigin(a, "apm")).length,
|
() => searchFilteredApps.value.filter((a) => hasOrigin(a, "apm")).length,
|
||||||
);
|
);
|
||||||
const sparkCount = computed(
|
const sparkCount = computed(
|
||||||
() => props.apps.filter((a) => hasOrigin(a, "spark")).length,
|
() => searchFilteredApps.value.filter((a) => hasOrigin(a, "spark")).length,
|
||||||
);
|
);
|
||||||
// 总数 = APM 包数 + Spark 包数(不同来源视为不同包,单独计数)
|
// 总数 = APM 包数 + Spark 包数(不同来源视为不同包,单独计数)
|
||||||
const totalCount = computed(() => apmCount.value + sparkCount.value);
|
const totalCount = computed(() => apmCount.value + sparkCount.value);
|
||||||
|
|||||||
Reference in New Issue
Block a user