Skip to content

Commit bc9003f

Browse files
committed
optimize pr files html (50% reduction)
1 parent 17255ce commit bc9003f

6 files changed

Lines changed: 129 additions & 107 deletions

File tree

diff.v

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,37 @@ module main
44

55
import veb
66
import highlight
7+
import strings
8+
9+
fn render_diff_table(fd FileDiff) veb.RawHtml {
10+
mut out := strings.new_builder(1024)
11+
out.write_string('<div class=pr-diff__table>')
12+
for hunk in fd.hunks {
13+
out.write_string(diff_hunk_header_html(hunk.header))
14+
for dline in hunk.lines {
15+
out.write_string(diff_line_row_html(fd.path, dline))
16+
}
17+
}
18+
out.write_string('</div>')
19+
return veb.RawHtml(out.str())
20+
}
21+
22+
fn diff_hunk_header_html(header string) string {
23+
return '<p class=h><code>${html_escape_text(header)}</code></p>'
24+
}
25+
26+
fn diff_line_row_html(file_path string, dline DiffLine) string {
27+
return '<p class=${dline.compact_class()}><u>${dline.old_line_str()}</u><u>${dline.new_line_str()}</u><i>${dline.compact_sign()}</i><s>${highlight.highlight_line(dline.content,
28+
file_path)}</s></p>'
29+
}
730

