index.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { app, BrowserWindow, net, protocol, shell } from 'electron'
  2. import path from 'path'
  3. import { pathToFileURL } from 'url'
  4. import { initSteam } from './services/steam.service'
  5. import { initLibrary } from './services/library.service'
  6. import { startWatcher } from './services/watcher.service'
  7. import { registerAllHandlers } from './ipc'
  8. import { initDesktopIcons, cleanupDesktopIcons } from './services/desktop-icons.service'
  9. import { getTrayEnabled, getAutostartPlaylistId, getKillLweOnQuit } from './services/config.service'
  10. import { createTray } from './services/tray.service'
  11. import { initPlaylistPlayer, startPlaylist } from './services/playlist-player.service'
  12. import { killAllLweProcesses, getLweStatus } from './services/lwe.service'
  13. const startMinimized = process.argv.includes('--minimized')
  14. let isQuitting = false
  15. let hasKilledLweOnQuit = false
  16. function createWindow(): BrowserWindow {
  17. const win = new BrowserWindow({
  18. width: 1280,
  19. height: 800,
  20. minWidth: 900,
  21. minHeight: 600,
  22. backgroundColor: '#0f0f0f',
  23. titleBarStyle: 'hiddenInset',
  24. show: !(startMinimized && getTrayEnabled()),
  25. webPreferences: {
  26. preload: path.join(__dirname, '../preload/index.cjs'),
  27. contextIsolation: true,
  28. nodeIntegration: false,
  29. sandbox: false
  30. }
  31. })
  32. win.webContents.setWindowOpenHandler(({ url }) => {
  33. shell.openExternal(url)
  34. return { action: 'deny' }
  35. })
  36. // When the tray is enabled, closing the window hides it instead of quitting so the
  37. // tray icon remains the only way back in (and the app keeps running for playlists).
  38. win.on('close', (event) => {
  39. if (getTrayEnabled() && !isQuitting) {
  40. event.preventDefault()
  41. win.hide()
  42. }
  43. })
  44. if (process.env.NODE_ENV === 'development' && process.env['ELECTRON_RENDERER_URL']) {
  45. win.loadURL(process.env['ELECTRON_RENDERER_URL'])
  46. } else {
  47. win.loadFile(path.join(__dirname, '../renderer/index.html'))
  48. }
  49. return win
  50. }
  51. app.whenReady().then(() => {
  52. // Serve local wallpaper files via custom protocol
  53. protocol.handle('wallpaper', (request) => {
  54. const filePath = decodeURIComponent(request.url.replace('wallpaper://', ''))
  55. return net.fetch(pathToFileURL(filePath).toString())
  56. })
  57. const steamOk = initSteam()
  58. if (!steamOk) {
  59. console.warn('[App] Steam unavailable, subscription features disabled')
  60. }
  61. initLibrary()
  62. const win = createWindow()
  63. registerAllHandlers(win)
  64. startWatcher(win)
  65. initDesktopIcons()
  66. const resumed = initPlaylistPlayer(win)
  67. if (getTrayEnabled()) createTray(win)
  68. const autostartPlaylistId = getAutostartPlaylistId()
  69. if (!resumed && autostartPlaylistId && getLweStatus().installed) {
  70. try {
  71. startPlaylist(autostartPlaylistId)
  72. } catch (err) {
  73. console.error('[App] Failed to autostart playlist:', err)
  74. }
  75. }
  76. })
  77. app.on('before-quit', (event) => {
  78. isQuitting = true
  79. if (getKillLweOnQuit() && !hasKilledLweOnQuit) {
  80. event.preventDefault()
  81. hasKilledLweOnQuit = true
  82. killAllLweProcesses().finally(() => app.quit())
  83. }
  84. })
  85. app.on('window-all-closed', () => {
  86. cleanupDesktopIcons()
  87. if (process.platform !== 'darwin') app.quit()
  88. })
  89. app.on('activate', () => {
  90. if (BrowserWindow.getAllWindows().length === 0) {
  91. createWindow()
  92. } else {
  93. BrowserWindow.getAllWindows()[0].show()
  94. }
  95. })