From 86a09a9fb1a304e53dd142125c90ec171253fa37 Mon Sep 17 00:00:00 2001 From: YeonV Date: Fri, 4 Oct 2024 02:54:46 +0200 Subject: [PATCH] Fix MIDI-Scenes. Add custom midi button mapping --- .../Dialogs/SceneDialogs/EditSceneDialog.tsx | 43 +---- src/components/Midi/LaunchpadButton.tsx | 54 +++++-- src/components/Midi/LaunchpadButtonMap.tsx | 87 +++++----- src/components/Midi/MidiListener.tsx | 151 ++++++++++-------- src/store/ui/storeMidi.tsx | 7 +- 5 files changed, 177 insertions(+), 165 deletions(-) diff --git a/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx b/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx index a8c7dd2d..9ccdb9ba 100644 --- a/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx +++ b/src/components/Dialogs/SceneDialogs/EditSceneDialog.tsx @@ -29,7 +29,6 @@ import { Autocomplete } from '@mui/material' import { Clear, Undo, NavigateBefore, MusicNote } from '@mui/icons-material' -import { WebMidi, Input, NoteMessageEvent } from 'webmidi' import { useDropzone } from 'react-dropzone' import isElectron from 'is-electron' import { filterKeys, ordered } from '../../../utils/helpers' @@ -76,7 +75,7 @@ const EditSceneDialog = () => { const getUserPresets = useStore((state) => state.getUserPresets) const getImage = useStore((state) => state.getImage) const [imageData, setImageData] = useState(null) - const midiInput = useStore((state) => state.midiInput) + const midiEvent = useStore((state) => state.midiEvent) const getFullConfig = useStore((state) => state.getFullConfig) @@ -227,34 +226,12 @@ const EditSceneDialog = () => { }, [open]) useEffect(() => { - if (features.scenemidi) { - const handleMidiEvent = (input: Input, event: NoteMessageEvent) => { + if (features.scenemidi && midiEvent.button > -1) { setMIDIActivate( - `${input.name} Note: ${event.note.identifier} buttonNumber: ${event.note.number}` + `${midiEvent.name} Note: ${midiEvent.note} buttonNumber: ${midiEvent.button}` ) - } - WebMidi.enable({ - callback(err: Error) { - if (err) { - console.error('WebMidi could not be enabled:', err) - } else { - const { inputs } = WebMidi - if (inputs.length > 0) { - inputs.forEach((input: Input) => { - if (midiInput === input.name) { - return input.addListener('noteon', (event: NoteMessageEvent) => { - handleMidiEvent(input, event) - }) - } - } - ) - } - } - } - }) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [midiEvent]) const renderPresets = ( current_ledfx_presets: any, @@ -665,7 +642,7 @@ const EditSceneDialog = () => { ) : ( <> )} - {features && features.scenemidi && WebMidi.inputs.length > 0 ? ( + {features && features.scenemidi ? ( <> @@ -771,15 +748,6 @@ const EditSceneDialog = () => { } /> - {/* setMIDIActivate('')} - avatar={ - - {/\((.*?)\)/.exec(midiActivate)?.[1]} - - } - /> */} { } /> setMIDIActivate('')} label={ midiActivate ?.split('buttonNumber: ')[1] diff --git a/src/components/Midi/LaunchpadButton.tsx b/src/components/Midi/LaunchpadButton.tsx index 3c2305f2..7f47dfac 100644 --- a/src/components/Midi/LaunchpadButton.tsx +++ b/src/components/Midi/LaunchpadButton.tsx @@ -1,12 +1,13 @@ import Button from '@mui/material/Button' import DialogTitle from '@mui/material/DialogTitle' import Dialog from '@mui/material/Dialog' -import { darken, DialogContent, Divider, MenuItem, Select, Stack, Typography } from '@mui/material' -import { useState } from 'react' +import { darken, DialogContent, Divider, IconButton, MenuItem, Select, Stack, TextField, Typography } from '@mui/material' +import { useEffect, useState } from 'react' import LpColorPicker from './LpColorPicker' import Assign from '../Gamepad/Assign' import useStore from '../../store/useStore' import { getColorFromValue } from './lpColors' +import { Autorenew, Save } from '@mui/icons-material' const LaunchpadButton = ({ buttonNumber, @@ -23,8 +24,8 @@ const LaunchpadButton = ({ bgColor?: string }) => { const [open, setOpen] = useState(false) - const midiMapping = useStore((state) => state.midiMapping) + const midiEvent = useStore((state) => state.midiEvent) const setMidiMapping = useStore((state) => state.setMidiMapping) const midiSceneInactiveColor = useStore((state) => state.midiColors.sceneInactiveColor) const midiSceneActiveColor = useStore((state) => state.midiColors.sceneActiveColor) @@ -41,6 +42,17 @@ const LaunchpadButton = ({ setOpen(false) } + const currentMapping = midiMapping[0][buttonNumber] || {}; + + const [midiButtonNumber, setMidiButtonNumber] = useState(currentMapping.buttonNumber || 0) + const [midiRecord, setMidiRecord] = useState(false) + + useEffect(() => { + if (midiRecord && midiEvent.button > -1) { + setMidiButtonNumber(midiEvent.button) + } + }, [midiEvent.button]) + return (