secutorpro commited on
Commit
62c7dbc
·
verified ·
1 Parent(s): 08a174c

ptt panel

Browse files
Files changed (1) hide show
  1. 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 busy = floor && floor.memberId !== 0;
7
 
8
  return (
9
- <section className="panel ptt-panel">
10
  <h2>Push to talk</h2>
11
  <div className="chips">
12
  {groups.map((g) => (
13
- <button
14
- key={g.id}
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="ptt"
32
- disabled={!selected || busy}
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 ? '● TALKING' : 'HOLD TO TALK'}
40
  </button>
41
- <p className="muted small">
42
- Select a talkgroup, then hold the button. One speaker per group —
43
- the floor indicator shows who has it.
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
  }