60 lines
2.1 KiB
TypeScript
60 lines
2.1 KiB
TypeScript
/**
|
|
* 轻应用 iframe 宿主页 —— 渲染某个已注册 iframe 类型应用。
|
|
*
|
|
* 路由:/page/strategy/light-app/view/:appId。侧边栏动态注入的 iframe 应用子项指向此页。
|
|
* 用 buildLightAppUrl 构造带路由参数(登录态 / 主题)的 src。
|
|
*/
|
|
import { useMemo } from "react";
|
|
import { useParams } from "react-router-dom";
|
|
|
|
import { useTheme } from "@/contexts/ThemeContext";
|
|
import { useLightApp } from "@/strategy-components/api/light-apps";
|
|
import { buildLightAppUrl, type AppThemeColor } from "@/strategy-components/lib/light-app";
|
|
|
|
export default function LightAppIframeView() {
|
|
const { appId } = useParams<{ appId: string }>();
|
|
const { theme } = useTheme();
|
|
const isDark = theme === "dark";
|
|
const { data: app, isLoading, error } = useLightApp(appId);
|
|
|
|
// 由 useTheme 的 theme 直接换算主题色并显式传入,切主题时 src 立即重建、
|
|
// 把新主题色传给被嵌套应用(不依赖 <html> 的 dark class,避免时序读旧值)。
|
|
// 深色=dark-blue,浅蓝=blue,其余(红白)=red。
|
|
const themeColor: AppThemeColor =
|
|
theme === "dark"
|
|
? "dark-blue"
|
|
: theme === "lightgreen"
|
|
? "green"
|
|
: theme === "lightblue"
|
|
? "blue"
|
|
: theme === "iceblue"
|
|
? "iceblue"
|
|
: theme === "lightyellow"
|
|
? "lightyellow"
|
|
: "red";
|
|
const src = useMemo(
|
|
() => (app ? buildLightAppUrl(app, undefined, themeColor) : ""),
|
|
[app, themeColor],
|
|
);
|
|
|
|
const centerClass = `flex h-full w-full items-center justify-center text-sm ${
|
|
isDark ? "text-slate-400" : "text-slate-500"
|
|
}`;
|
|
|
|
if (isLoading) {
|
|
return <div className={centerClass}>加载中…</div>;
|
|
}
|
|
if (error || !app) {
|
|
return <div className={centerClass}>应用不存在或已被删除</div>;
|
|
}
|
|
if (app.appType !== "iframe") {
|
|
return <div className={centerClass}>该应用不是 iframe 嵌套类型</div>;
|
|
}
|
|
|
|
return (
|
|
<div className="flex h-full w-full flex-col">
|
|
<iframe src={src} title={app.name} className="w-full flex-1 border-0" />
|
|
</div>
|
|
);
|
|
}
|