mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-11-03 22:32:27 +08:00
fix(web): load installed plugin icons through the authenticated route
Multi-Workspace deployments fail the public plugin icon route closed (404), so plain <img src> icons broke everywhere locally and for the runner picker in production. A shared cached hook fetches the authenticated icon for installed plugins and leaves marketplace surfaces on the cloud URL.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { httpClient } from '@/app/infra/http/HttpClient';
|
||||
import { useCurrentWorkspace } from '@/app/infra/http';
|
||||
import { useInstalledPluginIcon } from '@/app/infra/hooks/useInstalledPluginIcon';
|
||||
|
||||
type AuthenticatedResourceState = {
|
||||
key: string;
|
||||
@@ -14,50 +15,21 @@ const EMPTY_RESOURCE: AuthenticatedResourceState = {
|
||||
error: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* Backwards-compatible wrapper around the shared installed-plugin icon hook.
|
||||
* Kept for callers that want a `{ url, error }` shape; the url is '' while
|
||||
* loading or when the icon is unavailable.
|
||||
*/
|
||||
export function useAuthenticatedPluginIcon(
|
||||
author: string,
|
||||
name: string,
|
||||
enabled = true,
|
||||
): { url: string; error: boolean } {
|
||||
const [resource, setResource] =
|
||||
useState<AuthenticatedResourceState>(EMPTY_RESOURCE);
|
||||
const currentWorkspace = useCurrentWorkspace();
|
||||
const workspaceUuid = currentWorkspace?.workspace.uuid;
|
||||
const resourceKey = `${workspaceUuid ?? ''}:${author}/${name}`;
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) {
|
||||
setResource({ key: resourceKey, url: '', error: false });
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
let objectURL = '';
|
||||
setResource({ key: resourceKey, url: '', error: false });
|
||||
httpClient
|
||||
.getAuthenticatedPluginIconURL(author, name)
|
||||
.then((nextURL) => {
|
||||
objectURL = nextURL;
|
||||
if (active) {
|
||||
setResource({ key: resourceKey, url: nextURL, error: false });
|
||||
} else {
|
||||
URL.revokeObjectURL(nextURL);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (active) {
|
||||
setResource({ key: resourceKey, url: '', error: true });
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
if (objectURL) URL.revokeObjectURL(objectURL);
|
||||
};
|
||||
}, [author, enabled, name, resourceKey]);
|
||||
|
||||
return {
|
||||
url: resource.key === resourceKey ? resource.url : '',
|
||||
error: resource.key === resourceKey && resource.error,
|
||||
};
|
||||
const url = useInstalledPluginIcon(
|
||||
enabled ? author : null,
|
||||
enabled ? name : null,
|
||||
);
|
||||
return { url: url ?? '', error: false };
|
||||
}
|
||||
|
||||
export function useAuthenticatedPluginAsset(
|
||||
|
||||
Reference in New Issue
Block a user