|
- import Keyboard, {
- StyledNaturalKey,
- StyledAccidentalKey
- } from '@theoryofnekomata/react-musical-keyboard'
- import * as React from 'react'
- import { PedalBoard } from '../components/PedalBoard'
- import { Activity } from '../components/Activity'
- import { useMidi, useMidiActivity } from '../hooks/midi'
- import { RANGES } from '../../../common/config'
- import { useForm } from '../hooks/form'
-
- interface IndexPageProps {
- params: URLSearchParams
- }
-
- const IndexPage: React.FC<IndexPageProps> = ({ params: search }) => {
- const { handleAction } = useForm()
-
- const { midiAccess, lastStateChangeTimestamp: devicesLoadedTimestamp } = useMidi()
- const inputDevices = Array.from(midiAccess?.inputs.entries() ?? [])
- const queryDeviceKey = search.get('queryDeviceKey') || inputDevices?.[0]?.[0] || ''
- const currentDevice =
- typeof midiAccess?.inputs !== 'undefined' ? midiAccess.inputs.get(queryDeviceKey) : undefined
-
- const { keyChannels, unaCorda, isChannelActive, sustain, sostenuto } =
- useMidiActivity(currentDevice)
-
- const range = search.get('range') || RANGES['A0-C8']
- const [startKeyRaw, endKeyRaw] = range.split('|')
- const startKey = Number(startKeyRaw)
- const endKey = Number(endKeyRaw)
-
- return (
- <div
- className="flex flex-col items-center h-full w-full group relative select-none"
- key={devicesLoadedTimestamp}
- >
- <div className="absolute bottom-1 left-1">
- <Activity device={currentDevice} currentDeviceActive={isChannelActive} />
- </div>
- <div className="flex-auto relative w-full">
- <div
- className="absolute w-full h-full"
- style={{
- paddingRight: 'calc(var(--size-scale-factor) * 1px)'
- }}
- >
- <Keyboard
- key={range}
- height="100%"
- startKey={startKey}
- endKey={endKey}
- keyChannels={keyChannels}
- keyComponents={{
- natural: StyledNaturalKey,
- accidental: StyledAccidentalKey
- }}
- />
- </div>
- </div>
- <div className="flex sm:gap-16 w-full justify-between sm:justify-center items-center px-4 gap-4">
- <div className="w=0 flex-auto hidden sm:block" />
- <div className="flex-shrink-0 pt-2 pb-8">
- <PedalBoard unaCorda={unaCorda} sostenuto={sostenuto} sustain={sustain} />
- </div>
- <div className="w-0 flex-auto flex items-center justify-end opacity-0 group-hover:opacity-100 transition-opacity">
- <form className="contents" onSubmit={handleAction}>
- <button
- type="submit"
- name="action"
- value="showSettings"
- className="h-10 border rounded overflow-hidden px-4"
- >
- Settings
- </button>
- </form>
- </div>
- </div>
- </div>
- )
- }
-
- export default IndexPage
|