fix(add-extension): load real icon in install confirm dialog from URL params

When the install confirm dialog is opened via URL query params (e.g. from a
marketplace deep link), installInfo carried no icon, so the icon fell back to
the /resources/icon endpoint which 404s for extensions whose icon is an
external URL (simpleicons / iconify), showing a Package placeholder.

Fetch the icon from the marketplace detail API (mcp/skill/plugin) after opening
the dialog and inject it into installInfo, and reset the icon-failed state when
the resolved URL changes so the <img> retries instead of sticking on the
placeholder.
This commit is contained in:
RockChinQ
2026-06-06 04:45:46 -04:00
parent 7330732f62
commit 170a6756f4
2 changed files with 70 additions and 0 deletions
+24
View File
@@ -192,6 +192,13 @@ function AddExtensionContent() {
);
})();
// When the resolved icon URL changes (e.g. the real external icon arrives
// after an async fetch), clear any prior load failure so the <img> retries
// instead of staying on the placeholder.
useEffect(() => {
setInstallIconFailed(false);
}, [installIconURL]);
const [popoverOpen, setPopoverOpen] = useState(false);
const [popoverView, setPopoverView] = useState<PopoverView>('menu');
const [isDragOver, setIsDragOver] = useState(false);
@@ -279,6 +286,23 @@ function AddExtensionContent() {
setInstallIconFailed(false);
setModalOpen(true);
// The icon is not carried in the URL params, so fetch it from the
// marketplace record. Without this the confirm dialog falls back to the
// /resources/icon endpoint, which 404s for extensions whose icon is an
// external URL (simpleicons / iconify), showing a placeholder.
const cloud = getCloudServiceClientSync();
cloud
.fetchMarketplaceIcon(extType, author, name)
.then((icon) => {
if (!icon) return;
setInstallInfo((prev) =>
prev.plugin_author === author && prev.plugin_name === name
? { ...prev, plugin_icon: icon }
: prev,
);
})
.catch(() => {});
setSearchParams(
(current) => {
const next = new URLSearchParams(current);