Spaces:
Paused
Paused
Download web/src/components/PttPanel.jsx from secutorpro/dispatch-console: direct link, hf CLI and curl.
- Browser
- Download file 1.5 kB
-
https://huggingface.co/spaces/secutorpro/dispatch-console/resolve/main/web/src/components/PttPanel.jsx
- Command line
-
hf download hf://spaces/secutorpro/dispatch-console/web/src/components/PttPanel.jsx
-
curl -L -o PttPanel.jsx https://huggingface.co/spaces/secutorpro/dispatch-console/resolve/main/web/src/components/PttPanel.jsx
1.5 kB
| export default function PttPanel({ groups, floors, selected, onSelect, talking, muted, setMuted, onTalkStart, onTalkStop }) { | |
| const floor = selected != null ? floors[selected] : null; | |
| const canTalk = selected != null && (!floor || floor.memberId === 0); | |
| return ( | |
| <section className="panel"> | |
| <h2>Push to talk</h2> | |
| <div className="chips"> | |
| {groups.map((g) => ( | |
| <button key={g.id} className={`chip ${selected === g.id ? 'active' : ''}`} onClick={() => onSelect(g.id)}> | |
| {g.name} | |
| </button> | |
| ))} | |
| </div> | |
| <div className="floor"> | |
| {floor ? <span className="talking">🎙 {floor.name} is talking</span> : 'Floor open'} | |
| </div> | |
| <button | |
| className={`ptt-btn ${talking ? 'talking' : ''}`} | |
| disabled={!canTalk} | |
| onMouseDown={onTalkStart} | |
| onMouseUp={onTalkStop} | |
| onMouseLeave={() => talking && onTalkStop()} | |
| onTouchStart={(e) => { e.preventDefault(); onTalkStart(); }} | |
| onTouchEnd={(e) => { e.preventDefault(); onTalkStop(); }} | |
| > | |
| {talking ? '● TRANSMITTING' : 'HOLD TO TALK'} | |
| </button> | |
| <label className="mute-row"> | |
| <input type="checkbox" checked={muted} onChange={(e) => setMuted(e.target.checked)} /> | |
| Mute incoming audio & alarms | |
| </label> | |
| <p className="muted" style={{ marginTop: 8 }}> | |
| 16 kHz PCM relayed over WebSocket. Hold to request the floor; release to yield it. | |
| </p> | |
| </section> | |
| ); | |
| } |