1.1.3
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const { app, BrowserWindow, dialog, ipcMain, shell, screen, safeStorage, powerMonitor } = require('electron');
|
||||
const { app, BrowserWindow, dialog, ipcMain, shell, screen, safeStorage, powerMonitor, Notification, nativeImage } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
@@ -6,7 +6,7 @@ const fs = require('fs');
|
||||
const SESSION_FILE = path.join(app.getPath('userData'), 'secure-session.dat');
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
const { checkForUpdates } = require('./updater.cjs');
|
||||
const { checkForUpdates, getStatus: getUpdateStatus, onStatus: onUpdateStatus, downloadAndInstall: downloadAndInstallUpdate } = require('./updater.cjs');
|
||||
|
||||
function loadEnvVar(varName) {
|
||||
const envFiles = [
|
||||
@@ -191,6 +191,16 @@ function createWindow() {
|
||||
mainWindow.maximize();
|
||||
}
|
||||
|
||||
// Auto-clear attention state whenever the user comes back — no
|
||||
// point in flashing / badging a window the user is already
|
||||
// looking at.
|
||||
mainWindow.on('focus', () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.flashFrame(false);
|
||||
mainWindow.setOverlayIcon(null, '');
|
||||
try { app.setBadgeCount(0); } catch {}
|
||||
});
|
||||
|
||||
// Save window state on close
|
||||
mainWindow.on('close', () => {
|
||||
// Flush localStorage/sessionStorage to disk before renderer is destroyed
|
||||
@@ -249,14 +259,25 @@ app.whenReady().then(async () => {
|
||||
createWindow();
|
||||
} else {
|
||||
const splash = createSplashWindow();
|
||||
const noUpdate = await checkForUpdates(splash);
|
||||
if (noUpdate === false) {
|
||||
const shouldOpenMain = await checkForUpdates(splash);
|
||||
if (shouldOpenMain) {
|
||||
if (!splash.isDestroyed()) splash.close();
|
||||
createWindow();
|
||||
}
|
||||
// If update downloaded, quitAndInstall handles restart
|
||||
// Required-update path: splash stays; updater runs quitAndInstall itself.
|
||||
}
|
||||
|
||||
// Forward updater status changes to the renderer so the header
|
||||
// icon and the required-update blocker can react in real time.
|
||||
onUpdateStatus((status) => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('update:status', status);
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('update:get-status', () => getUpdateStatus());
|
||||
ipcMain.handle('update:download-and-install', () => downloadAndInstallUpdate());
|
||||
|
||||
ipcMain.on('window-minimize', () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
if (win) win.minimize();
|
||||
@@ -272,8 +293,49 @@ app.whenReady().then(async () => {
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
if (win) win.close();
|
||||
});
|
||||
ipcMain.on('flash-frame', () => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) mainWindow.flashFrame(true);
|
||||
ipcMain.on('flash-frame', (_event, on) => {
|
||||
if (!mainWindow || mainWindow.isDestroyed()) return;
|
||||
// `on` optional for backward compat — legacy call sites pass
|
||||
// no arg and expect a one-shot flash.
|
||||
mainWindow.flashFrame(on !== false);
|
||||
});
|
||||
|
||||
ipcMain.on('notification:show', (_event, opts) => {
|
||||
if (!Notification.isSupported()) return;
|
||||
const { title, body, silent } = opts || {};
|
||||
const n = new Notification({
|
||||
title: String(title ?? 'Brycord'),
|
||||
body: String(body ?? ''),
|
||||
silent: !!silent,
|
||||
icon: path.join(__dirname, 'icon.png'),
|
||||
});
|
||||
n.on('click', () => {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
if (mainWindow.isMinimized()) mainWindow.restore();
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
}
|
||||
});
|
||||
n.show();
|
||||
});
|
||||
|
||||
// Windows: overlay icon on the taskbar button (1x1 badge). Clearing
|
||||
// is `(null, '')`. `count <= 0` clears. Other OSes fall back to
|
||||
// `app.setBadgeCount` which is a no-op on platforms that don't
|
||||
// support it.
|
||||
ipcMain.on('notification:set-badge', (_event, count) => {
|
||||
if (!mainWindow || mainWindow.isDestroyed()) return;
|
||||
const n = Math.max(0, Math.floor(Number(count) || 0));
|
||||
if (n === 0) {
|
||||
mainWindow.setOverlayIcon(null, '');
|
||||
} else {
|
||||
const badgePath = path.join(__dirname, 'icon.png');
|
||||
try {
|
||||
const img = nativeImage.createFromPath(badgePath);
|
||||
mainWindow.setOverlayIcon(img, `${n} unread`);
|
||||
} catch {}
|
||||
}
|
||||
try { app.setBadgeCount(n); } catch {}
|
||||
});
|
||||
|
||||
// Helper to fetch metadata (Zero-Knowledge: Client fetches previews)
|
||||
|
||||
Reference in New Issue
Block a user