fix(update-center): cascade local and remote icon fallbacks

Keep update list icons from dropping straight to placeholders by retrying the remote store icon after local load failures. Align the update-center IPC and renderer types with the split local/remote icon contract.
This commit is contained in:
2026-04-11 11:41:01 +08:00
parent c16ba5536f
commit 180b88b5c0
11 changed files with 245 additions and 79 deletions

View File

@@ -181,21 +181,31 @@ export const buildRemoteFallbackIconUrl = ({
return `${baseUrl}/${storeArch}/${category}/${pkgname}/icon.png`;
};
export const resolveUpdateItemIcon = (item: UpdateCenterItem): string => {
export const resolveUpdateItemIcons = (
item: UpdateCenterItem,
): Pick<UpdateCenterItem, "localIcon" | "remoteIcon"> => {
const localIcon =
item.source === "aptss"
? resolveDesktopIcon(item.pkgname)
: resolveApmIcon(item.pkgname);
if (localIcon) {
return localIcon;
const remoteIcon = buildRemoteFallbackIconUrl({
pkgname: item.pkgname,
source: item.source,
arch: item.arch,
category: item.category,
});
if (localIcon && remoteIcon) {
return { localIcon, remoteIcon };
}
return (
buildRemoteFallbackIconUrl({
pkgname: item.pkgname,
source: item.source,
arch: item.arch,
category: item.category,
}) || ""
);
if (localIcon) {
return { localIcon };
}
if (remoteIcon) {
return { remoteIcon };
}
return {};
};

View File

@@ -9,7 +9,7 @@ import {
parseAptssUpgradableOutput,
parsePrintUrisOutput,
} from "./query";
import { resolveUpdateItemIcon } from "./icons";
import { resolveUpdateItemIcons } from "./icons";
import {
createUpdateCenterService,
type UpdateCenterIgnorePayload,
@@ -249,9 +249,9 @@ const enrichItemCategories = async (
const enrichItemIcons = (items: UpdateCenterItem[]): UpdateCenterItem[] => {
return items.map((item) => {
const icon = resolveUpdateItemIcon(item);
const icons = resolveUpdateItemIcons(item);
return icon ? { ...item, icon } : item;
return Object.keys(icons).length > 0 ? { ...item, ...icons } : item;
});
};

View File

@@ -25,7 +25,8 @@ export interface UpdateCenterServiceItem {
currentVersion: string;
newVersion: string;
source: UpdateSource;
icon?: string;
localIcon?: string;
remoteIcon?: string;
ignored?: boolean;
downloadUrl?: string;
fileName?: string;
@@ -41,7 +42,8 @@ export interface UpdateCenterServiceTask {
taskKey: string;
packageName: string;
source: UpdateSource;
icon?: string;
localIcon?: string;
remoteIcon?: string;
status: UpdateCenterQueueSnapshot["tasks"][number]["status"];
progress: number;
logs: UpdateCenterQueueSnapshot["tasks"][number]["logs"];
@@ -98,7 +100,8 @@ const toState = (
currentVersion: item.currentVersion,
newVersion: item.nextVersion,
source: item.source,
icon: item.icon,
localIcon: item.localIcon,
remoteIcon: item.remoteIcon,
ignored: item.ignored,
downloadUrl: item.downloadUrl,
fileName: item.fileName,
@@ -113,7 +116,8 @@ const toState = (
taskKey: getTaskKey(task.item),
packageName: task.pkgname,
source: task.item.source,
icon: task.item.icon,
localIcon: task.item.localIcon,
remoteIcon: task.item.remoteIcon,
status: task.status,
progress: task.progress,
logs: task.logs.map((log) => ({ ...log })),

View File

@@ -12,7 +12,8 @@ export interface UpdateCenterItem {
nextVersion: string;
arch?: string;
category?: string;
icon?: string;
localIcon?: string;
remoteIcon?: string;
ignored?: boolean;
downloadUrl?: string;
fileName?: string;

View File

@@ -8,12 +8,16 @@ type UpdateCenterSnapshot = {
currentVersion: string;
newVersion: string;
source: "aptss" | "apm";
localIcon?: string;
remoteIcon?: string;
ignored?: boolean;
}>;
tasks: Array<{
taskKey: string;
packageName: string;
source: "aptss" | "apm";
localIcon?: string;
remoteIcon?: string;
status:
| "queued"
| "downloading"