feat: add monitoring settings tab, workbench view, and inspection alert improvements
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
This commit is contained in:
@@ -947,6 +947,66 @@ const allowedOrigins = getAllowedRendererOrigins();
|
||||
if (isTrustedRendererLocation(allowedOrigins)) {
|
||||
contextBridge.exposeInMainWorld("netcatty", {
|
||||
...existing, ...api, ...figSpecApi,
|
||||
// 设置同步:renderer localStorage 变化通知主进程权威源
|
||||
settingsSync: (key, value) => ipcRenderer.invoke("netcatty:settings:sync", {
|
||||
key,
|
||||
value,
|
||||
delete: value === null,
|
||||
}),
|
||||
settingsSyncBatch: (entries) => ipcRenderer.invoke("netcatty:settings:syncBatch", { entries }),
|
||||
settingsGetAll: () => ipcRenderer.invoke("netcatty:settings:getAll"),
|
||||
// 远程浏览器改了设置 → 主窗口实时拉取更新 localStorage
|
||||
onSettingsChanged: (callback) => {
|
||||
const handler = () => {
|
||||
ipcRenderer.invoke("netcatty:settings:getAll").then((r) => {
|
||||
if (r?.ok && r.settings && typeof r.settings === "object") {
|
||||
// 逐键对比更新(不暴力清空,避免触发过度重渲染)
|
||||
try {
|
||||
const changedKeys = [];
|
||||
const changedEntries = {};
|
||||
const existingKeys = new Set(Object.keys(localStorage));
|
||||
for (const [k, v] of Object.entries(r.settings)) {
|
||||
if (v === null || v === undefined) {
|
||||
if (localStorage.getItem(k) !== null) {
|
||||
localStorage.removeItem(k);
|
||||
changedKeys.push(k);
|
||||
changedEntries[k] = null;
|
||||
}
|
||||
} else {
|
||||
const strVal = String(v);
|
||||
if (localStorage.getItem(k) !== strVal) {
|
||||
localStorage.setItem(k, strVal);
|
||||
changedKeys.push(k);
|
||||
changedEntries[k] = strVal;
|
||||
}
|
||||
}
|
||||
existingKeys.delete(k);
|
||||
}
|
||||
// 权威源里没有但本地有的键——保留(可能是 Electron 专有设置)
|
||||
// 只有实际有变化时才触发事件
|
||||
if (changedKeys.length > 0) {
|
||||
// 触发同窗口 CustomEvent 让 React hooks 感知(携带完整 settings 和变化的 key 列表)
|
||||
try {
|
||||
window.dispatchEvent(new CustomEvent("netcatty-settings-batch", {
|
||||
detail: { changedKeys, changedEntries, settings: r.settings },
|
||||
}));
|
||||
} catch {}
|
||||
try { window.dispatchEvent(new Event("monitoring-camera-changed")); } catch {}
|
||||
// 向后兼容:触发原生 storage 事件(不带 key 信息,同窗口内依赖它的 hook 至少能收到通知)
|
||||
try { window.dispatchEvent(new Event("storage")); } catch {}
|
||||
// 回调同时传递完整 settings 字典和逐 key 变化信息
|
||||
try { callback({ settings: r.settings, changedKeys, changedEntries }); } catch {}
|
||||
} else {
|
||||
// 即使没有变化也通知(权威源同步确认)
|
||||
try { callback({ settings: r.settings, changedKeys: [], changedEntries: {} }); } catch {}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}).catch(() => {});
|
||||
};
|
||||
ipcRenderer.on("netcatty:settings:changed", handler);
|
||||
return () => ipcRenderer.removeListener("netcatty:settings:changed", handler);
|
||||
},
|
||||
// portable 版标志:renderer 据此跳过 LS hosts_v1 加密读取,
|
||||
// 直接走 inspection-data.json 明文(DPAPI 绑定 userData 路径解不开 dev 加密 blob)。
|
||||
isPortable: process.env.NETCATTY_PORTABLE === "1",
|
||||
|
||||
Reference in New Issue
Block a user