From 7478f35f50324fd9b2a8fa205415626897352eaa Mon Sep 17 00:00:00 2001 From: YeonV Date: Sun, 15 Dec 2024 02:00:35 +0100 Subject: [PATCH] Quickly fix the linting :) --- .storybook/main.ts | 14 +- .storybook/preview.tsx | 39 +- eslint.config.mjs | 28 +- package.json | 3 +- src/App.tsx | 130 +- src/app/app/media.ts | 60 +- src/app/app/otp.ts | 78 +- src/app/app/toast.ts | 32 +- src/app/electron.ts | 105 +- src/components/AddButton/AddButton.tsx | 2 +- src/components/Bars/BarBottom.tsx | 2 +- src/components/Bars/BarLeft.styles.tsx | 2 +- src/components/Bars/BarLeft.tsx | 151 +- src/components/Bars/BarTop.tsx | 137 +- src/components/Dialogs/AboutDialog.tsx | 2 +- src/components/Dialogs/AddDeviceDialog.tsx | 15 +- .../Dialogs/AddExistingSegmentDialog.tsx | 137 +- .../Dialogs/AddIntegrationDialog.tsx | 2 +- src/components/Dialogs/AddWledDialog.tsx | 3 +- src/components/Dialogs/Download.tsx | 6 +- src/components/Dialogs/EffectTypeDialog.tsx | 9 +- .../Dialogs/FrontendPixelsTooSmall.tsx | 30 +- src/components/Dialogs/HostManager.tsx | 4 +- src/components/Dialogs/IntroDialog.tsx | 6 +- .../Dialogs/SceneDialogs/EditSceneDialog.tsx | 107 +- src/components/Dialogs/SmartBar.tsx | 2 +- src/components/Dialogs/_AddSegmentDialog.tsx | 50 +- src/components/DnD/OrderList.tsx | 48 +- src/components/DnD/OrderListBase.tsx | 72 +- src/components/DnD/OrderListDialog.tsx | 25 +- src/components/Gamepad/Assign.tsx | 4 +- src/components/Gamepad/Gamepad.tsx | 33 +- src/components/Gamepad/GamepadSvg.tsx | 2 +- src/components/Gamepad/OneEffect.tsx | 134 +- src/components/Gamepad/OneShot.tsx | 29 +- .../Icons/BladeIcon/BladeIcon.interface.tsx | 2 +- src/components/Icons/BladeIcon/BladeIcon.tsx | 44 +- src/components/Icons/Novation.tsx | 12 +- .../QLC/DialogAddEventListener.tsx | 9 +- .../Integrations/Spotify/SpotifyProvider.tsx | 8 +- .../Spotify/Widgets/Keybinding/Keybinding.tsx | 21 +- .../Keybinding/KeybindingComponents.tsx | 58 +- .../Widgets/Keybinding/KeybindingFloating.tsx | 11 +- .../Widgets/MGraphFlotaing/MGraphFloating.tsx | 13 +- .../Widgets/SpotifyWidgetPro/SpTexter.tsx | 439 ++++-- .../Widgets/SpotifyWidgetPro/SpTrack.tsx | 10 +- src/components/MGraph.tsx | 78 +- src/components/Midi/ColorTypePicker.tsx | 19 +- src/components/Midi/LaunchpadButton.tsx | 427 ++++-- src/components/Midi/LaunchpadButtonMap.tsx | 1264 +++++++++++------ src/components/Midi/LaunchpadColors.tsx | 307 ++-- src/components/Midi/LaunchpadSettings.tsx | 434 +++--- src/components/Midi/LpColorPicker.tsx | 167 ++- src/components/Midi/MidiInputDialog.tsx | 36 +- src/components/Midi/MidiListener.tsx | 236 +-- src/components/NoYet.tsx | 2 +- src/components/Number.tsx | 48 +- src/components/OneTimePassword.tsx | 2 +- src/components/PixelGraph.tsx | 45 +- src/components/Popover/Popover.tsx | 13 +- .../EffectsSchemaForm/EffectSchemaForm.tsx | 241 ++-- .../SchemaForm/components/Boolean/BBolean.tsx | 7 +- .../components/Boolean/BBoolean.props.tsx | 4 +- .../components/Boolean/BBoolean.stories.tsx | 6 +- .../components/Boolean/BladeBoolean.tsx | 3 +- .../components/DropDown/DropDown.tsx | 1 - .../components/DropDown/DropDown.wrapper.tsx | 12 +- .../GradientPicker/GradientPicker.tsx | 36 +- .../components/Number/SliderInput.tsx | 66 +- .../components/String/BladeSelect.tsx | 60 +- src/components/Tours/Tour.tsx | 5 +- src/components/Tours/Tour2dVirtual.tsx | 19 +- src/components/Webcam/Webcam.tsx | 19 +- src/components/Webcam/pixelMapper.ts | 11 +- src/components/Webcam/pixelUtils.ts | 7 +- src/components/Webcam/utils/adjust.ts | 2 +- .../Webcam/utils/createImageFromData.ts | 1 - src/components/Webcam/utils/initialize.ts | 4 +- .../Webcam/utils/iterativeOnOnlyOne.ts | 4 +- src/components/Webcam/utils/oneLed.ts | 5 +- src/components/Webcam/utils/preadjust.ts | 2 +- src/components/Webcam/utils/processImages.ts | 9 +- .../Webcam/utils/setWledBrightness.ts | 2 +- src/electronsquirrelstartup.d..ts | 2 +- src/launchpad.d.ts | 2 +- src/pages/Device/Device.tsx | 276 ++-- src/pages/Device/Effects.tsx | 63 +- src/pages/Device/EffectsComplex.tsx | 107 +- src/pages/Device/PresetButton.tsx | 2 +- src/pages/Device/Presets.tsx | 2 +- src/pages/Device/PresetsComplex.tsx | 65 +- src/pages/Device/TroubleshootButton.tsx | 6 +- .../Devices/DeviceCard/DeviceCard.stories.tsx | 2 +- .../Devices/DeviceCard/DeviceCard.wrapper.tsx | 223 +-- src/pages/Devices/Devices.tsx | 15 +- .../EditMatrix/Actions/assignPixels.ts | 56 +- .../EditMatrix/AssignPixelDialog.tsx | 13 +- .../EditVirtuals/EditMatrix/Draggable.tsx | 2 +- .../Devices/EditVirtuals/EditMatrix/M.tsx | 208 +-- .../EditVirtuals/EditMatrix/MContextMenu.tsx | 24 +- .../EditVirtuals/EditMatrix/MControls.tsx | 141 +- .../EditVirtuals/EditMatrix/MFillSelector.tsx | 23 +- .../EditVirtuals/EditMatrix/MSlider.tsx | 45 +- .../EditVirtuals/EditMatrix/MWrapper.tsx | 2 +- .../EditVirtuals/EditVirtuals.styles.tsx | 2 +- .../Devices/EditVirtuals/PixelSlider.tsx | 1 - src/pages/Devices/EditVirtuals/Segment.tsx | 4 +- src/pages/Graph/Graph.tsx | 4 +- src/pages/Home/BladeScene.tsx | 61 +- src/pages/Home/Dashboard.tsx | 49 +- src/pages/Home/DbDevices.tsx | 167 ++- src/pages/Home/DbGlobalActions.tsx | 12 +- src/pages/Home/DbStats.tsx | 15 +- .../IntegrationCardSpotify.tsx | 2 +- src/pages/Integrations/QLCplus/EventTable.tsx | 2 +- .../QLCplus/QLCScreen/QLCScreen.props.tsx | 4 +- src/pages/Scenes/Scenes.tsx | 136 +- src/pages/Scenes/ScenesImage.tsx | 17 +- src/pages/Scenes/ScenesMenu.tsx | 41 +- src/pages/Scenes/ScenesMostUsed.tsx | 4 +- src/pages/Scenes/ScenesPlaylist.tsx | 117 +- src/pages/Scenes/ScenesPlaylistMenu.tsx | 7 +- src/pages/Settings/DashboardCard.tsx | 4 +- src/pages/Settings/EffectsCard.tsx | 4 +- src/pages/Settings/ExpertFeatures.tsx | 1 - src/pages/Settings/GeneralCard.tsx | 8 +- src/pages/Settings/MidiCard.tsx | 63 +- .../Settings/PixelGraphsSettingsCard.tsx | 73 +- src/pages/Settings/Settings.tsx | 8 +- src/pages/Settings/SettingsComponents.tsx | 10 +- src/pages/Settings/UICard.tsx | 22 +- src/pages/Settings/Webaudio.tsx | 2 +- .../AvatarPicker/AvatarPicker.interface.tsx | 1 + src/pages/User/AvatarPicker/AvatarPicker.tsx | 3 +- src/store/api/storeScenes.tsx | 50 +- src/store/api/storeVirtuals.tsx | 7 +- src/store/ui-persist/storeUIpersist.tsx | 7 +- .../ui-persist/storeUIpersistActions.tsx | 17 +- src/store/ui/storeFeatures.tsx | 2 +- src/store/ui/storeMidi.tsx | 70 +- src/store/ui/storeSpotify.tsx | 57 +- src/store/ui/storeSpotifyActions.tsx | 23 +- src/store/useStore.ts | 9 +- src/utils/MidiDevices/LaunchPadDevice.ts | 198 +-- .../MidiDevices/LaunchpadMK2/LaunchpadMK2.ts | 113 +- .../MidiDevices/LaunchpadS/LaunchpadS.ts | 16 +- src/utils/MidiDevices/LaunchpadS/lpsColors.ts | 34 +- .../MidiDevices/LaunchpadX/LaunchpadX.ts | 147 +- src/utils/MidiDevices/LaunchpadX/lpColors.ts | 272 ++-- src/utils/MidiDevices/MidiDevices.ts | 2 +- src/utils/MidiDevices/colorHelper.ts | 47 +- src/utils/helpers.ts | 2 +- src/utils/useWakeLook.ts | 30 +- 153 files changed, 5567 insertions(+), 3393 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index 33319382..7e623966 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -2,13 +2,13 @@ import type { StorybookConfig } from '@storybook/react-webpack5' const config: StorybookConfig = { stories: [ - '../src/**/*.mdx', - '../src/components/SchemaForm/**/*.stories.tsx', - '../src/components/Icons/BladeIcon/BladeIcon.stories.tsx', - '../src/stories/Doc/Api.stories.tsx', - '../src/components/Popover/Popover.stories.tsx', - '../src/pages/Devices/DeviceCard/DeviceCard.stories.tsx', - ], + '../src/**/*.mdx', + '../src/components/SchemaForm/**/*.stories.tsx', + '../src/components/Icons/BladeIcon/BladeIcon.stories.tsx', + '../src/stories/Doc/Api.stories.tsx', + '../src/components/Popover/Popover.stories.tsx', + '../src/pages/Devices/DeviceCard/DeviceCard.stories.tsx' + ], addons: [ '@storybook/preset-create-react-app', // '@storybook/addon-onboarding', diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 061dd2d8..807beade 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,24 +1,27 @@ import type { Preview } from '@storybook/react' -import { BladeDarkBlueTheme as darkTheme, BladeLightBlueTheme as lightTheme } from '../src/themes/AppThemes' +import { + BladeDarkBlueTheme as darkTheme, + BladeLightBlueTheme as lightTheme +} from '../src/themes/AppThemes' import './globals.css' import '../src/index.css' -import { ThemeProvider, CssBaseline } from '@mui/material'; -import { withThemeFromJSXProvider } from '@storybook/addon-themes'; - +import { ThemeProvider, CssBaseline } from '@mui/material' +import { withThemeFromJSXProvider } from '@storybook/addon-themes' const preview: Preview = { decorators: [ withThemeFromJSXProvider({ - GlobalStyles: CssBaseline, - Provider: ThemeProvider, - themes: { - // Provide your custom themes here - light: lightTheme, - dark: darkTheme, - }, - defaultTheme: 'light', - })], + GlobalStyles: CssBaseline, + Provider: ThemeProvider, + themes: { + // Provide your custom themes here + light: lightTheme, + dark: darkTheme + }, + defaultTheme: 'light' + }) + ], parameters: { options: { storySort: { @@ -27,7 +30,13 @@ const preview: Preview = { 'BladeBook', ['Introduction', 'Getting Started', 'App Structure', 'Guides'], 'UI Components', - ['Examples', 'Schema Components', 'Base Components', 'Default', ['*', 'Color']], + [ + 'Examples', + 'Schema Components', + 'Base Components', + 'Default', + ['*', 'Color'] + ], 'Api' ] } @@ -40,7 +49,7 @@ const preview: Preview = { } } }, - tags: ['autodocs'], + tags: ['autodocs'] } export default preview diff --git a/eslint.config.mjs b/eslint.config.mjs index 4599d94d..60d8af74 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -17,21 +17,22 @@ const compat = new FlatCompat({ export default [ { - ignores: ['**/build/*', '**/*.js', '**/*.jsx', 'extraResources/**'] + ignores: [ + '**/build/*', + '**/*.js', + '**/*.jsx', + '**/*.mjs', + '**/*.cjs', + 'extraResources/**' + ] }, ...compat.extends( 'standard', 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended' - // 'plugin:react-hooks/recommended' + 'plugin:react-hooks/recommended', + 'plugin:prettier/recommended', ), { - plugins: { - '@typescript-eslint': typescriptEslint, - 'prettier/prettier': prettier - // 'react-hooks': reactHooks - }, - languageOptions: { parser: tsParser, parserOptions: { @@ -94,7 +95,7 @@ export default [ 'no-nested-ternary': 0, 'import/extensions': 0, 'import/first': 0, - '@typescript-eslint/indent': [2, 2], + '@/indent': [2, 2, { SwitchCase: 1}], 'react/react-in-jsx-scope': 'off', 'react/function-component-definition': [0], 'react/jsx-props-no-spreading': 0, @@ -107,6 +108,11 @@ export default [ '@typescript-eslint/no-explicit-any': 0, '@prettier/trailing-comma': 0, 'jsx-a11y/label-has-associated-control': 0 - } + }, + plugins: { + '@typescript-eslint': typescriptEslint, + 'prettier/prettier': prettier + // 'react-hooks': reactHooks + }, } ] diff --git a/package.json b/package.json index 854f7d83..dc74b879 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,7 @@ "cross-env": "^7.0.3", "electron": "^33.2.1", "electron-builder": "^25.1.8", - "eslint": "8.57", + "eslint": "9.17.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-flowtype": "^8.0.3", @@ -215,6 +215,7 @@ "eslint-plugin-n": "^17.14.0", "eslint-plugin-promise": "^7.2.1", "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-storybook": "^0.11.1", "gh-pages": "^6.1.1", "prettier": "^3.4.1", diff --git a/src/App.tsx b/src/App.tsx index 5faa5ff4..6b0b4c43 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useEffect, useMemo } from 'react' import { createTheme, ThemeProvider } from '@mui/material/styles' import { SnackbarProvider } from 'notistack' @@ -38,11 +38,16 @@ export default function App() { const reloadTheme = useStore((state) => state.ui.reloadTheme) const theme = useMemo( - () => createTheme({ - ...ledfxThemes[window.localStorage.getItem('ledfx-theme') ?? ledfxTheme], + () => + createTheme({ + ...ledfxThemes[ + window.localStorage.getItem('ledfx-theme') ?? ledfxTheme + ], ...common, palette: { - ...ledfxThemes[window.localStorage.getItem('ledfx-theme') ?? ledfxTheme].palette + ...ledfxThemes[ + window.localStorage.getItem('ledfx-theme') ?? ledfxTheme + ].palette } }), // eslint-disable-next-line react-hooks/exhaustive-deps @@ -59,7 +64,6 @@ export default function App() { initFrontendConfig() console.info( - // eslint-disable-next-line no-useless-concat '%c Ledfx ' + '%c\n ReactApp by Blade ', 'padding: 10px 40px; color: #ffffff; border-radius: 5px 5px 0 0; background-color: #800000;', 'background: #fff; color: #800000; border-radius: 0 0 5px 5px;padding: 5px 0;' @@ -159,41 +163,53 @@ export default function App() { } } else if (proto[1] === 'song') { const v = proto[2] - const virtual = (Object.keys(virtuals).find((virt) => virtuals[virt].id === v)) + const virtual = Object.keys(virtuals).find( + (virt) => virtuals[virt].id === v + ) if (virtual && proto[3].length > 3) { - setEffect(v, 'texter2d', { - "gradient": "linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)", - "option_2": false, - "flip": false, - "blur": 0, - "flip_horizontal": false, - "speed_option_1": 2, - "resize_method": "Fast", - "gradient_roll": 0, - "alpha": false, - "value_option_1": 0.5, - "font": "Blade-5x8", - "use_gradient": false, - "diag": false, - "test": false, - "impulse_decay": 0.1, - "mirror": false, - "flip_vertical": false, - "text_effect": "Side Scroll", - "multiplier": 1, - "brightness": 1, - "text_color": "#ff0000", - "background_brightness": 1, - "rotate": 0, - "dump": false, - "option_1": false, - "height_percent": 100, - "background_color": "#000000", - "text": proto[3] - }, true, true) + setEffect( + v, + 'texter2d', + { + gradient: + 'linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)', + option_2: false, + flip: false, + blur: 0, + flip_horizontal: false, + speed_option_1: 2, + resize_method: 'Fast', + gradient_roll: 0, + alpha: false, + value_option_1: 0.5, + font: 'Blade-5x8', + use_gradient: false, + diag: false, + test: false, + impulse_decay: 0.1, + mirror: false, + flip_vertical: false, + text_effect: 'Side Scroll', + multiplier: 1, + brightness: 1, + text_color: '#ff0000', + background_brightness: 1, + rotate: 0, + dump: false, + option_1: false, + height_percent: 100, + background_color: '#000000', + text: proto[3] + }, + true, + true + ) } } else { - showSnackbar('info', `External call: ${protoCall.replace('ledfx://', '')}`) + showSnackbar( + 'info', + `External call: ${protoCall.replace('ledfx://', '')}` + ) } setProtoCall('') } @@ -222,27 +238,27 @@ export default function App() { height={height} /> )} - {new Date().getFullYear() === 2024 && - new Date().getMonth() === 11 && + {new Date().getFullYear() === 2024 && + new Date().getMonth() === 11 && new Date().getDate() >= 24 && ( -
- )} +
+ )} {new Date().getFullYear() === 2025 && new Date().getMonth() === 0 && new Date().getDate() === 1 && ( diff --git a/src/app/app/media.ts b/src/app/app/media.ts index 55bf478f..65aa7a86 100644 --- a/src/app/app/media.ts +++ b/src/app/app/media.ts @@ -1,38 +1,38 @@ -const { execFile } = require('child_process'); -const path = require('path'); -import { fileURLToPath } from 'node:url'; +import { execFile } from 'child_process' +import path from 'path' +import { fileURLToPath } from 'node:url' -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) -const exePath = path.join(__dirname, 'path_to_dist_folder', 'media.exe'); +const exePath = path.join(__dirname, 'path_to_dist_folder', 'media.exe') interface MediaInfo { - title: string; - artist: string; - album: string; - error?: string; + 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; + if (error) { + console.error(`Error: ${error.message}`) + return + } + if (stderr) { + console.error(`Stderr: ${stderr}`) + return + } + try { + const mediaInfo: 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}`) } - if (stderr) { - console.error(`Stderr: ${stderr}`); - return; - } - try { - const mediaInfo: 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 as Error).message}`); - } -}); \ No newline at end of file + } catch (parseError) { + console.error(`JSON Parse Error: ${(parseError as Error).message}`) + } +}) diff --git a/src/app/app/otp.ts b/src/app/app/otp.ts index cf0a2fc0..4b697303 100644 --- a/src/app/app/otp.ts +++ b/src/app/app/otp.ts @@ -5,46 +5,45 @@ import base32Encode from 'base32-encode' import store from './utils/store.mjs' import { BrowserWindow } from 'electron' - export function generateHOTP(secret: string, counter: number) { - const decodedSecret = base32Decode(secret, 'RFC4648'); + const decodedSecret = base32Decode(secret, 'RFC4648') - const buffer = Buffer.alloc(8); + const buffer = Buffer.alloc(8) for (let i = 0; i < 8; i++) { - buffer[7 - i] = counter & 0xff; - counter = counter >> 8; + buffer[7 - i] = counter & 0xff + counter = counter >> 8 } // Step 1: Generate an HMAC-SHA-1 value - const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret)); - hmac.update(buffer); - const hmacResult = hmac.digest(); + const hmac = crypto.createHmac('sha1', Buffer.from(decodedSecret)) + hmac.update(buffer) + const hmacResult = hmac.digest() // Step 2: Generate a 4-byte string (Dynamic Truncation) - const offset = hmacResult[hmacResult.length - 1] & 0xf; + const offset = hmacResult[hmacResult.length - 1] & 0xf const code = ((hmacResult[offset] & 0x7f) << 24) | ((hmacResult[offset + 1] & 0xff) << 16) | ((hmacResult[offset + 2] & 0xff) << 8) | - (hmacResult[offset + 3] & 0xff); + (hmacResult[offset + 3] & 0xff) // Step 3: Compute an HOTP value - return `${code % 10 ** 6}`.padStart(6, '0'); + return `${code % 10 ** 6}`.padStart(6, '0') } export function generateTOTP(secret: string, window = 0) { - const counter = Math.floor(Date.now() / 30000); - return generateHOTP(secret, counter + window); + const counter = Math.floor(Date.now() / 30000) + return generateHOTP(secret, counter + window) } export function verifyTOTP(token: string, secret: string, window = 1) { for (let errorWindow = -window; errorWindow <= +window; errorWindow++) { - const totp = generateTOTP(secret, errorWindow); + const totp = generateTOTP(secret, errorWindow) if (token === totp) { - return true; + return true } } - return false; + return false } export function generateMfaQr(wind: BrowserWindow) { @@ -52,31 +51,32 @@ export function generateMfaQr(wind: BrowserWindow) { username: 'FreeUser', mfaEnabled: false, mfaSecret: null - }; + } // console.log('generate-mfa-qr:', user) // For security, we no longer show the QR code after is verified - if (user.mfaEnabled) return; + if (user.mfaEnabled) return if (!user.mfaSecret) { // generate unique secret for user // this secret will be used to check the verification code sent by user - const buffer = crypto.randomBytes(14); - user.mfaSecret = base32Encode(buffer, 'RFC4648', { padding: false }); + const buffer = crypto.randomBytes(14) + user.mfaSecret = base32Encode(buffer, 'RFC4648', { padding: false }) // console.log('generated-mfa-qr', user); - store.set('user', user); + store.set('user', user) } - const issuer = 'Blade\'s LedFx'; - const algorithm = 'SHA1'; - const digits = '6'; - const period = '30'; - const otpType = 'totp'; - const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}`; + // eslint-disable-next-line quotes + const issuer = "Blade's LedFx" + const algorithm = 'SHA1' + const digits = '6' + const period = '30' + const otpType = 'totp' + const configUri = `otpauth://${otpType}/${issuer}:${user.username}?algorithm=${algorithm}&digits=${digits}&period=${period}&issuer=${issuer}&secret=${user.mfaSecret}` - qrcode.toDataURL(configUri, { - color: { dark: '#333333FF', light: '#00000000' }, - }).then(((png: any) => wind.webContents.send('fromMain', ['mfa-qr-code', png]))); - - return; + qrcode + .toDataURL(configUri, { + color: { dark: '#333333FF', light: '#00000000' } + }) + .then((png: any) => wind.webContents.send('fromMain', ['mfa-qr-code', png])) } export function handleVerifyOTP(wind: BrowserWindow, parameters: any) { const user = store.get('user') || { @@ -84,17 +84,15 @@ export function handleVerifyOTP(wind: BrowserWindow, parameters: any) { mfaEnabled: false, mfaSecret: null } - const token = parameters.token; - const secret = user.mfaSecret; + const token = parameters.token + const secret = user.mfaSecret // console.log('verify_otp:', user) - const verified = verifyTOTP(token, secret); + const verified = verifyTOTP(token, secret) if (verified) { - user.mfaEnabled = true; - store.set('user', user); + user.mfaEnabled = true + store.set('user', user) } // console.log('verified_otp:', verified ,user) - wind.webContents.send('fromMain', ['mfa-verified', verified]); - return; + wind.webContents.send('fromMain', ['mfa-verified', verified]) } - diff --git a/src/app/app/toast.ts b/src/app/app/toast.ts index 1faae695..606f72bd 100644 --- a/src/app/app/toast.ts +++ b/src/app/app/toast.ts @@ -1,23 +1,32 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import fs from 'fs' import path from 'path' import { Notification } from 'electron' import { fileURLToPath } from 'node:url' -import isDev from 'electron-is-dev'; +import isDev from 'electron-is-dev' 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'; +const NOTIFICATION_TITLE = 'LedFx Client - by Blade' +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.toString()); + const configPath = path.join( + path.dirname(__dirname), + isDev ? '../' : '../../', + 'frontend_config.json' + ) + const configData = fs.readFileSync(configPath) + return JSON.parse(configData.toString()) } -export function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION_BODY) { - const config = getConfig(); - const updateUrl = config.updateUrl; +export function showNotification( + title = NOTIFICATION_TITLE, + body = NOTIFICATION_BODY +) { + const config = getConfig() + const updateUrl = config.updateUrl new Notification({ toastXml: ` @@ -30,7 +39,6 @@ export function showNotification(title = NOTIFICATION_TITLE, body = NOTIFICATION - `, - }).show(); + ` + }).show() } - diff --git a/src/app/electron.ts b/src/app/electron.ts index cf81f77f..67dc1da4 100644 --- a/src/app/electron.ts +++ b/src/app/electron.ts @@ -1,34 +1,42 @@ -import fs from 'fs'; -import path from 'path'; -import isDev from 'electron-is-dev'; -import { app, nativeTheme, BrowserWindow, ipcMain, shell, session } from 'electron'; -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 fs from 'fs' +import path from 'path' +import isDev from 'electron-is-dev' +import { + app, + nativeTheme, + BrowserWindow, + ipcMain, + shell, + session +} from 'electron' +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'; +import { handlers } from './app/handlers.mjs' -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) -EventEmitter.defaultMaxListeners = 15; +EventEmitter.defaultMaxListeners = 15 -const reduxDevtoolsPath = 'C:\\Users\\Blade\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\lmhkpmbekcpmknklioeibfkpmmfibljd\\3.2.7_0'; +const reduxDevtoolsPath = + 'C:\\Users\\Blade\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\lmhkpmbekcpmknklioeibfkpmmfibljd\\3.2.7_0' -const subpy: any = null; -const subprocesses: Record = {}; -let wind: BrowserWindow | null = null; -let win: BrowserWindow | null = null; +const subpy: any = null +const subprocesses: Record = {} +let wind: BrowserWindow | null = null +const win: BrowserWindow | null = null -setupProtocol(); -const gotTheLock = app.requestSingleInstanceLock(); +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')); + console.log('Creating .ledfx-cc folder') + fs.mkdirSync(path.join(app.getPath('userData'), '.ledfx-cc')) } const ready = () => @@ -44,37 +52,42 @@ const ready = () => : createWindow(win) const remoteMain = await import('@electron/remote/main/index.js') - - wind && remoteMain.enable(wind.webContents) - wind && wind.webContents.setWindowOpenHandler(({ url }) => { - if (url.includes(' https://accounts.spotify.com/authorize') - // || url.includes(`${backendUrl}/connect/github?callback`) - ) { - shell.openExternal(url) - // return { action: 'deny' } - } - return { action: 'allow' } - }) - - if (isCC && wind) startInstance(wind, 'instance1', subprocesses) - - - wind && createTray(isCC, wind, thePath, __dirname) + if (wind) { + remoteMain.enable(wind.webContents) + wind.webContents.setWindowOpenHandler(({ url }) => { + if ( + url.includes(' https://accounts.spotify.com/authorize') + // || url.includes(`${backendUrl}/connect/github?callback`) + ) { + shell.openExternal(url) + // return { action: 'deny' } + } + return { action: 'allow' } + }) + if (isCC) startInstance(wind, 'instance1', subprocesses) + createTray(isCC, wind, thePath, __dirname) + } - ipcMain.on('toMain', async (event, parameters) => - wind && handlers(wind, subprocesses, event, parameters) + ipcMain.on( + 'toMain', + async (event, parameters) => + wind && handlers(wind, subprocesses, event, parameters) ) - wind && wind.on('close', () => { - wind && closeAllSubs(wind, subpy, subprocesses) - wind = null; - }) + if (wind) { + wind.on('close', () => { + if (wind) { + closeAllSubs(wind, subpy, subprocesses) + wind = null + } + }) + } }) handleProtocol(() => wind, gotTheLock, ready) app.on('window-all-closed', () => { - wind && closeAllSubs(wind, subpy, subprocesses) + if (wind) closeAllSubs(wind, subpy, subprocesses) app.quit() }) diff --git a/src/components/AddButton/AddButton.tsx b/src/components/AddButton/AddButton.tsx index 1d574a87..c97c4f16 100644 --- a/src/components/AddButton/AddButton.tsx +++ b/src/components/AddButton/AddButton.tsx @@ -85,7 +85,7 @@ const AddButton = ({ className, style, setBackdrop, sx }: AddButtonProps) => { onClick={handleClick} sx={{ bgcolor: theme.palette.primary.main }} > - + ({ display: 'flex', justifyContent: 'space-between', alignItems: 'center', - minHeight: '55px', + minHeight: '55px' }, logo: { position: 'relative', diff --git a/src/components/Bars/BarLeft.tsx b/src/components/Bars/BarLeft.tsx index f4e8b0e3..2f4b7c96 100644 --- a/src/components/Bars/BarLeft.tsx +++ b/src/components/Bars/BarLeft.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useTheme } from '@mui/material/styles' import useMediaQuery from '@mui/material/useMediaQuery' @@ -45,19 +45,28 @@ const LeftBar = () => { <>
- logo + logo
window.localStorage.setItem('BladeMod', '0')} sx={{ - filter: theme.palette.mode === 'light' ? 'invert(1)' : 'invert(0)', + filter: + theme.palette.mode === 'light' ? 'invert(1)' : 'invert(0)', border: theme.palette.secondary.main, backgroundColor: isElectron() ? 'transparent' - : (theme.palette.mode === 'light' || theme.palette.primary.main === '#FFFFFF') ? 'transparent' : theme.palette.primary.main + : theme.palette.mode === 'light' || + theme.palette.primary.main === '#FFFFFF' + ? 'transparent' + : theme.palette.primary.main }} /> @@ -98,70 +107,78 @@ const LeftBar = () => { {Object.keys(virtuals) - .filter(v=> showComplex ? v : !(v.endsWith('-mask') || v.endsWith('-foreground') || v.endsWith('-background'))) - .filter(v=> showGaps ? v : !(v.startsWith('gap-'))) - .map((d, i) => ( - { - if (smallScreen) handleDrawerClose() - }} - > - + showComplex + ? v + : !( + v.endsWith('-mask') || + v.endsWith('-foreground') || + v.endsWith('-background') + ) + ) + .filter((v) => (showGaps ? v : !v.startsWith('gap-'))) + .map((d, i) => ( + { + if (smallScreen) handleDrawerClose() + }} + > + + + 0 } - : {} - } - key={virtuals[d].config.name} - > - - 0 - } - name={ - virtuals && - virtuals[d] && - virtuals[d].config && - virtuals[d].config.icon_name && - virtuals[d].config.icon_name - } + name={ + virtuals && + virtuals[d] && + virtuals[d].config && + virtuals[d].config.icon_name && + virtuals[d].config.icon_name + } + /> + + 0 + ? theme.palette.primary.light + : theme.palette.text.primary + }} + primary={virtuals[d].config.name} /> - - 0 - ? theme.palette.primary.light - : theme.palette.text.primary - }} - primary={virtuals[d].config.name} - /> - - - ))} + + + ))} diff --git a/src/components/Bars/BarTop.tsx b/src/components/Bars/BarTop.tsx index e0f492ef..97784453 100644 --- a/src/components/Bars/BarTop.tsx +++ b/src/components/Bars/BarTop.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @/indent */ import { useState, useEffect } from 'react' import { useLocation, useNavigate } from 'react-router-dom' import { compareVersions } from 'compare-versions' @@ -89,7 +90,7 @@ const LeftButtons = ( color="inherit" startIcon={} onClick={() => history(-1)} - sx={{ mt: .9 }} + sx={{ mt: 0.9 }} > Back @@ -135,12 +136,12 @@ const Title = ( ) => { const t = window.localStorage.getItem('ledfx-theme') const newVerOnline = - latestTag.replace('v', '').includes('-b') && pkg.version.includes('-b') + latestTag.replace('v', '').includes('-b') && pkg.version.includes('-b') ? compareVersions( - latestTag.replace('v', '').split('-b')[1], - pkg.version.split('-b')[1] + latestTag.replace('v', '').split('-b')[1], + pkg.version.split('-b')[1] ) === 1 - : compareVersions(latestTag.replace('v', ''), pkg.version) === 1; + : compareVersions(latestTag.replace('v', ''), pkg.version) === 1 if (pathname === '/') { return ( @@ -149,15 +150,16 @@ const Title = ( LedFx - {!process.env.MS_STORE && newVerOnline && frConfig.updateUrl && frConfig.releaseUrl ? ( + {!process.env.MS_STORE && + newVerOnline && + frConfig.updateUrl && + frConfig.releaseUrl ? ( ) : null} - + ) } if (pathname.split('/').length === 3 && pathname.split('/')[1] === 'device') { @@ -226,8 +228,10 @@ const TopBar = () => { const invScenes = useStore((state) => state.tours.scenes) const coreParams = useStore((state) => state.coreParams) const isCC = coreParams && Object.keys(coreParams).length > 0 - const updateNotificationInterval = useStore((state) => state.updateNotificationInterval) - const { requestWakeLock, releaseWakeLock } = useWakeLock(); + const updateNotificationInterval = useStore( + (state) => state.updateNotificationInterval + ) + const { requestWakeLock, releaseWakeLock } = useWakeLock() const isCreator = localStorage.getItem('ledfx-cloud-role') === 'creator' const invisible = () => { @@ -326,14 +330,14 @@ const TopBar = () => { useEffect(() => { if (frConfig.updateUrl) { const latest = async () => { - const res = await fetch(frConfig.updateUrl); - const resp = await res.json(); - return resp.tag_name as string; - }; - latest().then((r) => r !== latestTag && setLatestTag(r)); + const res = await fetch(frConfig.updateUrl) + const resp = await res.json() + return resp.tag_name as string + } + latest().then((r) => r !== latestTag && setLatestTag(r)) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [frConfig]); + }, [frConfig]) useEffect(() => { const handleDisconnect = (e: any) => { @@ -365,7 +369,6 @@ const TopBar = () => { }, []) useEffect(() => { - if (features.wakelock) { requestWakeLock() } else { @@ -376,7 +379,7 @@ const TopBar = () => { } // eslint-disable-next-line react-hooks/exhaustive-deps }, [features.wakelock]) - + const slug = pathname.split('/')[1] return ( @@ -423,7 +426,7 @@ const TopBar = () => {
{LeftButtons(pathname, history, open, handleLeftBarOpen)}
- + {Title(pathname, latestTag, updateAvailable, virtuals, frConfig)} @@ -594,10 +597,18 @@ const TopBar = () => { setAnchorEl(null)} /> ) : slug === 'Settings' ? ( setAnchorEl(null)} /> - ) : slug === 'Devices' ? ([ - setAnchorEl(null)} />, - setAnchorEl(null)} /> - ] + ) : slug === 'Devices' ? ( + [ + setAnchorEl(null)} + />, + setAnchorEl(null)} + /> + ] ) : slug === 'Integrations' ? ( setAnchorEl(null)} /> ) : ( @@ -608,42 +619,56 @@ const TopBar = () => { )} {slug !== 'Settings' && [ , - { - navigate(`/Settings?${slug === 'device' ? 'effects' : slug === 'Scenes' ? 'scenes' : slug === 'Devices' ? 'devices' : ''}`) - setAnchorEl(null)}}> + { + navigate( + `/Settings?${slug === 'device' ? 'effects' : slug === 'Scenes' ? 'scenes' : slug === 'Devices' ? 'devices' : ''}` + ) + setAnchorEl(null) + }} + > Settings ]} - {localStorage.getItem('username') === 'YeonV' && } - {localStorage.getItem('username') === 'YeonV' && - null} fullWidth - sx={{ pl: 2}} - disableUnderline - value={currentTheme} onChange={(e) => { - setCurrentTheme(e.target.value) - window.localStorage.setItem('ledfx-theme', e.target.value) - reloadTheme() - }} - > - {Object.keys(ledfxThemes).map((t) => ( - - - - - - + sx={{ pl: 2 }} + disableUnderline + value={currentTheme} + onChange={(e) => { + setCurrentTheme(e.target.value) + window.localStorage.setItem('ledfx-theme', e.target.value) + reloadTheme() + }} + > + {Object.keys(ledfxThemes).map((t) => ( + + + + {t} - - - - ))} - - } + + {t} + + + ))} + + )} )} diff --git a/src/components/Dialogs/AboutDialog.tsx b/src/components/Dialogs/AboutDialog.tsx index 7f220bfc..cc50f48d 100644 --- a/src/components/Dialogs/AboutDialog.tsx +++ b/src/components/Dialogs/AboutDialog.tsx @@ -62,7 +62,7 @@ export default function AboutDialog({ className, children, startIcon }: any) { if (open) { fetchData() - } + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]) diff --git a/src/components/Dialogs/AddDeviceDialog.tsx b/src/components/Dialogs/AddDeviceDialog.tsx index c76ca66b..a18e9d34 100644 --- a/src/components/Dialogs/AddDeviceDialog.tsx +++ b/src/components/Dialogs/AddDeviceDialog.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useState, useEffect } from 'react' import { styled } from '@mui/material/styles' @@ -111,12 +111,13 @@ const AddDeviceDialog = () => { (device: any) => device.config.ip_address ) const newDevices = [] as { name: string; ip_address: string }[] - res.nodes && + if (res.nodes) { res.nodes.forEach((node: any) => { if (node.ip && !deviceIps.includes(node.ip)) { newDevices.push({ name: node.name, ip_address: node.ip }) } }) + } if (newDevices.length > 0) { setAddWled(newDevices) } @@ -172,10 +173,12 @@ const AddDeviceDialog = () => { To add a device to LedFx, please first select the type of device you wish to add then provide the necessary configuration. - {deviceType === 'launchpad' && - When adding a Lunchpad as a led-output device, - you cannot use it as a MIDI input device at the same time (atm). - } + {deviceType === 'launchpad' && ( + + When adding a Lunchpad as a led-output device, you cannot use it as + a MIDI input device at the same time (atm). + + )}
@@ -140,49 +151,55 @@ function AddExistingSegmentDialog({ if (!newValue) { return } - const [name, segments] = Object.entries(JSON.parse(newValue))[0] as [string, [string, number, number, boolean]] + const [name, segments] = Object.entries(JSON.parse(newValue))[0] as [ + string, + [string, number, number, boolean] + ] // console.log(name) // console.log(segments) if (name && segments) { - const deviceKey = Object.keys(deviceList).find((d) => deviceList[d].id === segments[0]) + const deviceKey = Object.keys(deviceList).find( + (d) => deviceList[d].id === segments[0] + ) const device = deviceKey ? deviceList[deviceKey] : undefined // console.log(device) - const temp = [ - ...virtual.segments, - segments - ] - const test = temp.filter((t) => t.length === 4) - - updateSegments(virtual.id, test).then(() => { - getVirtuals() - if (device && virtual.active === false && virtual.segments.length === 0) { - if ( - device.active_virtuals && - device.active_virtuals[0] && - virtuals && - virtuals[device.active_virtuals[0]] && - virtuals[device.active_virtuals[0]].effect - ) { - setEffect( - virtual.id, - virtuals[device.active_virtuals[0]].effect.type, - virtuals[device.active_virtuals[0]].effect.config, - true - ) - } else { - setEffect(virtual.id, 'rainbow', {}, true) - } - } - if (device) { - highlightSegment( + const temp = [...virtual.segments, segments] + const test = temp.filter((t) => t.length === 4) + + updateSegments(virtual.id, test).then(() => { + getVirtuals() + if ( + device && + virtual.active === false && + virtual.segments.length === 0 + ) { + if ( + device.active_virtuals && + device.active_virtuals[0] && + virtuals && + virtuals[device.active_virtuals[0]] && + virtuals[device.active_virtuals[0]].effect + ) { + setEffect( virtual.id, - device.id, - segments[1], - segments[2], - false + virtuals[device.active_virtuals[0]].effect.type, + virtuals[device.active_virtuals[0]].effect.config, + true ) + } else { + setEffect(virtual.id, 'rainbow', {}, true) } - }) + } + if (device) { + highlightSegment( + virtual.id, + device.id, + segments[1], + segments[2], + false + ) + } + }) } } @@ -220,4 +237,4 @@ function AddExistingSegmentDialog({ ) } -export default AddExistingSegmentDialog \ No newline at end of file +export default AddExistingSegmentDialog diff --git a/src/components/Dialogs/AddIntegrationDialog.tsx b/src/components/Dialogs/AddIntegrationDialog.tsx index dc9bcee5..ef89031c 100644 --- a/src/components/Dialogs/AddIntegrationDialog.tsx +++ b/src/components/Dialogs/AddIntegrationDialog.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useState, useEffect } from 'react' import { styled } from '@mui/material/styles' diff --git a/src/components/Dialogs/AddWledDialog.tsx b/src/components/Dialogs/AddWledDialog.tsx index 606905bc..044a0932 100644 --- a/src/components/Dialogs/AddWledDialog.tsx +++ b/src/components/Dialogs/AddWledDialog.tsx @@ -110,7 +110,6 @@ const AddWledDialog = () => { }) } - // eslint-disable-next-line react-hooks/exhaustive-deps const col: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 130 }, @@ -125,7 +124,7 @@ const AddWledDialog = () => { width: 100 } ], - // eslint-disable-next-line react-hooks/exhaustive-deps + [col] ) return ( diff --git a/src/components/Dialogs/Download.tsx b/src/components/Dialogs/Download.tsx index 4b25f52f..4a959de8 100644 --- a/src/components/Dialogs/Download.tsx +++ b/src/components/Dialogs/Download.tsx @@ -5,10 +5,12 @@ interface LinearProgressWithLabelProps { * The value of the progress indicator for the determinate and buffer variants. * Value between 0 and 100. */ - value: number; + value: number } -export default function LinearProgressWithLabel(props: LinearProgressWithLabelProps) { +export default function LinearProgressWithLabel( + props: LinearProgressWithLabelProps +) { return ( diff --git a/src/components/Dialogs/EffectTypeDialog.tsx b/src/components/Dialogs/EffectTypeDialog.tsx index 31197462..6bc5236c 100644 --- a/src/components/Dialogs/EffectTypeDialog.tsx +++ b/src/components/Dialogs/EffectTypeDialog.tsx @@ -50,7 +50,14 @@ const EffectTypeDialog = ({ ) .filter((e: any) => !!e?.value) .sort((a, b) => { - const order = ['Non-Reactive', 'BPM', 'Classic', 'Atmospheric', '2D', 'Matrix'] + const order = [ + 'Non-Reactive', + 'BPM', + 'Classic', + 'Atmospheric', + '2D', + 'Matrix' + ] return order.indexOf(a.group) - order.indexOf(b.group) }) .sort((a, b) => { diff --git a/src/components/Dialogs/FrontendPixelsTooSmall.tsx b/src/components/Dialogs/FrontendPixelsTooSmall.tsx index 86d49732..772cf479 100644 --- a/src/components/Dialogs/FrontendPixelsTooSmall.tsx +++ b/src/components/Dialogs/FrontendPixelsTooSmall.tsx @@ -18,7 +18,7 @@ import { useLocation } from 'react-router-dom' // import { inverseLogScale, logScale } from '../../utils/helpers' export default function FrontendPixelsTooSmall() { - const sliderClasses = useSliderStyles() + const sliderClasses = useSliderStyles() const location = useLocation() const showWarning = useStore((state) => state.uiPersist.warnings.lessPixels) const fPixels = useStore((state) => state.config.visualisation_maxlen) @@ -52,14 +52,26 @@ export default function FrontendPixelsTooSmall() { virtuals[a]?.pixel_count > virtuals[b]?.pixel_count ? a : b, 0 ) - if (fPixels && (showMatrix || alphaMatrix) && tooBig.length > 0 && fPixels < 4096) { + if ( + fPixels && + (showMatrix || alphaMatrix) && + tooBig.length > 0 && + fPixels < 4096 + ) { setBiggestDevice({ id: biggest, pixels: virtuals[biggest]?.pixel_count }) setDialogOpenLessPixels(true) } if (fPixels && showMatrix && tooBig.length === 0) { setDialogOpenLessPixels(false) } - }, [showMatrix, fPixels, virtuals, setDialogOpenLessPixels, location, alphaMatrix]) + }, [ + showMatrix, + fPixels, + virtuals, + setDialogOpenLessPixels, + location, + alphaMatrix + ]) useEffect(() => { getSystemConfig() @@ -91,8 +103,16 @@ export default function FrontendPixelsTooSmall() { is configured to show only ${fPixels} pixels. Please increase the number of pixels`} - setShowWarning('lessPixels', !showWarning)}/> - toggleShowMatrix()} /> + setShowWarning('lessPixels', !showWarning)} + /> + toggleShowMatrix()} + /> { if (storedURL) setHostvalue(storedURL) if (storedURLs) setHosts(storedURLs) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [storedURL, setHosts]) useEffect(() => { diff --git a/src/components/Dialogs/IntroDialog.tsx b/src/components/Dialogs/IntroDialog.tsx index 6b5b94bd..0b8b061a 100644 --- a/src/components/Dialogs/IntroDialog.tsx +++ b/src/components/Dialogs/IntroDialog.tsx @@ -161,7 +161,7 @@ export default function IntroDialog({ }, action_right: handleNext }, - isCC ?? ({ + isCC ?? { key: 'theme', title: 'Choose your Theme', label_left: 'Lightmode', @@ -175,8 +175,8 @@ export default function IntroDialog({ window.localStorage.setItem('ledfx-theme', 'DarkWhite') reloadTheme() handleNext() - } - }), + } + }, { key: 'gotWled', title: 'Scan for devices?', diff --git a/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx b/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx index 255674b2..210a76d4 100644 --- a/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx +++ b/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useCallback, useEffect, useRef, useState } from 'react' import { AppBar, @@ -62,7 +62,6 @@ const EditSceneDialog = () => { const setMidiMapping = useStore((state) => state.setMidiMapping) const initMidi = useStore((state) => state.initMidi) - const { effects } = useStore((state) => state.schemas) const scenes = useStore((state) => state.scenes) const open = useStore((state) => state.dialogs.addScene?.edit || false) @@ -234,22 +233,27 @@ const EditSceneDialog = () => { getLedFxPresets().then(setLedFxPresets) getUserPresets().then(setUserPresets) if (open) activateScene(data.name?.toLowerCase().replaceAll(' ', '-')) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [open]) useEffect(() => { if (features.scenemidi && midiEvent.button > -1) { - setMIDIActivate( - `${midiEvent.name} Note: ${midiEvent.note} buttonNumber: ${midiEvent.button}` - ) + setMIDIActivate( + `${midiEvent.name} Note: ${midiEvent.note} buttonNumber: ${midiEvent.button}` + ) } }, [midiEvent, features.scenemidi]) - + useEffect(() => { if (features.scenemidi && open) { initMidi() - const output = midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1] - const currentBtnNumber = parseInt(scenes[sceneId].scene_midiactivate?.split('buttonNumber: ')[1]); + const output = + midiOutput !== '' + ? WebMidi.getOutputByName(midiOutput) + : WebMidi.outputs[1] + const currentBtnNumber = parseInt( + scenes[sceneId].scene_midiactivate?.split('buttonNumber: ')[1] + ) const lp = MidiDevices[midiType][midiModel].fn if (currentBtnNumber > -1) { setTimeout(() => { @@ -263,13 +267,18 @@ const EditSceneDialog = () => { } // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, features.scenemidi]) - + useEffect(() => { if (features.scenemidi && open) { setBlockMidiHandler(true) - const output = midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1] - const currentBtnNumber = parseInt(scenes[sceneId].scene_midiactivate?.split('buttonNumber: ')[1]); - const newBtnNumber = parseInt(midiActivate?.split('buttonNumber: ')[1]); + const output = + midiOutput !== '' + ? WebMidi.getOutputByName(midiOutput) + : WebMidi.outputs[1] + const currentBtnNumber = parseInt( + scenes[sceneId].scene_midiactivate?.split('buttonNumber: ')[1] + ) + const newBtnNumber = parseInt(midiActivate?.split('buttonNumber: ')[1]) const lp = MidiDevices[midiType][midiModel].fn if (newBtnNumber > -1) { setTimeout(() => { @@ -279,9 +288,12 @@ const EditSceneDialog = () => { } else { output.send(lp.ledOn(newBtnNumber, 57)) } - if (lastButton.current !== newBtnNumber && lastButton.current > -1) { + if ( + lastButton.current !== newBtnNumber && + lastButton.current > -1 + ) { output.send(lp.ledOff(lastButton.current)) - } + } } if (currentBtnNumber > -1 && newBtnNumber !== currentBtnNumber) { if ('ledPulse' in lp) { @@ -292,7 +304,12 @@ const EditSceneDialog = () => { output.send(lp.ledOn(newBtnNumber, 57)) } } - if (currentBtnNumber > -1 && lastButton.current > -1 && lastButton.current !== newBtnNumber && lastButton.current !== currentBtnNumber) { + if ( + currentBtnNumber > -1 && + lastButton.current > -1 && + lastButton.current !== newBtnNumber && + lastButton.current !== currentBtnNumber + ) { output.send(lp.ledOff(lastButton.current)) } lastButton.current = newBtnNumber @@ -844,7 +861,10 @@ const EditSceneDialog = () => { /> setMIDIActivate('')} - label={/\((.*?)\)/.exec(midiActivate)?.[1].replace(' MIDI', '').trim()} + label={/\((.*?)\)/ + .exec(midiActivate)?.[1] + .replace(' MIDI', '') + .trim()} icon={} /> @@ -853,9 +873,10 @@ const EditSceneDialog = () => { ) }} /> - {/\((.*?)\)/.exec(midiActivate)?.[1].replace(' MIDI', '').trim() === 'LPX' && ( - - )} + {/\((.*?)\)/ + .exec(midiActivate)?.[1] + .replace(' MIDI', '') + .trim() === 'LPX' && } ) : ( @@ -1048,29 +1069,41 @@ const EditSceneDialog = () => { - Change Order + + + + Change Order + diff --git a/src/components/Gamepad/Assign.tsx b/src/components/Gamepad/Assign.tsx index 08e858cc..e5f7b3f4 100644 --- a/src/components/Gamepad/Assign.tsx +++ b/src/components/Gamepad/Assign.tsx @@ -1,3 +1,5 @@ +/* eslint-disable prettier/prettier */ +/* eslint-disable @/indent */ import { Fab, FormControl, @@ -55,7 +57,7 @@ const Assign = ({ } return ( - + {compact && { function handleButtonPress(command: string, payload?: any) { if (command === 'scene' && payload?.scene) { - setScene(payload.scene); + setScene(payload.scene) } else if (command === 'padscreen') { - setOpen(!open); + setOpen(!open) } else if (command === 'smartbar') { - setSmartBarPadOpen(!smartBarPadOpen); + setSmartBarPadOpen(!smartBarPadOpen) } else if (command === 'play/pause') { - togglePause(); + togglePause() } else if (command === 'brightness-up') { setSystemSetting( 'global_brightness', Math.min(brightness + 0.1, 1).toFixed(2) - ); + ) } else if (command === 'brightness-down') { setSystemSetting( 'global_brightness', Math.max(brightness - 0.1, 0).toFixed(2) - ); + ) } else if (command === 'scan-wled') { - handleScan(); + handleScan() } else if (command === 'copy-to') { - setFeatures('streamto', !features.streamto); + setFeatures('streamto', !features.streamto) } else if (command === 'transitions') { - setFeatures('transitions', !features.transitions); + setFeatures('transitions', !features.transitions) } else if (command === 'frequencies') { - setFeatures('frequencies', !features.frequencies); + setFeatures('frequencies', !features.frequencies) } else if (command === 'scene-playlist') { - toggleScenePLplay(); + toggleScenePLplay() } else if (command === 'one-shot') { oneShotAll( payload?.color || '#0dbedc', payload?.ramp || 10, payload?.hold || 200, payload?.fade || 2000 - ); + ) } } @@ -172,9 +172,12 @@ const Gamepad = ({ setScene, bottom }: any) => { mapping[pad.index][i] && mapping[pad.index][i].command && mapping[pad.index][i].command !== 'none' - if (test) { - handleButtonPress(mapping[pad.index][i].command!, mapping[pad.index][i].payload); - } else if (pad.axes[0] === 1 && analogBrightness[0]) { + if (test) { + handleButtonPress( + mapping[pad.index][i].command!, + mapping[pad.index][i].payload + ) + } else if (pad.axes[0] === 1 && analogBrightness[0]) { setSystemSetting( 'global_brightness', Math.min(brightness + 0.1, 1).toFixed(2) diff --git a/src/components/Gamepad/GamepadSvg.tsx b/src/components/Gamepad/GamepadSvg.tsx index 6ae05988..a09c8f3f 100644 --- a/src/components/Gamepad/GamepadSvg.tsx +++ b/src/components/Gamepad/GamepadSvg.tsx @@ -46,7 +46,7 @@ const GamepadSvg = ({ { +const OneEffect = ({ setPayload, noButton }: any) => { const [dialogOpen, setDialogOpen] = useState(false) const [virtId, setVirtId] = useState('') @@ -48,7 +45,7 @@ const OneEffect = ({ setDialogOpen(false) } const handleSave = () => { - setPayload({ }) + setPayload({}) setDialogOpen(false) } // const handleTest = (virtId: string, type: string, config: EffectConfig, active: boolean, fallback: boolean | number) => { @@ -66,17 +63,22 @@ const OneEffect = ({ return ( <> - {!noButton && } + {!noButton && ( + + )} - One Effect + + One Effect - Virtual ID + + Virtual ID + - Preset + + Preset + setSelected(e.target.value)}> - {matrix.map((v) => ( - {v} - ))} - - - - - { - spotifyTexter.use_gradient - ? setSpTexterGradient(v)} /> - : setSpTexterTextColor(v)} /> - } - setSpTexterBackground(v)} /> - - - - typeof v === 'number' && setSpTexterBrightness(v)} /> - - - typeof v === 'number' && setSpTexterBackgroundBrightness(v)} /> - - - - {/* all booleans */} - - setSpTexterUseGradient(b)} - name={'Gradient'} - color="primary" - /> - - - setSpTexterAlpha(b)} - name={'Alpha'} - color="primary" - /> - - - setSpTexterFlipHorizontal(b)} - name={'Flip Hl'} - color="primary" - /> - - - setSpTexterFlipVertical(b)} - name={'Flip V'} - color="primary" - /> - - - - - typeof v === 'number' && setSpTexterGradientRoll(v)} /> - - - typeof v === 'number' && setSpTexterRotate(v)} /> - - - - - typeof v === 'number' && setSpTexterSpeed(v)} /> - - - typeof v === 'number' && setSpTexterHeightPercent(v)} /> - - - - - - - - - - - - - - ) + return ( + + setOpen(!open)}> + + + setOpen(false)} + PaperProps={{ onDrag: (e: any) => e.stopProagation() }} + onDrag={(e: any) => e.stopProagation()} + > + Send songname to matrix + + + + + + + {spotifyTexter.use_gradient ? ( + setSpTexterGradient(v)} + /> + ) : ( + setSpTexterTextColor(v)} + /> + )} + setSpTexterBackground(v)} + /> + + + + + typeof v === 'number' && setSpTexterBrightness(v) + } + /> + + + + typeof v === 'number' && setSpTexterBackgroundBrightness(v) + } + /> + + + + {/* all booleans */} + + setSpTexterUseGradient(b)} + name={'Gradient'} + color="primary" + /> + + + setSpTexterAlpha(b)} + name={'Alpha'} + color="primary" + /> + + + setSpTexterFlipHorizontal(b)} + name={'Flip Hl'} + color="primary" + /> + + + setSpTexterFlipVertical(b)} + name={'Flip V'} + color="primary" + /> + + + + + + typeof v === 'number' && setSpTexterGradientRoll(v) + } + /> + + + + typeof v === 'number' && setSpTexterRotate(v) + } + /> + + + + + + typeof v === 'number' && setSpTexterSpeed(v) + } + /> + + + + typeof v === 'number' && setSpTexterHeightPercent(v) + } + /> + + + + + + + + + + + + + + ) } -export default SpTexter \ No newline at end of file +export default SpTexter diff --git a/src/components/Integrations/Spotify/Widgets/SpotifyWidgetPro/SpTrack.tsx b/src/components/Integrations/Spotify/Widgets/SpotifyWidgetPro/SpTrack.tsx index 8c9d2130..30a395aa 100644 --- a/src/components/Integrations/Spotify/Widgets/SpotifyWidgetPro/SpTrack.tsx +++ b/src/components/Integrations/Spotify/Widgets/SpotifyWidgetPro/SpTrack.tsx @@ -41,9 +41,13 @@ export default function SpTrack({ className }: any) { spCtx?.item?.album?.name || '' - setCurrentTrack(`${artist.length > 1 - ? artist.map((art: any) => art.name).join(',') - : artist[0].name} - ${title}`) + setCurrentTrack( + `${ + artist.length > 1 + ? artist.map((art: any) => art.name).join(',') + : artist[0].name + } - ${title}` + ) return ( diff --git a/src/components/MGraph.tsx b/src/components/MGraph.tsx index fcaa844a..ebc9b884 100644 --- a/src/components/MGraph.tsx +++ b/src/components/MGraph.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @/indent */ import { useEffect, useState } from 'react' import { Line } from 'react-chartjs-2' import { @@ -139,8 +140,8 @@ const MGraph = () => { maxTicksLimit: 12, callback: (value: any, _index: number) => { // console.log('frequencies', messageData.frequencies) - const frequency = messageData.frequencies[_index]; - return `${JSON.stringify(frequency)} Hz`; + const frequency = messageData.frequencies[_index] + return `${JSON.stringify(frequency)} Hz` } }, grid: { @@ -175,13 +176,13 @@ const MGraph = () => { // setData({ chartData, chartOptions }) switch (messageData.graph_id) { case 'melbank_0': - setData1({ chartData, chartOptions}); + setData1({ chartData, chartOptions }) break case 'melbank_1': - setData2({ chartData, chartOptions}) + setData2({ chartData, chartOptions }) break case 'melbank_2': - setData3({ chartData, chartOptions}) + setData3({ chartData, chartOptions }) break default: break @@ -196,9 +197,13 @@ const MGraph = () => { return ( - setShowSettings(!showSettings)}> + setShowSettings(!showSettings)} + > - + { width: '100%', margin: '3rem', // background: theme.palette.mode === 'dark' ? '#1c1c1e' : '' - background: theme.palette.background.paper, + background: theme.palette.background.paper // border: theme.palette.background.paper === '#000000' ? '1px solid #333' : '' }} > @@ -306,21 +311,48 @@ const MGraph = () => { - {data1?.chartData && data1?.chartOptions && data1?.chartData?.labels && ( -
- -
- )} - {data2?.chartData && data2?.chartOptions && data2?.chartData?.labels && ( -
- -
- )} - {data3?.chartData && data3?.chartOptions && data3?.chartData?.labels && ( -
- -
- )} + {data1?.chartData && + data1?.chartOptions && + data1?.chartData?.labels && ( +
+ +
+ )} + {data2?.chartData && + data2?.chartOptions && + data2?.chartData?.labels && ( +
+ +
+ )} + {data3?.chartData && + data3?.chartOptions && + data3?.chartData?.labels && ( +
+ +
+ )}
) diff --git a/src/components/Midi/ColorTypePicker.tsx b/src/components/Midi/ColorTypePicker.tsx index 8e570195..19f4d198 100644 --- a/src/components/Midi/ColorTypePicker.tsx +++ b/src/components/Midi/ColorTypePicker.tsx @@ -1,18 +1,23 @@ -import { MenuItem, Select, SelectProps } from '@mui/material'; +import { MenuItem, Select, SelectProps } from '@mui/material' interface ColorTypePickerProps extends Omit { - value: string; - onChange: (e: any) => void; - isRgb?: boolean; + value: string + onChange: (_e: any) => void + isRgb?: boolean } -const ColorTypePicker: React.FC = ({ value, onChange, isRgb, ...props }) => ( +const ColorTypePicker: React.FC = ({ + value, + onChange, + isRgb, + ...props +}) => ( -); +) -export default ColorTypePicker; +export default ColorTypePicker diff --git a/src/components/Midi/LaunchpadButton.tsx b/src/components/Midi/LaunchpadButton.tsx index 397d3331..da88e222 100644 --- a/src/components/Midi/LaunchpadButton.tsx +++ b/src/components/Midi/LaunchpadButton.tsx @@ -1,7 +1,16 @@ +/* eslint-disable prettier/prettier */ import Button from '@mui/material/Button' import DialogTitle from '@mui/material/DialogTitle' import Dialog from '@mui/material/Dialog' -import { darken, DialogContent, Divider, IconButton, Stack, TextField, Typography } from '@mui/material' +import { + darken, + DialogContent, + Divider, + IconButton, + Stack, + TextField, + Typography +} from '@mui/material' import { useEffect, useRef, useState } from 'react' import LpColorPicker from './LpColorPicker' import Assign from '../Gamepad/Assign' @@ -11,22 +20,23 @@ import { MidiDevices } from '../../utils/MidiDevices/MidiDevices' import ColorTypePicker from './ColorTypePicker' const LaunchpadButton = ({ - uiButtonNumber, - active, - borderless, - bgColor, - children, - hidden, - showMidiLogs, - ...props + uiButtonNumber, + active, + borderless, + bgColor, + children, + hidden, + // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars + showMidiLogs, + ...props }: { - hidden?: boolean - uiButtonNumber: number - children: React.ReactNode - active?: boolean - borderless?: boolean - bgColor?: string - showMidiLogs?: boolean + hidden?: boolean + uiButtonNumber: number + children: React.ReactNode + active?: boolean + borderless?: boolean + bgColor?: string + showMidiLogs?: boolean }) => { // console.log(bgColor) const [open, setOpen] = useState(false) @@ -37,11 +47,19 @@ const LaunchpadButton = ({ const getColorFromValue = useStore((state) => state.getColorFromValue) const initMidi = useStore((state) => state.initMidi) const setMidiMapping = useStore((state) => state.setMidiMapping) - const midiSceneInactiveColor = useStore((state) => state.midiColors.sceneInactiveColor) - const midiSceneActiveColor = useStore((state) => state.midiColors.sceneActiveColor) + const midiSceneInactiveColor = useStore( + (state) => state.midiColors.sceneInactiveColor + ) + const midiSceneActiveColor = useStore( + (state) => state.midiColors.sceneActiveColor + ) const midiCommandColor = useStore((state) => state.midiColors.commandColor) - const midiSceneInactiveType = useStore((state) => state.midiColors.sceneInactiveType) - const midiSceneActiveType = useStore((state) => state.midiColors.sceneActiveType) + const midiSceneInactiveType = useStore( + (state) => state.midiColors.sceneInactiveType + ) + const midiSceneActiveType = useStore( + (state) => state.midiColors.sceneActiveType + ) const midiCommandType = useStore((state) => state.midiColors.commandType) const setFeatures = useStore((state) => state.setFeatures) const togglePause = useStore((state) => state.togglePause) @@ -75,11 +93,13 @@ const LaunchpadButton = ({ setOpen(false) } - const currentMapping = midiMapping[0][uiButtonNumber] || {}; - - const [midiButtonNumber, setMidiButtonNumber] = useState(currentMapping.buttonNumber || 0) + const currentMapping = midiMapping[0][uiButtonNumber] || {} + + const [midiButtonNumber, setMidiButtonNumber] = useState( + currentMapping.buttonNumber || 0 + ) const [midiRecord, setMidiRecord] = useState(false) - + const lp = MidiDevices[midiType][midiModel] const isRgb = 'rgb' in lp.fn function handleButtonPress(command: string, payload?: any) { @@ -109,7 +129,7 @@ const LaunchpadButton = ({ oneShotAll( payload?.color || '#0dbedc', payload?.ramp || 10, - payload?.holdType !== 'release' ? (payload?.hold || 200) : 10000, + payload?.holdType !== 'release' ? payload?.hold || 200 : 10000, payload?.fade || 2000 ) } else if (command === 'copy-to') { @@ -128,15 +148,15 @@ const LaunchpadButton = ({ ...midiMapping[0], [uiButtonNumber]: { ...currentMapping, - [type]: color, - }, - }, - }); - }; + [type]: color + } + } + }) + } useEffect(() => { if (midiRecord && midiEvent.button > -1) { - setMidiButtonNumber(midiEvent.button) + setMidiButtonNumber(midiEvent.button) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [midiEvent.button]) @@ -144,132 +164,251 @@ const LaunchpadButton = ({ // const [row, col] = uiButtonNumber.toString().split('').map(Number) return ( - ) } -export default LaunchpadButton \ No newline at end of file +export default LaunchpadButton diff --git a/src/components/Midi/LaunchpadButtonMap.tsx b/src/components/Midi/LaunchpadButtonMap.tsx index 4e7d39bb..8f9117e4 100644 --- a/src/components/Midi/LaunchpadButtonMap.tsx +++ b/src/components/Midi/LaunchpadButtonMap.tsx @@ -1,5 +1,40 @@ -import { ArrowForwardIos, BrightnessHigh, Collections, Pause, PlayArrow, ViewSidebar, Menu as MenuIcon, Save, Delete, DeleteForever, Visibility, Autorenew, Fullscreen, FullscreenExit, BugReport, Send } from '@mui/icons-material' -import { Box, Button, Divider, ListItemIcon, ListItemText, ListSubheader, Menu, MenuItem, Select, SelectChangeEvent, Stack, TextField, Tooltip, Typography, useTheme } from '@mui/material' +/* eslint-disable prettier/prettier */ +/* eslint-disable @/indent */ +import { + ArrowForwardIos, + BrightnessHigh, + Collections, + Pause, + PlayArrow, + ViewSidebar, + Menu as MenuIcon, + Save, + Delete, + DeleteForever, + Visibility, + Autorenew, + Fullscreen, + FullscreenExit, + BugReport, + Send +} from '@mui/icons-material' +import { + Box, + Button, + Divider, + ListItemIcon, + ListItemText, + ListSubheader, + Menu, + MenuItem, + Select, + SelectChangeEvent, + Stack, + TextField, + Tooltip, + Typography, + useTheme +} from '@mui/material' import BladeIcon from '../Icons/BladeIcon/BladeIcon' import useStore from '../../store/useStore' import Assign from '../Gamepad/Assign' @@ -12,440 +47,843 @@ import { download } from '../../utils/helpers' import { Launchpad, MidiDevices } from '../../utils/MidiDevices/MidiDevices' import LaunchpadSettings from './LaunchpadSettings' -const LaunchpadButtonMap = ({toggleSidebar, sideBarOpen, fullScreen, setFullScreen}:{toggleSidebar: () => void, sideBarOpen: boolean, fullScreen?: boolean, setFullScreen: (f:boolean) => void}) => { - const theme = useTheme() - const parentRef = useRef(null); - const childRef = useRef(null); - const [midiMessageToSend, setMidiMessageToSend] = useState('') - const [scale, setScale] = useState(1); - const [midiLogs, setMidiLogs] = useState<{ - name: string; - note: string; - button: number; - }[]>([]) - const [showMidiLogs, setShowMidiLogs] = useState(false) - const [showMapping, setShowMapping] = useState(false) - const setMidiMappingButtonNumbers = useStore((state) => state.setMidiMappingButtonNumbers) - const getColorFromValue = useStore((state) => state.getColorFromValue) - const initMidi = useStore((state) => state.initMidi) - const setMidiType = useStore((state) => state.setMidiType) - const setMidiModel = useStore((state) => state.setMidiModel) - const midiModel = useStore((state) => state.midiModel) - const midiType = useStore((state) => state.midiType) - const midiEvent = useStore((state) => state.midiEvent) - const midiOutput = useStore((state) => state.midiOutput) - const recentScenes = useStore((state) => state.recentScenes) - const midiMapping = useStore((state) => state.midiMapping) - const setMidiMapping = useStore((state) => state.setMidiMapping) - const setMidiSceneActiveColor = useStore((state) => state.setMidiSceneActiveColor) - const setMidiSceneInactiveColor = useStore((state) => state.setMidiSceneInactiveColor) - const setMidiCommandColor = useStore((state) => state.setMidiCommandColor) - const midiSceneActiveColor = useStore((state) => state.midiColors.sceneActiveColor) - const midiSceneInactiveColor = useStore((state) => state.midiColors.sceneInactiveColor) - const midiCommandColor = useStore((state) => state.midiColors.commandColor) - const setMidiSceneActiveType = useStore((state) => state.setMidiSceneActiveType) - const setMidiSceneInactiveType = useStore((state) => state.setMidiSceneInactiveType) - const setMidiCommandType = useStore((state) => state.setMidiCommandType) - const pressedButtonColor = useStore((state) => state.midiColors.pressedButtonColor) - const integrations = useStore((state) => state.integrations) - const currentTrack = useStore((state) => state.spotify.currentTrack) - const spAuthenticated = useStore((state) => state.spotify.spAuthenticated) - const sendSpotifyTrack = useStore((state) => state.spotify.sendSpotifyTrack) - const setSendSpotifyTrack = useStore((state) => state.setSendSpotifyTrack) - const paused = useStore((state) => state.paused) - const matrix = Array.from({ length: 9 }, () => Array.from({ length: 9 }, () => 0)) - const [anchorEl, setAnchorEl] = useState(null); - const open = Boolean(anchorEl); - const lp= MidiDevices[midiType][midiModel] - const isRgb = 'rgb' in lp.fn && lp.fn.rgb - - const output = WebMidi.enabled && (midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1]) +const LaunchpadButtonMap = ({ + toggleSidebar, + sideBarOpen, + fullScreen, + setFullScreen +}: { + toggleSidebar: () => void + sideBarOpen: boolean + fullScreen?: boolean + setFullScreen: (_f: boolean) => void +}) => { + const theme = useTheme() + const parentRef = useRef(null) + const childRef = useRef(null) + const [midiMessageToSend, setMidiMessageToSend] = useState('') + const [scale, setScale] = useState(1) + const [midiLogs, setMidiLogs] = useState< + { + name: string + note: string + button: number + }[] + >([]) + const [showMidiLogs, setShowMidiLogs] = useState(false) + const [showMapping, setShowMapping] = useState(false) + const setMidiMappingButtonNumbers = useStore( + (state) => state.setMidiMappingButtonNumbers + ) + const getColorFromValue = useStore((state) => state.getColorFromValue) + const initMidi = useStore((state) => state.initMidi) + const setMidiType = useStore((state) => state.setMidiType) + const setMidiModel = useStore((state) => state.setMidiModel) + const midiModel = useStore((state) => state.midiModel) + const midiType = useStore((state) => state.midiType) + const midiEvent = useStore((state) => state.midiEvent) + const midiOutput = useStore((state) => state.midiOutput) + const recentScenes = useStore((state) => state.recentScenes) + const midiMapping = useStore((state) => state.midiMapping) + const setMidiMapping = useStore((state) => state.setMidiMapping) + const setMidiSceneActiveColor = useStore( + (state) => state.setMidiSceneActiveColor + ) + const setMidiSceneInactiveColor = useStore( + (state) => state.setMidiSceneInactiveColor + ) + const setMidiCommandColor = useStore((state) => state.setMidiCommandColor) + const midiSceneActiveColor = useStore( + (state) => state.midiColors.sceneActiveColor + ) + const midiSceneInactiveColor = useStore( + (state) => state.midiColors.sceneInactiveColor + ) + const midiCommandColor = useStore((state) => state.midiColors.commandColor) + const setMidiSceneActiveType = useStore( + (state) => state.setMidiSceneActiveType + ) + const setMidiSceneInactiveType = useStore( + (state) => state.setMidiSceneInactiveType + ) + const setMidiCommandType = useStore((state) => state.setMidiCommandType) + const pressedButtonColor = useStore( + (state) => state.midiColors.pressedButtonColor + ) + const integrations = useStore((state) => state.integrations) + const currentTrack = useStore((state) => state.spotify.currentTrack) + const spAuthenticated = useStore((state) => state.spotify.spAuthenticated) + const sendSpotifyTrack = useStore((state) => state.spotify.sendSpotifyTrack) + const setSendSpotifyTrack = useStore((state) => state.setSendSpotifyTrack) + const paused = useStore((state) => state.paused) + const matrix = Array.from({ length: 9 }, () => + Array.from({ length: 9 }, () => 0) + ) + const [anchorEl, setAnchorEl] = useState(null) + const open = Boolean(anchorEl) + const lp = MidiDevices[midiType][midiModel] + const isRgb = 'rgb' in lp.fn && lp.fn.rgb - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - } - const handleClose = () => { - setAnchorEl(null); - } - const gotMidiMapping = async (e: any) => { - const fileReader = new FileReader() - fileReader.readAsText(e.target.files[0], 'UTF-8') - fileReader.onload = (ev: any) => { - if (ev.target.result && JSON.parse(ev.target.result).midiMapping) - setMidiMapping(JSON.parse(ev.target.result).midiMapping) - handleClose() - } + const output = + WebMidi.enabled && + (midiOutput !== '' + ? WebMidi.getOutputByName(midiOutput) + : WebMidi.outputs[1]) + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget) + } + const handleClose = () => { + setAnchorEl(null) + } + const gotMidiMapping = async (e: any) => { + const fileReader = new FileReader() + fileReader.readAsText(e.target.files[0], 'UTF-8') + fileReader.onload = (ev: any) => { + if (ev.target.result && JSON.parse(ev.target.result).midiMapping) + setMidiMapping(JSON.parse(ev.target.result).midiMapping) + handleClose() } - const RightButton = ({children}: { - children: React.ReactNode - }) => {children} - const labels = (rowI: number, butI: number) => { - if (rowI === 0 && butI === 0) return {showMapping && } - if (rowI === 0 && butI === 1) return {showMapping && } - if (rowI === 0 && butI === 2) return {showMapping && } - if (rowI === 0 && butI === 3) return {showMapping && } - if (rowI === 0 && butI === 3) return - if (rowI === 0 && butI === 4) return
Session Mixer
- if (rowI === 0 && butI === 5) return Note - if (rowI === 0 && butI === 6) return Custom - if (rowI === 0 && butI === 7) return
Capture MIDI
- if (rowI === 0 && butI === 8) return - if (rowI === 1 && butI === 8) return Volume - if (rowI === 2 && butI === 8) return Pan - if (rowI === 3 && butI === 8) return Send B - if (rowI === 4 && butI === 8) return Send A - if (rowI === 5 && butI === 8) return Stop Clip - if (rowI === 6 && butI === 8) return Mute - if (rowI === 7 && butI === 8) return Solo - if (rowI === 8 && butI === 8) return Record Arm - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'padscreen' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'scan-wled' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'scene-playlist' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'frequencies' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'transitions' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'copy-to' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'brightness-up' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'brightness-down' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'play/pause' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'smartbar' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'one-shot' && showMapping) return - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'scene' && showMapping) return ( - {/* {midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.payload?.scene} */} - ) - if (midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.command === 'play/pause' && showMapping) return - return showMapping ? `${(9 - rowI)}${butI + 1}` : null + } + const RightButton = ({ children }: { children: React.ReactNode }) => ( + + + + {children} + + + ) + const labels = (rowI: number, butI: number) => { + if (rowI === 0 && butI === 0) + return ( + + + {showMapping && } + + ) + if (rowI === 0 && butI === 1) + return ( + + + {showMapping && } + + ) + if (rowI === 0 && butI === 2) + return ( + + + {showMapping && } + + ) + if (rowI === 0 && butI === 3) + return ( + + + {showMapping && } + + ) + if (rowI === 0 && butI === 3) return + if (rowI === 0 && butI === 4) + return ( + +
+ Session Mixer +
+ ) + if (rowI === 0 && butI === 5) + return ( + + Note + + ) + if (rowI === 0 && butI === 6) + return ( + + Custom + + ) + if (rowI === 0 && butI === 7) + return ( + +
+ Capture MIDI +
+ ) + if (rowI === 0 && butI === 8) + return ( + + ) + if (rowI === 1 && butI === 8) return Volume + if (rowI === 2 && butI === 8) return Pan + if (rowI === 3 && butI === 8) return Send B + if (rowI === 4 && butI === 8) return Send A + if (rowI === 5 && butI === 8) + return Stop Clip + if (rowI === 6 && butI === 8) return Mute + if (rowI === 7 && butI === 8) return Solo + if (rowI === 8 && butI === 8) + return Record Arm + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'padscreen' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'scan-wled' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'scene-playlist' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'frequencies' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'transitions' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'copy-to' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'brightness-up' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'brightness-down' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'play/pause' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'smartbar' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'one-shot' && + showMapping + ) + return + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === 'scene' && + showMapping + ) + return ( + + + {/* {midiMapping[0][parseInt(`${(9 - rowI)}${butI + 1}`)]?.payload?.scene} */} + + ) + if ( + midiMapping[0][parseInt(`${9 - rowI}${butI + 1}`)]?.command === + 'play/pause' && + showMapping + ) + return ( + + ) + return showMapping ? `${9 - rowI}${butI + 1}` : null + } + // console.log(midiMapping) + + const setMode = (mode: 'programmer' | 'live' | 'standalone' | 'daw') => { + initMidi() + const output = + midiOutput !== '' + ? WebMidi.getOutputByName(midiOutput) + : WebMidi.outputs[1] + if (!output) return + switch (mode) { + case 'programmer': + output.send([0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x01, 0xf7]) + break + case 'live': + output.send([0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x00, 0xf7]) + break + case 'standalone': + output.send([0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x00, 0xf7]) + break + case 'daw': + output.send([0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x01, 0xf7]) + break + default: + break } - // console.log(midiMapping) + } - const setMode = (mode: 'programmer' | 'live' | 'standalone' | 'daw') => { - initMidi() - const output = midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1] - if (!output) return - switch (mode) { - case 'programmer': - output.send([0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x01, 0xF7]) - break - case 'live': - output.send([0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x00, 0xF7]) - break - case 'standalone': - output.send([0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x00, 0xF7]) - break - case 'daw': - output.send([0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x01, 0xF7]) - break - default: - break - } + useEffect(() => { + const parent = parentRef.current + const child = childRef.current + + if (parent && child) { + const scaleX = parent.clientWidth / child.clientWidth + const scaleY = parent.clientHeight / child.clientHeight + const scale = Math.min(scaleX, scaleY) + setScale(scale) } - - useEffect(() => { - const parent = parentRef.current; - const child = childRef.current; + }, [matrix]) - if (parent && child) { - const scaleX = parent.clientWidth / child.clientWidth; - const scaleY = parent.clientHeight / child.clientHeight; - const scale = Math.min(scaleX, scaleY); - setScale(scale); - } - }, [matrix]); + useEffect(() => { + initMidi() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) - useEffect(() => { - initMidi() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + useEffect(() => { + if (midiEvent.button === -1) return + setMidiLogs((prev) => [...prev, midiEvent]) + + }, [midiEvent]) - useEffect(() => { - if (midiEvent.button === -1) return - setMidiLogs((prev) => [...prev, midiEvent]) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [midiEvent]) + useEffect(() => { + if ( + output && + sendSpotifyTrack && + currentTrack !== '' && + 'text' in lp.fn && + lp.fn.text + ) { + output.send(lp.fn.text(currentTrack, 128, 0, 0, false, 10)) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentTrack, sendSpotifyTrack]) - useEffect(() => { - if (output && sendSpotifyTrack && currentTrack !== '' && 'text' in lp.fn && lp.fn.text) { - output.send(lp.fn.text(currentTrack, 128, 0, 0, false, 10)); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [currentTrack, sendSpotifyTrack]) - return ( <> - - - - - - - - - {integrations.spotify?.active && spAuthenticated && 'text' in lp.fn && - - } - - - - - { - setFullScreen(!fullScreen) - handleClose() - }}> - {fullScreen ? : } - - - { - toggleSidebar() - handleClose() - }}> - - - - - setShowMapping(!showMapping)}> - - - - - { - download({ midiMapping }, 'midiMapping.json', 'application/json') - handleClose() - }}> - - - - - { - gotMidiMapping(e) - }} - /> - - - - { - setMidiMapping({ 0: defaultMapping } as IMapping) - setTimeout(() => { - window.location.reload() - }, 100) - }}> - - - - { - const m = JSON.parse(JSON.stringify(midiMapping)); - Object.keys(m).forEach(mappingKey => { - const nestedMapping = m[parseInt(mappingKey) as keyof typeof m]; - Object.keys(nestedMapping).forEach(key => { - const b = nestedMapping[parseInt(key) as keyof typeof nestedMapping]; - delete b.colorCommand; - delete b.colorSceneActive; - delete b.colorSceneInactive; - }); - }); - setMidiMapping(m); - setTimeout(() => { - initMidi() - }, 100) - handleClose() - }}> - - - - - - - - - - - - {localStorage.getItem('ledfx-cloud-role') === 'creator' && {}} />} - - { - setShowMidiLogs(!showMidiLogs) - handleClose() - }}> - - - - + + + + + + + + + {integrations.spotify?.active && + spAuthenticated && + 'text' in lp.fn && ( + + + + )} + + + + + { + setFullScreen(!fullScreen) + handleClose() + }} + > + + {fullScreen ? : } + + + + { + toggleSidebar() + handleClose() + }} + > + + + + + + + setShowMapping(!showMapping)}> + + + + + + + { + download( + { midiMapping }, + 'midiMapping.json', + 'application/json' + ) + handleClose() + }} + > + + + + + + + { + gotMidiMapping(e) + }} + /> + + + + { + setMidiMapping({ 0: defaultMapping } as IMapping) + setTimeout(() => { + window.location.reload() + }, 100) + }} + > + + + + + + { + const m = JSON.parse(JSON.stringify(midiMapping)) + Object.keys(m).forEach((mappingKey) => { + const nestedMapping = + m[parseInt(mappingKey) as keyof typeof m] + Object.keys(nestedMapping).forEach((key) => { + const b = + nestedMapping[parseInt(key) as keyof typeof nestedMapping] + delete b.colorCommand + delete b.colorSceneActive + delete b.colorSceneInactive + }) + }) + setMidiMapping(m) + setTimeout(() => { + initMidi() + }, 100) + handleClose() + }} + > + + + + + + + + + + + + + + + {localStorage.getItem('ledfx-cloud-role') === 'creator' && ( + {}} /> + )} + + { + setShowMidiLogs(!showMidiLogs) + handleClose() + }} + > + + + + + + - - - {matrix.map((row, rowIndex) => { - return ( - - {row.map((_button, buttonIndex) => { - const row = 9 - rowIndex - const column = buttonIndex + 1 - const uiButtonNumber = `${row}${column}` - const uiBtnNumberInt = parseInt(uiButtonNumber) - const btn = midiMapping[0][uiBtnNumberInt] - const buttonNumber = btn?.buttonNumber + + + + {matrix.map((row, rowIndex) => { + return ( + + {row.map((_button, buttonIndex) => { + const row = 9 - rowIndex + const column = buttonIndex + 1 + const uiButtonNumber = `${row}${column}` + const uiBtnNumberInt = parseInt(uiButtonNumber) + const btn = midiMapping[0][uiBtnNumberInt] + const buttonNumber = btn?.buttonNumber - const sceneActiveColor = btn?.colorSceneActive || midiSceneActiveColor || lp.globalColors.sceneActiveColor - const sceneInactiveColor = btn?.colorSceneInactive || midiSceneInactiveColor || lp.globalColors.sceneInactiveColor - const commandColor = btn?.colorCommand || midiCommandColor || lp.globalColors.commandColor - const command = btn?.command - const sceneActive = btn?.payload?.scene === recentScenes[0] + const sceneActiveColor = + btn?.colorSceneActive || + midiSceneActiveColor || + lp.globalColors.sceneActiveColor + const sceneInactiveColor = + btn?.colorSceneInactive || + midiSceneInactiveColor || + lp.globalColors.sceneInactiveColor + const commandColor = + btn?.colorCommand || + midiCommandColor || + lp.globalColors.commandColor + const command = btn?.command + const sceneActive = btn?.payload?.scene === recentScenes[0] - const clr = (color: string) => isRgb && color.startsWith('rgb') ? color : getColorFromValue(color) || '#000' + const clr = (color: string) => + isRgb && color.startsWith('rgb') + ? color + : getColorFromValue(color) || '#000' - const bgColor = buttonNumber === -1 ? '#000' : (midiEvent.button === buttonNumber) - ? ( pressedButtonColor || theme.palette.primary.main ) - : command && command === 'scene' && sceneActive - ? clr(sceneActiveColor) - : command && command === 'scene' - ? clr(sceneInactiveColor) - : command && command !== 'none' && rowIndex !== 0 - ? clr(commandColor) - : rowIndex === 0 || buttonIndex === 8 - ? '#000' - : '#ccc' + const bgColor = + buttonNumber === -1 + ? '#000' + : midiEvent.button === buttonNumber + ? pressedButtonColor || theme.palette.primary.main + : command && command === 'scene' && sceneActive + ? clr(sceneActiveColor) + : command && command === 'scene' + ? clr(sceneInactiveColor) + : command && command !== 'none' && rowIndex !== 0 + ? clr(commandColor) + : rowIndex === 0 || buttonIndex === 8 + ? '#000' + : '#ccc' - return ( - + return ( + + ) })} - + + ) + })} + - {sideBarOpen && - {matrix.map((row, rowIndex) => row.map((button, buttonIndex) => { + {sideBarOpen && ( + + {matrix.map((row, rowIndex) => + row.map((button, buttonIndex) => { return ( - + ) - }))} - } - - {showMidiLogs && - - Name - Note - Button - setMidiLogs([])}>Clear Logs - - - - - {midiLogs.map((log, index) => - {log.name} - {log.note} - {log.button} - )} - - - {Object.keys(Launchpad.X.command).length && } - setMidiMessageToSend(e.target.value)} /> - + }) + )} + + )} + + {showMidiLogs && ( + + + + Name + + + Note + + + Button + + setMidiLogs([])} + > + Clear Logs + + + + + + {midiLogs.map((log, index) => ( + + + {log.name} + + + {log.note} + + + {log.button} + + ))} + + + {Object.keys(Launchpad.X.command).length && ( + + )} + setMidiMessageToSend(e.target.value)} + /> + - } - -) + +
+ )} + + ) } -export default LaunchpadButtonMap \ No newline at end of file +export default LaunchpadButtonMap diff --git a/src/components/Midi/LaunchpadColors.tsx b/src/components/Midi/LaunchpadColors.tsx index baf0a57e..27de8d1f 100644 --- a/src/components/Midi/LaunchpadColors.tsx +++ b/src/components/Midi/LaunchpadColors.tsx @@ -1,9 +1,19 @@ +/* eslint-disable prettier/prettier */ import Dialog from '@mui/material/Dialog' import Button from '@mui/material/Button' import useStore from '../../store/useStore' import DialogTitle from '@mui/material/DialogTitle' import LpColorPicker from './LpColorPicker' -import { DialogContent, ListItemIcon, ListItemText, MenuItem, Popover, Stack, Typography, useTheme } from '@mui/material' +import { + DialogContent, + ListItemIcon, + ListItemText, + MenuItem, + Popover, + Stack, + Typography, + useTheme +} from '@mui/material' import { useRef, useState } from 'react' import { ColorLens } from '@mui/icons-material' import ReactGPicker from 'react-gcolor-picker' @@ -12,29 +22,49 @@ import useClickOutside from '../../utils/useClickOutside' import { MidiDevices } from '../../utils/MidiDevices/MidiDevices' import ColorTypePicker from './ColorTypePicker' -const LaunchpadColors = ({component = 'Button'}:{component?: 'Button' | 'MenuItem'}) => { +const LaunchpadColors = ({ + component = 'Button' +}: { + component?: 'Button' | 'MenuItem' +}) => { const classes = useStyles() const [open, setOpen] = useState(false) const theme = useTheme() const midiType = useStore((state) => state.midiType) const midiModel = useStore((state) => state.midiModel) - const sceneInactiveType = useStore((state) => state.midiColors.sceneInactiveType) + const sceneInactiveType = useStore( + (state) => state.midiColors.sceneInactiveType + ) const sceneActiveType = useStore((state) => state.midiColors.sceneActiveType) const commandType = useStore((state) => state.midiColors.commandType) - const midiSceneInactiveColor = useStore((state) => state.midiColors.sceneInactiveColor) - const midiSceneActiveColor = useStore((state) => state.midiColors.sceneActiveColor) + const midiSceneInactiveColor = useStore( + (state) => state.midiColors.sceneInactiveColor + ) + const midiSceneActiveColor = useStore( + (state) => state.midiColors.sceneActiveColor + ) const midiCommandColor = useStore((state) => state.midiColors.commandColor) - const pressedButtonColor = useStore((state) => state.midiColors.pressedButtonColor) + const pressedButtonColor = useStore( + (state) => state.midiColors.pressedButtonColor + ) const getColorFromValue = useStore((state) => state.getColorFromValue) const setPressedButtonColor = useStore((state) => state.setPressedButtonColor) - const setMidiSceneInactiveColor = useStore((state) => state.setMidiSceneInactiveColor) - const setMidiSceneActiveColor = useStore((state) => state.setMidiSceneActiveColor) + const setMidiSceneInactiveColor = useStore( + (state) => state.setMidiSceneInactiveColor + ) + const setMidiSceneActiveColor = useStore( + (state) => state.setMidiSceneActiveColor + ) const setMidiCommandColor = useStore((state) => state.setMidiCommandColor) const setMidiCommandType = useStore((state) => state.setMidiCommandType) - const setMidiSceneActiveType = useStore((state) => state.setMidiSceneActiveType) - const setMidiSceneInactiveType = useStore((state) => state.setMidiSceneInactiveType) + const setMidiSceneActiveType = useStore( + (state) => state.setMidiSceneActiveType + ) + const setMidiSceneInactiveType = useStore( + (state) => state.setMidiSceneInactiveType + ) - const lp= MidiDevices[midiType][midiModel] + const lp = MidiDevices[midiType][midiModel] const isRgb = 'rgb' in lp.fn const [anchorEl, setAnchorEl] = useState(null) @@ -62,114 +92,169 @@ const LaunchpadColors = ({component = 'Button'}:{component?: 'Button' | 'MenuIte return (
- {component === 'Button' - ? - : - - - } + {component === 'Button' ? ( + + ) : ( + + + + + + + )} Edit Launchpad Global Colors - - - Scene inactive - - setMidiSceneInactiveType(e.target.value)} - isRgb={isRgb} - /> - { - setMidiSceneInactiveColor(color) - }} /> - - - - Scene active - - setMidiSceneActiveType(e.target.value)} - isRgb={isRgb} - /> - { - setMidiSceneActiveColor(color) - }} /> - - - - Command - - setMidiCommandType(e.target.value)} - isRgb={isRgb} - /> - { - setMidiCommandColor(color) - }} /> - - - - Pressed button -
- -
- { - return setPressedButtonColor(c) - }} - popupWidth={288} - showAlpha={false} - value={pressedButtonColor || '#0dbedc'} - // defaultColors={Object.values(defaultColors)} - /> -
-
- {/* { + + + Scene inactive + + setMidiSceneInactiveType(e.target.value)} + isRgb={isRgb} + /> + { + setMidiSceneInactiveColor(color) + }} + /> + + + + Scene active + + setMidiSceneActiveType(e.target.value)} + isRgb={isRgb} + /> + { + setMidiSceneActiveColor(color) + }} + /> + + + + Command + + setMidiCommandType(e.target.value)} + isRgb={isRgb} + /> + { + setMidiCommandColor(color) + }} + /> + + + + Pressed button +
+ +
+ { + return setPressedButtonColor(c) + }} + popupWidth={288} + showAlpha={false} + value={pressedButtonColor || '#0dbedc'} + // defaultColors={Object.values(defaultColors)} + /> +
+
+ {/* { setPressedButtonColor(color) }} /> */} - + -
+
) } -export default LaunchpadColors \ No newline at end of file +export default LaunchpadColors diff --git a/src/components/Midi/LaunchpadSettings.tsx b/src/components/Midi/LaunchpadSettings.tsx index 91aa0932..df497fc0 100644 --- a/src/components/Midi/LaunchpadSettings.tsx +++ b/src/components/Midi/LaunchpadSettings.tsx @@ -1,5 +1,16 @@ import { useEffect, useState } from 'react' -import { Box, DialogContent, Divider, ListItemIcon, MenuItem, Popover, Select, Stack, TextField, Typography } from '@mui/material' +import { + Box, + DialogContent, + Divider, + ListItemIcon, + MenuItem, + Popover, + Select, + Stack, + TextField, + Typography +} from '@mui/material' import Button from '@mui/material/Button' import ListItemText from '@mui/material/ListItemText' import DialogTitle from '@mui/material/DialogTitle' @@ -13,8 +24,8 @@ import useStore from '../../store/useStore' import { WebMidi } from 'webmidi' import LpColorPicker from './LpColorPicker' import ColorTypePicker from './ColorTypePicker' - -const LaunchpadSettings = ({onClick}: {onClick: () => void}) => { + +const LaunchpadSettings = ({ onClick }: { onClick: () => void }) => { const [open, setOpen] = useState(false) const [msg, setMsg] = useState('') const [loop, setLoop] = useState(false) @@ -24,8 +35,9 @@ const LaunchpadSettings = ({onClick}: {onClick: () => void}) => { const [colorType, setColorType] = useState('90') const [buttonNumber, setButtonNumber] = useState(-1) const [midiMessageToSend, setMidiMessageToSend] = useState('') - const [midiLogs, setMidiLogs] = useState<{ name: string; note: string; button: number; }[]>([]) - + const [midiLogs, setMidiLogs] = useState< + { name: string; note: string; button: number }[] + >([]) const midiOutput = useStore((state) => state.midiOutput) const midiEvent = useStore((state) => state.midiEvent) @@ -36,7 +48,8 @@ const LaunchpadSettings = ({onClick}: {onClick: () => void}) => { const setSendSpotifyTrack = useStore((state) => state.setSendSpotifyTrack) const lp = LaunchpadX - const output = midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1] + const output = + midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1] const buttons = ['programmer', 'live', 'standalone', 'daw'] as const const handleClickOpen = () => { @@ -44,7 +57,7 @@ const LaunchpadSettings = ({onClick}: {onClick: () => void}) => { onClick() } - const handleClose = (value: string) => { + const handleClose = (_value: string) => { setOpen(false) setAnchorEl(null) } @@ -52,170 +65,271 @@ const LaunchpadSettings = ({onClick}: {onClick: () => void}) => { useEffect(() => { if (midiEvent.button === -1) return setMidiLogs((prev) => [...prev, midiEvent]) - // eslint-disable-next-line react-hooks/exhaustive-deps }, [midiEvent]) - useEffect(() => { if (sendSpotifyTrack && currentTrack !== '') { - const [r, g, b] = rgbValues(color) || [128, 0, 0] - output.send(lp.fn.text(currentTrack, r, g, b, loop, speed)); + const [r, g, b] = rgbValues(color) || [128, 0, 0] + output.send(lp.fn.text(currentTrack, r, g, b, loop, speed)) } }, [currentTrack, sendSpotifyTrack, output, lp, color, loop, speed]) return ( <> - - - - - e.stopPropagation()} - PaperProps={{ - sx: { - maxWidth: 'min(95vw, 750px)', - minWidth: 'min(95vw, 750px)', - width: '100%' - } - }} - > - - - Launchpad X - Admin Controller - - - - - Mode - - {buttons.map((button) => ( - - ))} - - - - - ButtonColor - - - setColorType(e.target.value)} isRgb variant='outlined'/> - console.log(e)} type={colorType} height={56} /> - - - - - - Text - - setMsg(e.target.value)} - /> - setSpeed(parseInt(e.target.value))} - inputProps={{ - min: 1, - max: 40, - }}/> - - {integrations.spotify?.active && spAuthenticated && } - - + + + + + + + e.stopPropagation()} + PaperProps={{ + sx: { + maxWidth: 'min(95vw, 750px)', + minWidth: 'min(95vw, 750px)', + width: '100%' + } + }} + > + + + Launchpad X - Admin Controller + + + + + Mode + + {buttons.map((button) => ( + + ))} + + + + + ButtonColor + + + setColorType(e.target.value)} + isRgb + variant="outlined" + /> + console.log(e)} + type={colorType} + height={56} + /> + + + + + + Text + + setMsg(e.target.value)} + /> + setSpeed(parseInt(e.target.value))} + inputProps={{ + min: 1, + max: 40 + }} + /> + + {integrations.spotify?.active && spAuthenticated && ( + + )} + + + + + + + RAW MIDI + + setMidiMessageToSend(e.target.value)} + /> + + + + + + Incoming MIDI + + + + Name + + + Note + + + Button + + setMidiLogs([])} + > + Clear Logs + + + + + + {midiLogs.map((log, index) => ( + + + {log.name} + + + {log.note} + + + {log.button} + - - - - RAW MIDI - - setMidiMessageToSend(e.target.value)} /> - - - - - - Incoming MIDI - - - Name - Note - Button - setMidiLogs([])}>Clear Logs - - - - - {midiLogs.map((log, index) => - {log.name} - {log.note} - {log.button} - )} - - - - - - + ))} +
+ + + + + ) } -export default LaunchpadSettings \ No newline at end of file +export default LaunchpadSettings diff --git a/src/components/Midi/LpColorPicker.tsx b/src/components/Midi/LpColorPicker.tsx index 7ec83efc..a4edaf71 100644 --- a/src/components/Midi/LpColorPicker.tsx +++ b/src/components/Midi/LpColorPicker.tsx @@ -1,23 +1,44 @@ import { useState, useEffect } from 'react' -import { Box, Grid, Paper, Typography, Popover, Button, useTheme } from '@mui/material' +import { + Box, + Grid, + Paper, + Typography, + Popover, + Button, + useTheme +} from '@mui/material' import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown' import { darken } from '@mui/material/styles' -import { IColor, rgbValues, sortColorsByHSL, zeroPadHex } from '../../utils/MidiDevices/colorHelper' +import { + IColor, + rgbValues, + sortColorsByHSL, + zeroPadHex +} from '../../utils/MidiDevices/colorHelper' import useStore from '../../store/useStore' import { MidiDevices } from '../../utils/MidiDevices/MidiDevices' import ReactGPicker from 'react-gcolor-picker' import { WebMidi } from 'webmidi' interface LpColorPickerProps { - onColorSelect: (color: string) => void + onColorSelect: (_color: string) => void defaultColor?: IColor | string midiButtonNumber?: number type: string height?: number } -const LpColorPicker = ({ onColorSelect, defaultColor, midiButtonNumber, type = '90', height = 32 }: LpColorPickerProps) => { - const [selectedColor, setSelectedColor] = useState(null) +const LpColorPicker = ({ + onColorSelect, + defaultColor, + midiButtonNumber, + type = '90', + height = 32 +}: LpColorPickerProps) => { + const [selectedColor, setSelectedColor] = useState( + null + ) const [anchorEl, setAnchorEl] = useState(null) const theme = useTheme() const midiOutput = useStore((state) => state.midiOutput) @@ -25,9 +46,13 @@ const LpColorPicker = ({ onColorSelect, defaultColor, midiButtonNumber, type = ' const midiModel = useStore((state) => state.midiModel) const colors = MidiDevices[midiType][midiModel].colors const getColorFromValue = useStore((state) => state.getColorFromValue) - const output = WebMidi.enabled && (midiOutput !== '' ? WebMidi.getOutputByName(midiOutput) : WebMidi.outputs[1]) + const output = + WebMidi.enabled && + (midiOutput !== '' + ? WebMidi.getOutputByName(midiOutput) + : WebMidi.outputs[1]) const lp = MidiDevices[midiType][midiModel] - const isRgb = 'rgb' in lp.fn + const isRgb = 'rgb' in lp.fn useEffect(() => { if (isRgb && defaultColor?.startsWith('rgb')) { @@ -43,7 +68,11 @@ const LpColorPicker = ({ onColorSelect, defaultColor, midiButtonNumber, type = ' const handleColorClick = (color: IColor) => { setSelectedColor(color) if (onColorSelect) { - onColorSelect(isRgb && color.startsWith('rgb') ? color : zeroPadHex(colors[color as keyof typeof colors])) + onColorSelect( + isRgb && color.startsWith('rgb') + ? color + : zeroPadHex(colors[color as keyof typeof colors]) + ) } setAnchorEl(null) } @@ -70,21 +99,26 @@ const LpColorPicker = ({ onColorSelect, defaultColor, midiButtonNumber, type = ' sx={{ display: 'flex', pr: 0, - height: height, + height, alignItems: 'center', backgroundColor: selectedColor || defaultColor, - color: theme.palette.getContrastText((selectedColor || defaultColor || '#000000') as string), + color: theme.palette.getContrastText( + (selectedColor || defaultColor || '#000000') as string + ), '&:hover': { - backgroundColor: darken(selectedColor || defaultColor || '#ffffff', 0.2), - }, + backgroundColor: darken( + selectedColor || defaultColor || '#ffffff', + 0.2 + ) + } }} > - {isRgb && selectedColor?.startsWith('rgb') - ? '' - : selectedColor - ? zeroPadHex(colors[selectedColor as keyof typeof colors]) - : zeroPadHex((colors as any)[(defaultColor || '#FF0000')]) || ''} - {/* : zeroPadHex(((colors as any)[(defaultColor || '#FF0000')]).toString(16).toUpperCase()) || ''} */} + {isRgb && selectedColor?.startsWith('rgb') + ? '' + : selectedColor + ? zeroPadHex(colors[selectedColor as keyof typeof colors]) + : zeroPadHex((colors as any)[defaultColor || '#FF0000']) || ''} + {/* : zeroPadHex(((colors as any)[(defaultColor || '#FF0000')]).toString(16).toUpperCase()) || ''} */} {/* */} - - - {isRgb && type === 'rgb' - ? { - setSelectedColor(color) - const [r,g,b] = rgbValues(color) || [255,0,0] - if (output && 'rgb' in lp.fn && lp.fn.rgb && midiButtonNumber) { - output.send(lp.fn.rgb(midiButtonNumber,r,g,b)); - } - }} - /> - : - - {sortedColors.map((color: IColor) => ( - - + {isRgb && type === 'rgb' ? ( + { + setSelectedColor(color) + const [r, g, b] = rgbValues(color) || [255, 0, 0] + if (output && 'rgb' in lp.fn && lp.fn.rgb && midiButtonNumber) { + output.send(lp.fn.rgb(midiButtonNumber, r, g, b)) + } + }} + /> + ) : ( + + + {sortedColors.map((color: IColor) => ( + + handleColorClick(color)} + > + handleColorClick(color)} > - - {zeroPadHex(colors[color as keyof typeof colors])} - - - - ))} - - - } + {zeroPadHex(colors[color as keyof typeof colors])} + + + + ))} + + + )} diff --git a/src/components/Midi/MidiInputDialog.tsx b/src/components/Midi/MidiInputDialog.tsx index f8873b5a..0f356684 100644 --- a/src/components/Midi/MidiInputDialog.tsx +++ b/src/components/Midi/MidiInputDialog.tsx @@ -1,4 +1,10 @@ -import { Dialog, DialogContent, DialogTitle, IconButton, Tooltip } from '@mui/material' +import { + Dialog, + DialogContent, + DialogTitle, + IconButton, + Tooltip +} from '@mui/material' import { useState } from 'react' import useStore from '../../store/useStore' import BladeIcon from '../Icons/BladeIcon/BladeIcon' @@ -15,7 +21,7 @@ const MidiInputDialog = () => {
setOpen(true)}> - + { onClose={() => setOpen(false)} PaperProps={{ sx: { - maxWidth: fullScreen ? 'unset' : sideBarOpen ? 'min(95vw, 1060px)' : 'min(95vw, 742px)', - minWidth: sideBarOpen ? 'min(95vw, 750px)': 'min(95vw, 542px)', + maxWidth: fullScreen + ? 'unset' + : sideBarOpen + ? 'min(95vw, 1060px)' + : 'min(95vw, 742px)', + minWidth: sideBarOpen ? 'min(95vw, 750px)' : 'min(95vw, 542px)', width: '100%' } }} > - {!fullScreen && - {/\((.*?)\)/.exec(midiInput)?.[1]} Input Configuration - } - - + {!fullScreen && ( + + {' '} + {/\((.*?)\)/.exec(midiInput)?.[1]} Input Configuration + + )} + +
diff --git a/src/components/Midi/MidiListener.tsx b/src/components/Midi/MidiListener.tsx index 0d1664ba..598fc150 100644 --- a/src/components/Midi/MidiListener.tsx +++ b/src/components/Midi/MidiListener.tsx @@ -9,8 +9,12 @@ const MIDIListener = () => { const features = useStore((state) => state.features) const midiInitialized = useStore((state) => state.midiInitialized) const scenes = useStore((state) => state.scenes) - const midiSceneInactiveColor = useStore((state) => state.midiColors.sceneInactiveColor) - const midiSceneActiveColor = useStore((state) => state.midiColors.sceneActiveColor) + const midiSceneInactiveColor = useStore( + (state) => state.midiColors.sceneInactiveColor + ) + const midiSceneActiveColor = useStore( + (state) => state.midiColors.sceneActiveColor + ) const commandColor = useStore((state) => state.midiColors.commandColor) const midiType = useStore((state) => state.midiType) const midiModel = useStore((state) => state.midiModel) @@ -30,7 +34,9 @@ const MIDIListener = () => { const toggleScenePLplay = useStore((state) => state.toggleScenePLplay) const activateScene = useStore((state) => state.activateScene) const captivateScene = useStore((state) => state.captivateScene) - const setSmartBarOpen = useStore((state) => state.ui.bars && state.ui.setSmartBarOpen) + const setSmartBarOpen = useStore( + (state) => state.ui.bars && state.ui.setSmartBarOpen + ) const setMidiEvent = useStore((state) => state.setMidiEvent) const setMidiInputs = useStore((state) => state.setMidiInputs) const setMidiOutputs = useStore((state) => state.setMidiOutputs) @@ -39,18 +45,21 @@ const MIDIListener = () => { const setMidiMapping = useStore((state) => state.setMidiMapping) const showSnackbar = useStore((state) => state.ui.showSnackbar) - const sceneDialogOpen = useStore((state) => state.dialogs.addScene.sceneKey !== '') + const sceneDialogOpen = useStore( + (state) => state.dialogs.addScene.sceneKey !== '' + ) const lp = MidiDevices[midiType][midiModel] const fn = lp.fn - - const setSystemSetting = (setting: string, value: any) => { setSystemConfig({ [setting]: value }) } + + const setSystemSetting = (setting: string, value: any) => { + setSystemConfig({ [setting]: value }) + } const setScene = (e: string) => { activateScene(e) if (scenes[e]?.scene_puturl && scenes[e]?.scene_payload) captivateScene(scenes[e]?.scene_puturl, scenes[e]?.scene_payload) } - function handleButtonPress(command: string, payload?: any) { if (blockMidiHandler) return @@ -80,7 +89,7 @@ const MIDIListener = () => { oneShotAll( payload?.color || '#0dbedc', payload?.ramp || 10, - payload?.holdType !== 'release' ? (payload?.hold || 200) : 10000, + payload?.holdType !== 'release' ? payload?.hold || 200 : 10000, payload?.fade || 2000 ) } else if (command === 'copy-to') { @@ -93,71 +102,103 @@ const MIDIListener = () => { } const getMappingByButtonNumber = (buttonNumber: number) => { - return Object.values(midiMapping[0]).find(mapping => mapping.buttonNumber === buttonNumber) + return Object.values(midiMapping[0]).find( + (mapping) => mapping.buttonNumber === buttonNumber + ) } const initLeds = (output: Output) => { if (!output) return - - Object.entries(midiMapping[0]).forEach(([key, value]) => { + + Object.entries(midiMapping[0]).forEach(([_key, value]) => { const buttonNumber = value.buttonNumber if (buttonNumber === -1) return - + const sendMidiMessage = (color: string, typeCommand: string) => { // console.log(1,'color',color, typeCommand, lp.globalColors.commandType) - sendMidiMessageHelper(fn, output, buttonNumber, color, typeCommand, false) + sendMidiMessageHelper( + fn, + output, + buttonNumber, + color, + typeCommand, + false + ) } - + try { - if (value.command !== 'scene' && value.command && value.command !== 'none') { + if ( + value.command !== 'scene' && + value.command && + value.command !== 'none' + ) { const color = value.colorCommand || commandColor // console.log(1,'color',color, value.typeCommand, lp.globalColors.commandType) - sendMidiMessage(color, color.startsWith('rgb') ? 'rgb': value.typeCommand || lp.globalColors.commandType) + sendMidiMessage( + color, + color.startsWith('rgb') + ? 'rgb' + : value.typeCommand || lp.globalColors.commandType + ) } else if (value.command === 'scene') { const colorActive = value.colorSceneActive || midiSceneActiveColor - const colorInactive = value.colorSceneInactive || midiSceneInactiveColor + const colorInactive = + value.colorSceneInactive || midiSceneInactiveColor const isActiveScene = value.payload?.scene === recentScenes const color = isActiveScene ? colorActive : colorInactive - const typeCommand = isActiveScene ? value.typeSceneActive : value.typeSceneInactive + const typeCommand = isActiveScene + ? value.typeSceneActive + : value.typeSceneInactive sendMidiMessage(color, typeCommand || lp.globalColors.commandType) } } catch (error) { console.error('Error sending MIDI message:', error) } }) - } - + } + useEffect(() => { const handleMidiInput = (input: Input) => { if (!input || input.name !== midiInput) return - + input.removeListener('noteon') input.removeListener('noteoff') input.removeListener('controlchange') - + input.addListener('noteon', (event: any) => handleNoteOn(event, input)) input.addListener('noteoff', (event: any) => handleNoteOff(event, input)) - input.addListener('controlchange', (event: any) => handleControlChange(event, input)) + input.addListener('controlchange', (event: any) => + handleControlChange(event, input) + ) } - + const handleNoteOn = (event: any, input: Input) => { - if (!event.note || (midiEvent.button === event.note.number && midiEvent.name === input.name && midiEvent.note === event.note.identifier)) return - + if ( + !event.note || + (midiEvent.button === event.note.number && + midiEvent.name === input.name && + midiEvent.note === event.note.identifier) + ) + return + setMidiEvent({ name: input.name, note: event.note.identifier, button: event.note.number }) - + const mapping = getMappingByButtonNumber(event.note.number) if (mapping?.command !== undefined) { handleButtonPress(mapping.command, mapping.payload) } } - + const handleNoteOff = (event: any, input: Input) => { const mapping = getMappingByButtonNumber(event.note.number) - if (mapping?.command === 'one-shot' && mapping?.payload?.holdType === 'release') { + if ( + mapping?.command === 'one-shot' && + mapping?.payload?.holdType === 'release' + ) { oneShotAll( mapping.payload?.color || '#0dbedc', mapping.payload?.ramp || 10, @@ -172,16 +213,20 @@ const MIDIListener = () => { button: -1 }) } - + const handleControlChange = (event: any, input: Input) => { - if (event.controller.number === midiEvent.button && midiEvent.name === input.name) return + if ( + event.controller.number === midiEvent.button && + midiEvent.name === input.name + ) + return if (event.value === 1) { setMidiEvent({ name: input.name, note: 'CTRL', button: event.controller.number }) - + const mapping = getMappingByButtonNumber(event.controller.number) if (mapping?.command !== undefined) { handleButtonPress(mapping.command, mapping.payload) @@ -194,55 +239,61 @@ const MIDIListener = () => { }) } } - + const enableWebMidi = () => { WebMidi.enable({ sysex: true, callback: (err: any) => { if (err) { - setFeatures('scenemidi', false); - return; + setFeatures('scenemidi', false) + return } - - const { inputs, outputs } = WebMidi; - setMidiInputs(inputs.map((input) => input.name)); - setMidiOutputs(outputs.map((output) => output.name)); - - if (midiInput === '') setMidiInput(inputs[inputs.length - 1]?.name); - if (midiOutput === '') setMidiOutput(outputs[outputs.length - 1]?.name); - - const output = outputs[outputs.length - 1]; - const lp = MidiDevices[midiType][midiModel].fn; - - Object.entries(midiMapping).forEach(([key, value]) => { - const buttonNumber = value.buttonNumber; - if (!value.command || value.command === 'none' || buttonNumber === -1) { + + const { inputs, outputs } = WebMidi + setMidiInputs(inputs.map((input) => input.name)) + setMidiOutputs(outputs.map((output) => output.name)) + + if (midiInput === '') setMidiInput(inputs[inputs.length - 1]?.name) + if (midiOutput === '') + setMidiOutput(outputs[outputs.length - 1]?.name) + + const output = outputs[outputs.length - 1] + const lp = MidiDevices[midiType][midiModel].fn + + Object.entries(midiMapping).forEach(([_key, value]) => { + const buttonNumber = value.buttonNumber + if ( + !value.command || + value.command === 'none' || + buttonNumber === -1 + ) { if (output && buttonNumber !== -1) { try { - output.send(lp.ledOff(buttonNumber)); + output.send(lp.ledOff(buttonNumber)) } catch (error) { - console.log('Error sending MIDI message:', error); + console.log('Error sending MIDI message:', error) } } - return; } - }); - + }) + if (inputs.length > 0) { inputs.forEach((input) => { - handleMidiInput(input); - }); + handleMidiInput(input) + }) } - - initLeds(output); + + initLeds(output) } }).catch((_error) => { - setFeatures('scenemidi', false); - showSnackbar('error', 'Could not get MIDI permissions, please check your browser settings'); - }); - }; - - + setFeatures('scenemidi', false) + showSnackbar( + 'error', + 'Could not get MIDI permissions, please check your browser settings' + ) + }) + } + const handleWebsockets = (event: any) => { const output = WebMidi.enabled && WebMidi.getOutputByName(midiOutput) try { @@ -250,7 +301,10 @@ const MIDIListener = () => { const { scene_id } = event.detail Object.keys(scenes).forEach((key) => { const scene = scenes[key] - const buttonNumber = parseInt(scene.scene_midiactivate?.split('buttonNumber: ')[1], 10) + const buttonNumber = parseInt( + scene.scene_midiactivate?.split('buttonNumber: ')[1], + 10 + ) const uiButtonNumber = getUiBtnNo(buttonNumber) const value = uiButtonNumber && midiMapping[0][uiButtonNumber] if (!value || value.command !== 'scene' || !output) return @@ -265,34 +319,56 @@ const MIDIListener = () => { console.error('Error parsing websocket message:', error) } } - - const sendSceneMidiMessage = (output: any, buttonNumber: number, value: any, isActive: boolean) => { - const color = isActive ? (value.colorSceneActive || midiSceneActiveColor || lp.globalColors.sceneActiveColor) : (value.colorSceneInactive || midiSceneInactiveColor || lp.globalColors.sceneInactiveColor) - const typeCommand = isActive ? (value.typeSceneActive || lp.globalColors.sceneActiveType) : (value.typeSceneInactive || lp.globalColors.sceneInactiveType) - sendMidiMessageHelper(fn, output, buttonNumber, color, typeCommand, isActive) - } - + + const sendSceneMidiMessage = ( + output: any, + buttonNumber: number, + value: any, + isActive: boolean + ) => { + const color = isActive + ? value.colorSceneActive || + midiSceneActiveColor || + lp.globalColors.sceneActiveColor + : value.colorSceneInactive || + midiSceneInactiveColor || + lp.globalColors.sceneInactiveColor + const typeCommand = isActive + ? value.typeSceneActive || lp.globalColors.sceneActiveType + : value.typeSceneInactive || lp.globalColors.sceneInactiveType + sendMidiMessageHelper( + fn, + output, + buttonNumber, + color, + typeCommand, + isActive + ) + } + if (features.scenemidi) { enableWebMidi() } - + document.addEventListener('scene_activated', handleWebsockets) - + return () => { document.removeEventListener('scene_activated', handleWebsockets) } - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [scenes, sceneDialogOpen, midiInitialized, features.scenemidi]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [scenes, sceneDialogOpen, midiInitialized, features.scenemidi]) // init midiMapping from scenes useEffect(() => { - const mapping = {...midiMapping} + const mapping = { ...midiMapping } Object.keys(scenes).forEach((key) => { const scene = scenes[key] if (!scene.scene_midiactivate) return - const buttonNumber = parseInt(scene.scene_midiactivate.split('buttonNumber: ')[1], 10) + const buttonNumber = parseInt( + scene.scene_midiactivate.split('buttonNumber: ')[1], + 10 + ) const uiButtonNumber = getUiBtnNo(buttonNumber) || -1 mapping[0] = { ...mapping[0], @@ -300,7 +376,7 @@ const MIDIListener = () => { ...mapping[0][uiButtonNumber], command: 'scene', payload: { scene: key }, - buttonNumber: buttonNumber + buttonNumber } } }) diff --git a/src/components/NoYet.tsx b/src/components/NoYet.tsx index e59f307b..eaa5c94e 100644 --- a/src/components/NoYet.tsx +++ b/src/components/NoYet.tsx @@ -1,7 +1,7 @@ import { Card, CardHeader } from '@mui/material' import { Info } from '@mui/icons-material' -import type { JSX } from "react"; +import type { JSX } from 'react' interface NoYetProps { type?: string diff --git a/src/components/Number.tsx b/src/components/Number.tsx index 64208f0b..b673fd5c 100644 --- a/src/components/Number.tsx +++ b/src/components/Number.tsx @@ -1,38 +1,44 @@ -import React from 'react'; -import TextField from '@mui/material/TextField'; +import React from 'react' +import TextField from '@mui/material/TextField' interface NumberProps { - min: number; - max: number; - value: number; - onChange: (event: React.ChangeEvent) => void; - onBlur?: (event: React.FocusEvent) => void; + min: number + max: number + value: number + onChange: (_event: React.ChangeEvent) => void + onBlur?: (_event: React.FocusEvent) => void } -const Number: React.FC = ({ min, max, value, onChange, onBlur }) => { +const Number: React.FC = ({ + min, + max, + value, + onChange, + onBlur +}) => { const handleInput = (e: React.ChangeEvent) => { - const numericValue = parseFloat(e.target.value); + const numericValue = parseFloat(e.target.value) if (!isNaN(numericValue)) { if (numericValue > max) { - e.target.value = max.toString(); + e.target.value = max.toString() } else if (numericValue < min) { - e.target.value = min.toString(); + e.target.value = min.toString() } } - }; + } const handleBlur = (e: React.FocusEvent) => { - const numericValue = parseFloat(e.target.value); + const numericValue = parseFloat(e.target.value) if (isNaN(numericValue) || e.target.value === '') { - e.target.value = min.toString(); + e.target.value = min.toString() onChange(e) } if (onBlur) { - onBlur(e); + onBlur(e) } - }; + } return ( = ({ min, max, value, onChange, onBlur }) => name="quantity" type="number" inputProps={{ - min: min, - max: max, + min, + max }} onChange={onChange} onInput={handleInput} onBlur={handleBlur} /> - ); -}; + ) +} -export default Number; +export default Number diff --git a/src/components/OneTimePassword.tsx b/src/components/OneTimePassword.tsx index b88126f8..96fb9dfa 100644 --- a/src/components/OneTimePassword.tsx +++ b/src/components/OneTimePassword.tsx @@ -22,7 +22,7 @@ const OneTimePassword = ({ enabled }: { enabled: boolean }) => { useEffect(() => { if (otp.length === 6) handleSubmit() - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [otp]) useEffect(() => { diff --git a/src/components/PixelGraph.tsx b/src/components/PixelGraph.tsx index 8da5e373..049c0812 100644 --- a/src/components/PixelGraph.tsx +++ b/src/components/PixelGraph.tsx @@ -22,16 +22,21 @@ const PixelGraph = ({ db?: boolean }) => { const [pixels, setPixels] = useState([]) - const [shape, setShape] = useState<[null | number, null |number]>([null, null]) + const [shape, setShape] = useState<[null | number, null | number]>([ + null, + null + ]) const showWarning = useStore((state) => state.uiPersist.warnings.lessPixels) - const { pixelGraphs, virtuals, devices, graphs, config } = useStore((state) => ({ - pixelGraphs: state.pixelGraphs, - virtuals: state.virtuals, - devices: state.devices, - graphs: state.graphs, - config: state.config - })) + const { pixelGraphs, virtuals, devices, graphs, config } = useStore( + (state) => ({ + pixelGraphs: state.pixelGraphs, + virtuals: state.virtuals, + devices: state.devices, + graphs: state.graphs, + config: state.config + }) + ) const rows = virtuals[virtId]?.is_device ? devices[virtuals[virtId]?.is_device]?.config?.rows || @@ -50,7 +55,8 @@ const PixelGraph = ({ const handleWebsockets = (e: any) => { if (e.detail.id === virtId) { setPixels(e.detail.pixels) - if (e.detail.shape[0] !== shape[0] && e.detail.shape[1] !== shape[1]) setShape(e.detail.shape) + if (e.detail.shape[0] !== shape[0] && e.detail.shape[1] !== shape[1]) + setShape(e.detail.shape) } } document.addEventListener('visualisation_update', handleWebsockets) @@ -60,19 +66,26 @@ const PixelGraph = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [virtuals, pixelGraphs, virtId]) - const tooLessPixels = useStore((state) => state.dialogs.lessPixels?.open || false) + const tooLessPixels = useStore( + (state) => state.dialogs.lessPixels?.open || false + ) if (!(graphs || intGraphs)) { return null } - const totalPixels = decodedPixels.length > 0 ? decodedPixels.length : pixels[0]?.length + const totalPixels = + decodedPixels.length > 0 ? decodedPixels.length : pixels[0]?.length const realPixelCount = virtuals[virtId]?.pixel_count || totalPixels const realCols = Math.ceil(realPixelCount / rows) const aspectRatio = realCols / rows // console.log(shape) - const displayRows = (shape && shape[0]) || (realPixelCount > 4096 ? Math.sqrt(4096 / aspectRatio) : rows) - const displayCols = (shape && shape[1]) || (realPixelCount > 4096 ? 4096 / displayRows : realCols) + const displayRows = + (shape && shape[0]) || + (realPixelCount > 4096 ? Math.sqrt(4096 / aspectRatio) : rows) + const displayCols = + (shape && shape[1]) || + (realPixelCount > 4096 ? 4096 / displayRows : realCols) return dummy || (tooLessPixels && showWarning) ? (
- {(config.transmission_mode === 'compressed' && decodedPixels.length > 0 + {(config.transmission_mode === 'compressed' && + decodedPixels.length > 0 ? decodedPixels.slice(row * displayCols, (row + 1) * displayCols) : pixels[0]?.slice(row * displayCols, (row + 1) * displayCols) ).map((_p: any, i: number) => ( @@ -138,7 +152,8 @@ const PixelGraph = ({ style={{ flex: 1, margin: `${db || (totalPixels > 100 && displayRows > 7) ? 1 : 2}px`, - borderRadius: db || (totalPixels > 100 && displayRows > 7) ? '50%' : '5px', + borderRadius: + db || (totalPixels > 100 && displayRows > 7) ? '50%' : '5px', position: 'relative', overflow: 'hidden', maxWidth: db ? 3.6 : `${100 / displayCols}%`, diff --git a/src/components/Popover/Popover.tsx b/src/components/Popover/Popover.tsx index 3ffb81d6..df788134 100644 --- a/src/components/Popover/Popover.tsx +++ b/src/components/Popover/Popover.tsx @@ -70,10 +70,13 @@ const Popover = ({ }, [open]) return ( -
{ - e.preventDefault() - e.stopPropagation() - }}> +
{ + e.preventDefault() + e.stopPropagation() + }} + > {type === 'menuItem' ? ( { switch (s.type) { - case 'boolean': - return ( - { - const c: Record = {} - c[model_id] = value - return handleEffectConfig && handleEffectConfig(c) + case 'boolean': + return ( + { + const c: Record = {} + c[model_id] = value + return handleEffectConfig && handleEffectConfig(c) + }} + /> + ) + case 'string': { + const complex = ['mask', 'foreground', 'background'] + if (selectedType === 'blender' && complex.includes(s.id)) + !blenderAutomagic ? + - ) - case 'string': - const complex = ['mask', 'foreground', 'background'] - if (selectedType === 'blender' && complex.includes(s.id)) return ( - !blenderAutomagic ? - + { - const c: Record = {} - c[s.id] = e.target.value - return handleEffectConfig && handleEffectConfig(c) - }} - value={model[s.id]} - fullWidth - disableUnderline - > - {Object.keys(virtuals).filter( v => typeof virtuals[v].is_device === 'string' && virtuals[v].is_device !== '' && v).map((v) => { - return {virtuals[v].config.name} - })} - - - : null - ) - return ( - { - const c: Record = {} - c[model_id] = value - return handleEffectConfig && handleEffectConfig(c) - }} - /> - ) + {Object.keys(virtuals) + .filter( + (v) => + typeof virtuals[v].is_device === 'string' && + virtuals[v].is_device !== '' && + v + ) + .map((v) => { + return {virtuals[v].config.name} + + })} + + + : null + } + return ( + { + const c: Record = {} + c[model_id] = value + return handleEffectConfig && handleEffectConfig(c) + }} + /> + ) - case 'number': - return ( - { - const c: Record = {} - c[model_id] = value - return handleEffectConfig && handleEffectConfig(c) - }} - /> - ) + case 'number': + return ( + { + const c: Record = {} + c[model_id] = value + return handleEffectConfig && handleEffectConfig(c) + }} + /> + ) - case 'integer': - return ( - { - const c: Record = {} - c[model_id] = value - return handleEffectConfig && handleEffectConfig(c) - }} - /> - ) - case 'color': - return ( - - ) - default: - return ( - <> + case 'integer': + return ( + { + const c: Record = {} + c[model_id] = value + return handleEffectConfig && handleEffectConfig(c) + }} + /> + ) + case 'color': + return ( + + ) + default: + return ( + <> Unsupported type:-- - {s.type} - - ) + {s.type} + + ) } })} diff --git a/src/components/SchemaForm/components/Boolean/BBolean.tsx b/src/components/SchemaForm/components/Boolean/BBolean.tsx index a1bd4349..9cb1e5d9 100644 --- a/src/components/SchemaForm/components/Boolean/BBolean.tsx +++ b/src/components/SchemaForm/components/Boolean/BBolean.tsx @@ -16,7 +16,7 @@ const BBoolean = ({ value, title = '', description = '', - hideDesc = false, + hideDesc = false }: BBooleanProps) => { switch (type) { case 'switch': @@ -43,10 +43,7 @@ const BBoolean = ({ ) case 'checkbox': return ( - + void + onChange?: (_e: any) => void defaultValue?: any value: boolean title?: string description?: string hideDesc?: boolean -} \ No newline at end of file +} diff --git a/src/components/SchemaForm/components/Boolean/BBoolean.stories.tsx b/src/components/SchemaForm/components/Boolean/BBoolean.stories.tsx index 4a98b394..d9e5a477 100644 --- a/src/components/SchemaForm/components/Boolean/BBoolean.stories.tsx +++ b/src/components/SchemaForm/components/Boolean/BBoolean.stories.tsx @@ -1,6 +1,6 @@ import { Card, CardContent } from '@mui/material' import { StoryFn, Meta } from '@storybook/react' -import BBoolean from './BBolean'; +import BBoolean from './BBolean' export default { title: 'UI Components/SchemaForm/Base Components', @@ -20,7 +20,7 @@ export default { } } as Meta -const Template: StoryFn = (args) => ; +const Template: StoryFn = (args) => export const Boolean = Template.bind({}) Boolean.args = { @@ -32,5 +32,5 @@ Boolean.args = { index: 1, style: undefined, onChange: undefined, - value: undefined, + value: undefined } diff --git a/src/components/SchemaForm/components/Boolean/BladeBoolean.tsx b/src/components/SchemaForm/components/Boolean/BladeBoolean.tsx index 70b99a01..80374045 100644 --- a/src/components/SchemaForm/components/Boolean/BladeBoolean.tsx +++ b/src/components/SchemaForm/components/Boolean/BladeBoolean.tsx @@ -15,7 +15,7 @@ const BladeBoolean = ({ model, hideDesc = false, model_id -}: BladeBooleanProps) => +}: BladeBooleanProps) => ( +) export default BladeBoolean diff --git a/src/components/SchemaForm/components/DropDown/DropDown.tsx b/src/components/SchemaForm/components/DropDown/DropDown.tsx index 2cfd234b..3aac9423 100644 --- a/src/components/SchemaForm/components/DropDown/DropDown.tsx +++ b/src/components/SchemaForm/components/DropDown/DropDown.tsx @@ -28,7 +28,6 @@ const EffectDropDown = ({ }, showFilter = false }: EffectDropDownProps) => { - return ( <> { const effectNames = effects && Object.keys(effects) - .filter(e => !ommit?.includes(effects[e].name)) + .filter((e) => !ommit?.includes(effects[e].name)) .map((eid) => ({ - name: effects[eid].name, - id: effects[eid].id, - category: effects[eid].category - })) + name: effects[eid].name, + id: effects[eid].id, + category: effects[eid].category + })) const groups = effectNames && diff --git a/src/components/SchemaForm/components/GradientPicker/GradientPicker.tsx b/src/components/SchemaForm/components/GradientPicker/GradientPicker.tsx index 46687903..6372bf52 100644 --- a/src/components/SchemaForm/components/GradientPicker/GradientPicker.tsx +++ b/src/components/SchemaForm/components/GradientPicker/GradientPicker.tsx @@ -29,18 +29,22 @@ const GradientPicker = ({ const [pickerBgColorInt, setPickerBgColorInt] = useState(pickerBgColor) const defaultColors: any = {} - if (colors?.gradients?.builtin) Object.entries(colors.gradients.builtin).forEach(([k, g]) => { - defaultColors[k] = g - }) - if (colors?.gradients?.user) Object.entries(colors.gradients.user)?.forEach(([k, g]) => { - defaultColors[k] = g - }) - if (colors?.colors?.builtin) Object.entries(colors.colors.builtin)?.forEach(([k, g]) => { - defaultColors[k] = g - }) - if (colors?.colors?.user) Object.entries(colors.colors.user)?.forEach(([k, g]) => { - defaultColors[k] = g - }) + if (colors?.gradients?.builtin) + Object.entries(colors.gradients.builtin).forEach(([k, g]) => { + defaultColors[k] = g + }) + if (colors?.gradients?.user) + Object.entries(colors.gradients.user)?.forEach(([k, g]) => { + defaultColors[k] = g + }) + if (colors?.colors?.builtin) + Object.entries(colors.colors.builtin)?.forEach(([k, g]) => { + defaultColors[k] = g + }) + if (colors?.colors?.user) + Object.entries(colors.colors.user)?.forEach(([k, g]) => { + defaultColors[k] = g + }) const handleClick = (event: any) => { setAnchorEl(anchorEl ? null : event.currentTarget) @@ -100,7 +104,13 @@ const GradientPicker = ({ onClick={handleClick} /> - +
void + min?: number + max?: number + step?: number + title: string + value: number + titleWidth?: number + setValue: (_v: number) => void }) => { return ( - - setValue(v as number)} - valueLabelDisplay="auto" - min={min} - max={max} - step={step} - /> - setValue(Number(e.target.value))} - /> - + + setValue(v as number)} + valueLabelDisplay="auto" + min={min} + max={max} + step={step} + /> + setValue(Number(e.target.value))} + /> + ) } -export default SliderInput \ No newline at end of file +export default SliderInput diff --git a/src/components/SchemaForm/components/String/BladeSelect.tsx b/src/components/SchemaForm/components/String/BladeSelect.tsx index 71ceb2c2..654c76a9 100644 --- a/src/components/SchemaForm/components/String/BladeSelect.tsx +++ b/src/components/SchemaForm/components/String/BladeSelect.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { Select, MenuItem, @@ -94,18 +94,19 @@ const BladeSelect = ({ ))} - ) : (<> - onChange(model_id, e.target.value)} - style={textStyle as any} - /> + ) : ( + <> + onChange(model_id, e.target.value)} + style={textStyle as any} + /> ) ) : schema.enum && Array.isArray(schema.enum) ? ( @@ -188,10 +189,25 @@ const BladeSelect = ({ onBlur={(e) => onChange(model_id, e.target.value)} onChange={(e) => { if (schema.id === 'icon_name') setIcon(e.target.value) - const reservedParts = ['gap-', '-background', '-foreground', '-mask'] - if (schema.title === 'Name' && reservedParts.some((part) => e.target.value.startsWith(part) || e.target.value.endsWith(part))) { + const reservedParts = [ + 'gap-', + '-background', + '-foreground', + '-mask' + ] + if ( + schema.title === 'Name' && + reservedParts.some( + (part) => + e.target.value.startsWith(part) || + e.target.value.endsWith(part) + ) + ) { setShowReserved(true) - inputRef.current.value = e.target.value.replace(/(gap-|-background|-foreground|-mask)/g, '') + inputRef.current.value = e.target.value.replace( + /(gap-|-background|-foreground|-mask)/g, + '' + ) } else { setShowReserved(false) inputRef.current.value = e.target.value @@ -200,12 +216,12 @@ const BladeSelect = ({ style={textStyle as any} /> {showReserved && ( - setShowReserved(!showReserved)} sx={{ marginTop: 1, width: '400px' }}> - - Reserved word removed - + setShowReserved(!showReserved)} + sx={{ marginTop: 1, width: '400px' }} + > + Reserved word removed )} {schema.id === 'image_location' && ( diff --git a/src/components/Tours/Tour.tsx b/src/components/Tours/Tour.tsx index daed2ee3..61ac094f 100644 --- a/src/components/Tours/Tour.tsx +++ b/src/components/Tours/Tour.tsx @@ -1,5 +1,4 @@ - import Rt from 'reactour' -const Tour = Rt as any; -export default Tour; \ No newline at end of file +const Tour = Rt as any +export default Tour diff --git a/src/components/Tours/Tour2dVirtual.tsx b/src/components/Tours/Tour2dVirtual.tsx index a78ea2e5..5894c040 100644 --- a/src/components/Tours/Tour2dVirtual.tsx +++ b/src/components/Tours/Tour2dVirtual.tsx @@ -170,17 +170,18 @@ const Tour2dVirtual = () => { const theme = useTheme() return ( <> - - { - setIsTourOpen(true) - setTour('2d-virtual') - }} - > - - + + { + setIsTourOpen(true) + setTour('2d-virtual') + }} + > + + { getCount() }, [wledIp]) - - useEffect(() => { let animationFrameId: number | null = null let isCancelled = false @@ -164,7 +162,7 @@ const Webcam = ({ colN, rowN }: { colN: number; rowN: number }) => { width: 400 }} > - + WLED Devices {wledIps.length > 0 && ( { const img = await initialize(capture) setBaseImage(img) }} - className='step-2d-virtual-nine' + className="step-2d-virtual-nine" > Initialize - @@ -238,7 +239,7 @@ const Webcam = ({ colN, rowN }: { colN: number; rowN: number }) => { />
{!isCalibrating && !isAdjusting && ( - + Cut Top { )} {!isCalibrating && isAdjusting && ( - + Led { diff --git a/src/components/Webcam/pixelUtils.ts b/src/components/Webcam/pixelUtils.ts index 03dd4379..b0f1c09a 100644 --- a/src/components/Webcam/pixelUtils.ts +++ b/src/components/Webcam/pixelUtils.ts @@ -1,7 +1,6 @@ -import wait from "./utils/wait" -import wled from "./utils/wled" -import wledGet from "./utils/wledGet" - +import wait from './utils/wait' +import wled from './utils/wled' +import wledGet from './utils/wledGet' export const iterativeOn = async (waitingTime: number) => { const state = await wledGet() diff --git a/src/components/Webcam/utils/adjust.ts b/src/components/Webcam/utils/adjust.ts index 8fcb54a3..77d7ef3a 100644 --- a/src/components/Webcam/utils/adjust.ts +++ b/src/components/Webcam/utils/adjust.ts @@ -1,4 +1,4 @@ -import { processImages } from "./processImages" +import { processImages } from './processImages' async function adjust( capture: () => Promise, diff --git a/src/components/Webcam/utils/createImageFromData.ts b/src/components/Webcam/utils/createImageFromData.ts index 9102579a..aebdff80 100644 --- a/src/components/Webcam/utils/createImageFromData.ts +++ b/src/components/Webcam/utils/createImageFromData.ts @@ -1,4 +1,3 @@ - async function createImageFromData(imageData: Uint8Array) { const blob = new Blob([imageData], { type: 'image/webp' }) const url = URL.createObjectURL(blob) diff --git a/src/components/Webcam/utils/initialize.ts b/src/components/Webcam/utils/initialize.ts index 6e40a871..8b0fde0b 100644 --- a/src/components/Webcam/utils/initialize.ts +++ b/src/components/Webcam/utils/initialize.ts @@ -1,5 +1,5 @@ -import wait from "./wait" -import wled from "./wled" +import wait from './wait' +import wled from './wled' async function initialize(capture: () => Promise) { await wled({ seg: { on: false } }) diff --git a/src/components/Webcam/utils/iterativeOnOnlyOne.ts b/src/components/Webcam/utils/iterativeOnOnlyOne.ts index e879dedb..a374531c 100644 --- a/src/components/Webcam/utils/iterativeOnOnlyOne.ts +++ b/src/components/Webcam/utils/iterativeOnOnlyOne.ts @@ -1,9 +1,9 @@ +/* eslint-disable @/indent */ import { transpose } from '../matrixUtils' import wait from './wait' import wled from './wled' import wledGet from './wledGet' - const iterativeOnOnlyOne = async ( waitingTime: number, pointsRef?: any, @@ -12,7 +12,7 @@ const iterativeOnOnlyOne = async ( outputWidth = 50, outputHeight = 50, addPoint?: any, - device?: any, + device?: any ) => { const state = await wledGet() const segments = state.seg diff --git a/src/components/Webcam/utils/oneLed.ts b/src/components/Webcam/utils/oneLed.ts index fa149cb2..b95d819a 100644 --- a/src/components/Webcam/utils/oneLed.ts +++ b/src/components/Webcam/utils/oneLed.ts @@ -1,6 +1,5 @@ -import wled from "./wled" -import wledGet from "./wledGet" - +import wled from './wled' +import wledGet from './wledGet' const oneLed = async (led: number) => { const state = await wledGet('state') diff --git a/src/components/Webcam/utils/preadjust.ts b/src/components/Webcam/utils/preadjust.ts index c7bf8958..38b751dd 100644 --- a/src/components/Webcam/utils/preadjust.ts +++ b/src/components/Webcam/utils/preadjust.ts @@ -1,4 +1,4 @@ -import wled from "./wled" +import wled from './wled' async function preadjust() { await wled({ on: true }) diff --git a/src/components/Webcam/utils/processImages.ts b/src/components/Webcam/utils/processImages.ts index 28c06430..a5e30e6b 100644 --- a/src/components/Webcam/utils/processImages.ts +++ b/src/components/Webcam/utils/processImages.ts @@ -1,6 +1,6 @@ -import calculateImageDifference from "./calculateImageDifference" -import createImageFromData from "./createImageFromData" -import decodeBase64ToImageData from "./decodeBase64ToImageData" +import calculateImageDifference from './calculateImageDifference' +import createImageFromData from './createImageFromData' +import decodeBase64ToImageData from './decodeBase64ToImageData' export async function processImages( img1b64: string, @@ -30,7 +30,8 @@ export async function processImages( // console.log("BROOOOO", diffData.whitePixelsCenter) if (pointsRef) pointsRef.current = diffData.whitePixelsCenter const diffImageElement = document.getElementById('diffImage') - if (diffImageElement && diffImageElement instanceof HTMLImageElement) diffImageElement.src = diffImageBase64 + if (diffImageElement && diffImageElement instanceof HTMLImageElement) + diffImageElement.src = diffImageBase64 } catch (error) { console.error('Error processing images:', error) } diff --git a/src/components/Webcam/utils/setWledBrightness.ts b/src/components/Webcam/utils/setWledBrightness.ts index 9f54839a..a46d2fdb 100644 --- a/src/components/Webcam/utils/setWledBrightness.ts +++ b/src/components/Webcam/utils/setWledBrightness.ts @@ -1,4 +1,4 @@ -import wled from "./wled" +import wled from './wled' const setWledBrightness = async (brightness = 255) => { await wled({ bri: brightness }) diff --git a/src/electronsquirrelstartup.d..ts b/src/electronsquirrelstartup.d..ts index ea53c53e..ae92a85e 100644 --- a/src/electronsquirrelstartup.d..ts +++ b/src/electronsquirrelstartup.d..ts @@ -1 +1 @@ -declare module 'electron-squirrel-startup'; \ No newline at end of file +declare module 'electron-squirrel-startup' diff --git a/src/launchpad.d.ts b/src/launchpad.d.ts index 8f56b3e9..3f2a2079 100644 --- a/src/launchpad.d.ts +++ b/src/launchpad.d.ts @@ -1 +1 @@ -declare module 'launchpad-webmidi'; \ No newline at end of file +declare module 'launchpad-webmidi' diff --git a/src/pages/Device/Device.tsx b/src/pages/Device/Device.tsx index cb91738e..058551c0 100644 --- a/src/pages/Device/Device.tsx +++ b/src/pages/Device/Device.tsx @@ -1,3 +1,5 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +/* eslint-disable @/indent */ import { useEffect } from 'react' import { Grid, Stack, Typography } from '@mui/material' import { Link, useNavigate, useParams } from 'react-router-dom' @@ -51,7 +53,11 @@ const Device = () => { const effectType = virtual && virtual.effect.type - const addComlexDummy = async (virtual: Virtual, complex: 'mask' | 'foreground' | 'background', icon: string) => { + const addComlexDummy = async ( + virtual: Virtual, + complex: 'mask' | 'foreground' | 'background', + icon: string + ) => { return await addDevice({ type: 'dummy', config: { @@ -60,87 +66,126 @@ const Device = () => { name: `${virtId}-${complex}`, pixel_count: virtual.pixel_count, refresh_rate: 64, - rows: virtual.config.rows, + rows: virtual.config.rows } }) } const addDevices = async () => { - if (!virtual) return; - const promises = []; - - + if (!virtual) return + const promises = [] + if (!devices[`${virtId}-mask`]) { promises.push(addComlexDummy(virtual, 'mask', 'mdi:guy-fawkes-mask')) - } + } if (!devices[`${virtId}-foreground`]) { promises.push(addComlexDummy(virtual, 'foreground', 'mdi:star')) } - + if (!devices[`${virtId}-background`]) { promises.push(addComlexDummy(virtual, 'background', 'mdi:wallpaper')) } - - await Promise.all(promises); + + await Promise.all(promises) } const setEffects = async () => { - if (!virtId) return; - const promises = []; - const is2d = virtuals[virtId].config.rows > 1; - promises.push(setEffect( - `${virtId}-mask`, - is2d ? defaultEffects.blenderMask2d.type : defaultEffects.blenderMask.type, - is2d ? defaultEffects.blenderMask2d.config : defaultEffects.blenderMask.config, - true - ).then(() => { - updateVirtual(`${virtId}-mask`, true) - })) - promises.push(setEffect( - `${virtId}-foreground`, - is2d ? defaultEffects.blenderForeground2d.type : defaultEffects.blenderForeground.type, - is2d ? defaultEffects.blenderForeground2d.config : defaultEffects.blenderForeground.config, - true - ).then(() => { - updateVirtual(`${virtId}-foreground`, true) - })) - promises.push(setEffect( - `${virtId}-background`, - is2d ? defaultEffects.blenderBackground2d.type : defaultEffects.blenderBackground.type, - is2d ? defaultEffects.blenderBackground2d.config : defaultEffects.blenderBackground.config, - true - ).then(() => { - updateVirtual(`${virtId}-background`, true) - })) - - await Promise.all(promises); + if (!virtId) return + const promises = [] + const is2d = virtuals[virtId].config.rows > 1 + promises.push( + setEffect( + `${virtId}-mask`, + is2d + ? defaultEffects.blenderMask2d.type + : defaultEffects.blenderMask.type, + is2d + ? defaultEffects.blenderMask2d.config + : defaultEffects.blenderMask.config, + true + ).then(() => { + updateVirtual(`${virtId}-mask`, true) + }) + ) + promises.push( + setEffect( + `${virtId}-foreground`, + is2d + ? defaultEffects.blenderForeground2d.type + : defaultEffects.blenderForeground.type, + is2d + ? defaultEffects.blenderForeground2d.config + : defaultEffects.blenderForeground.config, + true + ).then(() => { + updateVirtual(`${virtId}-foreground`, true) + }) + ) + promises.push( + setEffect( + `${virtId}-background`, + is2d + ? defaultEffects.blenderBackground2d.type + : defaultEffects.blenderBackground.type, + is2d + ? defaultEffects.blenderBackground2d.config + : defaultEffects.blenderBackground.config, + true + ).then(() => { + updateVirtual(`${virtId}-background`, true) + }) + ) + + await Promise.all(promises) } - useEffect(() => { + useEffect(() => { if (fPixels < 256) setSystemSetting('visualisation_maxlen', 256) getVirtuals() getSchemas() if (effectType) { getPresets(effectType) } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [effectType]) useEffect(() => { - if (blenderAutomagic && (virtId && virtuals[virtId].effect.type === 'blender' && !(virtId.endsWith('-mask') || virtId.endsWith('-foreground') || virtId.endsWith('-background')) && (!devices[`${virtId}-mask`] || !devices[`${virtId}-foreground`] || !devices[`${virtId}-background`]))) { - addDevices().then(() => { - getDevices() - getVirtuals() - }).catch(error => { - console.error('Error adding devices:', error); - }); + if ( + blenderAutomagic && + virtId && + virtuals[virtId].effect.type === 'blender' && + !( + virtId.endsWith('-mask') || + virtId.endsWith('-foreground') || + virtId.endsWith('-background') + ) && + (!devices[`${virtId}-mask`] || + !devices[`${virtId}-foreground`] || + !devices[`${virtId}-background`]) + ) { + addDevices() + .then(() => { + getDevices() + getVirtuals() + }) + .catch((error) => { + console.error('Error adding devices:', error) + }) } - // eslint-disable-next-line react-hooks/exhaustive-deps -}, [virtId && virtuals[virtId]?.effect?.type, blenderAutomagic]) + }, [virtId && virtuals[virtId]?.effect?.type, blenderAutomagic]) useEffect(() => { - if (blenderAutomagic && (virtId && devices[`${virtId}-mask`] && devices[`${virtId}-foreground`] && devices[`${virtId}-background`] && virtuals[virtId].effect.type === 'blender' && (!virtuals[virtId].effect.config?.mask || !virtuals[virtId].effect.config?.foreground || !virtuals[virtId].effect.config?.background))) { - setEffects().then(() => { + if ( + blenderAutomagic && + virtId && + devices[`${virtId}-mask`] && + devices[`${virtId}-foreground`] && + devices[`${virtId}-background`] && + virtuals[virtId].effect.type === 'blender' && + (!virtuals[virtId].effect.config?.mask || + !virtuals[virtId].effect.config?.foreground || + !virtuals[virtId].effect.config?.background) + ) { + setEffects().then(() => { updateEffect( virtId, 'blender', @@ -153,32 +198,58 @@ const Device = () => { ).then(() => { updateVirtual(virtId, true) setNewBlender(virtId) - navigate(`/Devices`) + navigate('/Devices') }) }) } - if (blenderAutomagic && (virtId && devices[`${virtId}-mask`] && devices[`${virtId}-foreground`] && devices[`${virtId}-background`] && virtuals[virtId].effect.type !== 'blender')) { - if (virtuals[`${virtId}-mask`].effect.config) clearEffect(`${virtId}-mask`) - if (virtuals[`${virtId}-foreground`].effect.config) clearEffect(`${virtId}-foreground`) - if (virtuals[`${virtId}-background`].effect.config) clearEffect(`${virtId}-background`) + if ( + blenderAutomagic && + virtId && + devices[`${virtId}-mask`] && + devices[`${virtId}-foreground`] && + devices[`${virtId}-background`] && + virtuals[virtId].effect.type !== 'blender' + ) { + if (virtuals[`${virtId}-mask`].effect.config) + clearEffect(`${virtId}-mask`) + if (virtuals[`${virtId}-foreground`].effect.config) + clearEffect(`${virtId}-foreground`) + if (virtuals[`${virtId}-background`].effect.config) + clearEffect(`${virtId}-background`) } - // eslint-disable-next-line react-hooks/exhaustive-deps -}, [devices, virtId && virtuals[virtId]?.effect?.type, blenderAutomagic]) + }, [devices, virtId && virtuals[virtId]?.effect?.type, blenderAutomagic]) useEffect(() => { getVirtuals() getSchemas() if (graphs && virtId) { - if (blenderAutomagic && virtId && virtuals[virtId].effect.type === 'blender') { - setPixelGraphs([virtId, `${virtId}-mask`, `${virtId}-foreground`, `${virtId}-background`]) + if ( + blenderAutomagic && + virtId && + virtuals[virtId].effect.type === 'blender' + ) { + setPixelGraphs([ + virtId, + `${virtId}-mask`, + `${virtId}-foreground`, + `${virtId}-background` + ]) } else { setPixelGraphs([virtId]) } } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [graphs, effectType, virtId && virtuals[virtId].effect.type, blenderAutomagic]) + }, [ + graphs, + effectType, + virtId && virtuals[virtId].effect.type, + blenderAutomagic + ]) - const matrixOpen = !!(virtId && virtuals[virtId].pixel_count > 100 && virtuals[virtId].config.rows > 7) + const matrixOpen = !!( + virtId && + virtuals[virtId].pixel_count > 100 && + virtuals[virtId].config.rows > 7 + ) return ( { > - {!!(devices[`${virtId}-mask`], devices[`${virtId}-foreground`], devices[`${virtId}-background`]) && virtId && virtuals[virtId].effect.type === 'blender' && blenderAutomagic && - - - - - - - - } + {!!(devices[`${virtId}-mask`], + devices[`${virtId}-foreground`], + devices[`${virtId}-background`]) && + virtId && + virtuals[virtId].effect.type === 'blender' && + blenderAutomagic && ( + + + + + + + + + )} { width: '100%' }} > - {effectType && presets && !(devices[`${virtId}-mask`] && devices[`${virtId}-foreground`] && devices[`${virtId}-background`] && virtId && virtuals[virtId].effect.type === 'blender' && blenderAutomagic) && ( - - )} + {effectType && + presets && + !( + devices[`${virtId}-mask`] && + devices[`${virtId}-foreground`] && + devices[`${virtId}-background`] && + virtId && + virtuals[virtId].effect.type === 'blender' && + blenderAutomagic + ) && ( + + )} {!( features.streamto || features.transitions || diff --git a/src/pages/Device/Effects.tsx b/src/pages/Device/Effects.tsx index fe0c4610..db990c4a 100644 --- a/src/pages/Device/Effects.tsx +++ b/src/pages/Device/Effects.tsx @@ -1,4 +1,5 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable react-hooks/exhaustive-deps */ +/* eslint-disable @/indent */ import { useEffect, useState } from 'react' import { @@ -28,7 +29,7 @@ import TourEffect from '../../components/Tours/TourEffect' import TroubleshootButton from './TroubleshootButton' import { Schema } from '../../components/SchemaForm/SchemaForm/SchemaForm.props' import { EffectConfig, Virtual } from '../../store/api/storeVirtuals' -import { FullScreen, useFullScreenHandle } from "react-full-screen"; +import { FullScreen, useFullScreenHandle } from 'react-full-screen' const configOrder = ['color', 'number', 'integer', 'string', 'boolean'] @@ -77,7 +78,7 @@ const orderEffectProperties = ( const EffectsCard = ({ virtId }: { virtId: string }) => { const [fade, setFade] = useState(false) const showMatrix = useStore((state) => state.showMatrix) - + const getVirtuals = useStore((state) => state.getVirtuals) const clearEffect = useStore((state) => state.clearEffect) const setEffect = useStore((state) => state.setEffect) @@ -89,8 +90,13 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { const updateVirtual = useStore((state) => state.updateVirtual) const features = useStore((state) => state.features) const [virtual, setVirtual] = useState(undefined) - const [matrix, setMatrix] = useState(showMatrix || (virtuals[virtId]?.config?.rows > 7 && virtuals[virtId]?.pixel_count > 100 && virtuals[virtId].effect.type === 'blender') ) - const handle = useFullScreenHandle(); + const [matrix, setMatrix] = useState( + showMatrix || + (virtuals[virtId]?.config?.rows > 7 && + virtuals[virtId]?.pixel_count > 100 && + virtuals[virtId].effect.type === 'blender') + ) + const handle = useFullScreenHandle() const [fullScreen, setFullScreen] = useState(false) const getV = () => { @@ -104,7 +110,6 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { useEffect(() => { const v = getV() if (v) setVirtual(v) - // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(virtuals[virtId])]) const effectType = virtual && virtual.effect.type @@ -148,7 +153,6 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { updateVirtual(virtual.id, !virtual.active).then(() => getVirtuals()) } - useEffect(() => { // if (virtuals && virtual?.effect?.config) { // setTheModel(virtual.effect.config) @@ -164,12 +168,24 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { setTheModel(virtual?.effect.config) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [virtuals,virtuals[virtId],virtuals[virtId]?.effect,JSON.stringify(virtuals[virtId]?.effect?.config),virtual,virtual?.effect,virtual?.effect.config,effectType]) + }, [ + virtuals, + virtuals[virtId], + virtuals[virtId]?.effect, + JSON.stringify(virtuals[virtId]?.effect?.config), + virtual, + virtual?.effect, + virtual?.effect.config, + effectType + ]) useEffect(() => { - setMatrix(showMatrix || (virtuals[virtId]?.config?.rows > 7 && virtuals[virtId]?.pixel_count > 100 && virtuals[virtId].effect.type === 'blender')) - // eslint-disable-next-line react-hooks/exhaustive-deps + setMatrix( + showMatrix || + (virtuals[virtId]?.config?.rows > 7 && + virtuals[virtId]?.pixel_count > 100 && + virtuals[virtId].effect.type === 'blender') + ) }, [virtuals[virtId].effect.type]) useEffect(() => { @@ -180,7 +196,6 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { return () => { document.removeEventListener('effect_set', handleWebsockets) } - // eslint-disable-next-line react-hooks/exhaustive-deps }, []) // console.log('virtual', virtual?.effect?.config) return ( @@ -209,11 +224,15 @@ const EffectsCard = ({ virtId }: { virtId: string }) => { justifyContent: 'flex-end' }} > - {!(virtuals && + {!( + virtuals && virtual && effects && virtual.effect && - virtual.effect.config) && virtual?.config?.rows && virtual?.config?.rows > 1 && ( + virtual.effect.config + ) && + virtual?.config?.rows && + virtual?.config?.rows > 1 && ( - + + ) : null diff --git a/src/pages/Devices/Devices.tsx b/src/pages/Devices/Devices.tsx index 891429a0..f1fcacce 100644 --- a/src/pages/Devices/Devices.tsx +++ b/src/pages/Devices/Devices.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @/indent */ import { useEffect } from 'react' import { makeStyles } from '@mui/styles' import { Alert, Collapse } from '@mui/material' @@ -51,7 +52,7 @@ const Devices = () => { setNewBlender('') navigate(`/device/${newBlender}`) } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [newBlender, blenderAutomagic]) useEffect(() => { @@ -119,8 +120,16 @@ const Devices = () => {
{virtuals && Object.keys(virtuals).length ? ( Object.keys(virtuals) - .filter(v=> showComplex ? v : !(v.endsWith('-mask') || v.endsWith('-foreground') || v.endsWith('-background'))) - .filter(v=> showGaps ? v : !(v.startsWith('gap-'))) + .filter((v) => + showComplex + ? v + : !( + v.endsWith('-mask') || + v.endsWith('-foreground') || + v.endsWith('-background') + ) + ) + .filter((v) => (showGaps ? v : !v.startsWith('gap-'))) .map((virtual, i) => ( )) diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/Actions/assignPixels.ts b/src/pages/Devices/EditVirtuals/EditMatrix/Actions/assignPixels.ts index 0b34f78c..ec76d6a3 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/Actions/assignPixels.ts +++ b/src/pages/Devices/EditVirtuals/EditMatrix/Actions/assignPixels.ts @@ -46,50 +46,66 @@ const assignPixels = ({ group: `${row}-${col}` } if (direction.includes('diagonal-top-right')) { - for (let index = 0; index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && row - index >= 0 && col + index < colN; index++) { + for ( + let index = 0; + index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && + row - index >= 0 && + col + index < colN; + index++ + ) { const newM = { deviceId: currentDevice, pixel: Math.min(selectedPixel[0], selectedPixel[1]) + index, group: `${row}-${col}` } - updatedM[row - index][col + index] = newM; + updatedM[row - index][col + index] = newM } - } - - else if (direction.includes('diagonal-bottom-right')) { - for (let index = 0; index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && row + index < rowN && col + index < colN; index++) { + } else if (direction.includes('diagonal-bottom-right')) { + for ( + let index = 0; + index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && + row + index < rowN && + col + index < colN; + index++ + ) { const newM = { deviceId: currentDevice, pixel: Math.min(selectedPixel[0], selectedPixel[1]) + index, group: `${row}-${col}` } - updatedM[row + index][col + index] = newM; + updatedM[row + index][col + index] = newM } - } - - else if (direction.includes('diagonal-bottom-left')) { - for (let index = 0; index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && row + index < rowN && col - index >= 0; index++) { + } else if (direction.includes('diagonal-bottom-left')) { + for ( + let index = 0; + index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && + row + index < rowN && + col - index >= 0; + index++ + ) { const newM = { deviceId: currentDevice, pixel: Math.min(selectedPixel[0], selectedPixel[1]) + index, group: `${row}-${col}` } - updatedM[row + index][col - index] = newM; + updatedM[row + index][col - index] = newM } - } - - else if (direction.includes('diagonal-top-left')) { - for (let index = 0; index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && row - index >= 0 && col - index >= 0; index++) { + } else if (direction.includes('diagonal-top-left')) { + for ( + let index = 0; + index <= Math.abs(selectedPixel[1] - selectedPixel[0]) && + row - index >= 0 && + col - index >= 0; + index++ + ) { const newM = { deviceId: currentDevice, pixel: Math.min(selectedPixel[0], selectedPixel[1]) + index, group: `${row}-${col}` } - updatedM[row - index][col - index] = newM; + updatedM[row - index][col - index] = newM } - } - - else if (direction.includes('right')) { + } else if (direction.includes('right')) { if (direction.includes('flip')) { updatedM[row - Math.floor((index + col) / colN)][ (index + col) % colN diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/AssignPixelDialog.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/AssignPixelDialog.tsx index fc87f04a..f694eef5 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/AssignPixelDialog.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/AssignPixelDialog.tsx @@ -1,3 +1,4 @@ +/* eslint-disable prettier/prettier */ import { Button, Dialog, @@ -78,8 +79,16 @@ const AssignPixelDialog = ({ > {devices && Object.keys(devices) - .filter(v=> showComplex ? v : !(v.endsWith('-mask') || v.endsWith('-foreground') || v.endsWith('-background'))) - .filter(v=> showGaps ? v : !(v.startsWith('gap-'))) + .filter((v) => + showComplex + ? v + : !( + v.endsWith('-mask') || + v.endsWith('-foreground') || + v.endsWith('-background') + ) + ) + .filter((v) => (showGaps ? v : !v.startsWith('gap-'))) .map((d: any, i: number) => ( {devices[d].config.name} diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/Draggable.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/Draggable.tsx index 41740cd3..592c0283 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/Draggable.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/Draggable.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useDraggable } from '@dnd-kit/core' function Draggable({ children, id, ...props }: any) { diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/M.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/M.tsx index f2b46fee..34ff43c4 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/M.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/M.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useEffect, useRef, useState, FC } from 'react' import { Box, Stack, useTheme } from '@mui/material' import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch' @@ -29,7 +29,6 @@ const EditMatrix: FC<{ virtual: any }> = ({ virtual }) => { const theme = useTheme() const deviceRef = useRef(null) - const devices = useStore((state) => state.devices) const mode = useStore((state) => state.config).transmission_mode const addDevice = useStore((state) => state.addDevice) @@ -171,8 +170,6 @@ const EditMatrix: FC<{ virtual: any }> = ({ virtual }) => { setIsDragging(false) } - - /** * Set the selected pixel when the group changes */ @@ -276,7 +273,18 @@ const EditMatrix: FC<{ virtual: any }> = ({ virtual }) => { return ( - + = ({ virtual }) => { key={`row-${currentRowIndex}`} style={{ display: 'flex' }} > - {yzrow.map((yzcolumn: IMCell, currentColIndex: number) => { - const bg = getBackgroundColor( - mode, - decodedPixels, - pixels, - currentRowIndex, - colN, - currentColIndex - ) - const op = getOpacity(move, yzcolumn, selectedGroup) - return ( - -1 && hoveringCell[1] > -1 - ? m[hoveringCell[1]][hoveringCell[0]] - : undefined - } - id={`${currentColIndex}-${currentRowIndex}`} - key={`col-${currentColIndex}`} - bg={bg} - opacity={op} - onContextMenu={(e) => - handleContextMenu( - e, - currentColIndex, - currentRowIndex, - yzcolumn - ) - } - > - { + const bg = getBackgroundColor( + mode, + decodedPixels, + pixels, + currentRowIndex, + colN, + currentColIndex + ) + const op = getOpacity(move, yzcolumn, selectedGroup) + return ( + -1 && hoveringCell[1] > -1 + ? m[hoveringCell[1]][hoveringCell[0]] + : undefined + } + id={`${currentColIndex}-${currentRowIndex}`} key={`col-${currentColIndex}`} + bg={bg} + opacity={op} onContextMenu={(e) => handleContextMenu( e, @@ -370,72 +368,84 @@ const EditMatrix: FC<{ virtual: any }> = ({ virtual }) => { yzcolumn ) } - sx={{ - backgroundColor: bg, - opacity: op - }} > - {dnd ? ( - m[currentRowIndex][currentColIndex].deviceId !== - '' ? ( - - + handleContextMenu( + e, + currentColIndex, + currentRowIndex, + yzcolumn + ) + } + sx={{ + backgroundColor: bg, + opacity: op + }} + > + {dnd ? ( + m[currentRowIndex][currentColIndex] + .deviceId !== '' ? ( + - ) => setAnchorEl(e.currentTarget)} - isDragging={isDragging} - /> - - ) : null - ) : ( - - ) => setAnchorEl(e.currentTarget)} - isDragging={isDragging} - /> - )} - - - ) - })} + + ) => setAnchorEl(e.currentTarget)} + isDragging={isDragging} + /> + + ) : null + ) : ( + + ) => setAnchorEl(e.currentTarget)} + isDragging={isDragging} + /> + )} + + + ) + } + )}
))} diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/MContextMenu.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/MContextMenu.tsx index 9cc49e02..cf30cd31 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/MContextMenu.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/MContextMenu.tsx @@ -63,14 +63,22 @@ const MContextMenu = ({ > Move Group - { - clearPixel() - closeContextMenu(e) - }}>Clear Pixel - { - clearPixelGroup(m[currentCell[1]][currentCell[0]].group || '0-0') - closeContextMenu(e) - }}>Clear Group + { + clearPixel() + closeContextMenu(e) + }} + > + Clear Pixel + + { + clearPixelGroup(m[currentCell[1]][currentCell[0]].group || '0-0') + closeContextMenu(e) + }} + > + Clear Group + ) } diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/MControls.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/MControls.tsx index 79c2dd06..f21cc98e 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/MControls.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/MControls.tsx @@ -13,7 +13,7 @@ import { Save, Stop, SwapHoriz, - SwapVert, + SwapVert } from '@mui/icons-material' import { Alert, @@ -35,14 +35,13 @@ import { Ledfx } from '../../../../api/ledfx' import Popover from '../../../../components/Popover/Popover' import { transpose } from '../../../../utils/helpers' import { MCell } from './M.utils' -import { processArray } from './processMatrix' +import { processArray, reverseProcessArray } from './processMatrix' import moveSelectedGroupUp from './Actions/moveSelectedGroupUp' import moveSelectedGroupLeft from './Actions/moveSelectedGroupLeft' import moveSelectedGroupRight from './Actions/moveSelectedGroupRight' import moveSelectedGroupDown from './Actions/moveSelectedGroupDown' import useStore from '../../../../store/useStore' import Webcam from '../../../../components/Webcam/Webcam' -import { reverseProcessArray } from './processMatrix' const MControls = ({ rowN, @@ -99,24 +98,24 @@ const MControls = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [dnd]) - /** + /** * Update the pixel-graphs when the virtual changes */ - useEffect(() => { - const handleWebsockets = (e: any) => { - if (e.detail.id === virtual.id) { - setPixels(e.detail.pixels) - } - } - if (showPixelGraph && virtual.id) { - document.addEventListener('visualisation_update', handleWebsockets) - } else { - document.removeEventListener('visualisation_update', handleWebsockets) + useEffect(() => { + const handleWebsockets = (e: any) => { + if (e.detail.id === virtual.id) { + setPixels(e.detail.pixels) } - return () => { - document.removeEventListener('visualisation_update', handleWebsockets) - } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [virtuals, pixelGraphs, showPixelGraph, virtual]) + } + if (showPixelGraph && virtual.id) { + document.addEventListener('visualisation_update', handleWebsockets) + } else { + document.removeEventListener('visualisation_update', handleWebsockets) + } + return () => { + document.removeEventListener('visualisation_update', handleWebsockets) + } // eslint-disable-next-line react-hooks/exhaustive-deps + }, [virtuals, pixelGraphs, showPixelGraph, virtual]) return ( @@ -149,7 +148,8 @@ const MControls = ({ max={virtual2dLimit} value={rowN} onChange={(e, newRowNumber) => - typeof newRowNumber === 'number' && setRowNumber(newRowNumber) + typeof newRowNumber === 'number' && + setRowNumber(newRowNumber) } /> @@ -165,7 +165,8 @@ const MControls = ({ max={virtual2dLimit} value={colN} onChange={(e, newColNumber) => - typeof newColNumber === 'number' && setColNumber(newColNumber) + typeof newColNumber === 'number' && + setColNumber(newColNumber) } /> @@ -177,7 +178,7 @@ const MControls = ({ width={400} justifyContent="space-between" margin="1rem 0" - className='step-2d-virtual-four' + className="step-2d-virtual-four" spacing={1} > @@ -211,29 +212,37 @@ const MControls = ({
- + - - - { - setM(Array(rowN).fill(Array(colN).fill(MCell))) - }} - /> + { + setM(Array(rowN).fill(Array(colN).fill(MCell))) + }} + /> @@ -262,7 +271,14 @@ const MControls = ({ - + } @@ -280,9 +296,13 @@ const MControls = ({ - { - setInfoAlerts('camera', false) - }}> + { + setInfoAlerts('camera', false) + }} + > DND-Canvas Mode
  • Use Mousewheel to Zoom
  • @@ -300,8 +320,15 @@ const MControls = ({ - - setInfoAlerts('pixelMode', false)}> + + setInfoAlerts('pixelMode', false)} + > DND-Pixels Mode
    • move pixels individually with your mouse
    • @@ -312,7 +339,7 @@ const MControls = ({ {move ? ( - + } iconPosition="start" @@ -389,9 +416,13 @@ const MControls = ({ ) : ( - { - setInfoAlerts('matrixGroups', false) - }}> + { + setInfoAlerts('matrixGroups', false) + }} + > Right-Click an element to move a group.
      @@ -401,14 +432,20 @@ const MControls = ({
      )} - {features.matrix_cam && } + {features.matrix_cam && ( + + )} - {camMapper && } + {camMapper && } ) diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/MFillSelector.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/MFillSelector.tsx index f43b605b..3beb95c5 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/MFillSelector.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/MFillSelector.tsx @@ -336,7 +336,10 @@ const MFillSelector = ({
- +
+ >
Diagonal @@ -353,7 +356,10 @@ const MFillSelector = ({ topRight
- +
- +
- +
- ) diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/MSlider.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/MSlider.tsx index bae32ead..540a5c0a 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/MSlider.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/MSlider.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @/indent */ +/* eslint-disable prettier/prettier */ import { Slider, Stack } from '@mui/material' import BladeFrame from '../../../../components/SchemaForm/components/BladeFrame' import Number from '../../../../components/Number' @@ -21,7 +23,13 @@ const MSlider = ({ full={false} style={{ marginBottom: '1rem' }} > - + - { - typeof selectedPixel === 'number' - ? handleSliderChange(e, parseInt(e.target.value))} /> - : - handleSliderChange(e,[parseInt(e.target.value), selectedPixel[1]], 0)} /> - handleSliderChange(e,[selectedPixel[0], parseInt(e.target.value)], 1)} /> - + {typeof selectedPixel === 'number' + ? handleSliderChange(e, parseInt(e.target.value))} /> + : + + handleSliderChange( + e, + [parseInt(e.target.value), selectedPixel[1]], + 0 + ) + } + /> + + handleSliderChange( + e, + [selectedPixel[0], parseInt(e.target.value)], + 1 + ) + } + /> + } diff --git a/src/pages/Devices/EditVirtuals/EditMatrix/MWrapper.tsx b/src/pages/Devices/EditVirtuals/EditMatrix/MWrapper.tsx index 2ff6b353..42fc134f 100644 --- a/src/pages/Devices/EditVirtuals/EditMatrix/MWrapper.tsx +++ b/src/pages/Devices/EditVirtuals/EditMatrix/MWrapper.tsx @@ -17,7 +17,7 @@ const MWrapper = ({ children, move }: any) => { // flexGrow: 1, overflow: move ? 'auto' : 'hidden', height: '100%', - width: '100%', + width: '100%' } }} > diff --git a/src/pages/Devices/EditVirtuals/EditVirtuals.styles.tsx b/src/pages/Devices/EditVirtuals/EditVirtuals.styles.tsx index bbd74e2d..fda3e2a2 100644 --- a/src/pages/Devices/EditVirtuals/EditVirtuals.styles.tsx +++ b/src/pages/Devices/EditVirtuals/EditVirtuals.styles.tsx @@ -2,7 +2,7 @@ import { makeStyles } from '@mui/styles' const useEditVirtualsStyles = makeStyles(() => ({ appBar: { - position: 'relative', + position: 'relative' // marginBottom: '1rem' // background: theme.palette.background.default, // color: theme.palette.text.primary, diff --git a/src/pages/Devices/EditVirtuals/PixelSlider.tsx b/src/pages/Devices/EditVirtuals/PixelSlider.tsx index 6602846b..8b964fc7 100644 --- a/src/pages/Devices/EditVirtuals/PixelSlider.tsx +++ b/src/pages/Devices/EditVirtuals/PixelSlider.tsx @@ -21,7 +21,6 @@ const PixelSlider = ({ s, handleRangeSegment }: any) => { setRange([s[1], s[2]]) }, [s]) - if (!devices[s[0]]) { return null } diff --git a/src/pages/Devices/EditVirtuals/Segment.tsx b/src/pages/Devices/EditVirtuals/Segment.tsx index 4c244ba7..d965b145 100644 --- a/src/pages/Devices/EditVirtuals/Segment.tsx +++ b/src/pages/Devices/EditVirtuals/Segment.tsx @@ -11,7 +11,8 @@ const Segment = ({ s, i, virtual, segments, calib }: any) => { const virtuals = useStore((state) => state.virtuals) const title = - devices && virtuals && + devices && + virtuals && virtuals[devices && Object.keys(devices).find((d) => d === s[0])!].config! .name const classes = useSegmentStyles() @@ -89,7 +90,6 @@ const Segment = ({ s, i, virtual, segments, calib }: any) => { }) } - return (
{ useEffect(() => { const v = getV() if (v) setVirtual(v) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [virtId]) const effectType = virtual && virtual.effect.type diff --git a/src/pages/Home/BladeScene.tsx b/src/pages/Home/BladeScene.tsx index 3f8a4166..5c07baac 100644 --- a/src/pages/Home/BladeScene.tsx +++ b/src/pages/Home/BladeScene.tsx @@ -34,7 +34,7 @@ const BladeScene = ({ onClick }: { onClick: () => void }) => { const large = Object.keys(virtuals).filter( (v: string) => virtuals[v].pixel_count >= 100 ) - + const addBladeScene = () => { // if (noAuto) { large.map((v) => { @@ -134,48 +134,49 @@ export const defaultEffects = { type: 'blade_power_plus', config: { background_brightness: 1, - background_color: "#000000", + background_color: '#000000', blur: 2, brightness: 1, decay: 0.7, fix_hues: true, flip: false, - frequency_range: "Lows (beat+bass)", - gradient: "#ffffff", + frequency_range: 'Lows (beat+bass)', + gradient: '#ffffff', gradient_roll: 0, mirror: false, multiplier: 0.5 - } + } }, blenderForeground: { - type: "blade_power_plus", + type: 'blade_power_plus', config: { background_brightness: 0.63, - background_color: "#000080", + background_color: '#000080', blur: 2, brightness: 1, decay: 0.7, fix_hues: true, flip: false, - frequency_range: "Lows (beat+bass)", - gradient: "linear-gradient(90deg, #00ffff 0.00%,#0000ff 100.00%)", + frequency_range: 'Lows (beat+bass)', + gradient: 'linear-gradient(90deg, #00ffff 0.00%,#0000ff 100.00%)', gradient_roll: 0, mirror: false, multiplier: 0.5 - }, + } }, blenderBackground: { - type: "blade_power_plus", + type: 'blade_power_plus', config: { background_brightness: 0.09, - background_color: "#000080", + background_color: '#000080', blur: 2, brightness: 1, decay: 0.7, fix_hues: false, flip: true, - frequency_range: "High", - gradient: "linear-gradient(90deg, rgb(255, 40, 0) 0%, rgb(255, 0, 0) 100%)", + frequency_range: 'High', + gradient: + 'linear-gradient(90deg, rgb(255, 40, 0) 0%, rgb(255, 0, 0) 100%)', gradient_roll: 0, mirror: false, multiplier: 0.5 @@ -184,11 +185,11 @@ export const defaultEffects = { blenderMask2d: { type: 'texter2d', config: { - text: "LedFx", + text: 'LedFx', speed_option_1: 0.7, dump: false, - background_color: "#000000", - font: "Blade-5x8", + background_color: '#000000', + font: 'Blade-5x8', flip: false, option_2: false, option_1: false, @@ -197,17 +198,18 @@ export const defaultEffects = { use_gradient: false, brightness: 1, value_option_1: 0.5, - text_color: "#ffffff", + text_color: '#ffffff', advanced: false, gradient_roll: 0, - gradient: "linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)", + gradient: + 'linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)', background_brightness: 1, blur: 0, flip_horizontal: false, - resize_method: "Fast", + resize_method: 'Fast', diag: false, height_percent: 100, - text_effect: "Side Scroll", + text_effect: 'Side Scroll', mirror: false, test: false, impulse_decay: 0.1, @@ -220,11 +222,11 @@ export const defaultEffects = { type: 'blade_power_plus', config: { blur: 2, - background_color: "#000080", + background_color: '#000080', multiplier: 0.5, decay: 0.7, - frequency_range: "Lows (beat+bass)", - gradient: "linear-gradient(90deg, #00ffff 0.00%,#0000ff 100.00%)", + frequency_range: 'Lows (beat+bass)', + gradient: 'linear-gradient(90deg, #00ffff 0.00%,#0000ff 100.00%)', mirror: false, flip: true, gradient_roll: 0, @@ -235,10 +237,10 @@ export const defaultEffects = { }, blenderBackground2d: { type: 'plasma2d', - config:{ + config: { advanced: false, background_brightness: 1, - background_color: "#000000", + background_color: '#000000', blur: 0, brightness: 0.15, density: 0.5, @@ -248,14 +250,15 @@ export const defaultEffects = { flip: false, flip_horizontal: false, flip_vertical: false, - frequency_range: "Lows (beat+bass)", - gradient: "linear-gradient(90deg, #ff00b2 0.00%,#ff2800 50.00%,#ffc800 100.00%)", + frequency_range: 'Lows (beat+bass)', + gradient: + 'linear-gradient(90deg, #ff00b2 0.00%,#ff2800 50.00%,#ffc800 100.00%)', gradient_roll: 0, lower: 0.01, mirror: false, radius: 0.2, rotate: 0, - test: false, + test: false } } } diff --git a/src/pages/Home/Dashboard.tsx b/src/pages/Home/Dashboard.tsx index c1418c33..eae38fbf 100644 --- a/src/pages/Home/Dashboard.tsx +++ b/src/pages/Home/Dashboard.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { useEffect, useState } from 'react' import { @@ -52,13 +52,20 @@ const Dashboard = () => { .map((d) => !d.startsWith('gap-') && devices[d].config.pixel_count) .reduce((a, b) => a + b, 0) - const devicesOnline = Object.keys(devices).filter((d) => devices[d].online && !devices[d].id.startsWith('gap-')) + const devicesOnline = Object.keys(devices).filter( + (d) => devices[d].online && !devices[d].id.startsWith('gap-') + ) const virtualsReal = Object.keys(virtuals).filter( (d) => !virtuals[d]?.is_device && !virtuals[d]?.id.startsWith('gap-') ) const pixelTotalOnline = Object.keys(devices) - .map((d) => devices[d].online && !devices[d].id.startsWith('gap-') && devices[d].config.pixel_count) + .map( + (d) => + devices[d].online && + !devices[d].id.startsWith('gap-') && + devices[d].config.pixel_count + ) .reduce((a, b) => a + b, 0) const getSystemConfig = useStore((state) => state.getSystemConfig) @@ -202,7 +209,9 @@ const Dashboard = () => { height="auto" src={fx} alt="wled" - style={{ filter: `grayscale(100%) brightness(0)${theme.palette.primary.contrastText === '#fff' ? ' invert(1)' : ''}` }} + style={{ + filter: `grayscale(100%) brightness(0)${theme.palette.primary.contrastText === '#fff' ? ' invert(1)' : ''}` + }} /> @@ -240,7 +249,10 @@ const Dashboard = () => { {`${Math.round((scanning / 30) * 100)}%`} ) : ( - + )} {scanning > -1 && ( { height="auto" src={openrgbLogo} alt="wled" - style={{ filter: `grayscale(100%) brightness(0)${theme.palette.primary.contrastText === '#fff' ? ' invert(1)' : ''}` }} + style={{ + filter: `grayscale(100%) brightness(0)${theme.palette.primary.contrastText === '#fff' ? ' invert(1)' : ''}` + }} /> @@ -308,7 +322,7 @@ const Dashboard = () => { type="fab" color="primary" style={{ margin: '8px' }} - sx={{ color: theme.palette.primary.contrastText}} + sx={{ color: theme.palette.primary.contrastText }} icon={} text="Delete frontend data?" onConfirm={() => { @@ -336,7 +350,11 @@ const Dashboard = () => { */} - + @@ -357,7 +375,10 @@ const Dashboard = () => { }} sx={{ color: theme.palette.primary.contrastText, - bgcolor: theme.palette.mode === 'dark' ? theme.palette.primary.dark : theme.palette.primary.light, + bgcolor: + theme.palette.mode === 'dark' + ? theme.palette.primary.dark + : theme.palette.primary.light, '&:hover': { bgcolor: theme.palette.primary.main } @@ -382,7 +403,10 @@ const Dashboard = () => { }} sx={{ color: theme.palette.primary.contrastText, - bgcolor: theme.palette.mode === 'dark' ? theme.palette.primary.dark : theme.palette.primary.light, + bgcolor: + theme.palette.mode === 'dark' + ? theme.palette.primary.dark + : theme.palette.primary.light, '&:hover': { bgcolor: theme.palette.primary.main } @@ -407,7 +431,10 @@ const Dashboard = () => { }} sx={{ fill: theme.palette.primary.contrastText, - bgcolor: theme.palette.mode === 'dark' ? theme.palette.primary.dark : theme.palette.primary.light, + bgcolor: + theme.palette.mode === 'dark' + ? theme.palette.primary.dark + : theme.palette.primary.light, '&:hover': { bgcolor: theme.palette.primary.main } diff --git a/src/pages/Home/DbDevices.tsx b/src/pages/Home/DbDevices.tsx index 9fc82bfb..3d2fda7d 100644 --- a/src/pages/Home/DbDevices.tsx +++ b/src/pages/Home/DbDevices.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @/indent */ +/* eslint-disable prettier/prettier */ import { useTheme, Stack, Chip, IconButton, Typography } from '@mui/material' import { DataGrid, @@ -40,8 +42,12 @@ const DeviceActions = ({ const getVirtuals = useStore((state) => state.getVirtuals) const getDevices = useStore((state) => state.getDevices) const clearEffect = useStore((state) => state.clearEffect) - const setDialogOpenAddVirtual = useStore((state) => state.setDialogOpenAddVirtual) - const setDialogOpenAddDevice = useStore((state) => state.setDialogOpenAddDevice) + const setDialogOpenAddVirtual = useStore( + (state) => state.setDialogOpenAddVirtual + ) + const setDialogOpenAddDevice = useStore( + (state) => state.setDialogOpenAddDevice + ) const handleEditVirtual = () => { setDialogOpenAddVirtual(true, virtId) @@ -96,13 +102,15 @@ const DeviceActions = ({ )} - ) : } + ) : ( + + )} 1 ? 0 : 4.2) + - (!effect && virtuals[virtId]?.config.rows > 1 ? 4.2 : 0) + (!effect && virtuals[virtId]?.config.rows > 1 ? 4.2 : 0) }} size="small" onClick={(e) => { @@ -124,7 +132,7 @@ const DeviceActions = ({ } color={'inherit'} onConfirm={(e) => { @@ -214,21 +222,28 @@ const DbDevices = () => { { field: 'PixelGraph', headerName: 'Graph', - renderHeader: () => - - Graph - - {Object.keys(virtuals).some((v) => virtuals[v].config.rows > 1) && { - e.preventDefault() - e.stopPropagation() - setMatrix(!matrix) - }} + renderHeader: () => ( + - {matrix ? : } - } - , + Graph + {Object.keys(virtuals).some((v) => virtuals[v].config.rows > 1) && ( + { + e.preventDefault() + e.stopPropagation() + setMatrix(!matrix) + }} + > + {matrix ? : } + + )} + + ), width: 200, renderCell: (params: GridRenderCellParams) => graphsMulti && ( @@ -275,64 +290,79 @@ const DbDevices = () => { : 'Online' : virtuals[params.row.id]?.effect?.name ? `Effect: ${virtuals[params.row.id]?.effect?.name}` - : params.row.is_device ? 'Offline' : virtuals[params.row.id]?.active ? 'Active' : 'Inactive' + : params.row.is_device + ? 'Offline' + : virtuals[params.row.id]?.active + ? 'Active' + : 'Inactive' }, { field: 'actions', headerName: 'Actions', - renderHeader: () => + renderHeader: () => ( + - { - e.preventDefault() - e.stopPropagation() - await togglePause() - getVirtuals() - }} - > - {paused ? : } - - { - e.preventDefault() - e.stopPropagation() - await clearAllEffects() - getVirtuals() - }} - > - - + { + e.preventDefault() + e.stopPropagation() + await togglePause() + getVirtuals() + }} + > + {paused ? : } + + { + e.preventDefault() + e.stopPropagation() + await clearAllEffects() + getVirtuals() + }} + > + + Actions - , - width: 400, // eslint-disable-next-line - renderCell: (params: GridRenderCellParams) => // eslint-disable-next-line - devices[Object.keys(devices).find((d) => d === params.row.id) || '']?.online // eslint-disable-next-line - ? (virtuals[params.row.id]?.effect.name // eslint-disable-next-line - ? () // eslint-disable-next-line - : ()) // eslint-disable-next-line - : virtuals[params.row.id]?.effect.name // eslint-disable-next-line + + ), + width: 400, + renderCell: (params: GridRenderCellParams) => + devices[Object.keys(devices).find((d) => d === params.row.id) || '']?.online + ? (virtuals[params.row.id]?.effect.name + ? () + : ()) + : virtuals[params.row.id]?.effect.name ? () - : params.row.is_device ? ( activateDevice(params.row.id)} />) : null + : params.row.is_device ? ( + activateDevice(params.row.id)} /> + ) : null } ] const rows: any = Object.values(virtuals) - .filter(v => { - const vs = Object.keys(virtuals); - const virt = vs - .filter(v => showComplex ? v : !(v.endsWith('-mask') || v.endsWith('-foreground') || v.endsWith('-background'))) - .filter(v => showGaps ? v : !(v.startsWith('gap-'))) - .find(key => virtuals[key].id === v.id); - return virt !== undefined; - }) - .map((v: any) => ({ - ...v, - ...v.config - })); - + .filter((v) => { + const vs = Object.keys(virtuals) + const virt = vs + .filter((v) => + showComplex + ? v + : !( + v.endsWith('-mask') || + v.endsWith('-foreground') || + v.endsWith('-background') + ) + ) + .filter((v) => (showGaps ? v : !v.startsWith('gap-'))) + .find((key) => virtuals[key].id === v.id) + return virt !== undefined + }) + .map((v: any) => ({ + ...v, + ...v.config + })) return ( { sx={{ borderColor: 'transparent', '& .MuiDataGrid-row': { - backgroundColor: theme.palette.mode === 'light' ? theme.palette.background.default + '90' : '' + backgroundColor: + theme.palette.mode === 'light' + ? theme.palette.background.default + '90' + : '' }, '&.MuiDataGrid-root .MuiDataGrid-cell:focus-within': { outline: 'none !important' diff --git a/src/pages/Home/DbGlobalActions.tsx b/src/pages/Home/DbGlobalActions.tsx index bf2f5572..2a1662a5 100644 --- a/src/pages/Home/DbGlobalActions.tsx +++ b/src/pages/Home/DbGlobalActions.tsx @@ -89,7 +89,10 @@ const DbGlobalActions = () => { src={fx} alt="wled" style={{ - filter: theme.palette.mode=== 'dark' ? 'invert(1) brightness(2)' : '', + filter: + theme.palette.mode === 'dark' + ? 'invert(1) brightness(2)' + : '', objectFit: 'cover', marginRight: 8, marginLeft: -8 @@ -126,9 +129,10 @@ const DbGlobalActions = () => { src={openrgbLogo} alt="wled" style={{ - filter: theme.palette.mode=== 'dark' - ? 'grayscale(100%) brightness(0) invert(1) brightness(2)' - : 'grayscale(100%) brightness(0) invert(0) brightness(2)', + filter: + theme.palette.mode === 'dark' + ? 'grayscale(100%) brightness(0) invert(1) brightness(2)' + : 'grayscale(100%) brightness(0) invert(0) brightness(2)', marginRight: 22, marginLeft: 4 }} diff --git a/src/pages/Home/DbStats.tsx b/src/pages/Home/DbStats.tsx index 19d5a1d8..a7898cdd 100644 --- a/src/pages/Home/DbStats.tsx +++ b/src/pages/Home/DbStats.tsx @@ -9,17 +9,26 @@ const DbStats = () => { const devices = useStore((state) => state.devices) const virtuals = useStore((state) => state.virtuals) const scenes = useStore((state) => state.scenes) - const devicesOnline = Object.keys(devices).filter((d) => devices[d].online && !devices[d].id.startsWith('gap-')) + const devicesOnline = Object.keys(devices).filter( + (d) => devices[d].online && !devices[d].id.startsWith('gap-') + ) const virtualsReal = Object.keys(virtuals).filter( (d) => !virtuals[d].is_device && !virtuals[d].id.startsWith('gap-') ) const pixelTotalOnline = Object.keys(devices) - .map((d) => devices[d].online && !devices[d].id.startsWith('gap-') && devices[d].config.pixel_count) + .map( + (d) => + devices[d].online && + !devices[d].id.startsWith('gap-') && + devices[d].config.pixel_count + ) .reduce((a, b) => a + b, 0) const pixelTotal = Object.keys(devices) - .map((d) => !devices[d].id.startsWith('gap-') && devices[d].config.pixel_count) + .map( + (d) => !devices[d].id.startsWith('gap-') && devices[d].config.pixel_count + ) .reduce((a, b) => a + b, 0) return ( } = { children:
loading
}, + props: TransitionProps & { children?: React.ReactElement } = { + children:
loading
+ }, ref: React.Ref ) { return diff --git a/src/pages/Scenes/Scenes.tsx b/src/pages/Scenes/Scenes.tsx index 4b7927fb..eba120bd 100644 --- a/src/pages/Scenes/Scenes.tsx +++ b/src/pages/Scenes/Scenes.tsx @@ -25,7 +25,7 @@ import { ISceneOrder } from '../../store/api/storeScenes' const Scenes = () => { const classes = useStyles() const theme = useTheme() - + const getScenes = useStore((state) => state.getScenes) const scenes = useStore((state) => state.scenes) const sceneOrder = useStore((state) => state.sceneOrder) @@ -55,13 +55,13 @@ const Scenes = () => { // initial scene order if not set const sc = JSON.parse(JSON.stringify(sceneOrder)) as ISceneOrder[] Object.keys(scenes).map((s, i) => { - if (!(sc.some(o => o.sceneId === s))) { - return sc.push({sceneId: s, order: i}) + if (!sc.some((o) => o.sceneId === s)) { + return sc.push({ sceneId: s, order: i }) } return null }) setSceneOrder(sc) - // eslint-disable-next-line + // eslint-disable-next-line react-hooks/exhaustive-deps }, [scenes]) const sceneFilter = (sc: string) => @@ -69,7 +69,8 @@ const Scenes = () => { ?.split(',') .some((sce: string) => sceneActiveTags.includes(sce)) - const sceneBlenderFilter = (sc: string) => !(scenes[sc].scene_tags?.split(',')?.includes('blender')) + const sceneBlenderFilter = (sc: string) => + !scenes[sc].scene_tags?.split(',')?.includes('blender') return ( <>
{ ? Object.keys(scenes).filter(sceneFilter) : Object.keys(scenes) ) - .filter(sceneBlenderFilter) - .map((s, i) => { - return ( - o.sceneId === s)?.order || 0} - > - { + return ( + o.sceneId === s)?.order || 0} > - handleActivateScene(s)} - > - -
- {scenes[s].scene_tags?.split(',').map( - (t: string) => - t.length > 0 && - features.scenechips && ( - - ) - )} -
-
- - handleActivateScene(s)} > - {scenes[s].name || s} - - {!( - window.localStorage.getItem('guestmode') === 'activated' - ) && } - -
-
- ) - }) + +
+ {scenes[s].scene_tags?.split(',').map( + (t: string) => + t.length > 0 && + features.scenechips && ( + + ) + )} +
+ + + + {scenes[s].name || s} + + {!( + window.localStorage.getItem('guestmode') === 'activated' + ) && } + + + + ) + }) ) : ( )} diff --git a/src/pages/Scenes/ScenesImage.tsx b/src/pages/Scenes/ScenesImage.tsx index 33a52a66..40396ca6 100644 --- a/src/pages/Scenes/ScenesImage.tsx +++ b/src/pages/Scenes/ScenesImage.tsx @@ -5,7 +5,13 @@ import useStore from '../../store/useStore' import useStyles from './Scenes.styles' import BladeIcon from '../../components/Icons/BladeIcon/BladeIcon' -const SceneImage = ({ iconName, list }: { iconName: string, list?: boolean }) => { +const SceneImage = ({ + iconName, + list +}: { + iconName: string + list?: boolean +}) => { const classes = useStyles() const [imageData, setImageData] = useState(null) const getImage = useStore((state) => state.getImage) @@ -14,7 +20,7 @@ const SceneImage = ({ iconName, list }: { iconName: string, list?: boolean }) => ic.split('image:')[1]?.replaceAll('file:///', '') ) if (result?.image) setImageData(result.image) - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { if (iconName?.startsWith('image:')) { @@ -44,7 +50,12 @@ const SceneImage = ({ iconName, list }: { iconName: string, list?: boolean }) => /> ) ) : ( - + ) } diff --git a/src/pages/Scenes/ScenesMenu.tsx b/src/pages/Scenes/ScenesMenu.tsx index db1aff57..f1fd60c8 100644 --- a/src/pages/Scenes/ScenesMenu.tsx +++ b/src/pages/Scenes/ScenesMenu.tsx @@ -1,6 +1,12 @@ import { useState, MouseEvent } from 'react' import { Menu, MenuItem, ListItemIcon, Button } from '@mui/material' -import { PlaylistAdd, Edit, MoreVert, ChevronLeft, ChevronRight } from '@mui/icons-material' +import { + PlaylistAdd, + Edit, + MoreVert, + ChevronLeft, + ChevronRight +} from '@mui/icons-material' import Popover from '../../components/Popover/Popover' import useStore from '../../store/useStore' @@ -36,7 +42,13 @@ const ScenesMenu = ({ sceneId }: { sceneId: string }) => { - + { setDialogOpenAddScene(false, true, sceneId, scenes[sceneId]) @@ -51,23 +63,30 @@ const ScenesMenu = ({ sceneId }: { sceneId: string }) => { onClick={() => { addScene2PL(sceneId) handleClose() - }}> + }} + > - { - setSceneOrderUp(sceneId) - handleClose() - }}> + { + setSceneOrderUp(sceneId) + handleClose() + }} + > - = sceneOrder.length - 1} onClick={()=>{ - setSceneOrderDown(sceneId) - handleClose() - }}> + = sceneOrder.length - 1} + onClick={() => { + setSceneOrderDown(sceneId) + handleClose() + }} + > diff --git a/src/pages/Scenes/ScenesMostUsed.tsx b/src/pages/Scenes/ScenesMostUsed.tsx index efebe0b1..87818e76 100644 --- a/src/pages/Scenes/ScenesMostUsed.tsx +++ b/src/pages/Scenes/ScenesMostUsed.tsx @@ -28,7 +28,7 @@ export default function ScenesMostUsed({ Object.keys(scenes).find((s: any) => scenes[s].name === params.row?.name) ) getVirtuals() -} + } useEffect(() => { Object.keys(count).map((key: string) => setMostUsedScenes(key, count[key])) // eslint-disable-next-line react-hooks/exhaustive-deps @@ -88,7 +88,7 @@ export default function ScenesMostUsed({ {title} )} - c.field !== 'used') : columns} diff --git a/src/pages/Scenes/ScenesPlaylist.tsx b/src/pages/Scenes/ScenesPlaylist.tsx index f1f1033c..d8e3148c 100644 --- a/src/pages/Scenes/ScenesPlaylist.tsx +++ b/src/pages/Scenes/ScenesPlaylist.tsx @@ -29,13 +29,15 @@ export default function ScenesPlaylist({ db }: any) { const theme = useTheme() - const timer = useRef(null); + const timer = useRef(null) const [theScenes, setTheScenes] = useState([]) const scenePL = useStore((state) => state.scenePL) const scenePLintervals = useStore((state) => state.scenePLintervals) const setScenePLintervals = useStore((state) => state.setScenePLintervals) const sceneUseIntervals = useStore((state) => state.sceneUseIntervals) - const toggleSceneUseIntervals = useStore((state) => state.toggleSceneUseIntervals) + const toggleSceneUseIntervals = useStore( + (state) => state.toggleSceneUseIntervals + ) const scenePLplay = useStore((state) => state.scenePLplay) const toggleScenePLplay = useStore((state) => state.toggleScenePLplay) const scenePLrepeat = useStore((state) => state.scenePLrepeat) @@ -54,36 +56,46 @@ export default function ScenesPlaylist({ return setTheScenes(current) }, [scenes, scenePL]) - useEffect(() => { if (scenePLplay) { if (timer.current === null) { - timer.current = setTimeout(() => { - if (scenePL[scenePLactiveIndex + 1]) { - activateScene(scenePL[scenePLactiveIndex + 1]); - setScenePLactiveIndex(scenePLactiveIndex + 1); - } else if (scenePLrepeat) { - activateScene(scenePL[0]); - setScenePLactiveIndex(0); - } else { - toggleScenePLplay(); - } - timer.current = null; // Reset the timer - }, (sceneUseIntervals ? scenePLinterval : (scenePLintervals[scenePLactiveIndex] || 2)) * 1000); + timer.current = setTimeout( + () => { + if (scenePL[scenePLactiveIndex + 1]) { + activateScene(scenePL[scenePLactiveIndex + 1]) + setScenePLactiveIndex(scenePLactiveIndex + 1) + } else if (scenePLrepeat) { + activateScene(scenePL[0]) + setScenePLactiveIndex(0) + } else { + toggleScenePLplay() + } + timer.current = null // Reset the timer + }, + (sceneUseIntervals + ? scenePLinterval + : scenePLintervals[scenePLactiveIndex] || 2) * 1000 + ) } } else if (timer.current) { - clearTimeout(timer.current); - timer.current = null; + clearTimeout(timer.current) + timer.current = null } - + return () => { if (timer.current) { - clearTimeout(timer.current); - timer.current = null; + clearTimeout(timer.current) + timer.current = null } } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [scenePLplay, scenePLactiveIndex, scenePLintervals, scenePLinterval, scenePLrepeat]); + }, [ + scenePLplay, + scenePLactiveIndex, + scenePLintervals, + scenePLinterval, + scenePLrepeat + ]) const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 0 }, @@ -116,39 +128,39 @@ export default function ScenesPlaylist({ ) }, { - field: 'interval', + field: 'interval', headerName: 'Wait', - width: db ? 70 : 0, + width: db ? 70 : 0, renderCell: (params: GridRenderCellParams) => ( { - const newIntervals = [...scenePLintervals] - newIntervals[params.id as number] = e.target.value - setScenePLintervals(newIntervals)} - } - /> + variant="standard" + disabled={sceneUseIntervals} + sx={{ + display: 'flex', + width: 70, + height: '100%', + '& input': { + textAlign: 'right', + padding: '5px 15px 2px' + }, + '& .MuiInput-underline:before': { + display: 'none' + }, + '& .MuiInput-underline:after': { + display: 'none' + }, + '& .MuiInput-root': { + height: '100%' + } + }} + type="number" + value={sceneUseIntervals ? 2 : scenePLintervals[params.id as number]} + onChange={(e: any) => { + const newIntervals = [...scenePLintervals] + newIntervals[params.id as number] = e.target.value + setScenePLintervals(newIntervals) + }} + /> ) }, { @@ -156,7 +168,8 @@ export default function ScenesPlaylist({ headerName: 'Remove', width: 70, renderCell: (params: GridRenderCellParams) => { - const removeScene2PL = useStore((state) => state.removeScene2PL) // eslint-disable-line + // eslint-disable-next-line react-hooks/rules-of-hooks + const removeScene2PL = useStore((state) => state.removeScene2PL) return (
diff --git a/src/pages/Settings/EffectsCard.tsx b/src/pages/Settings/EffectsCard.tsx index 8e66741a..09a3fe34 100644 --- a/src/pages/Settings/EffectsCard.tsx +++ b/src/pages/Settings/EffectsCard.tsx @@ -10,7 +10,9 @@ const EffectsSettingsCard = () => { const setShowHex = useStore((state) => state.ui.setShowHex) const setFeatures = useStore((state) => state.setFeatures) const setBlenderAutomagic = useStore((state) => state.ui.setBlenderAutomagic) - const setEffectDescriptions = useStore((state) => state.ui.setEffectDescriptions) + const setEffectDescriptions = useStore( + (state) => state.ui.setEffectDescriptions + ) return ( <> diff --git a/src/pages/Settings/ExpertFeatures.tsx b/src/pages/Settings/ExpertFeatures.tsx index 2d1ed0ee..40319fa3 100644 --- a/src/pages/Settings/ExpertFeatures.tsx +++ b/src/pages/Settings/ExpertFeatures.tsx @@ -4,7 +4,6 @@ import useStore from '../../store/useStore' import useSliderStyles from '../../components/SchemaForm/components/Number/BladeSlider.styles' const ExpertFeatures = () => { - const sliderClasses = useSliderStyles() const setFeatures = useStore((state) => state.setFeatures) diff --git a/src/pages/Settings/GeneralCard.tsx b/src/pages/Settings/GeneralCard.tsx index 0897f334..0c94177a 100644 --- a/src/pages/Settings/GeneralCard.tsx +++ b/src/pages/Settings/GeneralCard.tsx @@ -1,5 +1,5 @@ /* eslint-disable no-self-assign */ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { CloudUpload, CloudDownload, @@ -43,7 +43,6 @@ const GeneralCard = () => { }, 500) window.location.href = window.location.href.split('/#/')[0] + '/#/' }) - } const fileChanged = async (e: any) => { @@ -200,7 +199,10 @@ const GeneralCard = () => { - onSystemSettingsChange('flush_on_deactivate', !settings.flush_on_deactivate) + onSystemSettingsChange( + 'flush_on_deactivate', + !settings.flush_on_deactivate + ) } /> diff --git a/src/pages/Settings/MidiCard.tsx b/src/pages/Settings/MidiCard.tsx index e9affeff..b2a4faf6 100644 --- a/src/pages/Settings/MidiCard.tsx +++ b/src/pages/Settings/MidiCard.tsx @@ -23,43 +23,40 @@ const MidiCard = ({ className }: any) => { return (
- - setMidiInput(e.target.value)} + > + {midiInputs.map((item: any, i: number) => ( + + {item} + + ))} + + + + + + - - - - - - + +
) } diff --git a/src/pages/Settings/PixelGraphsSettingsCard.tsx b/src/pages/Settings/PixelGraphsSettingsCard.tsx index a9cd5333..79bcd6eb 100644 --- a/src/pages/Settings/PixelGraphsSettingsCard.tsx +++ b/src/pages/Settings/PixelGraphsSettingsCard.tsx @@ -27,7 +27,7 @@ const PixelGraphsSettingsCard = () => { { value: 512, label: '512' }, { value: 1024, label: '1K' }, { value: 2048, label: '2K' }, - { value: 4096, label: '4K' }, + { value: 4096, label: '4K' } ] const setSystemSetting = (setting: string, value: any) => { setSystemConfig({ [setting]: value }).then(() => getSystemConfig()) @@ -82,11 +82,16 @@ const PixelGraphsSettingsCard = () => { variant="standard" value={'select'} onChange={(e) => - e.target.value !== 'select' && setSystemSetting('visualisation_maxlen', e.target.value) + e.target.value !== 'select' && + setSystemSetting('visualisation_maxlen', e.target.value) } > - {(marks).map((item: any) => ( - + {marks.map((item: any) => ( + {item.label} ))} @@ -194,34 +199,40 @@ const PixelGraphsSettingsCard = () => { }} /> - setShowWarning('lessPixels', !showWarning)}/> + setShowWarning('lessPixels', !showWarning)} + /> - - {showFeatures.alpha && <> - - { - setPixelLength(parseInt(e.target.value, 10)) - }} - onBlur={(e) => setVirtual2dLimit(parseInt(e.target.value, 10))} - sx={{ - '& input': { textAlign: 'right' } - }} - inputProps={{ - min: 1, - max: 4096, - type: 'number', - 'aria-labelledby': 'input-slider' - }} - /> - - - } + + {showFeatures.alpha && ( + <> + + { + setPixelLength(parseInt(e.target.value, 10)) + }} + onBlur={(e) => setVirtual2dLimit(parseInt(e.target.value, 10))} + sx={{ + '& input': { textAlign: 'right' } + }} + inputProps={{ + min: 1, + max: 4096, + type: 'number', + 'aria-labelledby': 'input-slider' + }} + /> + + + + )} ) } diff --git a/src/pages/Settings/Settings.tsx b/src/pages/Settings/Settings.tsx index e3810d0c..54cd3bb4 100644 --- a/src/pages/Settings/Settings.tsx +++ b/src/pages/Settings/Settings.tsx @@ -92,9 +92,11 @@ const Settings = () => { )} */} - {features.scenemidi && - - } + {features.scenemidi && ( + + + + )} diff --git a/src/pages/Settings/SettingsComponents.tsx b/src/pages/Settings/SettingsComponents.tsx index 4e3669d1..bb480964 100644 --- a/src/pages/Settings/SettingsComponents.tsx +++ b/src/pages/Settings/SettingsComponents.tsx @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable no-unused-vars */ import { makeStyles, styled } from '@mui/styles' import { Accordion, @@ -210,7 +208,7 @@ export const SettingsRow = ({ const alphaMode = useStore((state) => state.features.alpha) const betaMode = useStore((state) => state.features.beta) const expertMode = useStore((state) => state.viewMode) === 'expert' - + if (beta && !betaMode) return null if (alpha && !alphaMode) return null if (expert && !expertMode) return null @@ -226,9 +224,9 @@ export const SettingsRow = ({ }} > - {alpha && } - {beta && } - {expert && } + {alpha && } + {beta && } + {expert && }
{ return ( <> - viewMode === 'user' ? setViewMode('expert') : setViewMode('user')}/> - setFeatures('beta', !features.beta)} /> + + viewMode === 'user' ? setViewMode('expert') : setViewMode('user') + } + /> + setFeatures('beta', !features.beta)} + /> {showFeatures.alpha && ( - setFeatures('alpha', !features.alpha)} /> + setFeatures('alpha', !features.alpha)} + /> )} ) diff --git a/src/pages/Settings/Webaudio.tsx b/src/pages/Settings/Webaudio.tsx index abd6daa2..0662abdf 100644 --- a/src/pages/Settings/Webaudio.tsx +++ b/src/pages/Settings/Webaudio.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { Button, diff --git a/src/pages/User/AvatarPicker/AvatarPicker.interface.tsx b/src/pages/User/AvatarPicker/AvatarPicker.interface.tsx index a8b8a71f..d47309da 100644 --- a/src/pages/User/AvatarPicker/AvatarPicker.interface.tsx +++ b/src/pages/User/AvatarPicker/AvatarPicker.interface.tsx @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars const IStorage = ['localStorage', 'indexedDb', 'cloud', 'custom'] as const export const storageOptions = [ 'localStorage', diff --git a/src/pages/User/AvatarPicker/AvatarPicker.tsx b/src/pages/User/AvatarPicker/AvatarPicker.tsx index 9864b986..23c640e7 100644 --- a/src/pages/User/AvatarPicker/AvatarPicker.tsx +++ b/src/pages/User/AvatarPicker/AvatarPicker.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/rules-of-hooks */ import { useEffect, useRef, useState } from 'react' import Cropper, { Area } from 'react-easy-crop' import { Delete, Edit, GitHub, Save, UploadFile } from '@mui/icons-material' @@ -114,7 +115,7 @@ const AvatarPicker = ({ }, []) const { getByID, update } = - newStorage === 'indexedDb' && !setAvatar // eslint-disable-next-line + newStorage === 'indexedDb' && !setAvatar ? useIndexedDBStore('avatars') : { getByID: null, update: null } diff --git a/src/store/api/storeScenes.tsx b/src/store/api/storeScenes.tsx index 95db0e47..b975f589 100644 --- a/src/store/api/storeScenes.tsx +++ b/src/store/api/storeScenes.tsx @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ import { produce } from 'immer' import { Ledfx } from '../../api/ledfx' @@ -6,7 +6,7 @@ import type { IStore } from '../useStore' import useStore from '../useStore' export interface ISceneOrder { - sceneId: string, + sceneId: string order: number } @@ -33,22 +33,25 @@ const storeScenes = (set: any) => ({ ) }, setSceneOrderUp: (sceneId: string) => { - let current, target = null + let target = null const sceneOrder = useStore.getState().sceneOrder - current = sceneOrder.find((s: ISceneOrder) => s.sceneId === sceneId) || null + const current = + sceneOrder.find((s: ISceneOrder) => s.sceneId === sceneId) || null if (!current || current.order < 1) return - target = sceneOrder.find((s: ISceneOrder) => s.order === current?.order - 1) || null + target = + sceneOrder.find((s: ISceneOrder) => s.order === current?.order - 1) || + null if (!target) return // console.log('Move up', sceneId, current, target) const newSceneOrder = sceneOrder.map((o: ISceneOrder) => { - if (o.sceneId === sceneId) { - return { ...o, order: target.order } - } - if (o.sceneId === target.sceneId) { - return { ...o, order: current.order } - } - return o + if (o.sceneId === sceneId) { + return { ...o, order: target.order } + } + if (o.sceneId === target.sceneId) { + return { ...o, order: current.order } + } + return o }) // console.log('changing from ', sceneOrder, 'to', newSceneOrder) @@ -61,22 +64,25 @@ const storeScenes = (set: any) => ({ ) }, setSceneOrderDown: (sceneId: string) => { - let current, target = null + let target = null const sceneOrder = useStore.getState().sceneOrder - current = sceneOrder.find((s: ISceneOrder) => s.sceneId === sceneId) || null + const current = + sceneOrder.find((s: ISceneOrder) => s.sceneId === sceneId) || null if (!current || current.order >= sceneOrder.length - 1) return - target = sceneOrder.find((s: ISceneOrder) => s.order === current?.order + 1) || null + target = + sceneOrder.find((s: ISceneOrder) => s.order === current?.order + 1) || + null if (!target) return // console.log('Move down', sceneId, current, target) const newSceneOrder = sceneOrder.map((o: ISceneOrder) => { - if (o.sceneId === sceneId) { - return { ...o, order: target.order } - } - if (o.sceneId === target.sceneId) { - return { ...o, order: current.order } - } - return o + if (o.sceneId === sceneId) { + return { ...o, order: target.order } + } + if (o.sceneId === target.sceneId) { + return { ...o, order: current.order } + } + return o }) // console.log('changing from ', sceneOrder, 'to', newSceneOrder) diff --git a/src/store/api/storeVirtuals.tsx b/src/store/api/storeVirtuals.tsx index 5aae027b..41d9ad6b 100644 --- a/src/store/api/storeVirtuals.tsx +++ b/src/store/api/storeVirtuals.tsx @@ -2,9 +2,8 @@ import { produce } from 'immer' import { Ledfx } from '../../api/ledfx' import type { IStore } from '../useStore' - export interface IVirtualOrder { - virtId: string, + virtId: string order: number } @@ -202,9 +201,7 @@ const storeVirtuals = (set: any) => ({ ) } }, - setEffectFallback: ( - virtId: string - ) => { + setEffectFallback: (virtId: string) => { Ledfx(`/api/virtuals/${virtId}/fallback`) }, removeEffectfromHistory: async (type: string, virtId: string) => { diff --git a/src/store/ui-persist/storeUIpersist.tsx b/src/store/ui-persist/storeUIpersist.tsx index d1f70482..1c396f2e 100644 --- a/src/store/ui-persist/storeUIpersist.tsx +++ b/src/store/ui-persist/storeUIpersist.tsx @@ -1,4 +1,5 @@ -const storeUIPersist = (set: any) => ({ +// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars +const storeUIPersist = (set: any) => ({ infoAlerts: { scenes: true, devices: true, @@ -10,8 +11,8 @@ const storeUIPersist = (set: any) => ({ pixelMode: true }, warnings: { - lessPixels: true, - }, + lessPixels: true + } }) export default storeUIPersist diff --git a/src/store/ui-persist/storeUIpersistActions.tsx b/src/store/ui-persist/storeUIpersistActions.tsx index 14f6bfa3..6633b8df 100644 --- a/src/store/ui-persist/storeUIpersistActions.tsx +++ b/src/store/ui-persist/storeUIpersistActions.tsx @@ -3,7 +3,15 @@ import type { IStore } from '../useStore' const storeUIPersistActions = (set: any) => ({ setInfoAlerts: ( - key: 'scenes' | 'devices' | 'user' | 'gamepad' | 'matrix' | 'camera' | 'matrixGroups' | 'pixelMode', + key: + | 'scenes' + | 'devices' + | 'user' + | 'gamepad' + | 'matrix' + | 'camera' + | 'matrixGroups' + | 'pixelMode', val: boolean ): void => set( @@ -13,17 +21,14 @@ const storeUIPersistActions = (set: any) => ({ false, 'uiPersist/setInfoAlerts' ), - setWarnings: ( - key: 'lessPixels', - val: boolean - ): void => + setWarnings: (key: 'lessPixels', val: boolean): void => set( produce((state: IStore) => { state.uiPersist.warnings[key] = val }), false, 'uiPersist/setWarnings' - ), + ) }) export default storeUIPersistActions diff --git a/src/store/ui/storeFeatures.tsx b/src/store/ui/storeFeatures.tsx index e7f101dc..aa22eb7a 100644 --- a/src/store/ui/storeFeatures.tsx +++ b/src/store/ui/storeFeatures.tsx @@ -31,7 +31,7 @@ export type IFeatures = | 'gamepad' | 'wakelock' | 'melbankGraph' - + const storeFeatures = (set: any) => ({ features: { dev: false, diff --git a/src/store/ui/storeMidi.tsx b/src/store/ui/storeMidi.tsx index 8c2fb3a7..f8eb9367 100644 --- a/src/store/ui/storeMidi.tsx +++ b/src/store/ui/storeMidi.tsx @@ -21,12 +21,12 @@ export interface IDefaultMapping { export interface IMapping { [key: number]: IDefaultMapping } -const baseMapping = {} as IDefaultMapping; +const baseMapping = {} as IDefaultMapping for (let row = 1; row <= 9; row++) { for (let col = 1; col <= 9; col++) { - const key = parseInt(`${row}${col}`); - baseMapping[key] = { buttonNumber: key }; + const key = parseInt(`${row}${col}`) + baseMapping[key] = { buttonNumber: key } } } @@ -48,23 +48,39 @@ const presetMapping = { export const defaultMapping = { ...baseMapping, ...presetMapping } const storeMidi = (set: any, get: any) => ({ - getColorFromValue: (value: string ) => { - if (value === 'undefined') return undefined; - const state = get() as IStore; - const colors = MidiDevices[state.midiType][state.midiModel].colors; - const numericValue = parseInt(value, 16); - return Object.keys(colors).find(key => colors[key as keyof typeof colors] === numericValue) || undefined; + getColorFromValue: (value: string) => { + if (value === 'undefined') return undefined + const state = get() as IStore + const colors = MidiDevices[state.midiType][state.midiModel].colors + const numericValue = parseInt(value, 16) + return ( + Object.keys(colors).find( + (key) => colors[key as keyof typeof colors] === numericValue + ) || undefined + ) }, getUiBtnNo: (inputInt: number): number | null => { - const state = get() as IStore; - for (let i = 0; i < MidiDevices[state.midiType][state.midiModel].buttonNumbers.length; i++) { - for (let j = 0; j < MidiDevices[state.midiType][state.midiModel].buttonNumbers[i].length; j++) { - if (MidiDevices[state.midiType][state.midiModel].buttonNumbers[i][j] === inputInt) { - return MidiDevices.Launchpad.X.buttonNumbers[i][j]; + const state = get() as IStore + for ( + let i = 0; + i < MidiDevices[state.midiType][state.midiModel].buttonNumbers.length; + i++ + ) { + for ( + let j = 0; + j < + MidiDevices[state.midiType][state.midiModel].buttonNumbers[i].length; + j++ + ) { + if ( + MidiDevices[state.midiType][state.midiModel].buttonNumbers[i][j] === + inputInt + ) { + return MidiDevices.Launchpad.X.buttonNumbers[i][j] } } } - return null; + return null }, blockMidiHandler: false, setBlockMidiHandler: (block: boolean) => @@ -84,8 +100,8 @@ const storeMidi = (set: any, get: any) => ({ false, 'setMidiType' ), - midiModel: 'X' as keyof typeof MidiDevices[keyof typeof MidiDevices], - setMidiModel: (model: keyof typeof MidiDevices[keyof typeof MidiDevices]) => + midiModel: 'X' as keyof (typeof MidiDevices)[keyof typeof MidiDevices], + setMidiModel: (model: keyof (typeof MidiDevices)[keyof typeof MidiDevices]) => set( produce((state: IStore) => { state.midiModel = model @@ -111,7 +127,7 @@ const storeMidi = (set: any, get: any) => ({ false, 'setMidiOutputs' ), - midiInput:'', + midiInput: '', setMidiInput: (input: string) => set( produce((state: IStore) => { @@ -120,7 +136,7 @@ const storeMidi = (set: any, get: any) => ({ false, 'setMidiInput' ), - midiOutput:'', + midiOutput: '', setMidiOutput: (output: string) => set( produce((state: IStore) => { @@ -145,7 +161,7 @@ const storeMidi = (set: any, get: any) => ({ commandType: '90', sceneActiveType: '90', sceneInactiveType: '90', - pressedButtonColor: null as string | null, + pressedButtonColor: null as string | null }, setMidiCommandType: (type: string) => set( @@ -204,7 +220,7 @@ const storeMidi = (set: any, get: any) => ({ 'setPressedButtonColor' ), midiMapping: { - 0: defaultMapping, + 0: defaultMapping } as IMapping, setMidiMapping: (midiMapping: IMapping): void => set( @@ -217,7 +233,10 @@ const storeMidi = (set: any, get: any) => ({ setMidiMappingButtonNumbers: (inputArray: number[][]): void => set( produce((state: IStore) => { - if (inputArray.length !== 9 || !inputArray.every(row => row.length === 9)) { + if ( + inputArray.length !== 9 || + !inputArray.every((row) => row.length === 9) + ) { throw new Error('Input must be a 9x9 array') } const updatedMapping = { ...state.midiMapping } @@ -227,7 +246,10 @@ const storeMidi = (set: any, get: any) => ({ for (let col = 0; col < 9; col++) { const key = (row + 1) * 10 + (col + 1) if (updatedMapping[0][key]) { - updatedMapping[0][key] = { ...updatedMapping[0][key], buttonNumber: inputArray[row][col] } + updatedMapping[0][key] = { + ...updatedMapping[0][key], + buttonNumber: inputArray[row][col] + } } else { updatedMapping[0][key] = { buttonNumber: inputArray[row][col] } } @@ -238,7 +260,7 @@ const storeMidi = (set: any, get: any) => ({ false, 'updateMidiMapping' ), - + midiEvent: { name: '', note: '', diff --git a/src/store/ui/storeSpotify.tsx b/src/store/ui/storeSpotify.tsx index 8f9cbdac..ddb6ee17 100644 --- a/src/store/ui/storeSpotify.tsx +++ b/src/store/ui/storeSpotify.tsx @@ -27,34 +27,35 @@ const storeSpotify = () => ({ currentTrack: '', sendSpotifyTrack: false, spotifyTexter: { - "gradient": "linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)", - "option_2": false, - "flip": false, - "blur": 0, - "flip_horizontal": true, - "speed_option_1": 2, - "resize_method": "Fast", - "gradient_roll": 0, - "alpha": false, - "value_option_1": 0.5, - "font": "Blade-5x8", - "use_gradient": false, - "diag": false, - "test": false, - "impulse_decay": 0.1, - "mirror": false, - "flip_vertical": false, - "text_effect": "Side Scroll", - "multiplier": 1, - "brightness": 1, - "text_color": "#ff0000", - "background_brightness": 1, - "rotate": 2, - "dump": false, - "option_1": false, - "height_percent": 100, - "background_color": "#000000" -}, + gradient: + 'linear-gradient(90deg, rgb(255, 0, 0) 0%, rgb(255, 120, 0) 14%, rgb(255, 200, 0) 28%, rgb(0, 255, 0) 42%, rgb(0, 199, 140) 56%, rgb(0, 0, 255) 70%, rgb(128, 0, 128) 84%, rgb(255, 0, 178) 98%)', + option_2: false, + flip: false, + blur: 0, + flip_horizontal: true, + speed_option_1: 2, + resize_method: 'Fast', + gradient_roll: 0, + alpha: false, + value_option_1: 0.5, + font: 'Blade-5x8', + use_gradient: false, + diag: false, + test: false, + impulse_decay: 0.1, + mirror: false, + flip_vertical: false, + text_effect: 'Side Scroll', + multiplier: 1, + brightness: 1, + text_color: '#ff0000', + background_brightness: 1, + rotate: 2, + dump: false, + option_1: false, + height_percent: 100, + background_color: '#000000' + } }) export default storeSpotify diff --git a/src/store/ui/storeSpotifyActions.tsx b/src/store/ui/storeSpotifyActions.tsx index 5a4f6129..56285562 100644 --- a/src/store/ui/storeSpotifyActions.tsx +++ b/src/store/ui/storeSpotifyActions.tsx @@ -218,7 +218,10 @@ const storeSpotifyActions = (set: any) => ({ setSpTexter: (texter: any) => set( produce((state: IStore) => { - state.spotify.spotifyTexter = {...state.spotify.spotifyTexter, ...texter} + state.spotify.spotifyTexter = { + ...state.spotify.spotifyTexter, + ...texter + } }), false, 'spotify/setSpTexter' @@ -279,7 +282,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterGradientRoll: (value: number) => + setSpTexterGradientRoll: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.gradient_roll = value @@ -287,7 +290,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterRotate: (value: number) => + setSpTexterRotate: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.rotate = value @@ -295,7 +298,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterHeightPercent: (value: number) => + setSpTexterHeightPercent: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.height_percent = value @@ -303,7 +306,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterBrightness: (value: number) => + setSpTexterBrightness: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.brightness = value @@ -311,7 +314,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterBackgroundBrightness: (value: number) => + setSpTexterBackgroundBrightness: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.background_brightness = value @@ -319,7 +322,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterSpeed: (value: number) => + setSpTexterSpeed: (value: number) => set( produce((state: IStore) => { state.spotify.spotifyTexter.speed_option_1 = value @@ -327,7 +330,7 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterFont: (value: string) => + setSpTexterFont: (value: string) => set( produce((state: IStore) => { state.spotify.spotifyTexter.font = value @@ -335,14 +338,14 @@ const storeSpotifyActions = (set: any) => ({ false, 'spotify/setSpTexterValue' ), - setSpTexterTextEffect: (value: string) => + setSpTexterTextEffect: (value: string) => set( produce((state: IStore) => { state.spotify.spotifyTexter.text_effect = value }), false, 'spotify/setSpTexterValue' - ), + ) }) export default storeSpotifyActions diff --git a/src/store/useStore.ts b/src/store/useStore.ts index ab61de50..dbb08f21 100644 --- a/src/store/useStore.ts +++ b/src/store/useStore.ts @@ -76,7 +76,13 @@ const useStore = create( Object.fromEntries( Object.entries(state).filter( ([key]) => - !['dialogs', 'disconnected', 'ui', 'spotify', 'pixelGraphs'].includes(key) + ![ + 'dialogs', + 'disconnected', + 'ui', + 'spotify', + 'pixelGraphs' + ].includes(key) ) ) } @@ -84,6 +90,7 @@ const useStore = create( ) ) +// eslint-disable-next-line @typescript-eslint/no-unused-vars const state = useStore.getState() export type IStore = typeof state diff --git a/src/utils/MidiDevices/LaunchPadDevice.ts b/src/utils/MidiDevices/LaunchPadDevice.ts index e0ab3d37..4b6042c2 100644 --- a/src/utils/MidiDevices/LaunchPadDevice.ts +++ b/src/utils/MidiDevices/LaunchPadDevice.ts @@ -1,89 +1,129 @@ -import { lpsColors } from './LaunchpadS/lpsColors'; -import { lpColors } from './LaunchpadX/lpColors'; +/* eslint-disable no-unused-vars */ +import { lpsColors } from './LaunchpadS/lpsColors' +import { lpColors } from './LaunchpadX/lpColors' export interface LaunchpadXDevice { - buttonNumbers: number[][]; - colors: Record; - commonColors: Record; - globalColors: { - sceneActiveType: string; - sceneActiveColor: string; - sceneInactiveType: string; - sceneInactiveColor: string; - commandType: string; - commandColor: string; - }; - command: { - programmer: number[]; - live: number[]; - standalone: number[]; - daw: number[]; - ledOn: (number | string)[]; - ledFlash: (number | string)[]; - ledPulse: (number | string)[]; - rgb: (number | string)[]; - text: (number | string)[]; - stopText: number[]; - }; - fn: { - ledOff: (buttonNumber: number) => number[]; - ledOn: (buttonNumber: number, color: keyof typeof lpColors | number, mode?: 'solid' | 'flash' | 'pulse') => number[]; - ledSolid: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - ledFlash: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - ledPulse: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - rgb: (buttonNumber: number, r: number, g: number, b: number) => number[]; - text: (text: string, r: number, g: number, b: number, loop?: boolean, speed?: number) => number[]; - }; + buttonNumbers: number[][] + colors: Record + commonColors: Record + globalColors: { + sceneActiveType: string + sceneActiveColor: string + sceneInactiveType: string + sceneInactiveColor: string + commandType: string + commandColor: string + } + command: { + programmer: number[] + live: number[] + standalone: number[] + daw: number[] + ledOn: (number | string)[] + ledFlash: (number | string)[] + ledPulse: (number | string)[] + rgb: (number | string)[] + text: (number | string)[] + stopText: number[] + } + fn: { + ledOff: (buttonNumber: number) => number[] + ledOn: ( + buttonNumber: number, + color: keyof typeof lpColors | number, + mode?: 'solid' | 'flash' | 'pulse' + ) => number[] + ledSolid: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + ledFlash: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + ledPulse: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + rgb: (buttonNumber: number, r: number, g: number, b: number) => number[] + text: ( + text: string, + r: number, + g: number, + b: number, + loop?: boolean, + speed?: number + ) => number[] + } } export interface LaunchpadSDevice { - buttonNumbers: number[][]; - colors: Record; - commonColors: Record; - globalColors: { - sceneActiveType: string; - sceneActiveColor: string; - sceneInactiveType: string; - sceneInactiveColor: string; - commandType: string; - commandColor: string; - }; - fn: { - ledOff: (buttonNumber: number) => number[]; - ledOn: (buttonNumber: number, color: keyof typeof lpsColors | number) => number[]; - }; + buttonNumbers: number[][] + colors: Record + commonColors: Record + globalColors: { + sceneActiveType: string + sceneActiveColor: string + sceneInactiveType: string + sceneInactiveColor: string + commandType: string + commandColor: string + } + fn: { + ledOff: (buttonNumber: number) => number[] + ledOn: ( + buttonNumber: number, + color: keyof typeof lpsColors | number + ) => number[] + } } export interface LaunchpadMK2Device { - buttonNumbers: number[][]; - colors: Record; - commonColors: Record; - globalColors: { - sceneActiveType: string; - sceneActiveColor: string; - sceneInactiveType: string; - sceneInactiveColor: string; - commandType: string; - commandColor: string; - }; - command: { - programmer: number[]; - live: number[]; - standalone: number[]; - daw: number[]; - ledOn: (number | string)[]; - ledFlash: (number | string)[]; - ledPulse: (number | string)[]; - rgb: (number | string)[]; - }; - fn: { - ledOff: (buttonNumber: number) => number[]; - ledOn: (buttonNumber: number, color: keyof typeof lpColors | number, mode?: 'solid' | 'flash' | 'pulse') => number[]; - ledSolid: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - ledFlash: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - ledPulse: (buttonNumber: number, color: keyof typeof lpColors | number) => number[]; - rgb: (buttonNumber: number, r: number, g: number, b: number) => number[]; - }; + buttonNumbers: number[][] + colors: Record + commonColors: Record + globalColors: { + sceneActiveType: string + sceneActiveColor: string + sceneInactiveType: string + sceneInactiveColor: string + commandType: string + commandColor: string + } + command: { + programmer: number[] + live: number[] + standalone: number[] + daw: number[] + ledOn: (number | string)[] + ledFlash: (number | string)[] + ledPulse: (number | string)[] + rgb: (number | string)[] + } + fn: { + ledOff: (buttonNumber: number) => number[] + ledOn: ( + buttonNumber: number, + color: keyof typeof lpColors | number, + mode?: 'solid' | 'flash' | 'pulse' + ) => number[] + ledSolid: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + ledFlash: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + ledPulse: ( + buttonNumber: number, + color: keyof typeof lpColors | number + ) => number[] + rgb: (buttonNumber: number, r: number, g: number, b: number) => number[] + } } -export type LaunchpadDevice = LaunchpadXDevice | LaunchpadSDevice | LaunchpadMK2Device; +export type LaunchpadDevice = + | LaunchpadXDevice + | LaunchpadSDevice + | LaunchpadMK2Device diff --git a/src/utils/MidiDevices/LaunchpadMK2/LaunchpadMK2.ts b/src/utils/MidiDevices/LaunchpadMK2/LaunchpadMK2.ts index 0b458483..60988d53 100644 --- a/src/utils/MidiDevices/LaunchpadMK2/LaunchpadMK2.ts +++ b/src/utils/MidiDevices/LaunchpadMK2/LaunchpadMK2.ts @@ -2,44 +2,77 @@ import { LaunchpadMK2Device } from '../LaunchPadDevice' import { lpColors, lpCommonColors } from '../LaunchpadX/lpColors' export const LaunchpadMK2: LaunchpadMK2Device = { - buttonNumbers: [ - [11, 12, 13, 14, 15, 16, 17, 18, 19], - [21, 22, 23, 24, 25, 26, 27, 28, 29], - [31, 32, 33, 34, 35, 36, 37, 38, 39], - [41, 42, 43, 44, 45, 46, 47, 48, 49], - [51, 52, 53, 54, 55, 56, 57, 58, 59], - [61, 62, 63, 64, 65, 66, 67, 68, 69], - [71, 72, 73, 74, 75, 76, 77, 78, 79], - [81, 82, 83, 84, 85, 86, 87, 88, 89], - [-1, -1, -1, -1, -1, -1, -1, -1, -1], + buttonNumbers: [ + [11, 12, 13, 14, 15, 16, 17, 18, 19], + [21, 22, 23, 24, 25, 26, 27, 28, 29], + [31, 32, 33, 34, 35, 36, 37, 38, 39], + [41, 42, 43, 44, 45, 46, 47, 48, 49], + [51, 52, 53, 54, 55, 56, 57, 58, 59], + [61, 62, 63, 64, 65, 66, 67, 68, 69], + [71, 72, 73, 74, 75, 76, 77, 78, 79], + [81, 82, 83, 84, 85, 86, 87, 88, 89], + [-1, -1, -1, -1, -1, -1, -1, -1, -1] + ], + colors: lpColors, + commonColors: lpCommonColors, + globalColors: { + sceneActiveType: '90', + sceneActiveColor: '1E', + sceneInactiveType: '90', + sceneInactiveColor: '3C', + commandType: '90', + commandColor: '63' + }, + command: { + programmer: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x01, 0xf7], + live: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x00, 0xf7], + standalone: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x00, 0xf7], + daw: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x01, 0xf7], + ledOn: [0x90, 'buttonNumber', 'color'], + ledFlash: [0x91, 'buttonNumber', 'color'], + ledPulse: [0x92, 'buttonNumber', 'color'], + rgb: [240, 0, 32, 41, 2, 12, 3, 3, 'buttonNumber', 'r', 'g', 'b', 247] + }, + fn: { + ledOff: (buttonNumber: number) => [0x90, buttonNumber, 0x00], + ledOn: ( + buttonNumber: number, + color: keyof typeof lpColors | number, + mode: 'solid' | 'flash' | 'pulse' = 'solid' + ) => [ + mode === 'pulse' ? 0x92 : mode === 'flash' ? 0x91 : 0x90, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] ], - colors: lpColors, - commonColors: lpCommonColors, - globalColors: { - sceneActiveType: '90', - sceneActiveColor: '1E', - sceneInactiveType: '90', - sceneInactiveColor: '3C', - commandType: '90', - commandColor: '63', - }, - command: { - 'programmer': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x01, 0xF7], - 'live': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x00, 0xF7], - 'standalone': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x00, 0xF7], - 'daw': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x01, 0xF7], - 'ledOn': [0x90, "buttonNumber", "color"], - 'ledFlash': [0x91, "buttonNumber", "color"], - 'ledPulse': [0x92, "buttonNumber", "color"], - 'rgb': [240, 0, 32, 41, 2, 12, 3, 3, "buttonNumber", "r", "g", "b", 247] - }, - fn: { - 'ledOff': (buttonNumber: number) => [0x90, buttonNumber, 0x00], - 'ledOn': (buttonNumber: number, color: keyof typeof lpColors | number, mode: 'solid' | 'flash' | 'pulse' = 'solid') => [mode === 'pulse' ? 0x92 : mode === 'flash' ? 0x91 : 0x90, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledSolid': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x90, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledFlash': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x91, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledPulse': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x92, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'rgb': (buttonNumber: number, r: number, g: number, b: number) => [240, 0, 32, 41, 2, 12, 3, 3, buttonNumber, Math.floor(r/2), Math.floor(g/2), Math.floor(b/2), 247] - - } - } \ No newline at end of file + ledSolid: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x90, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + ledFlash: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x91, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + ledPulse: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x92, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + rgb: (buttonNumber: number, r: number, g: number, b: number) => [ + 240, + 0, + 32, + 41, + 2, + 12, + 3, + 3, + buttonNumber, + Math.floor(r / 2), + Math.floor(g / 2), + Math.floor(b / 2), + 247 + ] + } +} diff --git a/src/utils/MidiDevices/LaunchpadS/LaunchpadS.ts b/src/utils/MidiDevices/LaunchpadS/LaunchpadS.ts index b20b96d7..152c39de 100644 --- a/src/utils/MidiDevices/LaunchpadS/LaunchpadS.ts +++ b/src/utils/MidiDevices/LaunchpadS/LaunchpadS.ts @@ -3,7 +3,7 @@ import { lpsColors, lpsCommonColors } from './lpsColors' export const LaunchpadS: LaunchpadSDevice = { buttonNumbers: [ - [112, 113, 114, 115, 116, 117, 118, 119, 120], + [112, 113, 114, 115, 116, 117, 118, 119, 120], [96, 97, 98, 99, 100, 101, 102, 103, 104], [80, 81, 82, 83, 84, 85, 86, 87, 88], [64, 65, 66, 67, 68, 69, 70, 71, 72], @@ -11,7 +11,7 @@ export const LaunchpadS: LaunchpadSDevice = { [32, 33, 34, 35, 36, 37, 38, 39, 40], [16, 17, 18, 19, 20, 21, 22, 23, 24], [0, 1, 2, 3, 4, 5, 6, 7, 8], - [-1, -1, -1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1, -1, -1] ], colors: lpsColors, commonColors: lpsCommonColors, @@ -21,10 +21,14 @@ export const LaunchpadS: LaunchpadSDevice = { sceneInactiveType: '90', sceneInactiveColor: '0F', commandType: '90', - commandColor: '3E', + commandColor: '3E' }, fn: { - 'ledOff': (buttonNumber: number) => [0x90, buttonNumber, 0x0C], - 'ledOn': (buttonNumber: number, color: keyof typeof lpsColors | number ) => [0x90, buttonNumber, typeof color === 'number' ? color : lpsColors[color]], + ledOff: (buttonNumber: number) => [0x90, buttonNumber, 0x0c], + ledOn: (buttonNumber: number, color: keyof typeof lpsColors | number) => [ + 0x90, + buttonNumber, + typeof color === 'number' ? color : lpsColors[color] + ] } -} \ No newline at end of file +} diff --git a/src/utils/MidiDevices/LaunchpadS/lpsColors.ts b/src/utils/MidiDevices/LaunchpadS/lpsColors.ts index 84051a61..2e17b595 100644 --- a/src/utils/MidiDevices/LaunchpadS/lpsColors.ts +++ b/src/utils/MidiDevices/LaunchpadS/lpsColors.ts @@ -1,20 +1,20 @@ export const lpsColors = { - '#FF0000': 0x0F, - '#FFA500': 0x2F, - '#00FF00': 0x3C, - '#8B0000': 0x0D, - '#526F50': 0x1C, - '#FFFF00': 0x3E, - '#000000': 0x0C, - '#FF7F00': 0x3F, + '#FF0000': 0x0f, + '#FFA500': 0x2f, + '#00FF00': 0x3c, + '#8B0000': 0x0d, + '#526F50': 0x1c, + '#FFFF00': 0x3e, + '#000000': 0x0c, + '#FF7F00': 0x3f } export const lpsCommonColors = { - 'red': 0x0F, - 'orange': 0x2F, - 'lime': 0x3C, - 'darkred': 0x0D, - 'darkolivegreen': 0x1C, - 'yellow': 0x3E, - 'black': 0x0C, - 'darkorange': 0x3F, -} \ No newline at end of file + red: 0x0f, + orange: 0x2f, + lime: 0x3c, + darkred: 0x0d, + darkolivegreen: 0x1c, + yellow: 0x3e, + black: 0x0c, + darkorange: 0x3f +} diff --git a/src/utils/MidiDevices/LaunchpadX/LaunchpadX.ts b/src/utils/MidiDevices/LaunchpadX/LaunchpadX.ts index cc5b34cd..8bf6b498 100644 --- a/src/utils/MidiDevices/LaunchpadX/LaunchpadX.ts +++ b/src/utils/MidiDevices/LaunchpadX/LaunchpadX.ts @@ -1,50 +1,107 @@ import { LaunchpadXDevice } from '../LaunchPadDevice' import { lpColors, lpCommonColors } from './lpColors' - - export const LaunchpadX: LaunchpadXDevice = { - buttonNumbers: [ - [11, 12, 13, 14, 15, 16, 17, 18, 19], - [21, 22, 23, 24, 25, 26, 27, 28, 29], - [31, 32, 33, 34, 35, 36, 37, 38, 39], - [41, 42, 43, 44, 45, 46, 47, 48, 49], - [51, 52, 53, 54, 55, 56, 57, 58, 59], - [61, 62, 63, 64, 65, 66, 67, 68, 69], - [71, 72, 73, 74, 75, 76, 77, 78, 79], - [81, 82, 83, 84, 85, 86, 87, 88, 89], - [91, 92, 93, 94, 95, 96, 97, 98, 99], + buttonNumbers: [ + [11, 12, 13, 14, 15, 16, 17, 18, 19], + [21, 22, 23, 24, 25, 26, 27, 28, 29], + [31, 32, 33, 34, 35, 36, 37, 38, 39], + [41, 42, 43, 44, 45, 46, 47, 48, 49], + [51, 52, 53, 54, 55, 56, 57, 58, 59], + [61, 62, 63, 64, 65, 66, 67, 68, 69], + [71, 72, 73, 74, 75, 76, 77, 78, 79], + [81, 82, 83, 84, 85, 86, 87, 88, 89], + [91, 92, 93, 94, 95, 96, 97, 98, 99] + ], + colors: lpColors, + commonColors: lpCommonColors, + globalColors: { + sceneActiveType: 'rgb', + sceneActiveColor: 'rgb(0, 255, 0)', + sceneInactiveType: 'rgb', + sceneInactiveColor: 'rgb(255, 0, 0)', + commandType: 'rgb', + commandColor: 'rgb(255, 255, 0)' + }, + command: { + programmer: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x01, 0xf7], + live: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x0e, 0x00, 0xf7], + standalone: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x00, 0xf7], + daw: [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0c, 0x10, 0x01, 0xf7], + ledOn: [0x90, 'buttonNumber', 'color'], + ledFlash: [0x91, 'buttonNumber', 'color'], + ledPulse: [0x92, 'buttonNumber', 'color'], + rgb: [240, 0, 32, 41, 2, 12, 3, 3, 'buttonNumber', 'r', 'g', 'b', 247], + text: [ + 240, 0, 32, 41, 2, 12, 7, 1, 7, 0, 37, 72, 97, 99, 107, 101, 100, 32, 98, + 121, 32, 66, 108, 97, 100, 101, 33, 247 + ], + stopText: [240, 0, 32, 41, 2, 12, 7, 247] + }, + fn: { + ledOff: (buttonNumber: number) => [0x90, buttonNumber, 0x00], + ledOn: ( + buttonNumber: number, + color: keyof typeof lpColors | number, + mode: 'solid' | 'flash' | 'pulse' = 'solid' + ) => [ + mode === 'pulse' ? 0x92 : mode === 'flash' ? 0x91 : 0x90, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + ledSolid: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x90, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + ledFlash: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x91, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + ledPulse: (buttonNumber: number, color: keyof typeof lpColors | number) => [ + 0x92, + buttonNumber, + typeof color === 'number' ? color : lpColors[color] + ], + rgb: (buttonNumber: number, r: number, g: number, b: number) => [ + 240, + 0, + 32, + 41, + 2, + 12, + 3, + 3, + buttonNumber, + Math.floor(r / 2), + Math.floor(g / 2), + Math.floor(b / 2), + 247 ], - colors: lpColors, - commonColors: lpCommonColors, - globalColors: { - sceneActiveType: 'rgb', - sceneActiveColor: 'rgb(0, 255, 0)', - sceneInactiveType: 'rgb', - sceneInactiveColor: 'rgb(255, 0, 0)', - commandType: 'rgb', - commandColor: 'rgb(255, 255, 0)', - }, - command: { - 'programmer': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x01, 0xF7], - 'live': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x0E, 0x00, 0xF7], - 'standalone': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x00, 0xF7], - 'daw': [0xF0, 0x00, 0x20, 0x29, 0x02, 0x0C, 0x10, 0x01, 0xF7], - 'ledOn': [0x90, "buttonNumber", "color"], - 'ledFlash': [0x91, "buttonNumber", "color"], - 'ledPulse': [0x92, "buttonNumber", "color"], - 'rgb': [240, 0, 32, 41, 2, 12, 3, 3, "buttonNumber", "r", "g", "b", 247], - 'text': [240, 0, 32, 41, 2, 12, 7, 1, 7, 0, 37, 72, 97, 99, 107, 101, 100, 32, 98, 121, 32, 66, 108, 97, 100, 101, 33, 247], - 'stopText': [240, 0, 32, 41, 2, 12, 7, 247] - }, - fn: { - 'ledOff': (buttonNumber: number) => [0x90, buttonNumber, 0x00], - 'ledOn': (buttonNumber: number, color: keyof typeof lpColors | number, mode: 'solid' | 'flash' | 'pulse' = 'solid') => [mode === 'pulse' ? 0x92 : mode === 'flash' ? 0x91 : 0x90, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledSolid': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x90, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledFlash': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x91, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'ledPulse': (buttonNumber: number, color: keyof typeof lpColors | number ) => [0x92, buttonNumber, typeof color === 'number' ? color : lpColors[color]], - 'rgb': (buttonNumber: number, r: number, g: number, b: number) => [240, 0, 32, 41, 2, 12, 3, 3, buttonNumber, Math.floor(r/2), Math.floor(g/2), Math.floor(b/2), 247], - 'text': (text: string, r: number, g: number, b: number, loop?: boolean, speed: number = 7) => [240, 0, 32, 41, 2, 12, 7, loop ? 1 : 0, speed, 1, Math.floor(r/2), Math.floor(g/2), Math.floor(b/2), ...text.split('').map(char => char.charCodeAt(0)), 247], - - } - } \ No newline at end of file + text: ( + text: string, + r: number, + g: number, + b: number, + loop?: boolean, + speed: number = 7 + ) => [ + 240, + 0, + 32, + 41, + 2, + 12, + 7, + loop ? 1 : 0, + speed, + 1, + Math.floor(r / 2), + Math.floor(g / 2), + Math.floor(b / 2), + ...text.split('').map((char) => char.charCodeAt(0)), + 247 + ] + } +} diff --git a/src/utils/MidiDevices/LaunchpadX/lpColors.ts b/src/utils/MidiDevices/LaunchpadX/lpColors.ts index fca3919e..dc66fda3 100644 --- a/src/utils/MidiDevices/LaunchpadX/lpColors.ts +++ b/src/utils/MidiDevices/LaunchpadX/lpColors.ts @@ -1,140 +1,140 @@ export const lpCommonColors = { - 'red': 0x05, - 'orange': 0x09, - 'lime': 0x15, - 'darkred': 0x07, - 'darkolivegreen': 0x17, - 'yellow': 0x0d, - 'black': 0x00, - 'darkorange': 0x3c, + red: 0x05, + orange: 0x09, + lime: 0x15, + darkred: 0x07, + darkolivegreen: 0x17, + yellow: 0x0d, + black: 0x00, + darkorange: 0x3c } export const lpColors = { - '#616161': 0x00, - '#b3b3b3': 0x01, - '#dddddd': 0x02, - '#ffffff': 0x03, - '#ffb3b3': 0x04, - '#ff6161': 0x05, - '#dd6161': 0x06, - '#b36161': 0x07, - '#fff3d5': 0x08, - '#ffb361': 0x09, - '#dd8c61': 0x0a, - '#b37661': 0x0b, - '#ffeea1': 0x0c, - '#ffff61': 0x0d, - '#dddd61': 0x0e, - '#b3b361': 0x0f, - '#ddffa1': 0x10, - '#c2ff61': 0x11, - '#a1dd61': 0x12, - '#81b361': 0x13, - '#c2ffb3': 0x14, - '#61ff61': 0x15, - '#61dd61': 0x16, - '#61b361': 0x17, - '#c2ffc2': 0x18, - '#61ff8c': 0x19, - '#61dd76': 0x1a, - '#61b36b': 0x1b, - '#c2ffcc': 0x1c, - '#61ffcc': 0x1d, - '#61dda1': 0x1e, - '#61b381': 0x1f, - '#c2fff3': 0x20, - '#61ffe9': 0x21, - '#61ddc2': 0x22, - '#61b396': 0x23, - '#c2f3ff': 0x24, - '#61eeff': 0x25, - '#61c7dd': 0x26, - '#61a1b3': 0x27, - '#c2ddff': 0x28, - '#61c7ff': 0x29, - '#61a1dd': 0x2a, - '#6181b3': 0x2b, - '#a18cff': 0x2c, - '#6161ff': 0x2d, - '#6161dd': 0x2e, - '#6161b3': 0x2f, - '#ccb3ff': 0x30, - '#a161ff': 0x31, - '#8161dd': 0x32, - '#7661b3': 0x33, - '#ffb3ff': 0x34, - '#ff61ff': 0x35, - '#dd61dd': 0x36, - '#b361b3': 0x37, - '#ffb3d5': 0x38, - '#ff61c2': 0x39, - '#dd61a1': 0x3a, - '#b3618c': 0x3b, - '#ff7661': 0x3c, - '#e9b361': 0x3d, - '#ddc261': 0x3e, - '#a1a161': 0x3f, - '#61b261': 0x40, - '#61b38c': 0x41, - '#618cd5': 0x42, - '#6162ff': 0x43, - '#61b3b3': 0x44, - '#8c61f3': 0x45, - '#ccb3c2': 0x46, - '#8c7681': 0x47, - '#ff6261': 0x48, - '#f3ffa1': 0x49, - '#eefc61': 0x4a, - '#ccff61': 0x4b, - '#76dd61': 0x4c, - '#61ffcd': 0x4d, - '#61e9ff': 0x4e, - '#61a1ff': 0x4f, - '#8c61ff': 0x50, - '#cc61fc': 0x51, - '#ee8cdd': 0x52, - '#a17661': 0x53, - '#ffa161': 0x54, - '#cbe558': 0x55, - '#d5ff8c': 0x56, - '#61ff62': 0x57, - '#b3ffa1': 0x58, - '#ccfcd5': 0x59, - '#b3fff6': 0x5a, - '#cce4ff': 0x5b, - '#a1c2f6': 0x5c, - '#d5c2f9': 0x5d, - '#f98cff': 0x5e, - '#ff61cc': 0x5f, - '#ffc261': 0x60, - '#f3ee61': 0x61, - '#e3fe60': 0x62, - '#ddcc61': 0x63, - '#b3a161': 0x64, - '#61ba76': 0x65, - '#76c28c': 0x66, - '#8181a1': 0x67, - '#818ccc': 0x68, - '#ccaa81': 0x69, - '#dd6261': 0x6a, - '#f9b3a1': 0x6b, - '#f9ba76': 0x6c, - '#fff38c': 0x6d, - '#e9f9a1': 0x6e, - '#d5ee76': 0x6f, - '#8181a2': 0x70, - '#f9f9d5': 0x71, - '#ddfce4': 0x72, - '#e9e9ff': 0x73, - '#e4d5ff': 0x74, - '#b3b3b4': 0x75, - '#d5d5d5': 0x76, - '#f9ffff': 0x77, - '#e96161': 0x78, - '#aa6161': 0x79, - '#81f661': 0x7a, - '#61b461': 0x7b, - '#f3ee62': 0x7c, - '#b3a162': 0x7d, - '#eec261': 0x7e, - '#c27661': 0x7f, + '#616161': 0x00, + '#b3b3b3': 0x01, + '#dddddd': 0x02, + '#ffffff': 0x03, + '#ffb3b3': 0x04, + '#ff6161': 0x05, + '#dd6161': 0x06, + '#b36161': 0x07, + '#fff3d5': 0x08, + '#ffb361': 0x09, + '#dd8c61': 0x0a, + '#b37661': 0x0b, + '#ffeea1': 0x0c, + '#ffff61': 0x0d, + '#dddd61': 0x0e, + '#b3b361': 0x0f, + '#ddffa1': 0x10, + '#c2ff61': 0x11, + '#a1dd61': 0x12, + '#81b361': 0x13, + '#c2ffb3': 0x14, + '#61ff61': 0x15, + '#61dd61': 0x16, + '#61b361': 0x17, + '#c2ffc2': 0x18, + '#61ff8c': 0x19, + '#61dd76': 0x1a, + '#61b36b': 0x1b, + '#c2ffcc': 0x1c, + '#61ffcc': 0x1d, + '#61dda1': 0x1e, + '#61b381': 0x1f, + '#c2fff3': 0x20, + '#61ffe9': 0x21, + '#61ddc2': 0x22, + '#61b396': 0x23, + '#c2f3ff': 0x24, + '#61eeff': 0x25, + '#61c7dd': 0x26, + '#61a1b3': 0x27, + '#c2ddff': 0x28, + '#61c7ff': 0x29, + '#61a1dd': 0x2a, + '#6181b3': 0x2b, + '#a18cff': 0x2c, + '#6161ff': 0x2d, + '#6161dd': 0x2e, + '#6161b3': 0x2f, + '#ccb3ff': 0x30, + '#a161ff': 0x31, + '#8161dd': 0x32, + '#7661b3': 0x33, + '#ffb3ff': 0x34, + '#ff61ff': 0x35, + '#dd61dd': 0x36, + '#b361b3': 0x37, + '#ffb3d5': 0x38, + '#ff61c2': 0x39, + '#dd61a1': 0x3a, + '#b3618c': 0x3b, + '#ff7661': 0x3c, + '#e9b361': 0x3d, + '#ddc261': 0x3e, + '#a1a161': 0x3f, + '#61b261': 0x40, + '#61b38c': 0x41, + '#618cd5': 0x42, + '#6162ff': 0x43, + '#61b3b3': 0x44, + '#8c61f3': 0x45, + '#ccb3c2': 0x46, + '#8c7681': 0x47, + '#ff6261': 0x48, + '#f3ffa1': 0x49, + '#eefc61': 0x4a, + '#ccff61': 0x4b, + '#76dd61': 0x4c, + '#61ffcd': 0x4d, + '#61e9ff': 0x4e, + '#61a1ff': 0x4f, + '#8c61ff': 0x50, + '#cc61fc': 0x51, + '#ee8cdd': 0x52, + '#a17661': 0x53, + '#ffa161': 0x54, + '#cbe558': 0x55, + '#d5ff8c': 0x56, + '#61ff62': 0x57, + '#b3ffa1': 0x58, + '#ccfcd5': 0x59, + '#b3fff6': 0x5a, + '#cce4ff': 0x5b, + '#a1c2f6': 0x5c, + '#d5c2f9': 0x5d, + '#f98cff': 0x5e, + '#ff61cc': 0x5f, + '#ffc261': 0x60, + '#f3ee61': 0x61, + '#e3fe60': 0x62, + '#ddcc61': 0x63, + '#b3a161': 0x64, + '#61ba76': 0x65, + '#76c28c': 0x66, + '#8181a1': 0x67, + '#818ccc': 0x68, + '#ccaa81': 0x69, + '#dd6261': 0x6a, + '#f9b3a1': 0x6b, + '#f9ba76': 0x6c, + '#fff38c': 0x6d, + '#e9f9a1': 0x6e, + '#d5ee76': 0x6f, + '#8181a2': 0x70, + '#f9f9d5': 0x71, + '#ddfce4': 0x72, + '#e9e9ff': 0x73, + '#e4d5ff': 0x74, + '#b3b3b4': 0x75, + '#d5d5d5': 0x76, + '#f9ffff': 0x77, + '#e96161': 0x78, + '#aa6161': 0x79, + '#81f661': 0x7a, + '#61b461': 0x7b, + '#f3ee62': 0x7c, + '#b3a162': 0x7d, + '#eec261': 0x7e, + '#c27661': 0x7f } diff --git a/src/utils/MidiDevices/MidiDevices.ts b/src/utils/MidiDevices/MidiDevices.ts index e3320a79..d9888fa6 100644 --- a/src/utils/MidiDevices/MidiDevices.ts +++ b/src/utils/MidiDevices/MidiDevices.ts @@ -10,4 +10,4 @@ export const Launchpad = { export const MidiDevices = { Launchpad -} \ No newline at end of file +} diff --git a/src/utils/MidiDevices/colorHelper.ts b/src/utils/MidiDevices/colorHelper.ts index bab5ddb3..21e8894e 100644 --- a/src/utils/MidiDevices/colorHelper.ts +++ b/src/utils/MidiDevices/colorHelper.ts @@ -1,5 +1,7 @@ import { MidiDevices } from './MidiDevices' +export type IColor = keyof (typeof MidiDevices)['Launchpad']['X']['colors'] + // Helper function to zero-pad hex values export const zeroPadHex = (value: number | string | undefined) => { if (value === undefined) { @@ -14,7 +16,9 @@ export const zeroPadHex = (value: number | string | undefined) => { // Helper function to convert hex to HSL export const hexToHSL = (hex: string) => { - let r = 0, g = 0, b = 0 + let r = 0 + let g = 0 + let b = 0 if (hex.length === 4) { r = parseInt(hex[1] + hex[1], 16) g = parseInt(hex[2] + hex[2], 16) @@ -27,15 +31,24 @@ export const hexToHSL = (hex: string) => { r /= 255 g /= 255 b /= 255 - const max = Math.max(r, g, b), min = Math.min(r, g, b) - let h = 0, s = 0, l = (max + min) / 2 + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) + let h = 0 + let s = 0 + const l = (max + min) / 2 if (max !== min) { const d = max - min s = l > 0.5 ? d / (2 - max - min) : d / (max + min) switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break - case g: h = (b - r) / d + 2; break - case b: h = (r - g) / d + 4; break + case r: + h = (g - b) / d + (g < b ? 6 : 0) + break + case g: + h = (b - r) / d + 2 + break + case b: + h = (r - g) / d + 4 + break } h /= 6 } @@ -53,28 +66,32 @@ export const sortColorsByHSL = (colors: IColor[]) => { }) } -export type IColor = keyof typeof MidiDevices['Launchpad']['X']['colors'] - -export const rgbValues = (rgbString: string) => rgbString.match(/\d+/g)?.map(Number); +export const rgbValues = (rgbString: string) => + rgbString.match(/\d+/g)?.map(Number) export const sendMidiMessageHelper = ( - fn: typeof MidiDevices[keyof typeof MidiDevices][keyof typeof MidiDevices[keyof typeof MidiDevices]]['fn'], + fn: (typeof MidiDevices)[keyof typeof MidiDevices][keyof (typeof MidiDevices)[keyof typeof MidiDevices]]['fn'], output: any, buttonNumber: number, color: string, typeCommand: string, isActive: boolean -) => { +) => { if (!output || buttonNumber === -1 || Number.isNaN(buttonNumber)) { console.error('No MIDI output devices found') return } - // console.log(1,'rgb' in fn , color?.startsWith('rgb') , typeCommand === 'rgb') - if ('rgb' in fn && fn.rgb && color?.startsWith('rgb') && typeCommand === 'rgb') { + // console.log(1,'rgb' in fn , color?.startsWith('rgb') , typeCommand === 'rgb') + if ( + 'rgb' in fn && + fn.rgb && + color?.startsWith('rgb') && + typeCommand === 'rgb' + ) { const [r, g, b] = rgbValues(color) || (isActive ? [0, 255, 0] : [255, 0, 0]) output.send(fn.rgb(buttonNumber, r, g, b)) // console.log('rgb', buttonNumber, r, g, b) - } else { + } else { const colorValue = parseInt(color || (isActive ? '1E' : '3C'), 16) // console.log(2, colorValue, color) if (typeCommand === '91' && 'ledFlash' in fn) { @@ -85,4 +102,4 @@ export const sendMidiMessageHelper = ( output.send(fn.ledOn(buttonNumber, colorValue)) } } -} \ No newline at end of file +} diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 13239c90..c23fd26e 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -2,7 +2,7 @@ import { IMCell } from '../pages/Devices/EditVirtuals/EditMatrix/M.utils' -/* eslint-disable @typescript-eslint/indent */ +/* eslint-disable @/indent */ export const drawerWidth = 240 export const frontendConfig = 14 diff --git a/src/utils/useWakeLook.ts b/src/utils/useWakeLook.ts index 95addc4d..83840e40 100644 --- a/src/utils/useWakeLook.ts +++ b/src/utils/useWakeLook.ts @@ -1,32 +1,32 @@ -import { useState, useCallback } from 'react'; +import { useState, useCallback } from 'react' import { log } from './helpers' const useWakeLock = () => { - const [wakeLock, setWakeLock] = useState(null); + const [wakeLock, setWakeLock] = useState(null) const requestWakeLock = useCallback(async () => { try { - const wakeLockSentinel = await navigator.wakeLock.request('screen'); - setWakeLock(wakeLockSentinel); - log('successWakeLock on'); + const wakeLockSentinel = await navigator.wakeLock.request('screen') + setWakeLock(wakeLockSentinel) + log('successWakeLock on') } catch (err) { - console.error('Failed to acquire wake lock:', err); + console.error('Failed to acquire wake lock:', err) } - }, []); + }, []) const releaseWakeLock = useCallback(async () => { if (wakeLock) { try { - await wakeLock.release(); - log('successWakeLock off'); - setWakeLock(null); + await wakeLock.release() + log('successWakeLock off') + setWakeLock(null) } catch (err) { - console.error('Failed to release wake lock:', err); + console.error('Failed to release wake lock:', err) } } - }, [wakeLock]); + }, [wakeLock]) - return { requestWakeLock, releaseWakeLock }; -}; + return { requestWakeLock, releaseWakeLock } +} -export default useWakeLock; +export default useWakeLock