diff --git a/build/icon.png b/build/icon.png deleted file mode 100644 index dde0232..0000000 Binary files a/build/icon.png and /dev/null differ diff --git a/build/icon16x16.png b/build/icon16x16.png new file mode 100644 index 0000000..8795861 Binary files /dev/null and b/build/icon16x16.png differ diff --git a/electron-builder.json5 b/electron-builder.json5 index 0429429..70d1577 100644 --- a/electron-builder.json5 +++ b/electron-builder.json5 @@ -1,46 +1,48 @@ { - "$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json", - "appId": "b1730d2e-6f3c-4f92-9f4a-9f8e918b40d2", - "productName": "Zulip messages", - "asar": { - "smartUnpack": true + $schema: "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json", + appId: "b1730d2e-6f3c-4f92-9f4a-9f8e918b40d2", + productName: "Zulip notes", + asar: { + smartUnpack: true, }, - "compression": "maximum", - "directories": { - "output": "release/${version}" + compression: "maximum", + directories: { + output: "release/${version}", }, - "files": [ + files: [ "dist/**", "dist-electron/**", "!**/*.map", "!**/*.ts", "!**/*.md", - "!**/__tests__/**" + "!**/__tests__/**", ], - "mac": { - "target": ["dmg"], - "artifactName": "${productName}-Mac-${version}-Installer.${ext}", - "icon": "build/icons/icon.icns" + mac: { + target: ["dmg"], + artifactName: "${productName}-Mac-${version}-Installer.${ext}", + icon: "build/icons/icon.icns", }, - "win": { - "target": [ + win: { + target: [ { - "target": "nsis", - "arch": ["x64"] - } + // "target": "nsis", + target: "portable", + arch: ["x64"], + }, ], - "artifactName": "${productName}-Windows-${version}-Setup.${ext}", - "icon": "build/icons/icon.ico" + // "artifactName": "${productName}-Windows-${version}-Setup.${ext}", + artifactName: "${productName}-Windows-${version}.${ext}", + icon: "build/icons/icon.ico", }, - "linux": { - "target": ["AppImage"], - "artifactName": "${productName}-Linux-${version}.${ext}", - "icon": "build/icons/icon.png" + linux: { + target: ["AppImage"], + artifactName: "${productName}-Linux-${version}.${ext}", + icon: "build/icons/icon.png", + }, + nsis: { + oneClick: false, + perMachine: false, + allowToChangeInstallationDirectory: true, + deleteAppDataOnUninstall: false, }, - "nsis": { - "oneClick": false, - "perMachine": false, - "allowToChangeInstallationDirectory": true, - "deleteAppDataOnUninstall": false - } } diff --git a/electron/main.ts b/electron/main.ts index f7ba552..cdeae20 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -7,6 +7,7 @@ import { Menu, Notification, screen, + Tray, } from "electron"; import path from "node:path"; import { fileURLToPath } from "node:url"; @@ -42,11 +43,11 @@ process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL : RENDERER_DIST; let win: BrowserWindow | null; +let tray; +let isQuiting = false; Menu.setApplicationMenu(null); - - function createWindow() { // Lấy thông tin tất cả các màn hình const displays = screen.getAllDisplays(); @@ -72,16 +73,22 @@ function createWindow() { const { width, height } = display.workAreaSize; + const browserWidth = 400; + const browserHeight = 400; + // 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, + width: browserWidth, + height: browserHeight, 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(app.isPackaged ? process.resourcesPath : ".", 'build/icons/icon.png'), + icon: path.join( + app.isPackaged ? process.resourcesPath : ".", + "build/icons/icon24x24.png" + ), // icon: path.join(process.env.VITE_PUBLIC ,'assets', 'icon.png'), webPreferences: { preload: path.join(__dirname, "preload.mjs"), @@ -93,7 +100,7 @@ function createWindow() { win?.webContents.send("main-process-message", new Date().toLocaleString()); }); - win.setPosition(width - 400, height - 400); + win.setPosition(width - browserWidth, height - browserHeight); if (VITE_DEV_SERVER_URL) { win.loadURL(VITE_DEV_SERVER_URL); @@ -101,6 +108,41 @@ function createWindow() { // win.loadFile('dist/index.html') win.loadFile(path.join(RENDERER_DIST, "index.html")); } + + // Khi bấm dấu X + win.on("close", (event) => { + if (!isQuiting) { + event.preventDefault(); + win?.hide(); + } + }); +} + +function createTray() { + tray = new Tray(path.join(process.env.VITE_PUBLIC, "assets", "icon16x16.png")); + + const contextMenu = Menu.buildFromTemplate([ + { + label: "Show", + click: () => { + win?.show(); + }, + }, + { + label: "Quit", + click: () => { + isQuiting = true; + app.quit(); + }, + }, + ]); + + tray.setToolTip("Zulip notes"); + tray.setContextMenu(contextMenu); + + tray.on("double-click", () => { + win?.show(); + }); } // Quit when all windows are closed, except on macOS. There, it's common @@ -121,7 +163,12 @@ app.on("activate", () => { } }); -app.whenReady().then(createWindow); +app.whenReady().then(() => { + // tạo cửa sổ chính + createWindow(); + // tạo cửa sổ chạy nền + createTray(); +}); // IPC Main Events ipcMain.on("open-devtools", (event) => { diff --git a/public/assets/icon.png b/public/assets/icon.png deleted file mode 100644 index f2959fd..0000000 Binary files a/public/assets/icon.png and /dev/null differ diff --git a/public/assets/icon16x16.png b/public/assets/icon16x16.png new file mode 100644 index 0000000..8795861 Binary files /dev/null and b/public/assets/icon16x16.png differ diff --git a/public/assets/icon24x24.png b/public/assets/icon24x24.png new file mode 100644 index 0000000..8d6d64b Binary files /dev/null and b/public/assets/icon24x24.png differ diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index f546a3a..f2ec6bf 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -2,22 +2,22 @@ /// declare global { - interface Window { - electronAPI: { - // openDevTools: () => void; - onNewNote: (data: any) => void; - }; - } + interface Window { + electronAPI: { + // openDevTools: () => void; + onNewNote: (data: any) => void; + }; + } } interface IMessage { - id: number; - sender: string; - time: number; - message: string; + id: number; + sender: string; + time: number; + message: string; } interface IEmail { - id: number; - email: string; + id: number; + email: string; }