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
+ }
+ }
+ })
+ }
+ />
+ )}
: