diff options
Diffstat (limited to 'contexts.c')
-rw-r--r-- | contexts.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/contexts.c b/contexts.c index d432cb1..bf5811f 100644 --- a/contexts.c +++ b/contexts.c @@ -22,10 +22,27 @@ #include "server.h" const char *ContextsQuery = SQL( - SELECT name - FROM contexts - WHERE network = :network AND coalesce(query = :query, true) - ORDER BY query, name; + WITH recentEvents AS ( + SELECT time, context + FROM events + ORDER BY event DESC + LIMIT 500 // TODO: Configurable. + ), activeContexts AS ( + SELECT name, query + FROM contexts + JOIN recentEvents USING (context) + WHERE network = :network AND coalesce(query = :query, true) + GROUP BY context + ORDER BY max(time) DESC + ), allContexts AS ( + SELECT name, query + FROM contexts + WHERE network = :network AND coalesce(query = :query, true) + ORDER BY query, name + ) + SELECT name, query, 1 FROM activeContexts + UNION ALL + SELECT name, query, 0 FROM allContexts; ); enum kcgi_err pageContexts(struct kreq *req) { @@ -41,16 +58,38 @@ enum kcgi_err pageContexts(struct kreq *req) { || khtml_open(&html, req, KHTML_PRETTY) || htmlHead(&html, network) || htmlNav(&html, network, NULL) - || htmlSearch(&html, network, NULL) - || khtml_elem(&html, KELEM_UL); + || htmlSearch(&html, network, NULL); if (error) return error; dbBindText(stmt.contexts, ":network", network); if (pagePublic) dbBindInt(stmt.contexts, ":query", false); + enum State { + None, + Active, + Channels, + Queries, + } state = None; + const char *Headings[] = { NULL, "Active", "Channels", "Queries" }; + int result; while (SQLITE_ROW == (result = sqlite3_step(stmt.contexts))) { const char *context = (const char *)sqlite3_column_text(stmt.contexts, 0); + bool query = sqlite3_column_int(stmt.contexts, 1); + bool active = sqlite3_column_int(stmt.contexts, 2); + + enum State prev = state; + state = (active ? Active : (query ? Queries : Channels)); + if (state != prev) { + error = 0 + || khtml_closeelem(&html, 1) + || khtml_elem(&html, KELEM_H2) + || khtml_puts(&html, Headings[state]) + || khtml_closeelem(&html, 1) + || khtml_elem(&html, KELEM_UL); + if (error) return error; + } + char *href = khttp_urlpart( NULL, NULL, Pages[Events], Keys[Network].name, network, @@ -58,7 +97,6 @@ enum kcgi_err pageContexts(struct kreq *req) { NULL ); if (!href) err(EX_OSERR, "khttp_urlpart"); - error = 0 || khtml_elem(&html, KELEM_LI) || khtml_attr(&html, KELEM_A, KATTR_HREF, href, KATTR__MAX) |