From 95a4fb537703a2b959e86dcd4c4cd9b1e8210cd3 Mon Sep 17 00:00:00 2001 From: YeonV Date: Thu, 5 Dec 2024 01:29:38 +0100 Subject: [PATCH] Why don't you just update all libs & deps --- package.json | 10 +- public/app/core.js | 77 ------ public/app/devtools.js | 12 - public/app/handlers.js | 22 +- public/app/instances.js | 23 +- public/app/media.js | 27 +++ public/app/otp.js | 21 +- public/app/protocol.js | 19 +- public/app/toast.js | 12 +- public/app/utils/coreFile.mjs | 7 + public/app/utils/coreParams.mjs | 6 + public/app/utils/corePath.mjs | 15 ++ public/app/utils/defaultCoreParams.mjs | 13 + public/app/utils/isCC.mjs | 7 + public/app/utils/runCore.mjs | 9 + public/app/utils/startCore.mjs | 83 +++++++ public/app/utils/store.mjs | 5 + public/app/{tray.js => utils/tray.mjs} | 106 ++++---- public/app/{win.js => utils/win.mjs} | 25 +- public/electron.js | 52 ++-- src/components/Gamepad/Assign.tsx | 24 +- src/components/Webcam/Webcam.tsx | 10 +- src/components/Webcam/pixelMapper.cjs | 24 ++ src/components/Webcam/pixelMapper.js | 65 ----- src/components/Webcam/pixelUtils.cjs | 20 ++ src/components/Webcam/pixelUtils.js | 229 ------------------ src/components/Webcam/utils/adjust.cjs | 26 ++ .../Webcam/utils/calculateImageDifference.cjs | 93 +++++++ src/components/Webcam/utils/calibrate.cjs | 40 +++ .../Webcam/utils/createImageFromData.cjs | 14 ++ .../Webcam/utils/decodeBase64ToImageData.cjs | 11 + src/components/Webcam/utils/getLedCount.ts | 11 + src/components/Webcam/utils/initialize.cjs | 11 + .../Webcam/utils/iterativeOnOnlyOne.cjs | 64 +++++ src/components/Webcam/utils/oneLed.cjs | 37 +++ src/components/Webcam/utils/preadjust.cjs | 17 ++ src/components/Webcam/utils/processImages.cjs | 37 +++ .../Webcam/utils/setWledBrightness.cjs | 7 + src/components/Webcam/utils/wait.cjs | 3 + src/components/Webcam/utils/wled.cjs | 20 ++ src/components/Webcam/utils/wledGet.cjs | 17 ++ 41 files changed, 808 insertions(+), 523 deletions(-) delete mode 100644 public/app/core.js delete mode 100644 public/app/devtools.js create mode 100644 public/app/media.js create mode 100644 public/app/utils/coreFile.mjs create mode 100644 public/app/utils/coreParams.mjs create mode 100644 public/app/utils/corePath.mjs create mode 100644 public/app/utils/defaultCoreParams.mjs create mode 100644 public/app/utils/isCC.mjs create mode 100644 public/app/utils/runCore.mjs create mode 100644 public/app/utils/startCore.mjs create mode 100644 public/app/utils/store.mjs rename public/app/{tray.js => utils/tray.mjs} (57%) rename public/app/{win.js => utils/win.mjs} (67%) create mode 100644 src/components/Webcam/pixelMapper.cjs delete mode 100644 src/components/Webcam/pixelMapper.js create mode 100644 src/components/Webcam/pixelUtils.cjs delete mode 100644 src/components/Webcam/pixelUtils.js create mode 100644 src/components/Webcam/utils/adjust.cjs create mode 100644 src/components/Webcam/utils/calculateImageDifference.cjs create mode 100644 src/components/Webcam/utils/calibrate.cjs create mode 100644 src/components/Webcam/utils/createImageFromData.cjs create mode 100644 src/components/Webcam/utils/decodeBase64ToImageData.cjs create mode 100644 src/components/Webcam/utils/getLedCount.ts create mode 100644 src/components/Webcam/utils/initialize.cjs create mode 100644 src/components/Webcam/utils/iterativeOnOnlyOne.cjs create mode 100644 src/components/Webcam/utils/oneLed.cjs create mode 100644 src/components/Webcam/utils/preadjust.cjs create mode 100644 src/components/Webcam/utils/processImages.cjs create mode 100644 src/components/Webcam/utils/setWledBrightness.cjs create mode 100644 src/components/Webcam/utils/wait.cjs create mode 100644 src/components/Webcam/utils/wled.cjs create mode 100644 src/components/Webcam/utils/wledGet.cjs diff --git a/package.json b/package.json index dc538c03..f96e14fe 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "engines": { "node": ">=20" }, + "type": "module", "dependencies": { "@dnd-kit/core": "^6.2.0", "@dnd-kit/modifiers": "^8.0.0", @@ -43,10 +44,9 @@ "conf": "^13.0.1", "crypto": "^1.0.1", "deep-object-diff": "^1.1.9", - "electron-devtools-installer": "^3.2.0", - "electron-is-dev": "2", + "electron-is-dev": "3.0.1", "electron-squirrel-startup": "^1.0.0", - "electron-store": "8.2.0", + "electron-store": "10.0.0", "eslint-config-react-app": "7.0.1", "eslint-config-standard": "^17.1.0", "eslint-plugin-prettier": "^5.2.1", @@ -201,7 +201,7 @@ "@types/styled-components": "^5.1.34", "concurrently": "^9.1.0", "cross-env": "^7.0.3", - "electron": "^27.1.2", + "electron": "^33.2.1", "electron-builder": "^25.1.8", "eslint": "8.57", "eslint-config-prettier": "^9.1.0", @@ -285,4 +285,4 @@ ] } } -} +} \ No newline at end of file diff --git a/public/app/core.js b/public/app/core.js deleted file mode 100644 index 52514fcd..00000000 --- a/public/app/core.js +++ /dev/null @@ -1,77 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const isDev = require('electron-is-dev'); -const Store = require('electron-store'); -const { app } = require('electron'); -const store = new Store(); - -const coreFile = { - 'darwin': 'LedFx_core.app/Contents/MacOS/LedFx_v2', - 'linux': 'LedFx', - 'win32': 'LedFx/LedFx.exe' - }; - - const defaultCoreParams = { - 'darwin': { - 'instance1': [] - }, - 'linux': { - 'instance1': ['-p', '8888', '--no-tray'] - }, - 'win32': { - 'instance1': ['-p', '8888', '--no-tray'] - } - }; - -const coreParams = store.get('coreParams', defaultCoreParams); - -const corePath = (file) => path.join(path.dirname(__dirname), isDev ? '../extraResources' : '../../extraResources', file) -const runCore = (file, options) => require('child_process').spawn(`${corePath(file)}`, options).on('error', (err) => { console.error(`Failed to start subprocess. ${err}`); }); - -if (!fs.existsSync(path.join(app.getPath("userData"), '.ledfx-cc'))) { - console.log('Creating .ledfx-cc folder') - fs.mkdirSync(path.join(app.getPath("userData"), '.ledfx-cc')); -} -function startCore(wind, platform, instance = 'instance1', port = '8889') { - let subpy; - - if (fs.existsSync(corePath(coreFile[platform]))) { - if (coreParams[platform] && instance && coreParams[platform][instance]) { - if (instance !== 'instance1') { - - coreParams[platform][instance] = ['-p', port, '-c', path.join(app.getPath("userData"), '.ledfx-cc', instance)]; - } - console.log('Starting core with params', platform, instance, coreParams[platform][instance]) - subpy = runCore(coreFile[platform], coreParams[platform][instance]); - } else { - coreParams[platform][`instance${Object.keys(coreParams[platform]).length + 1}`] = ['-p', port, '-c', path.join(app.getPath("userData"), '.ledfx-cc', instance)]; - console.log('Creating core with params', platform, Object.keys(coreParams[platform]).length, coreParams[platform][`instance${Object.keys(coreParams[platform]).length}`]) - subpy = runCore(coreFile[platform], coreParams[platform][`instance${Object.keys(coreParams[platform]).length}`]); - } - store.set('coreParams', coreParams); - wind.webContents.send('fromMain', ['coreParams', coreParams[process.platform]]); - if (subpy !== null) { - subpy.on('stdout', (data) => { - console.log(`stdout: ${data}`); - }); - subpy.stdout.on('data', (data) => { - console.log(`stdout: ${data}`); - }); - subpy.stderr.on('data', (data) => { - console.log(`stderr: ${data}`); - wind.webContents.send('fromMain', ['snackbar', data.toString()]); - }); - subpy.on('exit', (code, signal) => { - console.log(`Child process exited with code ${code} and signal ${signal}`); - }); - subpy.on('error', (err) => { - console.error(`Failed to start subprocess. ${err}`); - }); - } - } - return subpy; - } - -const isCC = fs.existsSync(corePath(coreFile[process.platform])) - -module.exports = { startCore, corePath, isCC, coreFile, coreParams, store, defaultCoreParams }; diff --git a/public/app/devtools.js b/public/app/devtools.js deleted file mode 100644 index 28ae3e2f..00000000 --- a/public/app/devtools.js +++ /dev/null @@ -1,12 +0,0 @@ -const installDevtools = async (installExtension) => - await installExtension( - ['lmhkpmbekcpmknklioeibfkpmmfibljd', 'fmkadmapgofadopljbjfkapdkoienihi'], - { - loadExtensionOptions: { allowFileAccess: true }, - forceDownload: false - } - ) - .then((name) => console.log(`Added Extension: ${name}`)) - .catch((error) => console.log(`An error occurred: , ${error}`)) - -module.exports = { installDevtools } diff --git a/public/app/handlers.js b/public/app/handlers.js index 528bbe28..33e6c9a3 100644 --- a/public/app/handlers.js +++ b/public/app/handlers.js @@ -1,10 +1,13 @@ -const { app, shell, BrowserWindow, nativeTheme } = require('electron') -const path = require('path') -const { generateMfaQr, handleVerifyOTP } = require('./otp.js') -const { coreParams, isCC, defaultCoreParams, store } = require('./core.js') -const { startInstance, stopInstance, sendStatus } = require('./instances.js') +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 coreParams from './utils/coreParams.mjs' +import defaultCoreParams from './utils/defaultCoreParams.mjs' +import store from './utils/store.mjs' +import isCC from './utils/isCC.mjs' -const handlers = async (wind, subprocesses, event, parameters) => { +export const handlers = async (wind, subprocesses, event, parameters) => { console.log('ALL PARAMS', parameters) try { @@ -91,12 +94,6 @@ const handlers = async (wind, subprocesses, event, parameters) => { break case 'open-config': console.log('Open Config') - // wind.webContents.send('fromMain', ['currentdir', path.join(path.dirname(__dirname), isDev ? 'extraResources' : '../extraResources')]); - - // Windows: - // shell.showItemInFolder( - // path.join(app.getPath('appData'), '.ledfx', 'config.json') - // ) if (parameters.instance && parameters.instance !== 'instance1') { shell.showItemInFolder( @@ -141,4 +138,3 @@ const handlers = async (wind, subprocesses, event, parameters) => { } } -module.exports = { handlers } diff --git a/public/app/instances.js b/public/app/instances.js index b54c11c8..597c2b7f 100644 --- a/public/app/instances.js +++ b/public/app/instances.js @@ -1,6 +1,7 @@ -const { startCore, coreParams } = require('./core') +import coreParams from './utils/coreParams.mjs' +import startCore from './utils/startCore.mjs' -const poll = async (wind, subprocesses, name, p) => { +export const poll = async (wind, subprocesses, name, p) => { console.log('Polling core', name, 'on port', p) if (!p) return try { @@ -14,7 +15,7 @@ const poll = async (wind, subprocesses, name, p) => { } } -function stopInstance(wind, name, subprocesses) { +export function stopInstance(wind, name, subprocesses) { if (subprocesses[name]) { subprocesses[name].running = false sendStatus(wind, subprocesses, false, name) @@ -22,7 +23,7 @@ function stopInstance(wind, name, subprocesses) { } } -function startInstance(wind, name, subprocesses, port) { +export function startInstance(wind, name, subprocesses, port) { try { let subpy = startCore(wind, process.platform, name, port) if (subpy !== null) { @@ -58,7 +59,7 @@ function startInstance(wind, name, subprocesses, port) { } } -function sendStatus(wind, subprocesses, connected = false, n) { +export function sendStatus(wind, subprocesses, connected = false, n) { let status = {} let platformParams = coreParams[process.platform] // Check if `wind` is an instance of `BrowserWindow` @@ -97,13 +98,13 @@ function sendStatus(wind, subprocesses, connected = false, n) { if (wind && wind.webContents && !wind.isDestroyed() && status) wind.webContents.send('fromMain', ['status', status]) } -function kills(subprocess) { +export function kills(subprocess) { if (subprocess !== null) { subprocess.kill('SIGINT') } } -function closeAllSubs(wind, subpy, subprocesses) { +export function closeAllSubs(wind, subpy, subprocesses) { if (wind && wind.webContents && !wind.isDestroyed()) wind.webContents.send('fromMain', 'shutdown') if (subpy !== null) kills(subpy) if (subprocesses && Object.keys(subprocesses).length > 0) { @@ -113,11 +114,3 @@ function closeAllSubs(wind, subpy, subprocesses) { } } -module.exports = { - poll, - stopInstance, - startInstance, - sendStatus, - kills, - closeAllSubs -} diff --git a/public/app/media.js b/public/app/media.js new file mode 100644 index 00000000..9df3a7c4 --- /dev/null +++ b/public/app/media.js @@ -0,0 +1,27 @@ +const { execFile } = require('child_process'); +const path = require('path'); + +const exePath = path.join(__dirname, 'path_to_dist_folder', 'media.exe'); + +execFile(exePath, (error, stdout, stderr) => { + if (error) { + console.error(`Error: ${error.message}`); + return; + } + if (stderr) { + console.error(`Stderr: ${stderr}`); + return; + } + try { + const mediaInfo = JSON.parse(stdout); + if (mediaInfo.error) { + console.log(mediaInfo.error); + } else { + console.log(`Title: ${mediaInfo.title}`); + console.log(`Artist: ${mediaInfo.artist}`); + console.log(`Album: ${mediaInfo.album}`); + } + } catch (parseError) { + console.error(`JSON Parse Error: ${parseError.message}`); + } +}); \ No newline at end of file diff --git a/public/app/otp.js b/public/app/otp.js index ea3c7943..94daad6c 100644 --- a/public/app/otp.js +++ b/public/app/otp.js @@ -1,11 +1,11 @@ -const crypto = require('crypto') -const qrcode = require('qrcode'); -const base32Decode = require('base32-decode') -const base32Encode = require('base32-encode'); -const { store } = require('./core'); +import crypto from 'crypto' +import qrcode from 'qrcode' +import base32Decode from 'base32-decode' +import base32Encode from 'base32-encode' +import store from './utils/store.mjs' -function generateHOTP(secret, counter) { +export function generateHOTP(secret, counter) { const decodedSecret = base32Decode(secret, 'RFC4648'); const buffer = Buffer.alloc(8); @@ -31,12 +31,12 @@ function generateHOTP(secret, counter) { return `${code % 10 ** 6}`.padStart(6, '0'); } -function generateTOTP(secret, window = 0) { +export function generateTOTP(secret, window = 0) { const counter = Math.floor(Date.now() / 30000); return generateHOTP(secret, counter + window); } -function verifyTOTP(token, secret, window = 1) { +export function verifyTOTP(token, secret, window = 1) { for (let errorWindow = -window; errorWindow <= +window; errorWindow++) { const totp = generateTOTP(secret, errorWindow); if (token === totp) { @@ -46,7 +46,7 @@ function verifyTOTP(token, secret, window = 1) { return false; } -function generateMfaQr(event, parameters) { +export function generateMfaQr(event, parameters) { const user = store.get('user') || { username: 'FreeUser', mfaEnabled: false, @@ -77,7 +77,7 @@ function generateMfaQr(event, parameters) { return; } -function handleVerifyOTP(wind, event, parameters) { +export function handleVerifyOTP(wind, event, parameters) { const user = store.get('user') || { username: 'FreeUser', mfaEnabled: false, @@ -97,4 +97,3 @@ function handleVerifyOTP(wind, event, parameters) { return; } -module.exports = { generateHOTP, generateTOTP, verifyTOTP, handleVerifyOTP, generateMfaQr }; diff --git a/public/app/protocol.js b/public/app/protocol.js index b8291abf..81abaad1 100644 --- a/public/app/protocol.js +++ b/public/app/protocol.js @@ -1,10 +1,14 @@ -const { app, BrowserWindow } = require('electron') -const path = require('path') +import { app } from 'electron' +import path from 'path' + +export const setupProtocol = () => { + (async () => { + const isSquirrelStartup = await import('electron-squirrel-startup'); + if (isSquirrelStartup.default) { + app.quit() + } + })() -const setupProtocol = () => { - if (require('electron-squirrel-startup')) { - app.quit() - } if (process.defaultApp) { if (process.argv.length >= 2) { app.setAsDefaultProtocolClient('ledfx', process.execPath, [ @@ -16,7 +20,7 @@ const setupProtocol = () => { } } -const handleProtocol = (getWind, gotTheLock, ready) => { +export const handleProtocol = (getWind, gotTheLock, ready) => { if (process.platform === 'win32') { if (!gotTheLock) { app.quit() @@ -42,4 +46,3 @@ const handleProtocol = (getWind, gotTheLock, ready) => { } } -module.exports = { setupProtocol, handleProtocol } diff --git a/public/app/toast.js b/public/app/toast.js index 6033917d..880a21ff 100644 --- a/public/app/toast.js +++ b/public/app/toast.js @@ -1,7 +1,10 @@ -const fs = require('fs'); -const path = require('path'); -const { Notification } = require('electron'); +import fs from 'fs' +import path from 'path' +import { Notification } from 'electron' +import { fileURLToPath } from 'node:url' +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) const NOTIFICATION_TITLE = 'LedFx Client - by Blade'; const NOTIFICATION_BODY = 'Testing Notification from the Main process'; @@ -11,7 +14,7 @@ function getConfig() { return JSON.parse(configData); } -function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION_BODY) { +export function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION_BODY) { const config = getConfig(); const updateUrl = config.updateUrl; @@ -30,4 +33,3 @@ function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION_BODY) }).show(); } -module.exports = { showNotification }; diff --git a/public/app/utils/coreFile.mjs b/public/app/utils/coreFile.mjs new file mode 100644 index 00000000..dfb9bee6 --- /dev/null +++ b/public/app/utils/coreFile.mjs @@ -0,0 +1,7 @@ +const coreFile = { + darwin: 'LedFx_core.app/Contents/MacOS/LedFx_v2', + linux: 'LedFx', + win32: 'LedFx/LedFx.exe' +} + +export default coreFile diff --git a/public/app/utils/coreParams.mjs b/public/app/utils/coreParams.mjs new file mode 100644 index 00000000..df7499f2 --- /dev/null +++ b/public/app/utils/coreParams.mjs @@ -0,0 +1,6 @@ +import defaultCoreParams from './defaultCoreParams.mjs' +import store from './store.mjs' + +const coreParams = store.get('coreParams', defaultCoreParams) + +export default coreParams diff --git a/public/app/utils/corePath.mjs b/public/app/utils/corePath.mjs new file mode 100644 index 00000000..ba3f65f9 --- /dev/null +++ b/public/app/utils/corePath.mjs @@ -0,0 +1,15 @@ +import path from 'path' +import isDev from 'electron-is-dev' +import { fileURLToPath } from 'url' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +const corePath = (file) => + path.join( + path.dirname(__dirname), + isDev ? '../extraResources' : '../../extraResources', + file + ) + +export default corePath diff --git a/public/app/utils/defaultCoreParams.mjs b/public/app/utils/defaultCoreParams.mjs new file mode 100644 index 00000000..2fe1d9df --- /dev/null +++ b/public/app/utils/defaultCoreParams.mjs @@ -0,0 +1,13 @@ +const defaultCoreParams = { + darwin: { + instance1: [] + }, + linux: { + instance1: ['-p', '8888', '--no-tray'] + }, + win32: { + instance1: ['-p', '8888', '--no-tray'] + } +} + +export default defaultCoreParams diff --git a/public/app/utils/isCC.mjs b/public/app/utils/isCC.mjs new file mode 100644 index 00000000..a84d4416 --- /dev/null +++ b/public/app/utils/isCC.mjs @@ -0,0 +1,7 @@ +import fs from 'fs' +import corePath from './corePath.mjs' +import coreFile from './coreFile.mjs' + +export const isCC = fs.existsSync(corePath(coreFile[process.platform])) + +export default isCC diff --git a/public/app/utils/runCore.mjs b/public/app/utils/runCore.mjs new file mode 100644 index 00000000..40c03284 --- /dev/null +++ b/public/app/utils/runCore.mjs @@ -0,0 +1,9 @@ +import * as cp from 'child_process' +import corePath from './corePath.mjs' + +const runCore = (file, options) => + cp.spawn(`${corePath(file)}`, options).on('error', (err) => { + console.error(`Failed to start subprocess. ${err}`) + }) + +export default runCore diff --git a/public/app/utils/startCore.mjs b/public/app/utils/startCore.mjs new file mode 100644 index 00000000..11ab6606 --- /dev/null +++ b/public/app/utils/startCore.mjs @@ -0,0 +1,83 @@ +import { app } from 'electron' +import fs from 'fs' +import path from 'path' +import runCore from './runCore.mjs' +import corePath from './corePath.mjs' +import coreFile from './coreFile.mjs' +import coreParams from './coreParams.mjs' +import store from './store.mjs' + +function startCore(wind, platform, instance = 'instance1', port = '8889') { + let subpy + + if (fs.existsSync(corePath(coreFile[platform]))) { + if (coreParams[platform] && instance && coreParams[platform][instance]) { + if (instance !== 'instance1') { + coreParams[platform][instance] = [ + '-p', + port, + '-c', + path.join(app.getPath('userData'), '.ledfx-cc', instance) + ] + } + console.log( + 'Starting core with params', + platform, + instance, + coreParams[platform][instance] + ) + subpy = runCore(coreFile[platform], coreParams[platform][instance]) + } else { + coreParams[platform][ + `instance${Object.keys(coreParams[platform]).length + 1}` + ] = [ + '-p', + port, + '-c', + path.join(app.getPath('userData'), '.ledfx-cc', instance) + ] + console.log( + 'Creating core with params', + platform, + Object.keys(coreParams[platform]).length, + coreParams[platform][ + `instance${Object.keys(coreParams[platform]).length}` + ] + ) + subpy = runCore( + coreFile[platform], + coreParams[platform][ + `instance${Object.keys(coreParams[platform]).length}` + ] + ) + } + store.set('coreParams', coreParams) + wind.webContents.send('fromMain', [ + 'coreParams', + coreParams[process.platform] + ]) + if (subpy !== null) { + subpy.on('stdout', (data) => { + console.log(`stdout: ${data}`) + }) + subpy.stdout.on('data', (data) => { + console.log(`stdout: ${data}`) + }) + subpy.stderr.on('data', (data) => { + console.log(`stderr: ${data}`) + wind.webContents.send('fromMain', ['snackbar', data.toString()]) + }) + subpy.on('exit', (code, signal) => { + console.log( + `Child process exited with code ${code} and signal ${signal}` + ) + }) + subpy.on('error', (err) => { + console.error(`Failed to start subprocess. ${err}`) + }) + } + } + return subpy +} + +export default startCore diff --git a/public/app/utils/store.mjs b/public/app/utils/store.mjs new file mode 100644 index 00000000..0ebf2af3 --- /dev/null +++ b/public/app/utils/store.mjs @@ -0,0 +1,5 @@ +import Store from 'electron-store' + +const store = new Store() + +export default store diff --git a/public/app/tray.js b/public/app/utils/tray.mjs similarity index 57% rename from public/app/tray.js rename to public/app/utils/tray.mjs index 5f8310ca..c6aeb53f 100644 --- a/public/app/tray.js +++ b/public/app/utils/tray.mjs @@ -1,96 +1,106 @@ -const path = require('path'); -const { app, Menu, shell, Tray } = require('electron'); -const { startCore } = require('./core'); -const isDev = require('electron-is-dev'); +import path from 'path' +import { app, Menu, shell, Tray } from 'electron' +import isDev from 'electron-is-dev' +import startCore from './startCore.mjs' +import coreParams from './coreParams.mjs' // const { download } = require('electron-dl') -function createMenu(isCC, wind, thePath) { - let contextMenu; +export function createMenu(isCC, wind, thePath) { + let contextMenu if (isCC) { contextMenu = Menu.buildFromTemplate([ - { label: 'Show', click: () => { - if (process.platform === 'darwin') app.dock.show() - wind.show() }}, + { + label: 'Show', + click: () => { + if (process.platform === 'darwin') app.dock.show() + wind.show() + } + }, { label: 'Minimize', click: () => wind.minimize() }, - { label: 'Minimize to tray', click: () => { - if (process.platform === 'darwin') app.dock.hide() - wind.hide() - }}, + { + label: 'Minimize to tray', + click: () => { + if (process.platform === 'darwin') app.dock.hide() + wind.hide() + } + }, // { label: 'Test Notifiation', click: () => showNotification('Update Available', 'v2.0.62') }, { label: 'seperator', type: 'separator' }, { label: 'Dev', click: () => wind.webContents.openDevTools() }, { label: 'seperator', type: 'separator' }, { label: 'Start core', - click: () => startCore(wind, process.platform, parameters.instance) + click: () => startCore(wind, process.platform, coreParams.instance) }, { label: 'Stop core', - click: () => wind.webContents.send('fromMain', 'shutdown'), + click: () => wind.webContents.send('fromMain', 'shutdown') }, // { label: 'Download core', click: () => download(wind, `https://github.com/YeonV/LedFx-Frontend-v2/releases/latest/download/LedFx_core-${app.getVersion().split('-')[1]}--win-portable.exe`, { directory: thePath, overwrite: true }).then((f) => { app.relaunch(); app.exit() }) }, { label: 'Restart Client', click: () => { - app.relaunch(); - app.exit(); - }, + app.relaunch() + app.exit() + } }, { label: 'Open folder', click: () => shell.openPath(thePath) }, { label: 'seperator', type: 'separator' }, - { label: 'Exit', click: () => app.quit() }, - ]); + { label: 'Exit', click: () => app.quit() } + ]) } else { contextMenu = Menu.buildFromTemplate([ - { label: 'Show', click: () => { - if (process.platform === 'darwin') app.dock.show() - wind.show() - }}, + { + label: 'Show', + click: () => { + if (process.platform === 'darwin') app.dock.show() + wind.show() + } + }, { label: 'Minimize', click: () => wind.minimize() }, - { label: 'Minimize to tray', click: () => { - if (process.platform === 'darwin') app.dock.hide() - wind.hide() - }}, + { + label: 'Minimize to tray', + click: () => { + if (process.platform === 'darwin') app.dock.hide() + wind.hide() + } + }, // { label: 'Test Notifiation', click: () => showNotification('Update Available', 'v2.0.62') }, { label: 'seperator', type: 'separator' }, { label: 'Dev', click: () => wind.webContents.openDevTools() }, { label: 'seperator', type: 'separator' }, { label: 'Stop core', - click: () => wind.webContents.send('fromMain', 'shutdown'), + click: () => wind.webContents.send('fromMain', 'shutdown') }, // { label: 'Download core', click: () => download(wind, `https://github.com/YeonV/LedFx-Frontend-v2/releases/latest/download/LedFx_core-${app.getVersion().split('-')[1]}--win-portable.exe`, { directory: thePath, overwrite: true, onProgress: (obj)=>{wind.webContents.send('fromMain', ['download-progress', obj])} }).then((f) => { wind.webContents.send('fromMain', 'clear-frontend'); app.relaunch(); app.exit() })}, { label: 'Restart Client', click: () => { - app.relaunch(); - app.exit(); - }, + app.relaunch() + app.exit() + } }, { label: 'Open folder', click: () => shell.openPath(thePath) }, { label: 'seperator', type: 'separator' }, - { label: 'Exit', click: () => app.quit() }, - ]); + { label: 'Exit', click: () => app.quit() } + ]) } - return contextMenu; + return contextMenu } +export function createTray(isCC, wind, thePath, dir) { + const icon = path.join(dir, 'icon_16x16a.png') + const tray = new Tray(icon) -function createTray(isCC, wind, thePath, dir) { - const icon = path.join(dir, 'icon_16x16a.png'); - let tray = new Tray(icon); + const contextMenu = createMenu(isCC, wind, thePath) - let contextMenu = createMenu(isCC, wind, thePath); + tray.setToolTip(`LedFx Client${isDev ? ' DEV' : ''}`) + tray.setContextMenu(contextMenu) + tray.setIgnoreDoubleClickEvents(true) + tray.on('click', () => wind.show()) - tray.setToolTip(`LedFx Client${isDev ? ' DEV' : ''}`); - tray.setContextMenu(contextMenu); - tray.setIgnoreDoubleClickEvents(true); - tray.on('click', () => wind.show()); - - return tray; + return tray } - -module.exports = { createTray }; - diff --git a/public/app/win.js b/public/app/utils/win.mjs similarity index 67% rename from public/app/win.js rename to public/app/utils/win.mjs index 67bb72ff..a14121a2 100644 --- a/public/app/win.js +++ b/public/app/utils/win.mjs @@ -1,9 +1,14 @@ -const { BrowserWindow } = require('electron'); -const path = require('path'); -const isDev = require('electron-is-dev'); +import { BrowserWindow } from 'electron' +import path from 'path' +import isDev from 'electron-is-dev' +import { initialize } from '@electron/remote/main/index.js' +import { fileURLToPath } from 'node:url' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) function createWindow(win, args = {}) { - require('@electron/remote/main').initialize(); + initialize() // Create the browser window. win = new BrowserWindow({ width: 1024, @@ -23,17 +28,17 @@ function createWindow(win, args = {}) { nodeIntegration: true, contextIsolation: true, preload: path.join(__dirname, '../preload.js'), - ...args, - }, - }); + ...args + } + }) win.loadURL( isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../../build/index.html')}` - ); + ) - return win; + return win } -module.exports = { createWindow }; \ No newline at end of file +export default createWindow diff --git a/public/electron.js b/public/electron.js index 00485a7c..dd8192a0 100644 --- a/public/electron.js +++ b/public/electron.js @@ -1,24 +1,25 @@ /* eslint-disable no-console */ /* eslint-disable global-require */ /* eslint-disable @typescript-eslint/no-var-requires */ -const path = require('path') -const isDev = require('electron-is-dev') -const { app, nativeTheme, BrowserWindow, ipcMain, shell } = require('electron') -const { isCC } = require('./app/core.js') -const { createWindow } = require('./app/win.js') -const { createTray } = require('./app/tray.js') -const { startInstance, closeAllSubs } = require('./app/instances.js') -const { handlers } = require('./app/handlers.js') -const { installDevtools } = require('./app/devtools.js') -const { setupProtocol, handleProtocol } = require('./app/protocol.js') - -require('events').EventEmitter.defaultMaxListeners = 15 - -let installExtension -if (isDev) { - const devTools = require('electron-devtools-installer') - installExtension = devTools.default -} +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' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +EventEmitter.defaultMaxListeners = 15 + +const reduxDevtoolsPath = 'C:\\Users\\49152\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\lmhkpmbekcpmknklioeibfkpmmfibljd\\3.2.7_0' const subpy = null const subprocesses = {} @@ -28,8 +29,16 @@ let win setupProtocol() const gotTheLock = app.requestSingleInstanceLock() +if (!fs.existsSync(path.join(app.getPath('userData'), '.ledfx-cc'))) { + console.log('Creating .ledfx-cc folder') + fs.mkdirSync(path.join(app.getPath('userData'), '.ledfx-cc')) +} + const ready = () => app.whenReady().then(async () => { + if (isDev) { + await session.defaultSession.loadExtension(reduxDevtoolsPath) + } nativeTheme.themeSource = 'dark' const thePath = process.env.PORTABLE_EXECUTABLE_DIR || path.resolve('.') @@ -37,7 +46,8 @@ const ready = () => ? createWindow(win, { additionalArguments: ['integratedCore'] }) : createWindow(win) - require('@electron/remote/main').enable(wind.webContents) + const remoteMain = await import('@electron/remote/main/index.js') + remoteMain.enable(wind.webContents) wind.webContents.setWindowOpenHandler(({ url }) => { if (url.includes(' https://accounts.spotify.com/authorize') @@ -49,8 +59,8 @@ const ready = () => return { action: 'allow' } }) - if (isCC) startInstance(wind, 'instance1', subprocesses) - if (isDev) installDevtools(installExtension) + if (isCC) startInstance(wind, 'instance1', subprocesses) + createTray(isCC, wind, thePath, __dirname) diff --git a/src/components/Gamepad/Assign.tsx b/src/components/Gamepad/Assign.tsx index 2a9d78e2..08e858cc 100644 --- a/src/components/Gamepad/Assign.tsx +++ b/src/components/Gamepad/Assign.tsx @@ -13,6 +13,7 @@ import { Collections, CopyAll, GraphicEq, + LensBlur, LocalPlay, PlayArrow, QuestionMark, @@ -22,6 +23,7 @@ import { import useStore from '../../store/useStore' import BladeIcon from '../Icons/BladeIcon/BladeIcon' import OneShot from './OneShot' +import OneEffect from './OneEffect' const Assign = ({ type, @@ -48,7 +50,8 @@ const Assign = ({ 'scene-playlist': , padscreen: , 'one-shot': , - 'scan-wled': + 'scan-wled': , + 'effect': } return ( @@ -129,7 +132,7 @@ const Assign = ({ {mapping[padIndex]?.[index]?.command === 'one-shot' && ( )} + {mapping[padIndex]?.[index]?.command === 'effect' && ( + + setMapping({ + ...mapping, + [padIndex]: { + ...mapping[padIndex], + [index]: { + ...mapping[padIndex]?.[index], + payload: v + } + } + }) + } + /> + )} :