Simple monitor for displaying MIDI status for digital pianos.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

84 linhas
2.8 KiB

  1. import Keyboard, {
  2. StyledNaturalKey,
  3. StyledAccidentalKey
  4. } from '@theoryofnekomata/react-musical-keyboard'
  5. import * as React from 'react'
  6. import { PedalBoard } from '../components/PedalBoard'
  7. import { Activity } from '../components/Activity'
  8. import { useMidi, useMidiActivity } from '../hooks/midi'
  9. import { RANGES } from '../../../common/config'
  10. import { useForm } from '../hooks/form'
  11. interface IndexPageProps {
  12. params: URLSearchParams
  13. }
  14. const IndexPage: React.FC<IndexPageProps> = ({ params: search }) => {
  15. const { handleAction } = useForm()
  16. const { midiAccess, lastStateChangeTimestamp: devicesLoadedTimestamp } = useMidi()
  17. const inputDevices = Array.from(midiAccess?.inputs.entries() ?? [])
  18. const queryDeviceKey = search.get('queryDeviceKey') || inputDevices?.[0]?.[0] || ''
  19. const currentDevice =
  20. typeof midiAccess?.inputs !== 'undefined' ? midiAccess.inputs.get(queryDeviceKey) : undefined
  21. const { keyChannels, unaCorda, isChannelActive, sustain, sostenuto } =
  22. useMidiActivity(currentDevice)
  23. const range = search.get('range') || RANGES['A0-C8']
  24. const [startKeyRaw, endKeyRaw] = range.split('|')
  25. const startKey = Number(startKeyRaw)
  26. const endKey = Number(endKeyRaw)
  27. return (
  28. <div
  29. className="flex flex-col items-center h-full w-full group relative select-none"
  30. key={devicesLoadedTimestamp}
  31. >
  32. <div className="absolute bottom-1 left-1">
  33. <Activity device={currentDevice} currentDeviceActive={isChannelActive} />
  34. </div>
  35. <div className="flex-auto relative w-full">
  36. <div
  37. className="absolute w-full h-full"
  38. style={{
  39. paddingRight: 'calc(var(--size-scale-factor) * 1px)'
  40. }}
  41. >
  42. <Keyboard
  43. key={range}
  44. height="100%"
  45. startKey={startKey}
  46. endKey={endKey}
  47. keyChannels={keyChannels}
  48. keyComponents={{
  49. natural: StyledNaturalKey,
  50. accidental: StyledAccidentalKey
  51. }}
  52. />
  53. </div>
  54. </div>
  55. <div className="flex sm:gap-16 w-full justify-between sm:justify-center items-center px-4 gap-4">
  56. <div className="w=0 flex-auto hidden sm:block" />
  57. <div className="flex-shrink-0 pt-2 pb-8">
  58. <PedalBoard unaCorda={unaCorda} sostenuto={sostenuto} sustain={sustain} />
  59. </div>
  60. <div className="w-0 flex-auto flex items-center justify-end opacity-0 group-hover:opacity-100 transition-opacity">
  61. <form className="contents" onSubmit={handleAction}>
  62. <button
  63. type="submit"
  64. name="action"
  65. value="showSettings"
  66. className="h-10 border rounded overflow-hidden px-4"
  67. >
  68. Settings
  69. </button>
  70. </form>
  71. </div>
  72. </div>
  73. </div>
  74. )
  75. }
  76. export default IndexPage