2024-04-08 20:49:31 +08:00

449 lines
9.9 KiB
TypeScript

import {
app,
BrowserWindow,
screen,
globalShortcut,
ipcMain,
nativeImage as NativeImage,
Menu,
Tray,
} from "electron";
import fs from "fs";
import tmp from 'tmp';
import Screenshots from "electron-screenshots";
import { join } from "path";
import logo, { getNoMessageTrayIcon } from "./logo";
import TSDD_FONFIG from "./confing";
let forceQuit = false;
let mainWindow: any;
let isMainWindowFocusedWhenStartScreenshot = false;
let screenshots: any;
let tray: any;
let trayIcon: any;
let settings: any = {};
let screenShotWindowId = 0;
let isFullScreen = false;
let isOsx = process.platform === "darwin";
let isWin = !isOsx;
const isDevelopment = process.env.NODE_ENV === "development";
let mainMenu: (Electron.MenuItemConstructorOptions | Electron.MenuItem)[] = [
{
label: "唐僧叨叨",
submenu: [
{
label: `关于唐僧叨叨`,
},
{ label: "服务", role: "services" },
{ type: "separator" },
{
label: "退出",
accelerator: "Command+Q",
click() {
forceQuit = true;
mainWindow = null;
setTimeout(() => {
app.exit(0);
}, 1000);
},
},
],
},
{
label: "编辑",
submenu: [
{
role: "undo",
label: "撤销",
},
{
role: "redo",
label: "重做",
},
{
type: "separator",
},
{
role: "cut",
label: "剪切",
},
{
role: "copy",
label: "复制",
},
{
role: "paste",
label: "粘贴",
},
{
role: "pasteAndMatchStyle",
label: "粘贴并匹配样式",
},
{
role: "delete",
label: "删除",
},
{
role: "selectAll",
label: "全选",
},
],
},
{
label: "显示",
submenu: [
{
label: isFullScreen ? "全屏" : "退出全屏",
accelerator: "Shift+Cmd+F",
click() {
isFullScreen = !isFullScreen;
mainWindow.show();
mainWindow.setFullScreen(isFullScreen);
},
},
{
label: "切换会话",
accelerator: "Shift+Cmd+M",
click() {
mainWindow.show();
mainWindow.webContents.send("show-conversations");
},
},
{
type: "separator",
},
{
type: "separator",
},
{
role: "toggleDevTools",
label: "切换开发者工具",
},
{
role: "togglefullscreen",
label: "切换全屏",
},
],
},
{
label: "窗口",
role: "window",
submenu: [
{
label: "最小化",
role: "minimize",
},
{
label: "关闭窗口",
role: "close",
},
],
},
{
label: "帮助",
role: "help",
submenu: [
{
type: "separator",
},
{
role: "reload",
label: "刷新",
},
{
role: "forceReload",
label: "强制刷新",
},
],
},
];
let trayMenu: Electron.MenuItemConstructorOptions[] = [
{
label: "显示窗口",
click() {
let isVisible = mainWindow.isVisible();
isVisible ? mainWindow.hide() : mainWindow.show();
},
},
{
type: "separator",
},
{
label: "退出",
accelerator: "Command+Q",
click() {
forceQuit = true;
mainWindow = null;
setTimeout(() => {
app.exit(0);
}, 1000);
},
},
];
function updateTray(unread = 0): any {
settings.showOnTray = true;
// linux 系统不支持 tray
if (process.platform === "linux") {
return;
}
if (settings.showOnTray) {
let contextmenu = Menu.buildFromTemplate(trayMenu);
if (!trayIcon) {
trayIcon = getNoMessageTrayIcon();
}
setTimeout(() => {
if (!tray) {
// Init tray icon
tray = new Tray(trayIcon);
if (process.platform === "linux") {
tray.setContextMenu(contextmenu);
}
tray.on("right-click", () => {
tray.popUpContextMenu(contextmenu);
});
tray.on("click", () => {
mainWindow.show();
});
}
if (isOsx) {
tray.setTitle(unread > 0 ? " " + unread : "");
}
tray.setImage(trayIcon);
});
} else {
if (!tray) return;
tray.destroy();
tray = null;
}
}
function createMenu() {
var menu = Menu.buildFromTemplate(mainMenu);
if (isOsx) {
Menu.setApplicationMenu(menu);
} else {
mainWindow.setMenu(null);
}
}
function regShortcut() {
globalShortcut.register("CommandOrControl+shift+a", () => {
isMainWindowFocusedWhenStartScreenshot = mainWindow.isFocused();
console.log(
"isMainWindowFocusedWhenStartScreenshot",
mainWindow.isFocused()
);
screenshots.startCapture();
});
// 打开所有窗口控制台
globalShortcut.register("ctrl+shift+i", () => {
let windows = BrowserWindow.getAllWindows();
windows.forEach((win: any) => win.openDevTools());
});
}
const createMainWindow = async () => {
const NODE_ENV = process.env.NODE_ENV;
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
mainWindow = new BrowserWindow({
width: 960,
height: 600,
minWidth: 960,
minHeight: 600,
// frame: true, // * app边框(包括关闭,全屏,最小化按钮的导航栏) @false: 隐藏
// titleBarStyle: "hidden",
// transparent: true, // * app 背景透明
hasShadow: false, // * app 边框阴影
show: false, // 启动窗口时隐藏,直到渲染进程加载完成「ready-to-show 监听事件」 再显示窗口,防止加载时闪烁
resizable: true, // 禁止手动修改窗口尺寸
webPreferences: {
// 加载脚本
preload: join(__dirname, "..", "preload/index"),
nodeIntegration: true,
},
// frame: !isWin,
});
mainWindow.center();
mainWindow.once("ready-to-show", () => {
mainWindow.show(); // 显示窗口
mainWindow.focus();
});
mainWindow.on("close", (e: any) => {
if (forceQuit || !tray) {
mainWindow = null;
} else {
e.preventDefault();
if (mainWindow.isFullScreen()) {
mainWindow.setFullScreen(false);
mainWindow.once("leave-full-screen", () => mainWindow.hide());
} else {
mainWindow.hide();
}
}
});
if (NODE_ENV === "development") mainWindow.loadURL("http://localhost:3000");
if (NODE_ENV !== "development") {
process.env.DIST_ELECTRON = join(__dirname, "../");
const WEB_URL = join(process.env.DIST_ELECTRON, "../build/index.html");
mainWindow.loadFile(WEB_URL);
}
ipcMain.on("screenshots-start", (event, args) => {
console.log("main voip-message event", args);
screenShotWindowId = event.sender.id;
screenshots.startCapture();
});
createMenu();
};
function onDeepLink(url: string) {
console.log("onOpenDeepLink", url);
mainWindow.webContents.send("deep-link", url);
}
app.setName(TSDD_FONFIG.name);
isDevelopment && app.dock && app.dock.setIcon(logo);
app.on("open-url", (event, url) => {
onDeepLink(url);
});
// 单例模式启动
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
app.on("second-instance", (event, argv) => {
if (mainWindow) {
mainWindow.show();
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.focus();
}
});
}
app.on("ready", () => {
regShortcut();
createMainWindow(); // 创建窗口
screenshots = new Screenshots({
singleWindow: true,
});
const onScreenShotEnd = (result?: any) => {
console.log(
"onScreenShotEnd",
isMainWindowFocusedWhenStartScreenshot,
screenShotWindowId
);
if (isMainWindowFocusedWhenStartScreenshot) {
if (result) {
mainWindow.webContents.send("screenshots-ok", result);
}
mainWindow.show();
isMainWindowFocusedWhenStartScreenshot = false;
} else if (screenShotWindowId) {
let windows = BrowserWindow.getAllWindows();
let tms = windows.filter(
(win) => win.webContents.id === screenShotWindowId
);
if (tms.length > 0) {
if (result) {
tms[0].webContents.send("screenshots-ok", result);
}
tms[0].show();
}
screenShotWindowId = 0;
}
};
// 截图添加快捷键esc
screenshots.on('windowCreated', ($win) => {
$win.on('focus', () => {
globalShortcut.register('esc', () => {
if ($win?.isFocused()) {
screenshots.endCapture();
}
});
});
$win.on('blur', () => {
globalShortcut.unregister('esc');
});
});
// 点击确定按钮回调事件
screenshots.on("ok", (e, buffer, bounds) => {
let filename = tmp.tmpNameSync() + '.png';
let image = NativeImage.createFromBuffer(buffer);
fs.writeFileSync(filename, image.toPNG());
console.log("screenshots ok", e);
onScreenShotEnd({ filePath: filename });
});
// 点击取消按钮回调事件
screenshots.on("cancel", (e: any) => {
// 执行了preventDefault
// 点击取消不会关闭截图窗口
// e.preventDefault()
// console.log('capture', 'cancel2')
console.log("screenshots cancel", e);
onScreenShotEnd();
});
// 点击保存按钮回调事件
screenshots.on("save", (e, { viewer }) => {
console.log("screenshots save", e);
onScreenShotEnd();
});
try {
updateTray();
} catch (e) {
// do nothing
console.log("==updateTray==", e);
}
});
app.on("activate", () => {
if (!mainWindow) {
return createMainWindow();
}
if (!mainWindow.isVisible()) {
mainWindow.show();
}
});
app.on("before-quit", () => {
forceQuit = true;
if (!tray) return;
tray.destroy();
tray = null;
});
// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 macOS窗口全部关闭时,dock中程序不会退出
app.on("window-all-closed", () => {
process.platform !== "darwin" && app.quit();
});