8-
// render_diff_line is a template helper that returns the diff line's
9-
// content with single-line syntax highlighting applied.
10-
fn render_diff_line(content string, file_path string) veb.RawHtml {
11-
return veb.RawHtml(highlight.highlight_line(content, file_path))
31+
fn diff_comment_box_html(file_path string, dline DiffLine, lang Lang) string {
32+
if dline.kind == 'context' {
33+
return ''
34+
}
35+
name := html_escape_text(dline.comment_field_name(file_path))
36+
placeholder := html_escape_text(veb.tr(lang.str(), 'pr_line_comment_placeholder').trim_space())
37+
return '<p class=m><textarea name="${name}" placeholder="${placeholder}" rows=2></textarea></p>'
1238
}
1339

1440
struct FileDiff {
@@ -134,11 +160,19 @@ fn parse_unified_diff(raw string) []FileDiff {
134160
return files
135161
}
136162

137-
fn (d &DiffLine) sign() string {
163+
fn (d &DiffLine) compact_sign() string {
138164
return match d.kind {
139165
'add' { '+' }
140166
'del' { '-' }
141-
else { ' ' }
167+
else { '' }
168+
}
169+
}
170+
171+
fn (d &DiffLine) compact_class() string {
172+
return match d.kind {
173+
'add' { 'a' }
174+
'del' { 'd' }
175+
else { 'c' }
142176
}
143177
}
144178

pr_routes.v

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import veb
66
import validation
77
import git
88
import time
9+
import strings
910

1011
struct PrWithUser {
1112
pr PullRequest
@@ -300,6 +301,7 @@ pub fn (mut app App) pull_request_files(mut ctx Context, username string, repo_n
300301
user: u
301302
}
302303
}
304+
can_comment := ctx.logged_in && pr.is_open()
303305
return $veb.html('templates/pull_files.html')
304306
}
305307

@@ -603,9 +605,26 @@ fn merge_branches_in_bare(repo Repo, base string, head string, author string, me
603605
return commit_sha
604606
}
605607

606-
// render_inline_comments returns the HTML rows for any line comments
607-
// attached to a given diff line (matched on file_path, side, line_number).
608-
fn render_inline_comments(file_path string, dline DiffLine, comments_by_key map[string][]PrReviewCommentWithUser) veb.RawHtml {
608+
fn render_pr_diff_table(fd FileDiff, comments_by_key map[string][]PrReviewCommentWithUser, can_comment bool, lang Lang) veb.RawHtml {
609+
mut out := strings.new_builder(1024)
610+
out.write_string('<div class=pr-diff__table>')
611+
for hunk in fd.hunks {
612+
out.write_string(diff_hunk_header_html(hunk.header))
613+
for dline in hunk.lines {
614+
out.write_string(diff_line_row_html(fd.path, dline))
615+
if can_comment && dline.kind != 'context' {
616+
out.write_string(diff_comment_box_html(fd.path, dline, lang))
617+
}
618+
out.write_string(inline_comments_html(fd.path, dline, comments_by_key))
619+
}
620+
}
621+
out.write_string('</div>')
622+
return veb.RawHtml(out.str())
623+
}
624+
625+
// inline_comments_html returns any line comments attached to a given diff line,
626+
// matched on file_path, side, and line_number.
627+
fn inline_comments_html(file_path string, dline DiffLine, comments_by_key map[string][]PrReviewCommentWithUser) string {
609628
mut side := ''
610629
mut line_no := 0
611630
if dline.kind == 'add' {
@@ -615,24 +634,21 @@ fn render_inline_comments(file_path string, dline DiffLine, comments_by_key map[
615634
side = 'old'
616635
line_no = dline.old_line
617636
} else {
618-
return veb.RawHtml('')
637+
return ''
619638
}
620639
key := '${file_path}|${side}|${line_no}'
621-
list := comments_by_key[key] or { return veb.RawHtml('') }
640+
list := comments_by_key[key] or { return '' }
622641
if list.len == 0 {
623-
return veb.RawHtml('')
642+
return ''
624643
}
625644
mut out := ''
626645
for c in list {
627646
body := html_escape_text(c.item.text)
628647
username := html_escape_text(c.user.username)
629648
rel := html_escape_text(c.item.relative())
630-
out += '<tr class="pr-diff__inline-comment"><td colspan="4">' +
631-
'<div class="pr-inline-comment">' +
632-
'<strong>${username}</strong> <span class="pr-inline-comment__meta">commented ${rel}</span>' +
633-
'<p>${body}</p>' + '</div></td></tr>'
649+
out += '<p class=n><b>${username}</b> <i>commented ${rel}</i><br><s>${body}</s></p>'
634650
}
635-
return veb.RawHtml(out)
651+
return out
636652
}
637653

638654
// is_safe_ref does a strict whitelist check for branch names used in shell.

static/assets/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
06e10ac
1+
17255ce

static/css/gitly.scss

Lines changed: 59 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,71 +2540,76 @@ form {
25402540

25412541
.pr-diff__table {
25422542
width: 100%;
2543-
border-collapse: collapse;
2543+
overflow-x: auto;
25442544
font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
25452545
font-size: 12px;
25462546
background-color: $white;
2547-
table-layout: auto;
25482547
}
25492548

2550-
.pr-diff__hunk-header td,
2551-
.pr-diff__hunk-header td code {
2552-
background-color: #ddf4ff;
2553-
color: #57606a;
2554-
padding: 4px 12px;
2555-
font-size: 12px;
2549+
.pr-diff__table > p {
2550+
display: grid;
2551+
grid-template-columns: 56px 56px 18px max-content;
2552+
min-width: 100%;
2553+
margin: 0;
2554+
line-height: 20px;
25562555
font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
2556+
font-size: 12px;
25572557
}
25582558

2559-
.pr-diff__row td {
2559+
.pr-diff__table > p > u,
2560+
.pr-diff__table > p > i,
2561+
.pr-diff__table > p > s {
25602562
padding: 0 8px;
25612563
white-space: pre;
2562-
vertical-align: top;
2563-
line-height: 20px;
25642564
font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
25652565
font-size: 12px;
25662566
}
25672567

2568-
.pr-diff__row--context td { background-color: $white; }
2569-
.pr-diff__row--add td { background-color: #e6ffec; }
2570-
.pr-diff__row--del td { background-color: #ffebe9; }
2568+
.pr-diff__table > p.h {
2569+
display: block;
2570+
background-color: #ddf4ff;
2571+
}
2572+
2573+
.pr-diff__table > p.h > code {
2574+
display: block;
2575+
color: #57606a;
2576+
padding: 4px 12px;
2577+
font-size: 12px;
2578+
font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
2579+
}
2580+
2581+
.pr-diff__table > p.c > * { background-color: $white; }
2582+
.pr-diff__table > p.a > * { background-color: #e6ffec; }
2583+
.pr-diff__table > p.d > * { background-color: #ffebe9; }
25712584

2572-
.pr-diff__row--add .pr-diff__lineno,
2573-
.pr-diff__row--add .pr-diff__sign {
2585+
.pr-diff__table > p.a > u,
2586+
.pr-diff__table > p.a > i {
25742587
background-color: #ccffd8;
25752588
}
25762589

2577-
.pr-diff__row--del .pr-diff__lineno,
2578-
.pr-diff__row--del .pr-diff__sign {
2590+
.pr-diff__table > p.d > u,
2591+
.pr-diff__table > p.d > i {
25792592
background-color: #ffd7d5;
25802593
}
25812594

2582-
.pr-diff__lineno {
2595+
.pr-diff__table > p > u {
25832596
color: rgba(36, 41, 46, 0.4);
25842597
text-align: right;
2585-
width: 1%;
2598+
text-decoration: none;
25862599
user-select: none;
2587-
min-width: 40px;
25882600
border-right: 1px solid rgba(0, 0, 0, 0.04);
25892601
}
25902602

2591-
.pr-diff__sign {
2592-
width: 1%;
2593-
min-width: 18px;
2603+
.pr-diff__table > p > i {
2604+
color: inherit;
2605+
font-style: normal;
25942606
text-align: center;
25952607
user-select: none;
25962608
}
25972609

2598-
.pr-diff__content {
2599-
width: 100%;
2600-
2601-
pre {
2602-
margin: 0;
2603-
font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
2604-
font-size: 12px;
2605-
line-height: 20px;
2606-
white-space: pre;
2607-
}
2610+
.pr-diff__table > p > s {
2611+
display: block;
2612+
text-decoration: none;
26082613

26092614
b {
26102615
font-weight: 600;
@@ -2622,22 +2627,23 @@ form {
26222627
}
26232628
}
26242629

2625-
.pr-diff__commentrow td {
2630+
.pr-diff__table > p.m {
26262631
background-color: $white;
26272632
padding: 4px 8px;
26282633
}
26292634

2630-
.pr-files-content .pr-diff__commentrow {
2635+
.pr-files-content .pr-diff__table > p.m {
26312636
display: none;
26322637
}
26332638

2634-
.pr-files-content .pr-diff__row:hover + .pr-diff__commentrow,
2635-
.pr-files-content .pr-diff__commentrow:hover,
2636-
.pr-files-content .pr-diff__commentrow:focus-within {
2637-
display: table-row;
2639+
.pr-files-content .pr-diff__table > p.a:hover + p.m,
2640+
.pr-files-content .pr-diff__table > p.d:hover + p.m,
2641+
.pr-files-content .pr-diff__table > p.m:hover,
2642+
.pr-files-content .pr-diff__table > p.m:focus-within {
2643+
display: block;
26382644
}
26392645

2640-
.pr-diff__commentbox {
2646+
.pr-diff__table > p.m > textarea {
26412647
width: 100%;
26422648
box-sizing: border-box;
26432649
font-family: system-ui, sans-serif;
@@ -2646,22 +2652,24 @@ form {
26462652
resize: vertical;
26472653
}
26482654

2649-
.pr-diff__inline-comment td {
2655+
.pr-diff__table > p.n {
26502656
background-color: #fffbea;
26512657
padding: 8px 12px;
2652-
}
2653-
2654-
.pr-inline-comment {
26552658
font-family: system-ui, sans-serif;
2659+
font-size: 13px;
26562660

2657-
p {
2658-
margin: 4px 0 0;
2661+
i {
2662+
color: $gray-dark;
2663+
font-size: 12px;
2664+
font-style: normal;
26592665
}
2660-
}
26612666

2662-
.pr-inline-comment__meta {
2663-
color: $gray-dark;
2664-
font-size: 12px;
2667+
s {
2668+
display: block;
2669+
margin-top: 4px;
2670+
text-decoration: none;
2671+
white-space: pre-wrap;
2672+
}
26652673
}
26662674

26672675
.pr-review-form {

templates/commit.html

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,7 @@ <h1 class="commit-page__title">@commit.message</h1>
5656
@if fd.is_binary
5757
<div class="pr-diff__binary">%commit_binary_file</div>
5858
@else
59-
<table class="pr-diff__table">
60-
@for hunk in fd.hunks
61-
<tr class="pr-diff__hunk-header">
62-
<td colspan="4"><code>@hunk.header</code></td>
63-
</tr>
64-
@for dline in hunk.lines
65-
<tr class="pr-diff__row pr-diff__row--@dline.kind">
66-
<td class="pr-diff__lineno">@{dline.old_line_str()}</td>
67-
<td class="pr-diff__lineno">@{dline.new_line_str()}</td>
68-
<td class="pr-diff__sign">@{dline.sign()}</td>
69-
<td class="pr-diff__content"><pre>@{render_diff_line(dline.content, fd.path)}</pre></td>
70-
</tr>
71-
@end
72-
@end
73-
</table>
59+
@{render_diff_table(fd)}
7460
@end
7561
</div>
7662
@end

templates/pull_files.html

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -131,29 +131,7 @@ <h1 class="pr-header__title">@{pr.formatted_title()} <span class="pr-header__num
131131
@if fd.is_binary
132132
<div class='pr-diff__binary'>%pr_binary_file</div>
133133
@else
134-
<table class='pr-diff__table'>
135-
@for hunk in fd.hunks
136-
<tr class='pr-diff__hunk-header'>
137-
<td colspan='4'><code>@hunk.header</code></td>
138-
</tr>
139-
@for dline in hunk.lines
140-
<tr class='pr-diff__row pr-diff__row--@dline.kind'>
141-
<td class='pr-diff__lineno'>@{dline.old_line_str()}</td>
142-
<td class='pr-diff__lineno'>@{dline.new_line_str()}</td>
143-
<td class='pr-diff__sign'>@{dline.sign()}</td>
144-
<td class='pr-diff__content'><pre>@{render_diff_line(dline.content, fd.path)}</pre></td>
145-
</tr>
146-
@{render_inline_comments(fd.path, dline, comments_by_key)}
147-
@if ctx.logged_in && pr.is_open() && dline.kind != 'context'
148-
<tr class='pr-diff__commentrow'>
149-
<td colspan='4'>
150-
<textarea name='@{dline.comment_field_name(fd.path)}' placeholder='%pr_line_comment_placeholder' rows='2' class='pr-diff__commentbox'></textarea>
151-
</td>
152-
</tr>
153-
@end
154-
@end
155-
@end
156-
</table>
134+
@{render_pr_diff_table(fd, comments_by_key, can_comment, ctx.lang)}
157135
@end
158136
</div>
159137
@end

0 commit comments

Comments
 (0)