()
| 12 | import { VideoPane } from "./components/VideoPane.js"; |
| 13 | |
| 14 | export function Tracker() { |
| 15 | const { stream, conn } = useTracker(); |
| 16 | const { state, config } = stream; |
| 17 | |
| 18 | if (!state || !config) { |
| 19 | return ( |
| 20 | <div className="loading"> |
| 21 | <div className={`dot ${stream.connected ? "ok" : "bad"}`} /> |
| 22 | {stream.connected ? "waiting for tracker state…" : "connecting to tracker…"} |
| 23 | </div> |
| 24 | ); |
| 25 | } |
| 26 | |
| 27 | const pick = (hex: string | null) => conn.send({ type: "manualTarget", hex }); |
| 28 | |
| 29 | return ( |
| 30 | <div className="tracker"> |
| 31 | <StatusBar state={state} connected={stream.connected} conn={conn} /> |
| 32 | |
| 33 | <main className="layout"> |
| 34 | <section className="left"> |
| 35 | <VideoPane state={state} config={config} connected={stream.connected} /> |
| 36 | <RecordPanel state={state} connected={stream.connected} /> |
| 37 | <div className="bottom-row"> |
| 38 | <JogPad conn={conn} /> |
| 39 | {state.mode === "calibrate" ? ( |
| 40 | <CalibrationWizard state={state} conn={conn} /> |
| 41 | ) : ( |
| 42 | <ConfigPanel config={config} conn={conn} /> |
| 43 | )} |
| 44 | </div> |
| 45 | </section> |
| 46 | |
| 47 | <aside className="right"> |
| 48 | <SkyPolar state={state} config={config} onPick={(hex) => pick(hex)} /> |
| 49 | <TargetTable state={state} onPick={pick} /> |
| 50 | </aside> |
| 51 | </main> |
| 52 | </div> |
| 53 | ); |
| 54 | } |
nothing calls this directly
no test coverage detected