Spaces:
Paused
Paused
ptt panel
Browse files- web/src/components/PttPanel.jsx +15 -28
web/src/components/PttPanel.jsx
CHANGED
|
@@ -1,51 +1,38 @@
|
|
| 1 |
-
export default function PttPanel({
|
| 2 |
-
groups, floors, selected, setSelected,
|
| 3 |
-
onTalkStart, onTalkStop, talking, muted, setMuted,
|
| 4 |
-
}) {
|
| 5 |
const floor = selected != null ? floors[selected] : null;
|
| 6 |
-
const
|
| 7 |
|
| 8 |
return (
|
| 9 |
-
<section className="panel
|
| 10 |
<h2>Push to talk</h2>
|
| 11 |
<div className="chips">
|
| 12 |
{groups.map((g) => (
|
| 13 |
-
<button
|
| 14 |
-
|
| 15 |
-
className={`chip ${selected === g.id ? 'active' : ''}`}
|
| 16 |
-
style={{ '--c': g.color }}
|
| 17 |
-
onClick={() => setSelected(g.id)}
|
| 18 |
-
>
|
| 19 |
-
{g.name}{floors[g.id] ? ' ●' : ''}
|
| 20 |
</button>
|
| 21 |
))}
|
| 22 |
</div>
|
| 23 |
<div className="floor">
|
| 24 |
-
{floor ?
|
| 25 |
-
<span className="talking">🎙 {floor.name} is talking</span>
|
| 26 |
-
) : (
|
| 27 |
-
<span className="muted">Floor open</span>
|
| 28 |
-
)}
|
| 29 |
</div>
|
| 30 |
<button
|
| 31 |
-
className=
|
| 32 |
-
disabled={!
|
| 33 |
onMouseDown={onTalkStart}
|
| 34 |
onMouseUp={onTalkStop}
|
| 35 |
onMouseLeave={() => talking && onTalkStop()}
|
| 36 |
onTouchStart={(e) => { e.preventDefault(); onTalkStart(); }}
|
| 37 |
onTouchEnd={(e) => { e.preventDefault(); onTalkStop(); }}
|
| 38 |
>
|
| 39 |
-
{talking ? '●
|
| 40 |
</button>
|
| 41 |
-
<
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
</p>
|
| 45 |
-
<label className="muted small">
|
| 46 |
-
<input type="checkbox" style={{ width: 'auto' }} checked={muted} onChange={(e) => setMuted(e.target.checked)} />{' '}
|
| 47 |
-
Mute incoming audio
|
| 48 |
</label>
|
|
|
|
|
|
|
|
|
|
| 49 |
</section>
|
| 50 |
);
|
| 51 |
}
|
|
|
|
| 1 |
+
export default function PttPanel({ groups, floors, selected, onSelect, talking, muted, setMuted, onTalkStart, onTalkStop }) {
|
|
|
|
|
|
|
|
|
|
| 2 |
const floor = selected != null ? floors[selected] : null;
|
| 3 |
+
const canTalk = selected != null && (!floor || floor.memberId === 0);
|
| 4 |
|
| 5 |
return (
|
| 6 |
+
<section className="panel">
|
| 7 |
<h2>Push to talk</h2>
|
| 8 |
<div className="chips">
|
| 9 |
{groups.map((g) => (
|
| 10 |
+
<button key={g.id} className={`chip ${selected === g.id ? 'active' : ''}`} onClick={() => onSelect(g.id)}>
|
| 11 |
+
{g.name}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
</button>
|
| 13 |
))}
|
| 14 |
</div>
|
| 15 |
<div className="floor">
|
| 16 |
+
{floor ? <span className="talking">🎙 {floor.name} is talking</span> : 'Floor open'}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
</div>
|
| 18 |
<button
|
| 19 |
+
className={`ptt-btn ${talking ? 'talking' : ''}`}
|
| 20 |
+
disabled={!canTalk}
|
| 21 |
onMouseDown={onTalkStart}
|
| 22 |
onMouseUp={onTalkStop}
|
| 23 |
onMouseLeave={() => talking && onTalkStop()}
|
| 24 |
onTouchStart={(e) => { e.preventDefault(); onTalkStart(); }}
|
| 25 |
onTouchEnd={(e) => { e.preventDefault(); onTalkStop(); }}
|
| 26 |
>
|
| 27 |
+
{talking ? '● TRANSMITTING' : 'HOLD TO TALK'}
|
| 28 |
</button>
|
| 29 |
+
<label className="mute-row">
|
| 30 |
+
<input type="checkbox" checked={muted} onChange={(e) => setMuted(e.target.checked)} />
|
| 31 |
+
Mute incoming audio & alarms
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
</label>
|
| 33 |
+
<p className="muted" style={{ marginTop: 8 }}>
|
| 34 |
+
16 kHz PCM relayed over WebSocket. Hold to request the floor; release to yield it.
|
| 35 |
+
</p>
|
| 36 |
</section>
|
| 37 |
);
|
| 38 |
}
|