import {AppRuntime} from "../env"; import {ipcMain, WebContents} from "electron"; import {StrUtil} from "../../lib/util"; // 导入 taskEventSystem 以注册 IPC handlers import './taskEventSystem'; const init = async () => { }; type NameType = "main" | string | WebContents; type EventType = "APP_READY" | "CALL_PAGE" | "CHANNEL" | "BROADCAST"; type BroadcastType = | "ConfigChange" | "ConfigEnvChange" | "UserChange" | "DarkModeChange" | "HotkeyWatch" | "Notice" | "MonitorEvent" | "TaskStatusChange" | "TaskProgressChange" | "TaskComplete" | "TaskFailed"; const broadcast = ( type: BroadcastType, data: any, option?: { limit?: boolean; scopes?: string[]; pages?: string[]; } ) => { data = data || {}; option = Object.assign( { limit: false, scopes: [], pages: [], }, option ); if (option.pages.length > 0) { for (const p of option.pages) { send(p, "BROADCAST", {type, data}); } } else { if (!option.limit || option.scopes.includes("main")) { send("main", "BROADCAST", {type, data}); } if (!option.limit || option.scopes.includes("pages")) { for (let name in AppRuntime.windows) { send(name, "BROADCAST", {type, data}); } } } }; const sendRaw = (webContents: any, type: EventType, data: any = {}, id?: string): boolean => { id = id || StrUtil.randomString(32); const payload = {id, type, data}; webContents.send("MAIN_PROCESS_MESSAGE", payload); return true; }; const send = (name: NameType, type: EventType, data: any = {}, id?: string): boolean => { id = id || StrUtil.randomString(32); const payload = {id, type, data}; if (typeof name !== 'string') { (name as WebContents).send("MAIN_PROCESS_MESSAGE", payload); return true; } if (name === "main") { if (!AppRuntime.mainWindow) { return false; } // console.log('send', payload) AppRuntime.mainWindow?.webContents.send("MAIN_PROCESS_MESSAGE", payload); } else { if (!AppRuntime.windows[name]) { return false; } AppRuntime.windows[name]?.webContents.send("MAIN_PROCESS_MESSAGE", payload); } return true; }; ipcMain.handle("event:send", async (_, name: NameType, type: EventType, data: any) => { send(name, type, data); }); const callPage = async ( name: NameType, type: string, data: any, option?: { waitReadyTimeout?: number; timeout?: number; } ): Promise<{ code: number; msg: string; data?: any; }> => { option = Object.assign( { waitReadyTimeout: 10 * 1000, timeout: 60 * 1000, }, option ); return new Promise((resolve, reject) => { const id = StrUtil.randomString(32); const timer = setTimeout(() => { ipcMain.removeListener(listenerKey, listener); resolve({code: -1, msg: "timeout"}); }, option.timeout); const listener = (_, result) => { clearTimeout(timer); resolve(result); return true; }; const listenerKey = "event:callPage:" + id; ipcMain.once(listenerKey, listener); const payload = { type, data, option: { waitReadyTimeout: option.waitReadyTimeout, }, }; if (!send(name, "CALL_PAGE", payload, id)) { clearTimeout(timer); ipcMain.removeListener(listenerKey, listener); resolve({code: -1, msg: "send failed"}); } }); }; ipcMain.handle( "event:callPage", async ( _, name: string, type: string, data: any, option?: { timeout?: number; } ) => { return callPage(name, type, data, option); } ); let onChannelIsListen = false; let channelOnCallback = {}; const sendChannel = (channel: string, data: any) => { send("main", "CHANNEL", {channel, data}); }; const onChannel = (channel: string, callback: (data: any) => void) => { if (!channelOnCallback[channel]) { channelOnCallback[channel] = []; } channelOnCallback[channel].push(callback); if (!onChannelIsListen) { onChannelIsListen = true; ipcMain.handle("event:channelSend", (event, channel_, data) => { if (channelOnCallback[channel_]) { channelOnCallback[channel_].forEach((callback: (data: any) => void) => { callback(data); }); } }); } }; const offChannel = (channel: string, callback: (data: any) => void) => { if (channelOnCallback[channel]) { channelOnCallback[channel] = channelOnCallback[channel].filter((item: (data: any) => void) => { return item !== callback; }); } if (channelOnCallback[channel].length === 0) { delete channelOnCallback[channel]; } }; export default { init, send, }; export const Events = { broadcast, send, sendRaw, sendChannel, callPage, onChannel, offChannel, };