/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { app, BrowserWindow, ipcMain, Menu, Notification, screen } from 'electron'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { io } from 'socket.io-client'; import { addEmail, deleteEmail, deleteMessage, fetchEmails, fetchMessages } from '../src/apis'; import { createMailWindow } from './windows/mails.window'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // The built directory structure // // ├─┬─┬ dist // │ │ └── index.html // │ │ // │ ├─┬ dist-electron // │ │ ├── main.js // │ │ └── preload.mjs // │ process.env.APP_ROOT = path.join(__dirname, '..'); // 🚧 Use ['ENV_NAME'] avoid vite:define plugin - Vite@2.x export const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']; export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron'); export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist'); process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, 'public') : RENDERER_DIST; let win: BrowserWindow | null; Menu.setApplicationMenu(null); function createWindow() { // Lấy thông tin tất cả các màn hình const displays = screen.getAllDisplays(); // Lấy vị trí con trỏ chuột const cursorPoint = screen.getCursorScreenPoint(); // Tìm màn hình có chứa con trỏ chuột let display = displays.find((display) => { const { x, y, width, height } = display.bounds; return cursorPoint.x >= x && cursorPoint.x <= x + width && cursorPoint.y >= y && cursorPoint.y <= y + height; }); // Nếu không tìm thấy màn hình chứa con trỏ, sử dụng màn hình chính if (!display) { display = screen.getPrimaryDisplay(); } const { width, height } = display.workAreaSize; // Vị trí cửa sổ ở góc phải dưới của màn hình đã chọn win = new BrowserWindow({ width: 400, height: 400, x: 0, // Đặt cửa sổ ở góc phải y: 0, // Đặt cửa sổ ở góc dưới alwaysOnTop: true, // Cửa sổ luôn nằm trên các cửa sổ khác resizable: true, // Không cho phép thay đổi kích thước icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'), webPreferences: { preload: path.join(__dirname, 'preload.mjs'), }, }); // Test active push message to Renderer-process. win.webContents.on('did-finish-load', () => { win?.webContents.send('main-process-message', new Date().toLocaleString()); }); win.setPosition(width - 400, height - 400); if (VITE_DEV_SERVER_URL) { win.loadURL(VITE_DEV_SERVER_URL); } else { // win.loadFile('dist/index.html') win.loadFile(path.join(RENDERER_DIST, 'index.html')); } } // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); win = null; } }); app.on('activate', () => { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); app.whenReady().then(createWindow); // IPC Main Events ipcMain.on('open-devtools', (event) => { const webContents = event.sender; webContents.openDevTools({ mode: 'detach' }); }); // Xử lý connect socket ipcMain.handle('connect-socket', async (_) => { const socket = io('https://zulip.ipsupply.com.au', { path: '/apac-custom/socket.io', secure: true, query: { token: import.meta.env.VITE_API_KEY }, rejectUnauthorized: false, }); if (!socket.connected) { socket.connect(); } socket.on('connect', () => { console.log(socket.connected); // true }); socket.on('newNote', (data) => { win?.webContents.send('newNote', data); }); }); ipcMain.handle('fetchMessages', async () => { return await fetchMessages(); }); ipcMain.handle('fetchEmails', async () => { return await fetchEmails(); }); ipcMain.handle('open-new-window', async () => { createMailWindow({ RENDERER_DIST }); }); ipcMain.handle('add-email', async (_, email: string) => { return addEmail(email); }); ipcMain.handle('del-email', async (_, id: number) => { return deleteEmail(id); }); ipcMain.handle('del-message', async (_, id: number) => { return deleteMessage(id); }); ipcMain.handle('show-notification', async (_, { title, body }) => { const notification = new Notification({ title, body, silent: false, }); notification.show(); });