import React from "react"; import { html } from "htm"; import * as Store from "./store.js"; import * as Tone from "./tone.js"; /** @typedef {({children}:{children?:preact.ComponentChildren})=>preact.VNode} BasicElement */ /** @type {({children, icon, light, disabled, inactive, onClick, classes}:{children:preact.VNode, icon?:preact.VNode, light:boolean, disabled:boolean, inactive:boolean, onClick:()=>void, classes?:string})=>preact.VNode} */ export function Button({children, icon, light, disabled, inactive, onClick, classes}) { const [FlashGet, FlashSet] = React.useState(0); const handleClick =()=> { if(inactive||disabled){ return; } FlashSet(FlashGet+1); onClick(); }; return html` `; } /** @type {BasicElement} */ export const Select =()=> { const [State, Dispatch] = Store.Consumer(); const grade = Store.Grade(State.Live.Test); /** @type {(e:Event)=>void} */ const handleChange =(e)=> Dispatch({Name:"Test", Data:parseInt(/** @type {HTMLSelectElement}*/(e.target).value)}); return html`
`; } /** @type {BasicElement} */ export const Controls =()=> { const [State, Dispatch] = Store.Consumer(); const [pulsedGet, pulsedSet] = React.useState(true); const [playGet, playSet] = React.useState(0); React.useEffect(()=> { /** @type {number|undefined} */ let timer; if(playGet == 1) { const volNorm = (State.Stim.Value-State.Stim.Min)/(State.Stim.Max-State.Stim.Min); Tone.Play(!pulsedGet, State.Chan.Value, Store.ColumnMapping[State.Freq.Value][0], (volNorm*0.8) + 0.1); if(State.Live.Freq) { const testMark = State.Live.Freq[/** @type {"TestL"|"TestR"}*/(`Test${State.Chan.Value ? "R":"L"}`)]; const handler = testMark.Stim <= State.Stim.Value ? ()=>{playSet(2)} : ()=>{playSet(0)} timer = setTimeout(handler, 800 + Math.random()*1300); } } return () => clearTimeout(timer); }, [playGet]); const classTitle = "flex-1 text-sm" return html` `; }; /** @type {BasicElement} */ export const Audiogram =()=> { const [State] = Store.Consumer(); const testMarksL = State.Draw.TestL.Points.map(p=>html`<${Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${false}/>`); const userMarksL = State.Draw.UserL.Points.map(p=>html`<${Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${false} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); const testMarksR = State.Draw.TestR.Points.map(p=>html`<${Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${true} />`); const userMarksR = State.Draw.UserR.Points.map(p=>html`<${Mark} x=${p.X} y=${p.Y} response=${p.Mark?.Resp} right=${true} classes=${State.Live.Mark == p.Mark ? "stroke-bold":""}/>`); const testLinesL = State.Draw.TestL.Paths.map( p=>html`