[fix](trx-frontend-http): let the decode lists fill their panel
FT8, FT4, FT2 and WSPR size their list against the panel with flex, and the sidebar layout made the panel a grid item aligned to the start of its row — sized to its own content. The lists collapsed to their 120px minimum with several hundred pixels of the page empty underneath. The panel stretches to the row now and the sidebar keeps its own height. The marine lists were sized a different way, by formula: 100vh minus a guess at everything above them. That guess stopped matching the moment the panel changed shape, so they left a few hundred pixels unused as well. They fill the panel like the rest now, and so does CW, which had a 360px ceiling. HF APRS had no container styling at all — no scroller, no frame, no height — so its packets ran down the page. It gets what the other packet lists have. The smoke test measures each list against its panel and requires it to scroll on its own. Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -2085,9 +2085,15 @@ small { color: var(--text-muted); }
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(8.5rem, 11rem) minmax(0, 1fr);
|
grid-template-columns: minmax(8.5rem, 11rem) minmax(0, 1fr);
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: start;
|
/* The panel takes the full height of the tab, which is what the decode
|
||||||
|
lists inside it size against: FT8, FT4, FT2 and WSPR fill their panel
|
||||||
|
with flex, so a panel sized to its own content collapsed them to their
|
||||||
|
120px minimum however much room was going spare. */
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
#tab-digital-modes > .sub-tab-bar {
|
#tab-digital-modes > .sub-tab-bar {
|
||||||
|
/* The list keeps its own height while the panel stretches. */
|
||||||
|
align-self: start;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: 0.12rem;
|
gap: 0.12rem;
|
||||||
@@ -2130,6 +2136,7 @@ small { color: var(--text-muted); }
|
|||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.sub-tab { flex-shrink: 0; background: transparent; border: none; border-bottom: 2px solid transparent; border-radius: 0; padding: 0.35rem 0.75rem; color: var(--text-muted); cursor: pointer; font-size: 0.85rem; height: auto; }
|
.sub-tab { flex-shrink: 0; background: transparent; border: none; border-bottom: 2px solid transparent; border-radius: 0; padding: 0.35rem 0.75rem; color: var(--text-muted); cursor: pointer; font-size: 0.85rem; height: auto; }
|
||||||
.sub-tab.active { border-bottom-color: var(--accent-green); color: var(--accent-green); font-weight: 600; }
|
.sub-tab.active { border-bottom-color: var(--accent-green); color: var(--accent-green); font-weight: 600; }
|
||||||
@@ -2816,23 +2823,26 @@ body.map-fake-fullscreen-active {
|
|||||||
#aprs-packets,
|
#aprs-packets,
|
||||||
#ais-messages,
|
#ais-messages,
|
||||||
#vdes-messages { max-height: 360px; overflow-y: auto; border: 1px solid var(--border-light); border-radius: 6px; background: var(--input-bg); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
|
#vdes-messages { max-height: 360px; overflow-y: auto; border: 1px solid var(--border-light); border-radius: 6px; background: var(--input-bg); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
|
||||||
#aprs-packets {
|
/* Fill the panel, the way the FT8, FT4, FT2 and WSPR lists do. These were
|
||||||
flex: 0 1 auto;
|
sized by formula against the viewport — 100vh minus a guess at everything
|
||||||
height: calc(100vh - 28rem);
|
above them — which stopped matching the moment the panel changed shape, and
|
||||||
min-height: 16rem;
|
left a few hundred pixels of the page empty under a scrolling list. */
|
||||||
max-height: calc(100vh - 28rem);
|
#aprs-packets,
|
||||||
|
#ais-messages,
|
||||||
|
#vdes-messages,
|
||||||
|
#hf-aprs-packets {
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-height: 12rem;
|
||||||
|
max-height: none;
|
||||||
}
|
}
|
||||||
#ais-messages {
|
/* HF APRS had no container styling at all: no scroller, no frame, no height —
|
||||||
flex: 0 1 auto;
|
its packets simply ran down the page. */
|
||||||
height: calc(100vh - 24rem);
|
#hf-aprs-packets {
|
||||||
min-height: 16rem;
|
overflow-y: auto;
|
||||||
max-height: calc(100vh - 24rem);
|
border: 1px solid var(--border-light);
|
||||||
}
|
border-radius: 6px;
|
||||||
#vdes-messages {
|
background: var(--input-bg);
|
||||||
flex: 0 1 auto;
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
height: calc(100vh - 24rem);
|
|
||||||
min-height: 16rem;
|
|
||||||
max-height: calc(100vh - 24rem);
|
|
||||||
}
|
}
|
||||||
.aprs-packet { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 0.82rem; padding: 0.45rem 0.55rem; border-bottom: 1px solid var(--border); line-height: 1.35; }
|
.aprs-packet { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 0.82rem; padding: 0.45rem 0.55rem; border-bottom: 1px solid var(--border); line-height: 1.35; }
|
||||||
.aprs-packet:last-child { border-bottom: none; }
|
.aprs-packet:last-child { border-bottom: none; }
|
||||||
@@ -3387,7 +3397,7 @@ body.map-fake-fullscreen-active {
|
|||||||
.cw-tone-picker-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.35rem; color: var(--text-muted); font-size: 0.78rem; }
|
.cw-tone-picker-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.35rem; color: var(--text-muted); font-size: 0.78rem; }
|
||||||
#cw-tone-waterfall { width: 100%; height: 56px; display: block; border-radius: 6px; background: linear-gradient(180deg, rgba(8, 14, 18, 0.92), rgba(18, 28, 36, 0.98)); cursor: crosshair; }
|
#cw-tone-waterfall { width: 100%; height: 56px; display: block; border-radius: 6px; background: linear-gradient(180deg, rgba(8, 14, 18, 0.92), rgba(18, 28, 36, 0.98)); cursor: crosshair; }
|
||||||
.cw-tone-picker.is-auto #cw-tone-waterfall { cursor: not-allowed; }
|
.cw-tone-picker.is-auto #cw-tone-waterfall { cursor: not-allowed; }
|
||||||
#cw-output { max-height: 360px; overflow-y: auto; border: 1px solid var(--border-light); border-radius: 6px; background: var(--input-bg); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 0.85rem; padding: 0.4rem 0.5rem; min-height: 60px; white-space: pre-wrap; word-break: break-all; }
|
#cw-output { flex: 1 1 0; max-height: none; overflow-y: auto; border: 1px solid var(--border-light); border-radius: 6px; background: var(--input-bg); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 0.85rem; padding: 0.4rem 0.5rem; min-height: 60px; white-space: pre-wrap; word-break: break-all; }
|
||||||
.cw-line { line-height: 1.5; }
|
.cw-line { line-height: 1.5; }
|
||||||
.cw-signal-on { width: 10px; height: 10px; border-radius: 50%; background: var(--accent-green); box-shadow: 0 0 6px var(--accent-green); flex-shrink: 0; }
|
.cw-signal-on { width: 10px; height: 10px; border-radius: 50%; background: var(--accent-green); box-shadow: 0 0 6px var(--accent-green); flex-shrink: 0; }
|
||||||
.cw-signal-off { width: 10px; height: 10px; border-radius: 50%; background: var(--border-light); flex-shrink: 0; }
|
.cw-signal-off { width: 10px; height: 10px; border-radius: 50%; background: var(--border-light); flex-shrink: 0; }
|
||||||
@@ -4006,14 +4016,10 @@ body[data-operator-layout="broadcast"] #cw-bar-overlay {
|
|||||||
#subtab-aprs {
|
#subtab-aprs {
|
||||||
min-height: calc(100vh - 14rem);
|
min-height: calc(100vh - 14rem);
|
||||||
}
|
}
|
||||||
#aprs-packets {
|
#aprs-packets,
|
||||||
min-height: calc(100vh - 26rem);
|
#ais-messages,
|
||||||
}
|
|
||||||
#ais-messages {
|
|
||||||
min-height: calc(100vh - 22rem);
|
|
||||||
}
|
|
||||||
#vdes-messages {
|
#vdes-messages {
|
||||||
min-height: calc(100vh - 22rem);
|
min-height: 60vh;
|
||||||
}
|
}
|
||||||
.aprs-details-grid {
|
.aprs-details-grid {
|
||||||
grid-template-columns: minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
|||||||
@@ -47,6 +47,29 @@ try {
|
|||||||
assert.ok(digital.panelBesideSidebar, "the decoder panel does not sit beside the sidebar");
|
assert.ok(digital.panelBesideSidebar, "the decoder panel does not sit beside the sidebar");
|
||||||
assert.deepEqual(digital.panelsShown, ["subtab-ft8"], `panels shown: ${JSON.stringify(digital.panelsShown)}`);
|
assert.deepEqual(digital.panelsShown, ["subtab-ft8"], `panels shown: ${JSON.stringify(digital.panelsShown)}`);
|
||||||
assert.ok(digital.decoders >= 10, `only ${digital.decoders} decoders in the sidebar`);
|
assert.ok(digital.decoders >= 10, `only ${digital.decoders} decoders in the sidebar`);
|
||||||
|
|
||||||
|
// Each decoder's list fills its panel. FT8, FT4, FT2 and WSPR size against
|
||||||
|
// the panel with flex, so a panel sized to its own content collapsed them to
|
||||||
|
// their 120px minimum with the rest of the page left empty; the marine lists
|
||||||
|
// were sized by a viewport formula that stopped matching when the panel
|
||||||
|
// changed shape.
|
||||||
|
for (const [subtab, list] of [["ft8", "ft8-messages"], ["wspr", "wspr-messages"],
|
||||||
|
["ais", "ais-messages"], ["aprs", "aprs-packets"], ["hf-aprs", "hf-aprs-packets"]]) {
|
||||||
|
await page.locator(`.sub-tab[data-subtab="${subtab}"]`).click();
|
||||||
|
await page.waitForTimeout(150);
|
||||||
|
const filled = await page.evaluate((id) => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
const panel = element.closest(".sub-tab-panel");
|
||||||
|
return {
|
||||||
|
list: Math.round(element.getBoundingClientRect().height),
|
||||||
|
panel: Math.round(panel.getBoundingClientRect().height),
|
||||||
|
scrolls: getComputedStyle(element).overflowY,
|
||||||
|
};
|
||||||
|
}, list);
|
||||||
|
assert.ok(filled.list > filled.panel * 0.6,
|
||||||
|
`${subtab}: the list is ${filled.list}px in a ${filled.panel}px panel`);
|
||||||
|
assert.equal(filled.scrolls, "auto", `${subtab}: the list does not scroll on its own`);
|
||||||
|
}
|
||||||
await page.locator('.tab[data-tab="main"]').click();
|
await page.locator('.tab[data-tab="main"]').click();
|
||||||
await page.waitForTimeout(200);
|
await page.waitForTimeout(200);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user