neocgit

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

commit afb66a4a4694b37629b1f8895e617059683a0cea
parent bc9e61bbeadee6b71fdfd9b295093e2573ee1de1
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Tue, 10 Jul 2018 16:32:29 +0200

NEW: File preview, proper select for branches

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

Diffstat:
Mcgit.css | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mui-blame.c | 36++++++++++++++++++++++++++++++------
Mui-shared.c | 27++++++++++++++++++---------
Mui-summary.c | 4++--
Mui-tree.c | 97++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mui-tree.h | 1+
6 files changed, 230 insertions(+), 71 deletions(-)

diff --git a/cgit.css b/cgit.css @@ -277,7 +277,7 @@ option:not(:checked) { border: 0; } -.summary-header .repo-url .select select { +.select select { background: transparent; border: 0; -moz-appearance: none; /* Firefox */ @@ -288,7 +288,7 @@ option:not(:checked) { padding: 0px 25px 0 10px; } -.summary-header .repo-url .select-arrow { +.select-arrow { margin-left: -25px; padding-right: 10px; padding: 6px 10px 6px 0; @@ -354,6 +354,32 @@ option:not(:checked) { margin: 0; } +.summary-branches ul li .select-container { + display: inline-block; + width: 100%; + border: 1px solid #e5e5e5; + border-radius: 3px; +} + +.summary-branches ul li .select-container li { + display: inline-block; +} + +.summary-branches ul li .select-container .select { + width: 85%; +} + +.summary-branches ul li .select-container .select select { + border: 0; + line-height: 1em; +} + +.summary-branches ul li .select-container .select-arrow { + width: 10%; + border: 0; + text-align: center; +} + .summary-branches ul li select { background: #FFFFFF; border: 1px solid #eee; @@ -364,11 +390,8 @@ option:not(:checked) { .summary-branches ul .repo-name { width: 60%; - padding-left: 15px; -} - -.summary-branches ul .repo-name { color: #999; + padding-left: 10px; } .summary-branches ul .repo-name a { @@ -527,7 +550,6 @@ option:not(:checked) { cursor: pointer; } - .repository-tree { padding: 10px 15px; } @@ -587,20 +609,90 @@ option:not(:checked) { max-width: 320px; } -.repo-readme { +.repo-file { margin: 10px 15px; border: 1px solid #e5e5e5; border-radius: 4px; } -.repo-readme .readme-header { +.repo-file .header { background: #fafafa; border-bottom: 1px solid #e5e5e5; padding: 10px 16px; border-radius: 4px 4px 0 0; } -.repo-readme .content { +.repo-file .header i { + margin-right: 5px; + font-size: 14px; +} + +.repo-file .header .size { + font-weight: 400; + font-size: 80%; + margin-left: 5px; +} + +.repo-file .header ul { + display: inline-block; + list-style: none; + float: right; + margin-top: 1px; +} + +.repo-file .header ul li { + display: inline-block; +} + +.repo-file .header ul li a { + padding: 5px 10px; + background: #fff; + border-radius: 3px; + border: 1px solid #e5e5e5; + color: #2e2e2e !important; + text-decoration: none; + transition-property: all; + transition-duration: 0.3s; +} + +.repo-file .header ul li a:hover { + background: #f0f0f0; + text-decoration: none !important; +} + +.repo-file .header ul .blame a { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.repo-file .header ul .raw a { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + margin-left: -1px; +} + +.repo-file .content { + padding: 32px; +} + +.commit-list-container { + padding: 10px 15px; +} + +.commit-list { + list-style: none; + padding: 0; + margin: 0; + padding: 16px; +} + +.commit-list .commit ul .commit-info { + width: calc(95% - 200px); + padding: 0; + margin: 0; +} + +.repo-file .content { padding: 32px; } @@ -710,23 +802,35 @@ div#cgit td.ls-mode { width: 10em; } -div#cgit table.blob { - margin-top: 0.5em; - border-top: solid 1px black; -} - div#cgit table.blob td.hashes, div#cgit table.blob td.lines { margin: 0; padding: 0 0 0 0.5em; vertical-align: top; color: black; + padding-top: 10px; + padding-left: 10px; } div#cgit table.blob td.linenumbers { margin: 0; padding: 0 0.5em 0 0.5em; vertical-align: top; text-align: right; - border-right: 1px solid gray; + background: #fafafa; + padding-left: 15px; + padding-top: 10px; + border-right: 1px solid #f0f0f0; +} + +div#cgit table.blob td.linenumbers pre a { + color: rgba(0,0,0,0.3) !important; +} + +div#cgit table.blob td.linenumbers pre a:hover { + text-decoration: underline; +} + +div#cgit table.blob { + padding-top: 15px; } div#cgit table.blob pre { diff --git a/ui-blame.c b/ui-blame.c @@ -144,12 +144,6 @@ static void print_object(const struct object_id *oid, const char *path, cgit_set_title_from_path(path); cgit_print_layout_start(); - htmlf("blob: %s (", oid_to_hex(oid)); - cgit_plain_link("plain", NULL, NULL, ctx.qry.head, rev, path); - html(") ("); - cgit_tree_link("tree", NULL, NULL, ctx.qry.head, rev, path); - html(")\n"); - if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) { htmlf("<div class='error'>blob size (%ldKB)" " exceeds display size limit (%dKB).</div>", @@ -157,6 +151,31 @@ static void print_object(const struct object_id *oid, const char *path, goto cleanup; } + _html("<div class='repo-file'>") { + _html("<div class='header'>") { + print_file_icon(basename, 0); + htmlf("<strong>%s</strong>", basename); + htmlf("<span class='size'>%zu Bytes</span>", size); + + _html("<ul class='file-link'>") { + htmlf("<li class='blame'>" + "<a href='/%s/tree/%s/?%s=%s'>Plain</a>" + "</li>", + ctx.repo->name, path, + ctx.qry.sha1 != NULL ? "id" : "h", + ctx.qry.sha1 != NULL ? ctx.qry.sha1 : ctx.qry.head); + htmlf("<li class='raw'>" + "<a href='/%s/plain/%s?%s=%s'>Raw</a>" + "</li>", + ctx.repo->name, path, + ctx.qry.sha1 != NULL ? "id" : "h", + ctx.qry.sha1 != NULL ? ctx.qry.sha1 : ctx.qry.head); + } _html("</ul>"); + + } _html("</div>"); + + _html("<div class='content' style='padding: 0'>") { + html("<table class='blame blob'>\n<tr>\n"); /* Commit hashes */ @@ -212,6 +231,11 @@ static void print_object(const struct object_id *oid, const char *path, html("</tr>\n</table>\n"); + } _html("</div>"); + + } _html("</div>"); + + cgit_print_layout_end(); cleanup: diff --git a/ui-shared.c b/ui-shared.c @@ -919,10 +919,6 @@ void cgit_add_hidden_formfields(int incl_head, int incl_search, strcmp(ctx.qry.head, ctx.repo->defbranch)) html_hidden("h", ctx.qry.head); - if (ctx.qry.sha1) - html_hidden("id", ctx.qry.sha1); - if (ctx.qry.sha2) - html_hidden("id2", ctx.qry.sha2); if (ctx.qry.showmsg) html_hidden("showmsg", "1"); @@ -1087,11 +1083,24 @@ void cgit_print_pageheader(void) _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); - if (ctx.qry.sha1 != NULL) - htmlf("<option value='%s' selected='selected'>%s</option>", ctx.qry.sha1, ctx.qry.sha1); - html("</select> "); + _html("<ul class='select-container'>") { + + html("<li class='select'>"); { + html("<select name='h' onchange='this.form.submit();'>\n"); + for_each_branch_ref(print_branch_option, ctx.qry.head); + + if (ctx.qry.sha1 != NULL) + htmlf("<option value='%s' selected='selected'>%s</option>", + ctx.qry.sha1, ctx.qry.sha1); + + html("</select>"); + } html("</li>"); + + html("<li class='select-arrow'>"); { + html("<i class='fa fa-caret-down'></i>"); + } html("</li>"); + + }_html("</ul>"); } html("</form>"); } _html("</li>"); diff --git a/ui-summary.c b/ui-summary.c @@ -114,8 +114,8 @@ void cgit_print_repo_readme(char *path, bool layout) filename = ctx.repo->readme.items[0].string; ref = ctx.repo->readme.items[0].util; - _html("<div class='repo-readme'>") { - _html("<div class='readme-header'>") { + _html("<div class='repo-file'>") { + _html("<div class='header'>") { htmlf("%s", filename); } _html("</div>"); diff --git a/ui-tree.c b/ui-tree.c @@ -110,6 +110,33 @@ static bool file_is_image(const char *filename) return format_match(formats, COUNT_OF(formats), filename); } +void print_file_icon(const char *filename, int mode) +{ + if (S_ISLNK(mode)) + html("<i class='fa fa-file-export'></i>"); + else if (S_ISDIR(mode)) + html("<i class='fa fa-folder'></i>"); + else + { + if (file_is_code(filename)) + html("<i class='far fa-file-code'></i>"); + else if (file_is_audio(filename)) + html("<i class='far fa-file-audio'></i>"); + else if (file_is_video(filename)) + html("<i class='far fa-file-video'></i>"); + else if (file_is_pdf(filename)) + html("<i class='far fa-file-pdf'></i>"); + else if (file_is_archive(filename)) + html("<i class='far fa-file-archive'></i>"); + else if (file_is_image(filename)) + html("<i class='far fa-file-image'></i>"); + else + html("<i class='far fa-file-alt'></i>"); + } +} + + + static void print_text_buffer(const char *name, char *buf, unsigned long size) { unsigned long lineno, idx; @@ -200,15 +227,6 @@ static void print_object(const struct object_id *oid, char *path, const char *ba cgit_set_title_from_path(path); cgit_print_layout_start(); - htmlf("blob: %s (", oid_to_hex(oid)); - cgit_plain_link("plain", NULL, NULL, ctx.qry.head, - rev, path); - if (ctx.cfg.enable_blame) { - html(") ("); - cgit_blame_link("blame", NULL, NULL, ctx.qry.head, - rev, path); - } - html(")\n"); if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) { htmlf("<div class='error'>blob size (%ldKB) exceeds display size limit (%dKB).</div>", @@ -216,10 +234,38 @@ static void print_object(const struct object_id *oid, char *path, const char *ba return; } - if (buffer_is_binary(buf, size)) - print_binary_buffer(buf, size); - else - print_text_buffer(basename, buf, size); + _html("<div class='repo-file'>") { + + _html("<div class='header'>") { + print_file_icon(basename, 0); + htmlf("<strong>%s</strong>", basename); + htmlf("<span class='size'>%zu Bytes</span>", size); + + _html("<ul class='file-link'>") { + htmlf("<li class='blame'>" + "<a href='/%s/blame/%s/?%s=%s'>Blame</a>" + "</li>", + ctx.repo->name, path, + ctx.qry.sha1 != NULL ? "id" : "h", + ctx.qry.sha1 != NULL ? ctx.qry.sha1 : ctx.qry.head); + htmlf("<li class='raw'>" + "<a href='/%s/plain/%s?%s=%s'>Raw</a>" + "</li>", + ctx.repo->name, path, + ctx.qry.sha1 != NULL ? "id" : "h", + ctx.qry.sha1 != NULL ? ctx.qry.sha1 : ctx.qry.head); + } _html("</ul>"); + + } _html("</div>"); + + _html("<div class='content' style='padding: 0'>") { + if (buffer_is_binary(buf, size)) + print_binary_buffer(buf, size); + else + print_text_buffer(basename, buf, size); + } _html("</div>"); + + } _html("</div>"); free(buf); } @@ -291,31 +337,6 @@ static void write_tree_link(const struct object_id *oid, char *name, strbuf_setlen(fullpath, initial_length); } -static void print_file_icon(const char *filename, int mode) -{ - if (S_ISLNK(mode)) - html("<i class='fa fa-file-export'></i>"); - else if (S_ISDIR(mode)) - html("<i class='fa fa-folder'></i>"); - else - { - if (file_is_code(filename)) - html("<i class='far fa-file-code'></i>"); - else if (file_is_audio(filename)) - html("<i class='far fa-file-audio'></i>"); - else if (file_is_video(filename)) - html("<i class='far fa-file-video'></i>"); - else if (file_is_pdf(filename)) - html("<i class='far fa-file-pdf'></i>"); - else if (file_is_archive(filename)) - html("<i class='far fa-file-archive'></i>"); - else if (file_is_image(filename)) - html("<i class='far fa-file-image'></i>"); - else - html("<i class='far fa-file-alt'></i>"); - } -} - static void print_tree_item(struct tree_link *ptr, struct walk_tree_context *tree_ctx) { struct strbuf fullpath = STRBUF_INIT; diff --git a/ui-tree.h b/ui-tree.h @@ -2,5 +2,6 @@ #define UI_TREE_H extern void cgit_print_tree(const char *rev, char *path, bool layout); +extern void print_file_icon(const char *filename, int mode); #endif /* UI_TREE_H */