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 / src / server / s-private.h
Author[]Andy Green <andy@warmcat.com> 2026-04-05 07:17 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-04-08 08:43 UTC
Treee9981203eea88baacbb399f31d9604a923be3dd9   Raw Patch
 
main page: pagination
main page: pagination
diff --git a/assets/sai.css b/assets/sai.css index bfd5711..914cb88 100644 --- a/assets/sai.css +++ b/assets/sai.css @@ -1217,3 +1217,13 @@ body.overlay-active { width: 10px; text-align: center; } + +.sai-pagination { + text-align: center; + margin: 20px 0; +} + +.sai-pagination-info { + color: #fff; + margin: 0 15px; +} diff --git a/assets/sai.js b/assets/sai.js index df4e768..182fffd 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -406,6 +406,14 @@ var seg_counter = 0; var pcon_topology = {}; var pcon_energy_cache = {}; var last_builder_list = []; +var current_overview_offset = 0; + +window.change_page = function(new_offset) { + current_overview_offset = new_offset; + sai.send("{\"schema\":" + + "\"com.warmcat.sai.taskinfo\", \"js_api_version\": " + SAI_JS_API_VERSION + + ", \"offset\": " + current_overview_offset + "}"); +}; function createPconDiv(pcon) { const pconDiv = document.createElement("div"); @@ -1849,7 +1857,8 @@ function ws_open_sai() */ sai.send("{\"schema\":" + - "\"com.warmcat.sai.taskinfo\", \"js_api_version\": " + SAI_JS_API_VERSION + "}"); + "\"com.warmcat.sai.taskinfo\", \"js_api_version\": " + SAI_JS_API_VERSION + + ", \"offset\": " + current_overview_offset + "}"); }; sai.onmessage = function got_packet(msg) { @@ -2034,10 +2043,25 @@ function ws_open_sai() * display events wholesale */ if (jso.overview.length) { + var pagination_html = ""; + if (!gitohashi_integ && jso.total_events > 6) { + pagination_html += "<div class=\"sai-pagination\">"; + if (jso.offset > 0) { + pagination_html += "<button class=\"btn sai-pagination-btn\" data-offset=\"" + Math.max(0, jso.offset - 6) + "\">&lt; Newer</button> "; + } + pagination_html += "<span class=\"sai-pagination-info\">Showing " + (jso.offset + 1) + " - " + Math.min(jso.offset + 6, jso.total_events) + " of " + jso.total_events + "</span>"; + if (jso.offset + 6 < jso.total_events) { + pagination_html += "<button class=\"btn sai-pagination-btn\" data-offset=\"" + (jso.offset + 6) + "\">Older &gt;</button>"; + } + pagination_html += "</div>"; + } + + s = pagination_html + s; + for (n = jso.overview.length - 1; n >= 0; n--) s += sai_event_render(jso.overview[n], now_ut, 1); - s = s + "</table>"; + s = s + "</table>" + pagination_html; if (document.getElementById("sai_sticky")) document.getElementById("sai_sticky").innerHTML = s; @@ -2581,6 +2605,12 @@ window.addEventListener("load", function() { var id = hdr.id.substring(8); toggleSegment(id); } + var pbtn = e.target.closest('.sai-pagination-btn'); + if (pbtn) { + if (window.change_page) { + window.change_page(parseInt(pbtn.getAttribute('data-offset'))); + } + } }); const savedFlex = localStorage.getItem('sai-left-pane-flex'); diff --git a/src/common/include/private.h b/src/common/include/private.h index 8e96344..92aee13 100644 --- a/src/common/include/private.h +++ b/src/common/include/private.h @@ -22,7 +22,6 @@ */ #include <libwebsockets.h> -#include <sqlite3.h> #if defined(WIN32) #define HAVE_STRUCT_TIMESPEC @@ -69,7 +68,7 @@ enum { typedef struct sais_sqlite_cache { lws_dll2_t list; char uuid[65]; - sqlite3 *pdb; + struct sqlite3 *pdb; lws_usec_t idle_since; int refcount; } sais_sqlite_cache_t; @@ -565,6 +564,7 @@ typedef struct sai_browse_rx_taskinfo { uint64_t last_log_ts; unsigned int log_start; unsigned int js_api_version; + unsigned int offset; uint8_t logs; } sai_browse_rx_taskinfo_t; @@ -797,9 +797,9 @@ sai_ss_tx_from_buflist_helper(struct lws_ss_handle *ss, struct lws_buflist **buf int sai_event_db_ensure_open(struct lws_context *cx, lws_dll2_owner_t *sqlite3_cache, const char *sqlite3_path_lhs, const char *event_uuid, - char create_if_needed, sqlite3 **ppdb); + char create_if_needed, struct sqlite3 **ppdb); void -sai_event_db_close(lws_dll2_owner_t *sqlite3_cache, sqlite3 **ppdb); +sai_event_db_close(lws_dll2_owner_t *sqlite3_cache, struct sqlite3 **ppdb); int sai_event_db_close_all_now(lws_dll2_owner_t *sqlite3_cache); @@ -808,5 +808,5 @@ int sai_event_db_delete_database(const char *sqlite3_path_lhs, const char *event_uuid); int -sai_sqlite3_statement(sqlite3 *pdb, const char *cmd, const char *desc); +sai_sqlite3_statement(struct sqlite3 *pdb, const char *cmd, const char *desc); diff --git a/src/web/w-private.h b/src/web/w-private.h index bd27cd7..b2ba540 100644 --- a/src/web/w-private.h +++ b/src/web/w-private.h @@ -98,6 +98,7 @@ struct pss { int specificity; int segment_flags; unsigned int js_api_version; + unsigned int overview_offset; /* notification hmac information */ char notification_sig[128]; diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c index 8082b74..b0ae98d 100644 --- a/src/web/w-ws-browser.c +++ b/src/web/w-ws-browser.c @@ -59,6 +59,7 @@ 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"), LSM_UNSIGNED (sai_browse_rx_taskinfo_t, js_api_version, "js_api_version"), + LSM_UNSIGNED (sai_browse_rx_taskinfo_t, offset, "offset"), LSM_UNSIGNED (sai_browse_rx_taskinfo_t, last_log_ts, "last_log_ts"), }; @@ -601,6 +602,7 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf, if (ti->js_api_version) pss->js_api_version = ti->js_api_version; + pss->overview_offset = ti->offset; saiw_browser_broadcast_queue_builders(pss->vhd, pss); saiw_browser_queue_overview(pss->vhd, pss); @@ -881,7 +883,7 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss) filt[0] = '\0'; esc[0] = '\0'; - n = -8; + n = -6; if (pss->specific_project[0]) { lws_sql_purify(esc, pss->specific_project, sizeof(esc) - 1); @@ -889,10 +891,24 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss) n = -1; } + unsigned int total_events = 0; + { + char q[256]; + sqlite3_stmt *stmt; + lws_snprintf(q, sizeof(q), "SELECT COUNT(*) FROM events%s%s", + filt[0] ? " WHERE " : "", + filt[0] ? filt + 5 : ""); + if (sqlite3_prepare_v2(vhd->pdb, q, -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) + total_events = (unsigned int)sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + } + } + pss->wants_event_updates = 1; if (lws_struct_sq3_deserialize(vhd->pdb, filt[0] ? filt : NULL, "created ", lsm_schema_sq3_map_event, - &owner, &ac, 0, n)) { + &owner, &ac, (int)pss->overview_offset, n)) { lwsl_notice("%s: OVERVIEW 2 failed\n", __func__); return 0; @@ -907,8 +923,11 @@ saiw_browser_queue_overview(struct vhd *vhd, struct pss *pss) "{\"schema\":\"sai.warmcat.com.overview\"," " \"api_version\":%u," " \"alang\":\"%s\"," + " \"total_events\":%u," + " \"offset\":%u," "\"overview\":[", SAIW_API_VERSION, - lws_json_purify(esc, pss->alang, sizeof(esc) - 1, NULL) + lws_json_purify(esc, pss->alang, sizeof(esc) - 1, NULL), + total_events, pss->overview_offset ); saiw_ws_browser_queue_REQUIRES_LWS_PRE(pss, start,
Page fetched 0s ago, creation time: 6ms (vhost etag hits: 0%, cache hits: 0%)