Fix SCUM file workbench interactions
This commit is contained in:
@@ -19,6 +19,7 @@ export interface PluginPageFileReadSnapshot {
|
||||
}
|
||||
|
||||
export interface PluginPageWorkspaceActions {
|
||||
refreshWorkspace?: () => Promise<unknown>;
|
||||
requestFile?: (fileKey: string) => Promise<PluginPageFileRequestResult>;
|
||||
getFileSnapshot?: (fileKey: string) => Promise<PluginPageFileReadSnapshot>;
|
||||
writeFile?: (fileKey: string, content: string, options?: { expectedChecksum?: string }) => Promise<PluginPageFileRequestResult>;
|
||||
|
||||
@@ -99,6 +99,8 @@ describe("PluginPageHostPage", () => {
|
||||
it("keeps file workspace callbacks stable across parent operational refreshes", () => {
|
||||
expect(hostSource).toContain("readyPluginRef.current = readyPlugin");
|
||||
expect(hostSource).toContain("hostContextRef.current = hostContext");
|
||||
expect(hostSource).toContain("refreshWorkspace: async ()");
|
||||
expect(hostSource).toContain("platformApiClient.listGamePlugins()");
|
||||
expect(hostSource).toContain("}, [pluginId, serverId]);");
|
||||
expect(hostSource).not.toContain("}, [hostContext, readyPlugin, serverId]);");
|
||||
});
|
||||
|
||||
@@ -67,11 +67,24 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin, embedded
|
||||
readyPluginRef.current = readyPlugin;
|
||||
hostContextRef.current = hostContext;
|
||||
const workspaceActions = useMemo<PluginPageWorkspaceActions | undefined>(() => {
|
||||
if (!pluginId || !serverId) return undefined;
|
||||
if (!pluginId) return undefined;
|
||||
return {
|
||||
refreshWorkspace: async () => {
|
||||
const response = await platformApiClient.listGamePlugins();
|
||||
const plugin = response.items.find((candidate) => candidate.id === pluginId);
|
||||
if (!plugin) {
|
||||
throw new Error("未找到已注册的插件声明。");
|
||||
}
|
||||
readyPluginRef.current = plugin;
|
||||
setState({ status: "ready", plugin });
|
||||
return plugin.fileWorkspace;
|
||||
},
|
||||
requestFile: async (fileKey) => {
|
||||
const plugin = readyPluginRef.current;
|
||||
const context = hostContextRef.current;
|
||||
if (!serverId) {
|
||||
return { status: "denied", message: "插件页面没有绑定服务器,无法读取文件。" };
|
||||
}
|
||||
if (!plugin || !context) {
|
||||
return { status: "denied", message: "插件页面上下文尚未就绪。" };
|
||||
}
|
||||
@@ -92,6 +105,9 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin, embedded
|
||||
},
|
||||
getFileSnapshot: async (fileKey) => {
|
||||
const plugin = readyPluginRef.current;
|
||||
if (!serverId) {
|
||||
return { serverInstanceId: "", pluginId, key: fileKey, state: "unavailable", reason: "插件页面没有绑定服务器,无法读取文件快照。" };
|
||||
}
|
||||
if (!plugin) {
|
||||
return { serverInstanceId: serverId, pluginId, key: fileKey, state: "unavailable", reason: "插件页面上下文尚未就绪。" };
|
||||
}
|
||||
@@ -113,6 +129,9 @@ export function PluginPageHostPage({ params, onNavigate, initialPlugin, embedded
|
||||
writeFile: async (fileKey, content, options) => {
|
||||
const plugin = readyPluginRef.current;
|
||||
const context = hostContextRef.current;
|
||||
if (!serverId) {
|
||||
return { status: "denied", message: "插件页面没有绑定服务器,无法写入文件。" };
|
||||
}
|
||||
if (!plugin || !context) {
|
||||
return { status: "denied", message: "插件页面上下文尚未就绪。" };
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ to{transform:translate(-50%,-50%) rotate(calc(var(--construct-drift) + 360deg))}
|
||||
.section-tab:focus-visible,.section-tab:hover{border-color:var(--accent);outline:0}
|
||||
.section-tab-active{background:var(--primary-command-surface);border-color:var(--accent-deep);color:#fff;font-weight:700;box-shadow:0 10px 24px var(--candy-glow),inset 0 1px 0 var(--crystal-rim),0 0 18px var(--moonbeam)}
|
||||
.file-workbench{display:grid;grid-template-columns:minmax(200px,.82fr) minmax(0,2fr);gap:12px;align-items:start;min-width:0}.file-workbench-nav{display:grid;gap:12px;min-width:0;padding-right:12px;border-right:1px solid var(--line)}.file-workbench-directory{display:grid;gap:4px;min-width:0}.file-workbench-directory-heading{display:grid;gap:2px;padding:0 8px 4px;color:var(--ink-soft);font-size:12px}.file-workbench-directory-heading strong{color:var(--ink);font-size:13px}.file-workbench-directory-heading span{font-family:var(--font-mono);overflow-wrap:anywhere}.file-workbench-file{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;width:100%;min-height:42px;align-items:center;padding:7px 8px;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--ink-soft);font:inherit;text-align:left;cursor:pointer}.file-workbench-file strong{min-width:0;color:var(--ink);overflow-wrap:anywhere}.file-workbench-file span{font-size:11px;color:var(--ink-faint);white-space:nowrap}.file-workbench-file:hover,.file-workbench-file:focus-visible{border-color:var(--line-strong);background:var(--control-surface);outline:0}.file-workbench-file[aria-current=page]{border-color:var(--accent);background:var(--primary-command-surface);color:#fff}.file-workbench-file[aria-current=page] strong,.file-workbench-file[aria-current=page] span{color:#fff}.file-workbench-detail{display:grid;gap:12px;min-width:0}.file-workbench-detail>.panel-header{padding-bottom:10px;border-bottom:1px solid var(--line)}.file-workbench-mode{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding-bottom:10px;border-bottom:1px solid var(--line)}.file-workbench-mode>span{margin-right:auto;color:var(--ink-soft);font-size:12px}.file-workbench-mode button{min-height:32px;padding:0 10px;border:1px solid var(--line-strong);border-radius:6px;background:var(--control-surface);color:var(--ink-soft);font:inherit;cursor:pointer}.file-workbench-mode button:hover,.file-workbench-mode button:focus-visible{border-color:var(--accent);outline:0}.file-workbench-mode .file-workbench-mode-active{border-color:var(--accent);background:var(--primary-command-surface);color:#fff}.file-workbench-fields{display:grid;gap:0}.file-workbench-field{display:grid;grid-template-columns:minmax(0,1fr) minmax(150px,.72fr);gap:8px 12px;align-items:center;padding:10px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 74%,transparent)}.file-workbench-field>span{display:grid;gap:3px;min-width:0}.file-workbench-field strong{color:var(--ink);font-size:13px}.file-workbench-field small{color:var(--ink-faint);overflow-wrap:anywhere}.file-workbench-field input{min-width:0;min-height:34px;border:1px solid var(--line-strong);border-radius:6px;padding:0 9px;background:var(--surface-solid);color:var(--ink);font:inherit}.file-workbench-field input:read-only,.file-workbench-field input:disabled{color:var(--ink-soft);background:color-mix(in srgb,var(--surface-solid) 72%,transparent)}.file-workbench-field>small{grid-column:1/-1}.file-workbench-raw{display:grid;gap:8px;min-width:0}.file-workbench-raw .runtime-task-log{margin:0;max-height:560px;overflow:auto}.file-workbench-raw small{color:var(--ink-faint);font-family:var(--font-mono);overflow-wrap:anywhere}
|
||||
.file-workbench-picker{display:grid;gap:6px;color:var(--ink-soft);font-size:12px;font-weight:700}.file-workbench-picker select,.file-workbench-field select{width:100%;min-height:36px;border:1px solid var(--line-strong);border-radius:7px;padding:0 10px;background:var(--surface-solid);color:var(--ink);font:inherit}.file-workbench-picker select:focus,.file-workbench-field select:focus{border-color:var(--accent);outline:2px solid var(--accent-soft)}.file-workbench-number-control{display:grid;grid-template-columns:minmax(0,1fr) 92px;gap:8px;align-items:center}.file-workbench-number-control input[type=range]{padding:0;accent-color:var(--accent)}.file-workbench-raw-editor{width:100%;min-height:420px;resize:vertical;border:1px solid var(--line-strong);border-radius:8px;padding:10px;background:var(--code-surface);color:var(--code-ink);font-family:var(--font-mono);font-size:12px;line-height:1.55}.file-workbench-raw-editor:focus{border-color:var(--accent);outline:2px solid var(--accent-soft)}.file-workbench-actions{justify-content:flex-start}.file-workbench-unknown,.file-workbench-diff{display:grid;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}.file-workbench-unknown h3{margin:0;color:var(--ink);font-size:13px}.file-workbench-diff .runtime-task-log{max-height:260px}.file-workbench-encoding{padding-top:0}
|
||||
.file-workbench-picker{display:grid;gap:6px;color:var(--ink-soft);font-size:12px;font-weight:700}.file-workbench-picker select,.file-workbench-field select{width:100%;min-height:36px;border:1px solid var(--line-strong);border-radius:7px;padding:0 10px;background:var(--surface-solid);color:var(--ink);font:inherit}.file-workbench-picker select:focus,.file-workbench-field select:focus{border-color:var(--accent);outline:2px solid var(--accent-soft)}.file-workbench-nav-actions,.file-workbench-actions{justify-content:flex-start}.file-workbench-number-control{display:grid;grid-template-columns:minmax(0,1fr) 92px;gap:8px;align-items:center}.file-workbench-number-control input[type=range]{padding:0;accent-color:var(--accent)}.file-workbench-raw-editor{width:100%;min-height:420px;resize:vertical;border:1px solid var(--line-strong);border-radius:8px;padding:10px;background:var(--code-surface);color:var(--code-ink);font-family:var(--font-mono);font-size:12px;line-height:1.55}.file-workbench-keyvalue-editor{min-height:260px}.file-workbench-raw-editor:focus{border-color:var(--accent);outline:2px solid var(--accent-soft)}.file-workbench-unknown,.file-workbench-diff{display:grid;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}.file-workbench-unknown h3{margin:0;color:var(--ink);font-size:13px}.file-workbench-diff .runtime-task-log{max-height:260px}.file-workbench-encoding{padding-top:0}
|
||||
@media (max-width:760px){.file-workbench{grid-template-columns:1fr}.file-workbench-nav{padding:0 0 10px;border-right:0;border-bottom:1px solid var(--line)}.file-workbench-field{grid-template-columns:1fr}.file-workbench-mode>span{width:100%;margin-right:0}.file-workbench-mode button{flex:1 1 0}}
|
||||
.overview-two-col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
|
||||
.log-filter-bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
|
||||
|
||||
Reference in New Issue
Block a user