frpc-desktop/electron/main/index.ts

253 lines
6.4 KiB
TypeScript
Raw Normal View History

2024-10-14 11:24:54 +08:00
import {
app,
BrowserWindow,
ipcMain,
Menu,
MenuItem,
MenuItemConstructorOptions,
shell,
Tray
} from "electron";
import { release } from "node:os";
import node_path, { join } from "node:path";
import { initGitHubApi } from "../api/github";
import { initConfigApi } from "../api/config";
import { initProxyApi } from "../api/proxy";
import {
initFrpcApi,
startFrpWorkerProcess,
stopFrpcProcess
} from "../api/frpc";
import { initLoggerApi } from "../api/logger";
import { initFileApi } from "../api/file";
import { getConfig } from "../storage/config";
2024-08-06 00:17:39 +08:00
import log from "electron-log";
2024-10-14 11:24:54 +08:00
import { initCommonApi } from "../api/common";
import { initLocalApi } from "../api/local";
2023-11-27 15:03:25 +08:00
// The built directory structure
//
// ├─┬ dist-electron
// │ ├─┬ main
// │ │ └── index.js > Electron-Main
// │ └─┬ preload
// │ └── index.js > Preload-Scripts
// ├─┬ dist
// │ └── index.html > Electron-Renderer
//
process.env.DIST_ELECTRON = join(__dirname, "..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
process.env.VITE_PUBLIC = process.env.VITE_DEV_SERVER_URL
2024-10-14 11:24:54 +08:00
? join(process.env.DIST_ELECTRON, "../public")
: process.env.DIST;
2023-11-27 15:03:25 +08:00
// Disable GPU Acceleration for Windows 7
if (release().startsWith("6.1")) app.disableHardwareAcceleration();
// Set application name for Windows 10+ notifications
if (process.platform === "win32") app.setAppUserModelId(app.getName());
if (!app.requestSingleInstanceLock()) {
2024-10-14 11:24:54 +08:00
app.quit();
process.exit(0);
2023-11-27 15:03:25 +08:00
}
// Remove electron security warnings
// This warning only shows in development mode
// Read more on https://www.electronjs.org/docs/latest/tutorial/security
// process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
let win: BrowserWindow | null = null;
2023-12-01 15:00:11 +08:00
let tray = null;
2023-11-27 15:03:25 +08:00
// Here, you can also use other preload
const preload = join(__dirname, "../preload/index.js");
const url = process.env.VITE_DEV_SERVER_URL;
const indexHtml = join(process.env.DIST, "index.html");
2023-12-01 15:00:11 +08:00
let isQuiting;
2024-10-14 11:24:54 +08:00
log.transports.file.level = "debug";
2024-08-06 00:17:39 +08:00
log.transports.console.level = "debug";
2023-11-27 15:03:25 +08:00
2024-10-14 11:24:54 +08:00
async function createWindow(config: FrpConfig) {
console.log("config", config);
let show = true;
if (config) {
show = !config.systemSilentStartup;
}
console.log("界面", show);
win = new BrowserWindow({
title: "Frpc Desktop",
icon: join(process.env.VITE_PUBLIC, "logo/only/16x16.png"),
width: 800,
height: 600,
minWidth: 800,
minHeight: 600,
maxWidth: 1280,
maxHeight: 960,
webPreferences: {
preload,
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
// Consider using contextBridge.exposeInMainWorld
// Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
nodeIntegration: true,
contextIsolation: false
},
show: show
});
if (process.env.VITE_DEV_SERVER_URL) {
// electron-vite-vue#298
win.loadURL(url);
// Open devTool if the app is not packaged
win.webContents.openDevTools();
} else {
win.loadFile(indexHtml);
}
// Test actively push message to the Electron-Renderer
win.webContents.on("did-finish-load", () => {
win?.webContents.send("main-process-message", new Date().toLocaleString());
});
// Make all links open with the browser, not with the application
win.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith("https:")) shell.openExternal(url);
return { action: "deny" };
});
// 隐藏菜单栏
const { Menu } = require("electron");
Menu.setApplicationMenu(null);
// hide menu for Mac
// if (process.platform !== "darwin") {
// app.dock.hide();
// }
win.on("minimize", function (event) {
event.preventDefault();
win.hide();
});
win.on("close", function (event) {
if (!isQuiting) {
event.preventDefault();
win.hide();
if (process.platform === "darwin") {
app.dock.hide();
}
2023-11-27 15:03:25 +08:00
}
2024-10-14 11:24:54 +08:00
return false;
});
2023-11-27 15:03:25 +08:00
}
2024-10-14 11:24:54 +08:00
export const createTray = (config: FrpConfig) => {
log.info(
`当前环境 platform${process.platform} arch${
process.arch
} appData${app.getPath("userData")} version:${app.getVersion()}`
);
let menu: Array<MenuItemConstructorOptions | MenuItem> = [
{
label: "显示主窗口",
click: function () {
2023-12-01 16:23:16 +08:00
win.show();
2024-10-14 11:24:54 +08:00
if (process.platform === "darwin") {
app.dock.show();
2024-07-17 14:21:31 +08:00
}
2024-10-14 11:24:54 +08:00
}
},
{
label: "退出",
click: () => {
isQuiting = true;
stopFrpcProcess(() => {
app.quit();
});
}
}
];
tray = new Tray(
node_path.join(process.env.VITE_PUBLIC, "logo/only/16x16.png")
);
tray.setToolTip("Frpc Desktop");
const contextMenu = Menu.buildFromTemplate(menu);
tray.setContextMenu(contextMenu);
// 托盘双击打开
tray.on("double-click", () => {
win.show();
});
if (config) {
if (config.systemStartupConnect) {
log.info(`已开启自动连接 正在自动连接服务器`);
startFrpWorkerProcess(config);
}
}
};
2023-12-01 15:00:11 +08:00
app.whenReady().then(() => {
2024-10-14 11:24:54 +08:00
getConfig((err, config) => {
createWindow(config).then(r => {
createTray(config);
// 初始化各个API
initGitHubApi();
initConfigApi(win);
initProxyApi();
initFrpcApi();
initLoggerApi();
initFileApi();
initCommonApi();
initLocalApi();
// initUpdaterApi(win);
});
});
2023-12-01 15:00:11 +08:00
});
2023-11-27 15:03:25 +08:00
app.on("window-all-closed", () => {
2024-10-14 11:24:54 +08:00
win = null;
if (process.platform !== "darwin") {
stopFrpcProcess(() => {
app.quit();
});
}
2023-11-27 15:03:25 +08:00
});
app.on("second-instance", () => {
2024-10-14 11:24:54 +08:00
if (win) {
// Focus on the main window if the user tried to open another
if (win.isMinimized()) win.restore();
win.focus();
}
2023-11-27 15:03:25 +08:00
});
app.on("activate", () => {
2024-10-14 11:24:54 +08:00
const allWindows = BrowserWindow.getAllWindows();
if (allWindows.length) {
allWindows[0].focus();
} else {
getConfig((err, config) => {
createWindow(config).then(r => {});
});
}
2023-11-27 15:03:25 +08:00
});
2024-10-14 11:24:54 +08:00
app.on("before-quit", () => {
log.info("before-quit");
isQuiting = true;
});
2023-12-01 15:00:11 +08:00
2023-11-27 15:03:25 +08:00
// New window example arg: new windows url
ipcMain.handle("open-win", (_, arg) => {
2024-10-14 11:24:54 +08:00
const childWindow = new BrowserWindow({
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false
2023-11-27 15:03:25 +08:00
}
2024-10-14 11:24:54 +08:00
});
if (process.env.VITE_DEV_SERVER_URL) {
childWindow.loadURL(`${url}#${arg}`);
} else {
childWindow.loadFile(indexHtml, { hash: arg });
}
2023-11-27 15:03:25 +08:00
});