import { app, BrowserWindow, nativeTheme, systemPreferences } from 'electron' import { createMainWindow, createReminderWindow, showMainWindow } from './windows' import { registerIpc } from './ipc' import { startScheduler, stopScheduler } from './scheduler' import { createTray } from './tray' import { flushNow, getState } from './store' import { wasStartedHidden } from './autostart' import { broadcastState } from './state-actions' import { startGamesRegistry, stopGamesRegistry } from './games/registry' import { initUpdater, stopUpdater } from './updater' import { IPC } from '@shared/ipc' const APP_ID = 'com.anril.exercise-reminder' // Must be set BEFORE app.whenReady() for Windows toasts to show // the correct app name / icon in Action Center. app.setAppUserModelId(APP_ID) app.setName('Exercise Reminder') const gotLock = app.requestSingleInstanceLock() if (!gotLock) { app.quit() } else { app.on('second-instance', () => showMainWindow()) app.whenReady().then(() => { registerIpc() createTray() const hidden = wasStartedHidden() || getState().settings.startMinimized createMainWindow(!hidden) // Pre-create the reminder window so first-trigger is instant (no load lag). createReminderWindow() startScheduler() startGamesRegistry().catch((err) => console.error('games registry failed:', err) ) initUpdater() nativeTheme.on('updated', () => { const theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light' for (const win of BrowserWindow.getAllWindows()) { if (!win.isDestroyed()) win.webContents.send(IPC.evtThemeChanged, theme) } }) try { systemPreferences.on('accent-color-changed' as never, () => { try { const color = '#' + systemPreferences.getAccentColor() for (const win of BrowserWindow.getAllWindows()) { if (!win.isDestroyed()) win.webContents.send(IPC.evtAccentChanged, color) } } catch { // ignore } }) } catch { // older Electron / non-Windows } }) app.on('window-all-closed', () => { // Keep running in tray instead of quitting when all windows closed. if (!getState().settings.minimizeToTray) { app.quit() } }) app.on('before-quit', () => { stopScheduler() stopUpdater() void stopGamesRegistry() flushNow() }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createMainWindow(true) else showMainWindow() }) // Broadcast state once on ready so any prebuilt windows hydrate. app.whenReady().then(() => broadcastState()) }