diff --git a/package.json b/package.json index 1fa3ec89..7536f71a 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "build:default": "GENERATE_SOURCEMAP=false CI=false react-scripts build", "prebuild": "node -e \"let pkg=require('./package.json'); pkg.homepage='/'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));\"", "postbuild": "run-script-os", - "postbuild:win32": "node -e \"let pkg=require('./package.json'); pkg.homepage='.'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));\" && del /q build\\app && rm -rf build\\preload.js && rm -rf build\\renderer.js && rm -rf build\\electron.js", + "postbuild:win32": "node -e \"let pkg=require('./package.json'); pkg.homepage='.'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));\" && del /q build\\app && del /q build\\preload.js && del /q build\\renderer.js && del /q build\\electron.js", "postbuild:default": "node -e \"let pkg=require('./package.json'); pkg.homepage='.'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));\" && rm -rf build/app && rm -rf build/preload.js && rm -rf build/renderer.js && rm -rf build/electron.js", "buildhass": "GENERATE_SOURCEMAP=false CI=false react-scripts build", "prebuildhass": "node -e \"let pkg=require('./package.json'); pkg.homepage='./'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));\"", @@ -195,6 +195,7 @@ "@types/eslint__js": "^8.42.3", "@types/node": "^22.10.2", "@types/prop-types": "^15.7.11", + "@types/qrcode": "^1.5.5", "@types/react": "^18.3.12", "@types/react-beautiful-dnd": "^13.1.8", "@types/react-dom": "^18.2.19", @@ -287,4 +288,4 @@ ] } } -} +} \ No newline at end of file diff --git a/src/app/app/handlers.js b/src/app/app/handlers.mts similarity index 70% rename from src/app/app/handlers.js rename to src/app/app/handlers.mts index 33e6c9a3..03f882ea 100644 --- a/src/app/app/handlers.js +++ b/src/app/app/handlers.mts @@ -1,34 +1,47 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { app, shell, BrowserWindow, nativeTheme } from 'electron' import path from 'path' import { generateMfaQr, handleVerifyOTP } from './otp.js' -import { startInstance, stopInstance, sendStatus } from './instances.js' +import { + startInstance, + stopInstance, + sendStatus, + Subprocesses, + IPlatform +} from './instances.mjs' import coreParams from './utils/coreParams.mjs' import defaultCoreParams from './utils/defaultCoreParams.mjs' import store from './utils/store.mjs' import isCC from './utils/isCC.mjs' -export const handlers = async (wind, subprocesses, event, parameters) => { +export const handlers = async ( + wind: BrowserWindow, + subprocesses: Subprocesses, + event: any, + parameters: any +) => { console.log('ALL PARAMS', parameters) try { switch (parameters.command) { case 'close-others': - BrowserWindow.getAllWindows().forEach(win => { + BrowserWindow.getAllWindows().forEach((win) => { if (win !== wind) { - win.close(); + win.close() } - }); - break; - case 'get-all-windows': + }) + break + case 'get-all-windows': { const allWIndows = BrowserWindow.getAllWindows() console.log('allWIndows', allWIndows) wind.webContents.send('fromMain', ['all-windows', allWIndows]) break + } case 'verify_otp': - handleVerifyOTP(wind, event, parameters) + handleVerifyOTP(wind, parameters) break case 'generate-mfa-qr': - generateMfaQr(event, parameters) + generateMfaQr(wind) break case 'get-platform': wind.webContents.send('fromMain', ['platform', process.platform]) @@ -39,7 +52,7 @@ export const handlers = async (wind, subprocesses, event, parameters) => { 'coreParams', coreParams[process.platform] ]) - sendStatus(wind, subprocesses) + sendStatus(wind, subprocesses, false, parameters.instance) } break case 'start-core': @@ -81,12 +94,12 @@ export const handlers = async (wind, subprocesses, event, parameters) => { case 'delete-core-params': if (isCC) { store.set('coreParams', defaultCoreParams) - coreParams.darwin = defaultCoreParams['darwin'] - coreParams.win32 = defaultCoreParams['win32'] - coreParams.linux = defaultCoreParams['linux'] + coreParams.darwin = defaultCoreParams.darwin + coreParams.win32 = defaultCoreParams.win32 + coreParams.linux = defaultCoreParams.linux wind.webContents.send('fromMain', [ 'coreParams', - defaultCoreParams[process.platform] + defaultCoreParams[process.platform as IPlatform] ]) app.relaunch() app.exit() @@ -97,20 +110,35 @@ export const handlers = async (wind, subprocesses, event, parameters) => { if (parameters.instance && parameters.instance !== 'instance1') { shell.showItemInFolder( - path.join(app.getPath("userData"), '.ledfx-cc', parameters.instance, 'config.json') + path.join( + app.getPath('userData'), + '.ledfx-cc', + parameters.instance, + 'config.json' + ) ) shell.showItemInFolder( - path.join(app.getPath("appData"), '.ledfx-cc', parameters.instance, 'config.json') + path.join( + app.getPath('appData'), + '.ledfx-cc', + parameters.instance, + 'config.json' + ) ) shell.showItemInFolder( - path.join(app.getPath("home"), '.ledfx-cc', parameters.instance, 'config.json') + path.join( + app.getPath('home'), + '.ledfx-cc', + parameters.instance, + 'config.json' + ) ) } else { shell.showItemInFolder( - path.join(app.getPath("userData"), '.ledfx', 'config.json') + path.join(app.getPath('userData'), '.ledfx', 'config.json') ) shell.showItemInFolder( - path.join(app.getPath("appData"), '.ledfx', 'config.json') + path.join(app.getPath('appData'), '.ledfx', 'config.json') ) shell.showItemInFolder( path.join(app.getPath('home'), '.ledfx', 'config.json') @@ -137,4 +165,3 @@ export const handlers = async (wind, subprocesses, event, parameters) => { console.error(`Error handling command "${parameters.command}": ${error}`) } } - diff --git a/src/app/app/instances.js b/src/app/app/instances.mts similarity index 55% rename from src/app/app/instances.js rename to src/app/app/instances.mts index 866fb3e3..145aec16 100644 --- a/src/app/app/instances.js +++ b/src/app/app/instances.mts @@ -1,22 +1,49 @@ import { BrowserWindow } from 'electron' import coreParams from './utils/coreParams.mjs' import startCore from './utils/startCore.mjs' +import { ChildProcessWithoutNullStreams } from 'child_process' -export const poll = async (wind, subprocesses, name, p) => { +export interface Subprocess extends ChildProcessWithoutNullStreams { + running?: boolean +} + +export interface Subprocesses { + [key: string]: Subprocess +} + +export type IPlatform = 'darwin' | 'win32' | 'linux' + +export function kills(subprocess: Subprocess | null): void { + if (subprocess !== null) { + subprocess.kill('SIGINT') + } +} + +export const poll = async ( + wind: BrowserWindow, + subprocesses: Subprocesses, + name: string, + p: string +) => { console.log('Polling core', name, 'on port', p) if (!p) return try { const response = await fetch(`http://127.0.0.1:${p}/api/info`) - const data = await response.json() + await response.json() sendStatus(wind, subprocesses, true, name) console.log('Polling core succeeded') - } catch (err) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (e) { console.log('Polling core ...') setTimeout(() => poll(wind, subprocesses, name, p), 1000) } } -export function stopInstance(wind, name, subprocesses) { +export function stopInstance( + wind: BrowserWindow, + name: string, + subprocesses: Subprocesses +) { if (subprocesses[name]) { subprocesses[name].running = false sendStatus(wind, subprocesses, false, name) @@ -24,14 +51,23 @@ export function stopInstance(wind, name, subprocesses) { } } -export function startInstance(wind, name, subprocesses, port) { +export function startInstance( + wind: BrowserWindow, + name: string, + subprocesses: Subprocesses, + port: string = '8889' +) { try { - let subpy = startCore(wind, process.platform, name, port) + const subpy = startCore(wind, process.platform as IPlatform, name, port) if (subpy !== null) { subprocesses[name] = subpy subprocesses[name].running = true sendStatus(wind, subprocesses, false, name) poll(wind, subprocesses, name, port) + if (!subpy) { + console.error('Error starting subprocess') + return + } subpy.on('exit', () => { if (subprocesses[name]) { subprocesses[name].running = false @@ -39,13 +75,13 @@ export function startInstance(wind, name, subprocesses, port) { if (wind && wind.webContents && !wind.isDestroyed() && subprocesses) { // `subprocesses` is defined, proceed with calling `sendStatus` try { - sendStatus(wind, subprocesses, false, name); + sendStatus(wind, subprocesses, false, name) } catch (error) { - console.error(error); + console.error(error) } } else { // `subprocesses` is not defined, handle this case as needed - console.error('subprocesses is not defined'); + console.error('subprocesses is not defined') } }) subpy.on('error', () => { @@ -60,28 +96,33 @@ export function startInstance(wind, name, subprocesses, port) { } } -export function sendStatus(wind, subprocesses, connected = false, n) { - let status = {} - let platformParams = coreParams[process.platform] +export function sendStatus( + wind: BrowserWindow, + subprocesses: Subprocesses, + connected = false, + n: string +) { + const status: { [key: string]: string } = {} + const platformParams = coreParams[process.platform] // Check if `wind` is an instance of `BrowserWindow` if (!(wind instanceof BrowserWindow)) { - console.error('wind is not an instance of BrowserWindow'); - return; + console.error('wind is not an instance of BrowserWindow') + return } // Check if `subprocesses` is defined if (!subprocesses) { - console.error('subprocesses is not defined'); - return; + console.error('subprocesses is not defined') + return } // Check if `n` is defined if (!n) { - console.error('n is not defined'); - return; + console.error('n is not defined') + return } - for (let name in platformParams) { + for (const name in platformParams) { if (subprocesses && subprocesses[name]) { if (name === n) { status[name] = connected @@ -96,17 +137,17 @@ export function sendStatus(wind, subprocesses, connected = false, n) { status[name] = 'stopped' } } - if (wind && wind.webContents && !wind.isDestroyed() && status) wind.webContents.send('fromMain', ['status', status]) -} - -export function kills(subprocess) { - if (subprocess !== null) { - subprocess.kill('SIGINT') - } + if (wind && wind.webContents && !wind.isDestroyed() && status) + wind.webContents.send('fromMain', ['status', status]) } -export function closeAllSubs(wind, subpy, subprocesses) { - if (wind && wind.webContents && !wind.isDestroyed()) wind.webContents.send('fromMain', 'shutdown') +export function closeAllSubs( + wind: BrowserWindow, + subpy: Subprocess, + subprocesses: Subprocesses +) { + if (wind && wind.webContents && !wind.isDestroyed()) + wind.webContents.send('fromMain', 'shutdown') if (subpy !== null) kills(subpy) if (subprocesses && Object.keys(subprocesses).length > 0) { Object.values(subprocesses).forEach((sub) => { @@ -114,4 +155,3 @@ export function closeAllSubs(wind, subpy, subprocesses) { }) } } - diff --git a/src/app/app/media.js b/src/app/app/media.ts similarity index 58% rename from src/app/app/media.js rename to src/app/app/media.ts index 9df3a7c4..55bf478f 100644 --- a/src/app/app/media.js +++ b/src/app/app/media.ts @@ -1,9 +1,20 @@ const { execFile } = require('child_process'); const path = require('path'); +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); const exePath = path.join(__dirname, 'path_to_dist_folder', 'media.exe'); -execFile(exePath, (error, stdout, stderr) => { +interface MediaInfo { + title: string; + artist: string; + album: string; + error?: string; +} + +execFile(exePath, (error: Error | null, stdout: string, stderr: string) => { if (error) { console.error(`Error: ${error.message}`); return; @@ -13,7 +24,7 @@ execFile(exePath, (error, stdout, stderr) => { return; } try { - const mediaInfo = JSON.parse(stdout); + const mediaInfo: MediaInfo = JSON.parse(stdout); if (mediaInfo.error) { console.log(mediaInfo.error); } else { @@ -22,6 +33,6 @@ execFile(exePath, (error, stdout, stderr) => { console.log(`Album: ${mediaInfo.album}`); } } catch (parseError) { - console.error(`JSON Parse Error: ${parseError.message}`); + console.error(`JSON Parse Error: ${(parseError as Error).message}`); } }); \ No newline at end of file diff --git a/src/app/app/otp.js b/src/app/app/otp.ts similarity index 85% rename from src/app/app/otp.js rename to src/app/app/otp.ts index 94daad6c..cf0a2fc0 100644 --- a/src/app/app/otp.js +++ b/src/app/app/otp.ts @@ -3,9 +3,10 @@ import qrcode from 'qrcode' import base32Decode from 'base32-decode' import base32Encode from 'base32-encode' import store from './utils/store.mjs' +import { BrowserWindow } from 'electron' -export function generateHOTP(secret, counter) { +export function generateHOTP(secret: string, counter: number) { const decodedSecret = base32Decode(secret, 'RFC4648'); const buffer = Buffer.alloc(8); @@ -31,12 +32,12 @@ export function generateHOTP(secret, counter) { return `${code % 10 ** 6}`.padStart(6, '0'); } -export function generateTOTP(secret, window = 0) { +export function generateTOTP(secret: string, window = 0) { const counter = Math.floor(Date.now() / 30000); return generateHOTP(secret, counter + window); } -export function verifyTOTP(token, secret, window = 1) { +export function verifyTOTP(token: string, secret: string, window = 1) { for (let errorWindow = -window; errorWindow <= +window; errorWindow++) { const totp = generateTOTP(secret, errorWindow); if (token === totp) { @@ -46,7 +47,7 @@ export function verifyTOTP(token, secret, window = 1) { return false; } -export function generateMfaQr(event, parameters) { +export function generateMfaQr(wind: BrowserWindow) { const user = store.get('user') || { username: 'FreeUser', mfaEnabled: false, @@ -73,11 +74,11 @@ export function generateMfaQr(event, parameters) { qrcode.toDataURL(configUri, { color: { dark: '#333333FF', light: '#00000000' }, - }).then((png=>wind.webContents.send('fromMain', ['mfa-qr-code', png]))); + }).then(((png: any) => wind.webContents.send('fromMain', ['mfa-qr-code', png]))); return; } -export function handleVerifyOTP(wind, event, parameters) { +export function handleVerifyOTP(wind: BrowserWindow, parameters: any) { const user = store.get('user') || { username: 'FreeUser', mfaEnabled: false, diff --git a/src/app/app/protocol.js b/src/app/app/protocol.js deleted file mode 100644 index 81abaad1..00000000 --- a/src/app/app/protocol.js +++ /dev/null @@ -1,48 +0,0 @@ -import { app } from 'electron' -import path from 'path' - -export const setupProtocol = () => { - (async () => { - const isSquirrelStartup = await import('electron-squirrel-startup'); - if (isSquirrelStartup.default) { - app.quit() - } - })() - - if (process.defaultApp) { - if (process.argv.length >= 2) { - app.setAsDefaultProtocolClient('ledfx', process.execPath, [ - path.resolve(process.argv[1]) - ]) - } - } else { - app.setAsDefaultProtocolClient('ledfx') - } -} - -export const handleProtocol = (getWind, gotTheLock, ready) => { - if (process.platform === 'win32') { - if (!gotTheLock) { - app.quit() - } else { - app.on('second-instance', (event, commandLine, workingDirectory) => { - const wind = getWind() - console.log(commandLine, wind) - if (wind) { - if (wind.isMinimized()) wind.restore() - wind.webContents.send('fromMain', [ - 'protocol', - JSON.stringify({ event, commandLine, workingDirectory }) - ]) - wind.focus() - } - }) - ready() - app.on('open-url', (event, url) => console.log(event, url)) - } - } else { - ready() - app.on('open-url', (event, url) => console.log(event, url)) - } -} - diff --git a/src/app/app/protocol.mts b/src/app/app/protocol.mts new file mode 100644 index 00000000..7317a5b5 --- /dev/null +++ b/src/app/app/protocol.mts @@ -0,0 +1,62 @@ +import { app } from 'electron' +import path from 'path' + +export const setupProtocol = () => { + ;(async () => { + const isSquirrelStartup = await import('electron-squirrel-startup') + if (isSquirrelStartup.default) { + app.quit() + } + })() + + if (process.defaultApp) { + if (process.argv.length >= 2) { + app.setAsDefaultProtocolClient('ledfx', process.execPath, [ + path.resolve(process.argv[1]) + ]) + } + } else { + app.setAsDefaultProtocolClient('ledfx') + } +} + +export const handleProtocol = ( + getWind: () => Electron.BrowserWindow | null, + gotTheLock: boolean, + ready: () => void +) => { + if (process.platform === 'win32') { + if (!gotTheLock) { + app.quit() + } else { + app.on( + 'second-instance', + ( + event: Electron.Event, + commandLine: string[], + workingDirectory: string + ) => { + const wind = getWind() + console.log(commandLine, wind) + if (wind) { + if (wind.isMinimized()) wind.restore() + wind.webContents.send('fromMain', [ + 'protocol', + JSON.stringify({ event, commandLine, workingDirectory }) + ]) + wind.focus() + } + } + ) + ready() + app.on('open-url', (event: Electron.Event, url: string) => + console.log(event, url) + ) + } + } else { + ready() + app.on('open-url', (event: Electron.Event, url: string) => + console.log(event, url) + ) + } +} diff --git a/src/app/app/toast.js b/src/app/app/toast.ts similarity index 93% rename from src/app/app/toast.js rename to src/app/app/toast.ts index 880a21ff..1faae695 100644 --- a/src/app/app/toast.js +++ b/src/app/app/toast.ts @@ -2,6 +2,7 @@ import fs from 'fs' import path from 'path' import { Notification } from 'electron' import { fileURLToPath } from 'node:url' +import isDev from 'electron-is-dev'; const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -11,7 +12,7 @@ const NOTIFICATION_BODY = 'Testing Notification from the Main process'; function getConfig() { const configPath = path.join(path.dirname(__dirname), isDev ? '../' : '../../', 'frontend_config.json') const configData = fs.readFileSync(configPath); - return JSON.parse(configData); + return JSON.parse(configData.toString()); } export function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION_BODY) { diff --git a/src/app/app/utils/coreFile.mjs b/src/app/app/utils/coreFile.mts similarity index 100% rename from src/app/app/utils/coreFile.mjs rename to src/app/app/utils/coreFile.mts diff --git a/src/app/app/utils/coreParams.mjs b/src/app/app/utils/coreParams.mts similarity index 100% rename from src/app/app/utils/coreParams.mjs rename to src/app/app/utils/coreParams.mts diff --git a/src/app/app/utils/corePath.mjs b/src/app/app/utils/corePath.mts similarity index 90% rename from src/app/app/utils/corePath.mjs rename to src/app/app/utils/corePath.mts index ba3f65f9..54034668 100644 --- a/src/app/app/utils/corePath.mjs +++ b/src/app/app/utils/corePath.mts @@ -5,7 +5,7 @@ import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) -const corePath = (file) => +const corePath = (file: string) => path.join( path.dirname(__dirname), isDev ? '../extraResources' : '../../extraResources', diff --git a/src/app/app/utils/defaultCoreParams.mjs b/src/app/app/utils/defaultCoreParams.mts similarity index 100% rename from src/app/app/utils/defaultCoreParams.mjs rename to src/app/app/utils/defaultCoreParams.mts diff --git a/src/app/app/utils/isCC.mjs b/src/app/app/utils/isCC.mts similarity index 52% rename from src/app/app/utils/isCC.mjs rename to src/app/app/utils/isCC.mts index a84d4416..fda121a2 100644 --- a/src/app/app/utils/isCC.mjs +++ b/src/app/app/utils/isCC.mts @@ -2,6 +2,8 @@ import fs from 'fs' import corePath from './corePath.mjs' import coreFile from './coreFile.mjs' -export const isCC = fs.existsSync(corePath(coreFile[process.platform])) +export const isCC = fs.existsSync( + corePath(coreFile[process.platform as 'darwin' | 'linux' | 'win32']) +) export default isCC diff --git a/src/app/app/utils/runCore.mjs b/src/app/app/utils/runCore.mts similarity index 68% rename from src/app/app/utils/runCore.mjs rename to src/app/app/utils/runCore.mts index 40c03284..9e6cd824 100644 --- a/src/app/app/utils/runCore.mjs +++ b/src/app/app/utils/runCore.mts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import * as cp from 'child_process' import corePath from './corePath.mjs' -const runCore = (file, options) => +const runCore = (file: string, options: any) => cp.spawn(`${corePath(file)}`, options).on('error', (err) => { console.error(`Failed to start subprocess. ${err}`) }) diff --git a/src/app/app/utils/startCore.mjs b/src/app/app/utils/startCore.mts similarity index 88% rename from src/app/app/utils/startCore.mjs rename to src/app/app/utils/startCore.mts index 11ab6606..7ff7fcc1 100644 --- a/src/app/app/utils/startCore.mjs +++ b/src/app/app/utils/startCore.mts @@ -1,4 +1,4 @@ -import { app } from 'electron' +import { app, BrowserWindow } from 'electron' import fs from 'fs' import path from 'path' import runCore from './runCore.mjs' @@ -6,9 +6,15 @@ import corePath from './corePath.mjs' import coreFile from './coreFile.mjs' import coreParams from './coreParams.mjs' import store from './store.mjs' +import { ChildProcessWithoutNullStreams } from 'child_process' -function startCore(wind, platform, instance = 'instance1', port = '8889') { - let subpy +function startCore( + wind: BrowserWindow, + platform: 'darwin' | 'linux' | 'win32', + instance = 'instance1', + port = '8889' +) { + let subpy: ChildProcessWithoutNullStreams | null = null if (fs.existsSync(corePath(coreFile[platform]))) { if (coreParams[platform] && instance && coreParams[platform][instance]) { diff --git a/src/app/app/utils/store.mjs b/src/app/app/utils/store.mjs deleted file mode 100644 index 0ebf2af3..00000000 --- a/src/app/app/utils/store.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import Store from 'electron-store' - -const store = new Store() - -export default store diff --git a/src/app/app/utils/store.mts b/src/app/app/utils/store.mts new file mode 100644 index 00000000..a5015e95 --- /dev/null +++ b/src/app/app/utils/store.mts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import Store from 'electron-store' + +const store: any = new Store() + +export default store diff --git a/src/app/app/utils/tray.mjs b/src/app/app/utils/tray.mts similarity index 89% rename from src/app/app/utils/tray.mjs rename to src/app/app/utils/tray.mts index 5e6fc32f..b21e29a5 100644 --- a/src/app/app/utils/tray.mjs +++ b/src/app/app/utils/tray.mts @@ -1,11 +1,15 @@ import path from 'path' -import { app, Menu, shell, Tray } from 'electron' +import { app, BrowserWindow, Menu, shell, Tray } from 'electron' import isDev from 'electron-is-dev' import startCore from './startCore.mjs' import coreParams from './coreParams.mjs' // import { download } from 'electron-dl' -export function createMenu(isCC, wind, thePath) { +export function createMenu( + isCC: boolean, + wind: BrowserWindow, + thePath: string +) { let contextMenu if (isCC) { @@ -31,7 +35,12 @@ export function createMenu(isCC, wind, thePath) { { label: 'seperator', type: 'separator' }, { label: 'Start core', - click: () => startCore(wind, process.platform, coreParams.instance) + click: () => + startCore( + wind, + process.platform as 'darwin' | 'linux' | 'win32', + coreParams.instance + ) }, { label: 'Stop core', @@ -91,7 +100,12 @@ export function createMenu(isCC, wind, thePath) { return contextMenu } -export function createTray(isCC, wind, thePath, dir) { +export function createTray( + isCC: boolean, + wind: BrowserWindow, + thePath: string, + dir: string +) { const icon = path.join(dir, 'icon_16x16a.png') const tray = new Tray(icon) diff --git a/src/app/app/utils/win.mjs b/src/app/app/utils/win.mts similarity index 91% rename from src/app/app/utils/win.mjs rename to src/app/app/utils/win.mts index 718d4b2a..65e7f643 100644 --- a/src/app/app/utils/win.mjs +++ b/src/app/app/utils/win.mts @@ -7,7 +7,8 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) -function createWindow(win, args = {}) { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function createWindow(win?: any, args = {}) { initialize() // Create the browser window. win = new BrowserWindow({ diff --git a/src/app/electron.ts b/src/app/electron.ts index 1ac49f42..251b06b6 100644 --- a/src/app/electron.ts +++ b/src/app/electron.ts @@ -1,15 +1,15 @@ import fs from 'fs'; import path from 'path'; -import isCC from './app/utils/isCC.mjs'; import isDev from 'electron-is-dev'; -import createWindow from './app/utils/win.mjs'; import { app, nativeTheme, BrowserWindow, ipcMain, shell, session } from 'electron'; -import { createTray } from './app/utils/tray.mjs'; -import { startInstance, closeAllSubs } from './app/instances.js'; -import { handlers } from './app/handlers.js'; -import { setupProtocol, handleProtocol } from './app/protocol.js'; import { EventEmitter } from 'events'; import { fileURLToPath } from 'node:url'; +import isCC from './app/utils/isCC.mjs'; +import createWindow from './app/utils/win.mjs'; +import { handleProtocol, setupProtocol } from './app/protocol.mjs'; +import { closeAllSubs, startInstance } from './app/instances.mjs'; +import { createTray } from './app/utils/tray.mjs' +import { handlers } from './app/handlers.mjs'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -63,10 +63,10 @@ const ready = () => createTray(isCC, wind, thePath, __dirname) ipcMain.on('toMain', async (event, parameters) => - handlers(wind, subprocesses, event, parameters) + wind && handlers(wind, subprocesses, event, parameters) ) wind.on('close', () => { - closeAllSubs(wind, subpy, subprocesses) + wind && closeAllSubs(wind, subpy, subprocesses) wind = null; }) }) @@ -74,11 +74,11 @@ const ready = () => handleProtocol(() => wind, gotTheLock, ready) app.on('window-all-closed', () => { - closeAllSubs(wind, subpy, subprocesses) + wind && closeAllSubs(wind, subpy, subprocesses) app.quit() }) -app.on('before-quit', () => closeAllSubs(wind, subpy, subprocesses)) +app.on('before-quit', () => wind && closeAllSubs(wind, subpy, subprocesses)) app.on( 'activate', diff --git a/src/electronsquirrelstartup.d..ts b/src/electronsquirrelstartup.d..ts new file mode 100644 index 00000000..ea53c53e --- /dev/null +++ b/src/electronsquirrelstartup.d..ts @@ -0,0 +1 @@ +declare module 'electron-squirrel-startup'; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 47c2bc76..9a288031 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,7 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "skipLibCheck": true + "skipLibCheck": true, }, "include": ["src"] }