Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / assets / coverity.svg
Author[]Andy Green <andy@warmcat.com> 2026-07-27 07:21 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-07-29 03:47 UTC
Treee46138bdf3302fcb8ae83a6c8c24365b1d288fd7   Raw Patch
 
hide-builders
hide-builders
diff --git a/assets/index.html b/assets/index.html index c9cf83e..a907111 100644 --- a/assets/index.html +++ b/assets/index.html @@ -23,14 +23,6 @@ </div> <div id="lws-login-status-container" class="login-status-container"></div> </div> - <div id="sai_power_overview" class="power-overview hidden"> - <div class="power-text">Total Power: <span id="sai_total_power">0W</span></div> - <canvas id="sai_power_graph" class="power-graph" height="20" width="150"></canvas> - </div> - <div id="sai_builders"></div> - </div> - <div class="resizer" id="resizer"></div> - <div class="right-pane"> <div class="event-decals-section" id="sai_event_decals"></div> <div class="tasks-section" id="sai_event_tasks"></div> <div class="resizer-h" id="resizer_h"></div> @@ -45,6 +37,14 @@ </div> </div> </div> + <div class="resizer" id="resizer"></div> + <div class="right-pane"> + <div id="sai_power_overview" class="power-overview hidden"> + <div class="power-text">Total Power: <span id="sai_total_power">0W</span></div> + <canvas id="sai_power_graph" class="power-graph" height="20" width="150"></canvas> + </div> + <div id="sai_builders"></div> + </div> </div> </body> </html> diff --git a/assets/sai.css b/assets/sai.css index f63aa1a..d1be255 100644 --- a/assets/sai.css +++ b/assets/sai.css @@ -1044,13 +1044,17 @@ body.overlay-active { height: 100vh; } .left-pane { - flex: 0 0 30%; - overflow: auto; - flex-shrink: 0; + flex: 1; + display: flex; + flex-direction: column; + height: 100vh; + overflow: hidden; } .right-pane { - flex-grow: 1; - overflow: auto; + flex: 0 0 0px; + overflow-x: hidden; + overflow-y: auto; + flex-shrink: 0; } .resizer { width: 5px; diff --git a/assets/sai.js b/assets/sai.js index f399d40..69cf70b 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -1586,17 +1586,20 @@ function selectEvent(uuid) { tfirst = 0; lli = 1; last_log_timestamp = 0; + } - var par = new URLSearchParams(window.location.search); + var par = new URLSearchParams(window.location.search); + par.set("event", uuid); + if (!hasTask) { par.delete("task"); par.delete("run"); - var qs = par.toString(); - var path = window.location.pathname; - if (!path.endsWith('/') && !path.endsWith('index.html')) { - path += '/'; - } - window.history.pushState({}, "", path + (qs ? ("?" + qs) : "")); } + var qs = par.toString(); + var path = window.location.pathname; + if (!path.endsWith('/') && !path.endsWith('index.html')) { + path += '/'; + } + window.history.pushState({}, "", path + (qs ? ("?" + qs) : "")); // Highlight card var container = document.getElementById("sai_event_decals"); @@ -2519,6 +2522,13 @@ function ws_open_sai() } document.body.classList.remove("overlay-active"); + let savedRightPaneFlex = localStorage.getItem('sai-right-pane-flex'); + let initialVisible = 0; + if (savedRightPaneFlex && parseInt(savedRightPaneFlex.replace(/[^0-9-]/g, '')) > 0) { + initialVisible = 1; + } + sai.send(JSON.stringify({ schema: "com.warmcat.sai.builder_visibility", visible: initialVisible })); + var par = new URLSearchParams(window.location.search), tid, eid, run_idx; tid = par.get('task'); @@ -3601,11 +3611,11 @@ window.addEventListener("load", function() { } }); - const savedFlex = localStorage.getItem('sai-left-pane-flex'); + const savedFlex = localStorage.getItem('sai-right-pane-flex'); if (savedFlex) { - const leftPane = document.querySelector('.left-pane'); - if (leftPane) { - leftPane.style.flex = savedFlex; + const rightPane = document.querySelector('.right-pane'); + if (rightPane) { + rightPane.style.flex = savedFlex; } } @@ -3791,49 +3801,64 @@ window.addEventListener("load", function() { }); const resizer = document.getElementById('resizer'); if (resizer) { - const leftPane = resizer.previousElementSibling; + const rightPane = resizer.nextElementSibling; let x = 0; - let leftWidth = 0; + let rightWidth = 0; + let lastVisible = -1; const onMouseMove = (e) => { - const dx = e.clientX - x; - const newLeftWidth = leftWidth + dx; - leftPane.style.flex = `0 0 ${newLeftWidth}px`; + const dx = x - e.clientX; + let newRightWidth = rightWidth + dx; + if (newRightWidth < 20) newRightWidth = 0; + rightPane.style.flex = `0 0 ${newRightWidth}px`; + let visible = newRightWidth > 0 ? 1 : 0; + if (visible !== lastVisible) { + lastVisible = visible; + sai.send(JSON.stringify({ schema: "com.warmcat.sai.builder_visibility", visible: visible })); + } }; const onMouseUp = () => { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); - localStorage.setItem('sai-left-pane-flex', leftPane.style.flex); + localStorage.setItem('sai-right-pane-flex', rightPane.style.flex); }; const onMouseDown = (e) => { x = e.clientX; - leftWidth = leftPane.getBoundingClientRect().width; + rightWidth = rightPane.getBoundingClientRect().width; + lastVisible = rightWidth > 0 ? 1 : 0; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }; const onTouchMove = (e) => { if (e.touches.length === 1) { - const dx = e.touches[0].clientX - x; - const newLeftWidth = leftWidth + dx; - leftPane.style.flex = `0 0 ${newLeftWidth}px`; + const dx = x - e.touches[0].clientX; + let newRightWidth = rightWidth + dx; + if (newRightWidth < 20) newRightWidth = 0; + rightPane.style.flex = `0 0 ${newRightWidth}px`; e.preventDefault(); + let visible = newRightWidth > 0 ? 1 : 0; + if (visible !== lastVisible) { + lastVisible = visible; + sai.send(JSON.stringify({ schema: "com.warmcat.sai.builder_visibility", visible: visible })); + } } }; const onTouchEnd = () => { document.removeEventListener('touchmove', onTouchMove); document.removeEventListener('touchend', onTouchEnd); - localStorage.setItem('sai-left-pane-flex', leftPane.style.flex); + localStorage.setItem('sai-right-pane-flex', rightPane.style.flex); }; const onTouchStart = (e) => { if (e.touches.length === 1) { x = e.touches[0].clientX; - leftWidth = leftPane.getBoundingClientRect().width; + rightWidth = rightPane.getBoundingClientRect().width; + lastVisible = rightWidth > 0 ? 1 : 0; document.addEventListener('touchmove', onTouchMove, { passive: false }); document.addEventListener('touchend', onTouchEnd); } diff --git a/src/web/w-private.h b/src/web/w-private.h index 831d910..5d0b19a 100644 --- a/src/web/w-private.h +++ b/src/web/w-private.h @@ -134,6 +134,7 @@ struct pss { unsigned int bulk_binary_data:1; unsigned int toggle_favour_sch:1; unsigned int resolved_task_offset:1; + uint8_t wants_builder_info; sai_auth_state_t auth_state; }; diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c index 8bb6526..79ee52e 100644 --- a/src/web/w-ws-browser.c +++ b/src/web/w-ws-browser.c @@ -59,6 +59,14 @@ static lws_struct_map_t lsm_browser_builderdelete[] = { LSM_CARRAY (sai_browse_rx_builderdelete_t, builder_name, "builder_name"), }; +typedef struct sai_browse_rx_builder_visibility { + uint8_t visible; +} sai_browse_rx_builder_visibility_t; + +static lws_struct_map_t lsm_browser_builder_visibility[] = { + LSM_UNSIGNED (sai_browse_rx_builder_visibility_t, visible, "visible"), +}; + static lws_struct_map_t lsm_browser_taskinfo[] = { LSM_CARRAY (sai_browse_rx_taskinfo_t, task_hash, "task_hash"), LSM_UNSIGNED (sai_browse_rx_taskinfo_t, logs, "logs"), @@ -110,6 +118,8 @@ static const lws_struct_map_t lsm_schema_json_map_bwsrx[] = { "com.warmcat.sai.closeshell"), LSM_SCHEMA (sai_ptydata_t, NULL, lsm_ptydata, "com.warmcat.sai.ptydata"), + LSM_SCHEMA (sai_browse_rx_builder_visibility_t, NULL, lsm_browser_builder_visibility, + "com.warmcat.sai.builder_visibility"), }; enum { @@ -131,6 +141,7 @@ enum { SAIM_WS_BROWSER_RX_OPENSHELL, SAIM_WS_BROWSER_RX_CLOSESHELL, SAIM_WS_BROWSER_RX_PTYDATA, + SAIM_WS_BROWSER_RX_BUILDER_VISIBILITY, }; @@ -686,6 +697,18 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf, switch (a.top_schema_index) { + case SAIM_WS_BROWSER_RX_BUILDER_VISIBILITY: + { + sai_browse_rx_builder_visibility_t *v = (sai_browse_rx_builder_visibility_t *)a.dest; + pss->wants_builder_info = v->visible; + if (v->visible) { + saiw_browser_broadcast_queue_builders(pss->vhd, pss); + saiw_browser_broadcast_queue_pcons(pss->vhd, pss); + saiw_browser_broadcast_queue_power_history(pss->vhd, pss); + } + } + goto ok; + case SAIM_WS_BROWSER_RX_TASKINFO: ti = (sai_browse_rx_taskinfo_t *)a.dest; @@ -1395,6 +1418,9 @@ saiw_browser_broadcast_queue_pcon_energy(struct vhd *vhd, struct pss *pss, sai_p lws_struct_json_serialize_result_t r; size_t w; + if (pss && !pss->wants_builder_info) + return 0; + if (!vhd || !energy) return 0; @@ -1445,7 +1471,10 @@ saiw_browser_broadcast_queue_pcons(struct vhd *vhd, struct pss *pss) lws_struct_json_serialize_result_t r; size_t w; - if (!vhd || !vhd->pcons) + if (pss && !pss->wants_builder_info) + return 0; + + if (!vhd || !vhd->pcons || !pss) return 0; memset(&d, 0, sizeof(d)); @@ -1491,7 +1520,6 @@ saiw_browser_broadcast_queue_pcons(struct vhd *vhd, struct pss *pss) int saiw_browser_broadcast_queue_builders(struct vhd *vhd, struct pss *pss) { - saiw_browser_broadcast_queue_pcons(vhd, pss); struct sai_dyn_buf d; char buf[1024]; /* temp buffer for serialization before append */ lws_struct_serialize_t *js; @@ -1501,6 +1529,14 @@ saiw_browser_broadcast_queue_builders(struct vhd *vhd, struct pss *pss) size_t w; int n; + if (pss && !pss->wants_builder_info) + return 0; + + if (!vhd || !vhd->builders || !pss) + return 0; + + saiw_browser_broadcast_queue_pcons(vhd, pss); + memset(&d, 0, sizeof(d)); /* Reserve LWS_PRE header space */ @@ -1680,6 +1716,9 @@ saiw_browser_broadcast_queue_power_history(struct vhd *vhd, struct pss *pss) char buf[2048]; int n, i; + if (pss && !pss->wants_builder_info) + return 0; + if (!vhd) return 0; diff --git a/src/web/w-ws-server.c b/src/web/w-ws-server.c index ecd466b..fd55d6b 100644 --- a/src/web/w-ws-server.c +++ b/src/web/w-ws-server.c @@ -149,7 +149,7 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags) memcpy(tmp + LWS_PRE, p, rem); lws_start_foreach_dll(struct lws_dll2 *, pt, vhd->browsers.head) { struct pss *pss = lws_container_of(pt, struct pss, same); - if (!pss->is_gitohashi) + if (!pss->is_gitohashi && pss->wants_builder_info) saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, tmp + LWS_PRE, rem, lws_write_ws_flags(LWS_WRITE_TEXT, is_start, 0)); } lws_end_foreach_dll(pt); @@ -194,7 +194,7 @@ saiw_lp_rx(void *userobj, const uint8_t *buf, size_t len, int flags) memcpy(tmp + LWS_PRE, p, consumed); lws_start_foreach_dll(struct lws_dll2 *, pt, vhd->browsers.head) { struct pss *pss = lws_container_of(pt, struct pss, same); - if (!pss->is_gitohashi) + if (!pss->is_gitohashi && pss->wants_builder_info) saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, tmp + LWS_PRE, consumed, lws_write_ws_flags(LWS_WRITE_TEXT, is_start, 1)); } lws_end_foreach_dll(pt);
Page fetched 0s ago, creation time: 6ms (vhost etag hits: 0%, cache hits: 0%)