fix(scum): gate plugin features by companion support

This commit is contained in:
npc0-hue
2026-07-29 11:28:19 +08:00
parent 63022baa18
commit 47738acfd6
8 changed files with 38 additions and 25 deletions
+4 -6
View File
@@ -9,7 +9,7 @@ import { EmptyState, ErrorState, LoadingState } from "../components/StateViews";
import type { PageComponentProps } from "../contracts/page";
import { pluginBridgeManifestContractFromResponse } from "../contracts/pluginBridge";
import { createPluginBridgeHostContext } from "../utils/pluginBridgeHost";
import { loadPluginPageBundle } from "../utils/pluginPageBundles";
import { loadPluginPageBundle, type PluginPageAvailability } from "../utils/pluginPageBundles";
type PluginPageState =
| { status: "loading" }
@@ -25,9 +25,9 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin }: Plugin
const routeKey = params.routeKey ?? "";
const serverId = params.serverId ?? "";
const [state, setState] = useState<PluginPageState>(() => initialPlugin ? { status: "ready", plugin: initialPlugin } : { status: "loading" });
const [bundle, setBundle] = useState<ComponentType<{ context: ReturnType<typeof createPluginBridgeHostContext>; workspace?: unknown; availability: { available: boolean; reason?: string } }> | null>(null);
const [bundle, setBundle] = useState<ComponentType<{ context: ReturnType<typeof createPluginBridgeHostContext>; workspace?: unknown; availability: PluginPageAvailability }> | null>(null);
const [bundleError, setBundleError] = useState("");
const [availability, setAvailability] = useState<{ available: boolean; reason?: string }>({ available: false, reason: "正在验证 Companion 可用性。" });
const [availability, setAvailability] = useState<PluginPageAvailability>({ available: false, reason: "正在验证 Companion 可用性。" });
const load = useCallback(async () => {
if (!pluginId || !routeKey) {
@@ -61,9 +61,7 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin }: Plugin
void loadPluginPageBundle(declaredBundlePage).then((loaded) => { if (active) setBundle(() => loaded); }).catch((error) => { if (active) setBundleError(error instanceof Error ? error.message : "插件页面 bundle 加载失败。"); });
if (!serverId) { setAvailability({ available: false, reason: "插件页面没有绑定服务器。" }); return () => { active = false; }; }
void platformApiClient.getGameClientBridgeStatus(serverId).then((status) => {
const requiredFeatures = declaredBundlePage.featureKeys ?? [];
const unavailable = requiredFeatures.map((key) => status.features?.find((feature) => feature.key === key)).find((feature) => !feature?.available);
if (active) setAvailability(unavailable ? { available: false, reason: unavailable.reason || `功能 ${unavailable.key} 没有兼容的 Companion 实现。` } : { available: status.available, reason: status.reason });
if (active) setAvailability({ available: status.available, reason: status.reason, features: status.features });
}).catch((error) => { if (active) setAvailability({ available: false, reason: error instanceof Error ? error.message : "无法验证 Companion 可用性。" }); });
return () => { active = false; };
}, [declaredBundlePage, serverId]);