git-trace

romele / git-trace public

62 commits · 1 branch · 1 tag · 1 contributor (top: Romele) · first commit 3d ago · last push 11m ago

src/web.h

#ifndef GT_WEB_H
#define GT_WEB_H

#include "db.h"
#include "httpd.h"

#include <limits.h>

/* shared application context (owned by main.c, passed to routes) */
struct app_ctx {
    char      repos_root[PATH_MAX]; /* absolute, canonicalised */
    char      db_path[PATH_MAX];
    int       port;
    int       open_reg;             /* GIT_TRACE_OPEN_REG: public signup */
    char      ssh_url[160];         /* GIT_TRACE_SSH_URL prefix, may be "" */
    char      base_host[160];       /* GIT_TRACE_BASE_URL host[:port] */
    char      site_name[80];        /* GIT_TRACE_NAME, default git-trace */
    sqlite3  *db;
};

void web_index(void *ctx, struct request *r);
void web_repo(void *ctx, struct request *r,
              const char *owner, const char *repo, const char *sub);
void web_login(void *ctx, struct request *r);
void web_logout(void *ctx, struct request *r);
void web_register(void *ctx, struct request *r);
void web_audit(void *ctx, struct request *r);
void web_new(void *ctx, struct request *r);
void web_account(void *ctx, struct request *r);
void web_feed_xsl(void *ctx, struct request *r);

/* shared page chrome, used by collab.c too */
void gt_page_top(struct buf *b, const char *title,
                 const struct request *r);
const char *gt_web_css(void);      /* shared stylesheet for export */
void gt_page_bottom(struct buf *b);
void gt_send_page(struct request *r, struct buf *b);
/* `active` is the URL-segment key of the current tab ("tree", "log",
 * "refs", "issues", "changes", "activity", "settings") or NULL.
 * Emits the owner/name header plus the summary stat line, then opens
 * the sidebar+work two-column layout — every caller must emit
 * gt_repo_body_end() before gt_page_bottom(). */
void gt_repo_tabs(struct buf *b, struct app_ctx *app,
                  const char *o, const char *n, int rank,
                  const char *active);
void gt_repo_body_end(struct buf *b);
void gt_render_diff(struct buf *b, const char *data, size_t n);

/* 16x16 inline SVG icons — pure markup, no resource load, CSP-safe.
 * draw via fill=currentColor or explicit stroke so they inherit color. */
#define I_REPO  "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.3 aria-hidden=true>" \
    "<rect x=3.5 y=2 width=9 height=12 rx=1/><path d='M6.2 2v12'/></svg>"
#define I_GLOBE "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.2 aria-hidden=true>" \
    "<circle cx=8 cy=8 r=5.8/><ellipse cx=8 cy=8 rx=2.6 ry=5.8/>" \
    "<path d='M2.3 8h11.4'/></svg>"
#define I_LOCK  "<svg class=ic viewBox='0 0 16 16' fill=currentColor " \
    "aria-hidden=true><rect x=3.8 y=7 width=8.4 height=6 rx=1.2/>" \
    "<path d='M5.3 7V5a2.7 2.7 0 0 1 5.4 0v2h-1.4V5a1.3 1.3 0 0 0-2.6 " \
    "0v2z'/></svg>"
#define I_FOLDER "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.3 aria-hidden=true>" \
    "<path d='M2 4a1 1 0 0 1 1-1h3.2l1.3 1.7H13a1 1 0 0 1 1 1V12a1 1 0 " \
    "0 1-1 1H3a1 1 0 0 1-1-1z'/></svg>"
#define I_COMMIT "<svg class=ic viewBox='0 0 16 16' fill=currentColor " \
    "aria-hidden=true><circle cx=8 cy=8 r=2.4/>" \
    "<path d='M1.5 8h4.2M10.3 8h4.2' stroke=currentColor " \
    "stroke-width=1.3 fill=none/></svg>"
