neocgit

a more 'modern' version of cgit
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/neocgit

commit a78ce3a598bc78649dce2dcf6095c20949c5ae87
parent f781631f9e07a84b94834a3a7e8b523c76998cf4
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Thu, 28 Jun 2018 20:11:15 +0200

NEW: Work on the repository page

Signed-off-by: Ne02ptzero <louis@ne02ptzero.me>

Diffstat:
Mcgit.css | 192++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mui-log.c | 37+++++++++++++++++++++++++++++++++++++
Mui-log.h | 1+
Mui-refs.c | 16++++++++++++++++
Mui-refs.h | 2++
Mui-repolist.c | 7+++++++
Mui-shared.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mui-summary.c | 26+++++++++++++-------------
8 files changed, 389 insertions(+), 76 deletions(-)

diff --git a/cgit.css b/cgit.css @@ -32,13 +32,14 @@ div#cgit table { background: #2C3E50; color: #D7DADB; padding: 0; + margin: 0; } #header ul { display: inline-block; list-style: none; width: 100%; - padding: 4px; + padding: 4px 0; margin: 0; } @@ -150,6 +151,16 @@ div#cgit table { display: inline-block; } +.repo-logo { + width: 3.5%; + padding-right: 5px; +} + +.repo-logo img { + height: auto; + width: 100%; +} + .repo-desc a { color: black !important; } @@ -169,7 +180,7 @@ div#cgit table { } .repo-infos { - width: 60%; + width: 55%; } .repo-details { @@ -188,6 +199,183 @@ div#cgit table { display: inline-block; } +.summary-header { + height: 20%; + text-align: center; + width: 100%; + border-bottom: 1px solid #eee; + padding: 20px 0; +} + +.summary-header img { + height: 70px; + width: auto; + margin-bottom: -20px; +} + +.summary-header h3 { + font-size: 24px; + margin-bottom: 5px; +} + +.summary-header span { + font-size: 1rem; +} + +.summary-header input { + height: 28px; + width: 220px; + text-align: center; + border: 1px solid #e5e5e5; + border-radius: 3px; +} + +.summary-menu { + display: inline-block; + text-align: center; + width: 100%; + border-bottom: 1px solid #eee; + padding: 7px 0; + color: #707070; +} + +.summary-menu li { + display: inline-block; + margin-left: 8px; + margin-right: 8px; +} + +.summary-menu a { + color: #707070 !important; + transition-property: all; + transition-duration: 0.3s; +} + +.summary-menu a:hover { + color: black !important; +} + +.summary-branches { + width: 100%; + padding: 10px 15px; +} + +.summary-branches ul { + list-style: none; + display: table; + margin: 0; + padding: 0; + width: calc(100% - 30px); +} + +.summary-branches ul li { + display: table-cell; + width: 20%; + margin: 0; +} + +.summary-branches ul li select { + background: #FFFFFF; + border: 1px solid #eee; + width: 100%; + padding: 5px 5px; + border-radius: 3px; +} + +.summary-branches ul .repo-name { + width: 60%; + padding-left: 15px; +} + +.summary-branches ul .history { + text-align: right; +} + +.summary-branches ul .history a { + border-radius: 3px; + font-size: 14px; + font-weight: 400; + padding: 6px 10px; + color: #2e2e2e !important; + border: 1px solid #e5e5e5; + transition-duration: 0.3s; + transition-property: all; + text-decoration: none !important; +} + +.summary-branches ul .history a:hover { + background: #0000001a; +} + +.summary-last-commit { + padding: 10px 15px; + margin-top: -10px; +} + +.last-commit { + background: #fafafa; + border-radius: 3px; + border: 1px solid #e5e5e5; + padding: 16px; +} + +.last-commit ul { + display: inline-block; + /*border: 1px solid green;*/ + width: 100%; + padding: 0; + margin: 0; +} + +.last-commit ul li { + display: inline-block; + vertical-align: middle; + /*border: 1px solid red;*/ + margin: 0; + padding: 0; +} + +.last-commit .avatar { + width: 6%; +} + +.last-commit .avatar img { + width: 90%; + height: auto; +} + +.last-commit ul .commit-info { + width: 84%; + padding: 0; + margin: 0; +} + +.last-commit ul .commit-info ul { + padding: 0; + margin: 0; +} + +.last-commit ul .commit-info ul li { + width: 100%; +} + +.last-commit ul .commit-info ul .title { + font-weight: bold; +} + +.last-commit .hash { + width: calc(10% - 8px); +} + +.last-commit .hash input { + width: 100%; + background: transparent; + border: 1px solid #eee; + padding: 5px 5px; + border-radius: 3px; + margin-left: -10px; +} + div#cgit table.tabs { border-collapse: collapse; margin-bottom: 0px; diff --git a/ui-log.c b/ui-log.c @@ -339,6 +339,43 @@ static const char *disambiguate_ref(const char *ref, int *must_free_result) return ref; } +int cgit_count_commits(void) +{ + struct rev_info rev; + struct commit *commit; + struct argv_array rev_argv = ARGV_ARRAY_INIT; + int ret = 0; + char *tip; + int must_free_tip; + + + argv_array_push(&rev_argv, "log_rev_setup"); + init_revisions(&rev, NULL); + tip = disambiguate_ref(ctx.qry.head, &must_free_tip); + argv_array_push(&rev_argv, tip); + rev.abbrev = default_abbrev; + rev.verbose_header = 1; + rev.show_root_diff = 0; + rev.ignore_missing = 1; + rev.simplify_history = 1; + setup_revisions(rev_argv.argc, rev_argv.argv, &rev, NULL); + rev.show_decorations = 1; + rev.grep_filter.ignore_case = 1; + rev.diffopt.detect_rename = 1; + rev.diffopt.rename_limit = ctx.cfg.renamelimit; + + compile_grep_patterns(&rev.grep_filter); + prepare_revision_walk(&rev); + + for (ret = 0; commit = get_revision(&rev) != NULL; ret) + ret++; + + if (must_free_tip) + free(tip); + + return ret; +} + static char *next_token(char **src) { char *result; diff --git a/ui-log.h b/ui-log.h @@ -5,5 +5,6 @@ extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, char *path, int pager, int commit_graph, int commit_sort); extern void show_commit_decorations(struct commit *commit); +extern int cgit_count_commits(void); #endif /* UI_LOG_H */ diff --git a/ui-refs.c b/ui-refs.c @@ -143,6 +143,14 @@ static void print_refs_link(char *path) html("</td></tr>"); } +int cgit_count_branches(void) +{ + struct reflist list = { 0 }; + + for_each_branch_ref(cgit_refs_cb, &list); + return list.count; +} + void cgit_print_branches(int maxcount) { struct reflist list; @@ -200,6 +208,14 @@ void cgit_print_tags(int maxcount) cgit_free_reflist_inner(&list); } +int cgit_count_tags(void) +{ + struct reflist list = { 0 }; + + for_each_tag_ref(cgit_refs_cb, &list); + return list.count; +} + void cgit_print_refs(void) { cgit_print_layout_start(); diff --git a/ui-refs.h b/ui-refs.h @@ -4,5 +4,7 @@ extern void cgit_print_branches(int maxcount); extern void cgit_print_tags(int maxcount); extern void cgit_print_refs(void); +extern int cgit_count_branches(void); +extern int cgit_count_tags(void); #endif /* UI_REFS_H */ diff --git a/ui-repolist.c b/ui-repolist.c @@ -322,6 +322,13 @@ void cgit_print_repolist(void) _html("<ul class='repo-pad'>") { + _html("<li class='repo-logo'>") { + if (ctx.repo->logo != NULL) + htmlf("<img src='%s' />", ctx.repo->logo); + else + htmlf("<img src='%s' />", ctx.cfg.logo); + } _html("</li>"); + _html("<li class='repo-infos'><ul>") { _html("<li class='repo-title'>") { htmlf("<a href='/%s'>%s</a>", ctx.repo->name, ctx.repo->name); diff --git a/ui-shared.c b/ui-shared.c @@ -11,6 +11,8 @@ #include "cmd.h" #include "html.h" #include "version.h" +#include "ui-log.h" +#include "ui-refs.h" static const char cgit_doctype[] = "<!DOCTYPE html>\n"; @@ -934,14 +936,9 @@ static void print_header(void) html_attr(cgit_rooturl()); html("'>"); - if (ctx.repo && ctx.repo->logo && *ctx.repo->logo) - logo = ctx.repo->logo; - else - logo = ctx.cfg.logo; - if (ctx.repo && ctx.repo->logo_link && *ctx.repo->logo_link) - logo_link = ctx.repo->logo_link; - else - logo_link = ctx.cfg.logo_link; + logo = ctx.cfg.logo; + logo_link = ctx.cfg.logo_link; + if (logo && *logo) { html("<img src='"); html_attr(logo); @@ -1010,66 +1007,131 @@ static void print_header(void) /*html("</td></tr></table>\n");*/ } +static void print_url(const char *url) +{ + static bool print = true; + + if (print) + { + htmlf("<input type='text' value='%s' readonly />", url); + print = false; + } +} + void cgit_print_pageheader(void) { html("<div id='cgit'>"); if (!ctx.env.authenticated || !ctx.cfg.noheader) print_header(); - html("<table class='tabs'><tr><td>\n"); - if (ctx.env.authenticated && ctx.repo) { - if (ctx.repo->readme.nr) - reporevlink("about", "about", NULL, - hc("about"), ctx.qry.head, NULL, - NULL); - cgit_summary_link("summary", NULL, hc("summary"), - ctx.qry.head); - cgit_refs_link("refs", NULL, hc("refs"), ctx.qry.head, - ctx.qry.sha1, NULL); - cgit_log_link("log", NULL, hc("log"), ctx.qry.head, - NULL, ctx.qry.vpath, 0, NULL, NULL, - ctx.qry.showmsg, ctx.qry.follow); - if (ctx.qry.page && !strcmp(ctx.qry.page, "blame")) - cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head, - ctx.qry.sha1, ctx.qry.vpath); - else - cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head, - ctx.qry.sha1, ctx.qry.vpath); - cgit_commit_link("commit", NULL, hc("commit"), - ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath); - cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head, - ctx.qry.sha1, ctx.qry.sha2, ctx.qry.vpath); - if (ctx.repo->max_stats) - cgit_stats_link("stats", NULL, hc("stats"), - ctx.qry.head, ctx.qry.vpath); - if (ctx.repo->homepage) { - html("<a href='"); - html_attr(ctx.repo->homepage); - html("'>homepage</a>"); - } - html("</td><td class='form'>"); - html("<form class='right' method='get' action='"); - if (ctx.cfg.virtual_root) { - char *fileurl = cgit_fileurl(ctx.qry.repo, "log", - ctx.qry.vpath, NULL); - html_url_path(fileurl); - free(fileurl); - } - html("'>\n"); - cgit_add_hidden_formfields(1, 0, "log"); - html("<select name='qt'>\n"); - html_option("grep", "log msg", ctx.qry.grep); - html_option("author", "author", ctx.qry.grep); - html_option("committer", "committer", ctx.qry.grep); - html_option("range", "range", ctx.qry.grep); - html("</select>\n"); - html("<input class='txt' type='search' size='10' name='q' value='"); - html_attr(ctx.qry.search); - html("'/>\n"); - html("<input type='submit' value='search'/>\n"); - html("</form>\n"); + if (ctx.env.authenticated && ctx.repo) { + _html("<div class='summary-header'>") { + if (ctx.repo->logo != NULL) + htmlf("<img src='%s' />", ctx.repo->logo); + else + htmlf("<img src='%s' />", ctx.cfg.logo); + html("<br />"); + htmlf("<h3>%s</h3>", ctx.repo->name); + htmlf("<span>%s</span>", ctx.repo->desc); + htmlf("<h5>%s</h5>", ctx.repo->owner); + cgit_add_clone_urls(print_url); + } _html("</div>"); + + _html("<div class='summary-menu'>") { + _html("<ul>") { + htmlf("<li><a href='#'>Commits (%d)</a></li>", cgit_count_commits()); + htmlf("<li><a href='#'>Branches (%d)</a></li>", cgit_count_branches()); + htmlf("<li><a href='#'>Tags (%d)</a></li>", cgit_count_tags()); + html("<li><a href='#'>Readme</a></li>"); + html("<li><a href='#'>Diff</a></li>"); + } _html("</ul>"); + } _html("</div>"); + + _html("<div class='summary-branches'>") { + _html("<ul>") { + _html("<li>") { + _html("<form method='get'>") { + cgit_add_hidden_formfields(0, 1, ctx.qry.page); + html("<select name='h' onchange='this.form.submit();'>\n"); + for_each_branch_ref(print_branch_option, ctx.qry.head); + html("</select>"); + } html("</form>"); + } _html("</li>"); + + _html("<li class='repo-name'>") { + html_txt(ctx.repo->name); + } _html("</li>"); + + _html("<li class='history'>") { + html("<a href='#'>History</a>"); + } _html("</li>"); + } _html("</ul>"); + } _html("</div>"); + + _html("<div class='summary-last-commit'>") { + _html("<div class='last-commit'>") { + struct commit *commit; + struct commitinfo *info; + struct object_id oid; + + get_oid(ctx.qry.head, &oid); + commit = lookup_commit_reference(&oid); + info = cgit_parse_commit(commit); + + _html("<ul>") { + + _html("<li class='avatar'>") { + htmlf("<img src='%s' />", ctx.cfg.logo); + } _html("</li>"); + + _html("<li class='commit-info'><ul>") { + htmlf("<li class='title'>%s</li>", info->subject); + htmlf("<li class='author'>%s authored ", info->author); + cgit_print_age(info->author_date, info->author_tz, -1); + html(" ago</li>"); + } _html("</ul></li>"); + + _html("<li class='hash'>") { + html("<input type='text' value='"); + html_txt(oid_to_hex(&oid)); + html("' readonly />"); + } _html("</li>"); + + } _html("</ul>"); + } _html("</div>"); + } _html("</div>"); + /* if (ctx.repo->readme.nr)*/ + /*reporevlink("about", "about", NULL,*/ + /*hc("about"), ctx.qry.head, NULL,*/ + /*NULL);*/ + /*cgit_summary_link("summary", NULL, hc("summary"),*/ + /*ctx.qry.head);*/ + /*cgit_refs_link("refs", NULL, hc("refs"), ctx.qry.head,*/ + /*ctx.qry.sha1, NULL);*/ + /*cgit_log_link("log", NULL, hc("log"), ctx.qry.head,*/ + /*NULL, ctx.qry.vpath, 0, NULL, NULL,*/ + /*ctx.qry.showmsg, ctx.qry.follow);*/ + /*if (ctx.qry.page && !strcmp(ctx.qry.page, "blame"))*/ + /*cgit_blame_link("blame", NULL, hc("blame"), ctx.qry.head,*/ + /*ctx.qry.sha1, ctx.qry.vpath);*/ + /*else*/ + /*cgit_tree_link("tree", NULL, hc("tree"), ctx.qry.head,*/ + /*ctx.qry.sha1, ctx.qry.vpath);*/ + /*cgit_commit_link("commit", NULL, hc("commit"),*/ + /*ctx.qry.head, ctx.qry.sha1, ctx.qry.vpath);*/ + /*cgit_diff_link("diff", NULL, hc("diff"), ctx.qry.head,*/ + /*ctx.qry.sha1, ctx.qry.sha2, ctx.qry.vpath);*/ + /*if (ctx.repo->max_stats)*/ + /*cgit_stats_link("stats", NULL, hc("stats"),*/ + /*ctx.qry.head, ctx.qry.vpath);*/ + /*if (ctx.repo->homepage) {*/ + /*html("<a href='");*/ + /*html_attr(ctx.repo->homepage);*/ + /*html("'>homepage</a>");*/ + /*}*/ + /*html("</td><td class='form'>");*/ } - html("</td></tr></table>\n"); + /*html("</td></tr></table>\n");*/ if (ctx.env.authenticated && ctx.repo && ctx.qry.vpath) { html("<div class='path'>"); html("path: "); diff --git a/ui-summary.c b/ui-summary.c @@ -50,19 +50,19 @@ void cgit_print_summary(void) columns++; cgit_print_layout_start(); - html("<table summary='repository info' class='list nowrap'>"); - cgit_print_branches(ctx.cfg.summary_branches); - htmlf("<tr class='nohover'><td colspan='%d'>&nbsp;</td></tr>", columns); - cgit_print_tags(ctx.cfg.summary_tags); - if (ctx.cfg.summary_log > 0) { - htmlf("<tr class='nohover'><td colspan='%d'>&nbsp;</td></tr>", columns); - cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, - NULL, NULL, 0, 0, 0); - } - urls = 0; - cgit_add_clone_urls(print_url); - html("</table>"); - cgit_print_layout_end(); + html("<table summary='repository info' class='list nowrap'>"); + cgit_print_branches(ctx.cfg.summary_branches); + htmlf("<tr class='nohover'><td colspan='%d'>&nbsp;</td></tr>", columns); + cgit_print_tags(ctx.cfg.summary_tags); + if (ctx.cfg.summary_log > 0) { + htmlf("<tr class='nohover'><td colspan='%d'>&nbsp;</td></tr>", columns); + cgit_print_log(ctx.qry.head, 0, ctx.cfg.summary_log, NULL, + NULL, NULL, 0, 0, 0); + } + urls = 0; + cgit_add_clone_urls(print_url); + html("</table>"); + cgit_print_layout_end(); } /* The caller must free the return value. */