[style](trx-frontend-http): name and fence the three audio groups
CI / lint (push) Successful in 2m19s
CI / test (push) Successful in 8m23s
CI / frontend (push) Successful in 3m18s
CI / reuse (push) Successful in 3s

The row carries three unrelated things — how loud it is, whether there
is any audio at all, and how much is arriving — and only the middle one
was named.  Each is a group now: VOLUME over the two sliders, SQL on its
own switch, LEVEL over the meter, with a hairline between each.

The rules are drawn only while the row is one line, measured against the
row rather than the viewport: what fits depends on whether the rig
transmits and whether it has a squelch at all.  A rule divides what sits
either side of it, so once a group wraps the wrap is the division and
the rule would just be a mark at the start of a line — which is what it
was at 900px before this.  The labels carry the grouping on their own
below that width, and the groups stack whole on a phone.

Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
sjg
2026-08-04 07:46:56 +02:00
parent 33aa7b807c
commit 9f495021f0
2 changed files with 64 additions and 14 deletions
@@ -413,17 +413,23 @@ SPDX-License-Identifier: GPL-2.0-or-later
<div class="inline" style="gap: 0.6rem; flex-wrap: wrap; align-items: center;"> <div class="inline" style="gap: 0.6rem; flex-wrap: wrap; align-items: center;">
<button id="rx-audio-btn" type="button">Play Audio</button> <button id="rx-audio-btn" type="button">Play Audio</button>
<button id="tx-audio-btn" type="button">Transmit Audio</button> <button id="tx-audio-btn" type="button">Transmit Audio</button>
<span class="audio-group audio-volume-group">
<span class="audio-group-label">Volume</span>
<label class="vol-label">RX<input type="range" id="rx-vol" min="0" max="100" value="80" class="vol-slider" /><small class="vol-pct" id="rx-vol-pct">80%</small></label> <label class="vol-label">RX<input type="range" id="rx-vol" min="0" max="100" value="80" class="vol-slider" /><small class="vol-pct" id="rx-vol-pct">80%</small></label>
<label class="vol-label">TX<input type="range" id="tx-vol" min="0" max="100" value="80" class="vol-slider" /><small class="vol-pct" id="tx-vol-pct">80%</small></label> <label class="vol-label">TX<input type="range" id="tx-vol" min="0" max="100" value="80" class="vol-slider" /><small class="vol-pct" id="tx-vol-pct">80%</small></label>
</span>
<span class="sql-control" id="sdr-squelch-wrap" style="display:none;"> <span class="sql-control" id="sdr-squelch-wrap" style="display:none;">
<button id="sdr-squelch-toggle" type="button" class="sql-toggle" aria-pressed="false" title="Turn the squelch on or off"><span class="sql-state" id="sdr-squelch-state" data-state="off" aria-hidden="true"></span>SQL</button> <button id="sdr-squelch-toggle" type="button" class="sql-toggle" aria-pressed="false" title="Turn the squelch on or off"><span class="sql-state" id="sdr-squelch-state" data-state="off" aria-hidden="true"></span>SQL</button>
<label class="sql-db"><input type="number" id="sdr-squelch-db" min="-120" max="-30" step="1" value="-95" inputmode="numeric" aria-label="Squelch threshold in dB" /><span class="sql-db-unit">dB</span></label> <label class="sql-db"><input type="number" id="sdr-squelch-db" min="-120" max="-30" step="1" value="-95" inputmode="numeric" aria-label="Squelch threshold in dB" /><span class="sql-db-unit">dB</span></label>
<button id="sdr-squelch-auto" type="button" class="sql-auto-btn" title="Set the threshold just above the noise floor">Auto</button> <button id="sdr-squelch-auto" type="button" class="sql-auto-btn" title="Set the threshold just above the noise floor">Auto</button>
</span> </span>
<span class="audio-group audio-level-group">
<span class="audio-group-label">Level</span>
<div id="audio-level"> <div id="audio-level">
<div id="audio-level-fill"></div> <div id="audio-level-fill"></div>
</div> </div>
<small id="audio-status" style="min-width: 60px;">Off</small> <small id="audio-status">Off</small>
</span>
</div> </div>
</div> </div>
</div> </div>
@@ -1856,9 +1856,35 @@ small { color: var(--text-muted); }
font-size: 0.82rem; font-size: 0.82rem;
white-space: nowrap; white-space: nowrap;
} }
/* Fenced off from the volume controls beside it: squelch decides whether there /* The row carries three unrelated things — how loud, whether there is audio at
is audio at all, which is not the same kind of control as how loud it is. all, and how much is arriving — so each is named and fenced from the next.
The rule belongs to the block, so it leaves with it on rigs without one. */ Each rule belongs to the block that follows it, so it leaves when that block
does (the squelch is absent on rigs without one). */
.audio-group {
display: inline-flex;
align-items: center;
gap: 0.5rem;
min-width: 0;
}
.audio-volume-group {
flex: 0 1 auto;
}
.audio-level-group {
flex: 1 1 12rem;
min-width: 8rem;
}
.audio-group-label {
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted);
white-space: nowrap;
}
.audio-level-group #audio-status {
min-width: 3.4rem;
}
.audio-level-group::before,
.sql-control::before { .sql-control::before {
content: ""; content: "";
align-self: stretch; align-self: stretch;
@@ -1866,6 +1892,22 @@ small { color: var(--text-muted); }
min-height: 1.5rem; min-height: 1.5rem;
margin-inline: 0.5rem 0.6rem; margin-inline: 0.5rem 0.6rem;
background: color-mix(in srgb, var(--border-light) 65%, transparent); background: color-mix(in srgb, var(--border-light) 65%, transparent);
display: none;
}
/* Only while the row is one line. A rule divides what sits either side of it,
so once a group wraps onto its own line the wrap is the division and the
rule would just be a mark at the start of a line. Measured against the row,
not the viewport: what fits depends on whether the rig transmits and whether
it has a squelch at all. */
#audio-row .inline {
container-type: inline-size;
container-name: audio-row;
}
@container audio-row (min-width: 57rem) {
.audio-level-group::before,
.sql-control::before {
display: block;
}
} }
/* The name is the switch: one target instead of a label and a button that /* The name is the switch: one target instead of a label and a button that
said the same thing twice, with the dot carrying the state. */ said the same thing twice, with the dot carrying the state. */
@@ -4567,9 +4609,11 @@ body[data-operator-layout="broadcast"] #cw-bar-overlay {
/* Wider volume sliders for touch */ /* Wider volume sliders for touch */
.vol-slider { width: 100%; flex: 1 1 auto; } .vol-slider { width: 100%; flex: 1 1 auto; }
/* The row stacks at this width, so the line break already separates the .audio-group {
squelch from the volumes and the rule would just start a line. */ flex-wrap: wrap;
.sql-control::before { display: none; } width: 100%;
}
.audio-group-label { width: 100%; }
.vol-label { .vol-label {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
@@ -4589,8 +4633,8 @@ body[data-operator-layout="broadcast"] #cw-bar-overlay {
} }
#rx-audio-btn, #rx-audio-btn,
#tx-audio-btn, #tx-audio-btn,
#audio-level, .audio-volume-group,
#audio-status, .audio-level-group,
#sdr-squelch-wrap { #sdr-squelch-wrap {
grid-column: 1 / -1; grid-column: 1 / -1;
} }