mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-23 18:47:15 +00:00
fix(plugin-pages): wait for page metadata before iframe load
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { httpClient } from '@/app/infra/http/HttpClient';
|
import { httpClient } from '@/app/infra/http/HttpClient';
|
||||||
import { useEffect, useRef, useState, useCallback } from 'react';
|
import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
|
||||||
import { useSidebarData } from '@/app/home/components/home-sidebar/SidebarDataContext';
|
import { useSidebarData } from '@/app/home/components/home-sidebar/SidebarDataContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useTheme } from '@/components/providers/theme-provider';
|
import { useTheme } from '@/components/providers/theme-provider';
|
||||||
@@ -24,7 +24,10 @@ export default function PluginPagesPage() {
|
|||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const id = searchParams.get('id');
|
const id = searchParams.get('id');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { setDetailEntityName, pluginPages } = useSidebarData();
|
const { setDetailEntityName, pluginPages, refreshPlugins } = useSidebarData();
|
||||||
|
const [lookupCompleteForId, setLookupCompleteForId] = useState<string | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
// Find the matching page for breadcrumb
|
// Find the matching page for breadcrumb
|
||||||
const page = pluginPages.find((p) => p.id === id);
|
const page = pluginPages.find((p) => p.id === id);
|
||||||
@@ -34,6 +37,18 @@ export default function PluginPagesPage() {
|
|||||||
return () => setDetailEntityName(null);
|
return () => setDetailEntityName(null);
|
||||||
}, [page, id, setDetailEntityName]);
|
}, [page, id, setDetailEntityName]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id || page) return;
|
||||||
|
let cancelled = false;
|
||||||
|
setLookupCompleteForId(null);
|
||||||
|
refreshPlugins().finally(() => {
|
||||||
|
if (!cancelled) setLookupCompleteForId(id);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [id, page, refreshPlugins]);
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-full text-muted-foreground">
|
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||||||
@@ -54,9 +69,23 @@ export default function PluginPagesPage() {
|
|||||||
|
|
||||||
const author = parts[0];
|
const author = parts[0];
|
||||||
const pluginName = parts[1];
|
const pluginName = parts[1];
|
||||||
// Use the asset path from the page manifest, not the page ID
|
if (!page) {
|
||||||
const assetPath = page?.path ?? parts.slice(2).join('/');
|
if (lookupCompleteForId === id) {
|
||||||
const pageId = parts.slice(2).join('/');
|
return (
|
||||||
|
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||||||
|
{t('pluginPages.invalidPage')}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center h-full text-muted-foreground">
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const assetPath = page.path;
|
||||||
|
const pageId = page.pageId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PluginPageIframe
|
<PluginPageIframe
|
||||||
@@ -84,7 +113,11 @@ function PluginPageIframe({
|
|||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
const assetUrl = httpClient.getPluginAssetURL(author, pluginName, pagePath);
|
const assetUrl = useMemo(() => {
|
||||||
|
const url = httpClient.getPluginAssetURL(author, pluginName, pagePath);
|
||||||
|
const separator = url.includes('?') ? '&' : '?';
|
||||||
|
return `${url}${separator}_lb_page_v=${Date.now()}`;
|
||||||
|
}, [author, pluginName, pagePath]);
|
||||||
|
|
||||||
// Send context (theme + language) to iframe
|
// Send context (theme + language) to iframe
|
||||||
// Use '*' as targetOrigin because sandboxed iframe has opaque (null) origin
|
// Use '*' as targetOrigin because sandboxed iframe has opaque (null) origin
|
||||||
|
|||||||
Reference in New Issue
Block a user