#define I_TAG   "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.3 aria-hidden=true>" \
    "<path d='M2 7.3V3a1 1 0 0 1 1-1h4.3L14 8.7a1 1 0 0 1 0 " \
    "1.4l-3.9 3.9a1 1 0 0 1-1.4 0z'/>" \
    "<circle cx=5 cy=5 r=1.1 fill=currentColor stroke=none/></svg>"
#define I_ISSUE "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.3 aria-hidden=true>" \
    "<circle cx=8 cy=8 r=5.8/>" \
    "<circle cx=8 cy=8 r=1.1 fill=currentColor stroke=none/></svg>"
#define I_MERGE "<svg class=ic viewBox='0 0 16 16' fill=currentColor " \
    "aria-hidden=true><circle cx=4.5 cy=4 r=1.9/>" \
    "<circle cx=4.5 cy=12 r=1.9/><circle cx=12 cy=8 r=1.9/>" \
    "<path d='M4.5 5.9v4.2M6 4.9c2.6 1 4 1.8 4 3.1' " \
    "stroke=currentColor stroke-width=1.3 fill=none/></svg>"
#define I_PULSE "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.4 stroke-linejoin=round " \
    "stroke-linecap=round aria-hidden=true>" \
    "<path d='M1 8h2.6l1.9-4.5 3.4 9 1.9-4.5H15'/></svg>"
#define I_SLIDER "<svg class=ic viewBox='0 0 16 16' fill=currentColor " \
    "aria-hidden=true>" \
    "<path d='M1.5 4.2h13M1.5 8h13M1.5 11.8h13' stroke=currentColor " \
    "stroke-width=1.3/><circle cx=6 cy=4.2 r=1.5/>" \
    "<circle cx=10.5 cy=8 r=1.5/><circle cx=5 cy=11.8 r=1.5/></svg>"
#define I_LOGO  "<svg width=16 height=16 viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.3 stroke-linecap=round " \
    "aria-hidden=true><path d='M4 3.5 1.8 8 4 12.5'/>" \
    "<path d='M12 3.5 14.2 8 12 12.5'/>" \
    "<path d='M7.5 5v4.2c0 1.1.5 1.8 1.6 1.8h.4'/>" \
    "<circle cx=7.5 cy=3.5 r=1.3 fill=currentColor stroke=none/>" \
    "<circle cx=10.1 cy=12.5 r=1.3 fill=currentColor stroke=none/></svg>"
/* 48px hero variant for the landing page */
#define I_LOGO_LG "<svg width=56 height=56 viewBox='0 0 64 64' fill=none " \
    "stroke=currentColor stroke-width=5 stroke-linecap=round " \
    "stroke-linejoin=round aria-hidden=true>" \
    "<path d='M16 14 6 32l10 18'/><path d='M48 14l10 18-10 18'/>" \
    "<path d='M30 20v16c0 5 2 8 7 8h1'/>" \
    "<circle cx=30 cy=14 r=4.5 fill=currentColor stroke=none/>" \
    "<circle cx=41 cy=50 r=4.5 fill=currentColor stroke=none/></svg>"
#define I_PLUS  "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.6 stroke-linecap=round " \
    "aria-hidden=true><path d='M8 3v10M3 8h10'/></svg>"
#define I_SEARCH "<svg class=ic viewBox='0 0 16 16' fill=none " \
    "stroke=currentColor stroke-width=1.4 aria-hidden=true>" \
    "<circle cx=7 cy=7 r=4.5/><path d='M10.5 10.5 14 14'/></svg>"
#define I_FEED  "<svg class=ic viewBox='0 0 16 16' fill=currentColor " \
    "aria-hidden=true><circle cx=3.5 cy=12.5 r=1.6/>" \
    "<path d='M2 8.5a6 6 0 0 1 5.5 5.5M2 4.5A10 10 0 0 1 11.5 14' " \
    "fill=none stroke=currentColor stroke-width=1.4/></svg>"

#endif