204 lines
5.2 KiB
TypeScript
204 lines
5.2 KiB
TypeScript
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,
|
|
};
|