[OCaml] Mobile-friendly clone of cgit.
feat color-coded conventional commit type pills in commit lists
Parse commit summaries for conventional commit types (feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert). When detected, display a color-coded pill between the timestamp and the commit title. On narrow screens, the timestamp is hidden to prioritize showing the commit type pill, truncated title, and relative ago time.
Changed files
lib/static/styles.css
@@ -201,6 +201,80 @@
201
201
color: #555;
202
202
}
203
203
204
Added:
.commit-pill {
205
Added:
display: inline-block;
206
Added:
padding: 0.15em 0.5em;
207
Added:
border-radius: 1em;
208
Added:
font-size: 0.75em;
209
Added:
font-weight: 600;
210
Added:
text-transform: uppercase;
211
Added:
letter-spacing: 0.03em;
212
Added:
margin-right: 0.5em;
213
Added:
vertical-align: middle;
214
Added:
flex-shrink: 0;
215
Added:
}
216
Added:
217
Added:
.commit-pill-feat {
218
Added:
background-color: #1a4d2e;
219
Added:
color: #6ee7a0;
220
Added:
}
221
Added:
222
Added:
.commit-pill-fix {
223
Added:
background-color: #4d1a1a;
224
Added:
color: #f87171;
225
Added:
}
226
Added:
227
Added:
.commit-pill-docs {
228
Added:
background-color: #1a3a4d;
229
Added:
color: #7dd3fc;
230
Added:
}
231
Added:
232
Added:
.commit-pill-style {
233
Added:
background-color: #3d1a4d;
234
Added:
color: #d8b4fe;
235
Added:
}
236
Added:
237
Added:
.commit-pill-refactor {
238
Added:
background-color: #4d3a1a;
239
Added:
color: #fbbf24;
240
Added:
}
241
Added:
242
Added:
.commit-pill-perf {
243
Added:
background-color: #4d2d1a;
244
Added:
color: #fb923c;
245
Added:
}
246
Added:
247
Added:
.commit-pill-test {
248
Added:
background-color: #1a2e4d;
249
Added:
color: #93c5fd;
250
Added:
}
251
Added:
252
Added:
.commit-pill-build {
253
Added:
background-color: #2d2d2d;
254
Added:
color: #a3a3a3;
255
Added:
}
256
Added:
257
Added:
.commit-pill-ci {
258
Added:
background-color: #2d2d2d;
259
Added:
color: #a3a3a3;
260
Added:
}
261
Added:
262
Added:
.commit-pill-chore {
263
Added:
background-color: #2d2d2d;
264
Added:
color: #a3a3a3;
265
Added:
}
266
Added:
267
Added:
.commit-pill-revert {
268
Added:
background-color: #4d1a3a;
269
Added:
color: #f9a8d4;
270
Added:
}
271
Added:
272
Added:
.commit-title {
273
Added:
overflow: hidden;
274
Added:
text-overflow: ellipsis;
275
Added:
white-space: nowrap;
276
Added:
}
277
Added:
204
278
h1 {
205
279
padding: 0;
206
280
}
@@ -404,6 +478,10 @@
404
478
405
479
div#main {
406
480
padding: 0 0.5em;
481
Added:
}
482
Added:
483
Added:
.timestamp {
484
Added:
display: none;
407
485
}
408
486
409
487
footer {
lib/views/repo.ml
@@ -33,6 +33,41 @@
33
33
let body = String.concat "\n" rest |> String.trim in
34
34
body)
35
35
36
Added:
let conventional_commit_types =
37
Added:
[
38
Added:
"feat";
39
Added:
"fix";
40
Added:
"docs";
41
Added:
"style";
42
Added:
"refactor";
43
Added:
"perf";
44
Added:
"test";
45
Added:
"build";
46
Added:
"ci";
47
Added:
"chore";
48
Added:
"revert";
49
Added:
]
50
Added:
51
Added:
let parse_conventional summary =
52
Added:
match String.index_opt summary ':' with
53
Added:
| None -> (None, summary)
54
Added:
| Some colon_pos ->
55
Added:
let prefix = String.sub summary 0 colon_pos in
56
Added:
let type_name =
57
Added:
match String.index_opt prefix '(' with
58
Added:
| Some paren_pos -> String.sub prefix 0 paren_pos
59
Added:
| None -> prefix
60
Added:
in
61
Added:
let type_lower = String.lowercase_ascii type_name in
62
Added:
if List.mem type_lower conventional_commit_types then
63
Added:
let rest =
64
Added:
String.sub summary (colon_pos + 1)
65
Added:
(String.length summary - colon_pos - 1)
66
Added:
|> String.trim
67
Added:
in
68
Added:
(Some type_lower, rest)
69
Added:
else (None, summary)
70
Added:
36
71
let li_of_commit repo (commit : Resolvers.Commit.t) =
37
72
let timestamp (date, _) =
38
73
let tm = date |> Int64.to_float |> Unix.localtime in
@@ -68,12 +103,22 @@
68
103
Printf.sprintf "%d year%s ago" years
69
104
(if years = 1 then "" else "s")
70
105
in
106
Added:
let summary = commit_summary commit.message in
107
Added:
let commit_type, title = parse_conventional summary in
71
108
let timestamp_span =
72
109
HTML.(
73
110
span [ class_ "timestamp" ] [ txt "%s" (timestamp commit.author.date) ])
74
111
in
75
Removed:
let summary = commit_summary commit.message in
76
Removed:
let description = if summary = "" then HTML.null [] else txt " %s" summary in
112
Added:
let pill =
113
Added:
match commit_type with
114
Added:
| None -> HTML.null []
115
Added:
| Some t ->
116
Added:
HTML.(
117
Added:
span
118
Added:
[ class_ (Printf.sprintf "commit-pill commit-pill-%s" t) ]
119
Added:
[ txt "%s" t ])
120
Added:
in
121
Added:
let title_span = HTML.(span [ class_ "commit-title" ] [ txt "%s" title ]) in
77
122
let ago_span =
78
123
HTML.(
79
124
span [ class_ "commit-ago" ] [ txt "%s" (time_ago commit.author.date) ])
@@ -83,7 +128,7 @@
83
128
HTML.(
84
129
null
85
130
[
86
Removed:
span [ class_ "commit-left" ] [ timestamp_span; description ];
131
Added:
span [ class_ "commit-left" ] [ timestamp_span; pill; title_span ];
87
132
ago_span;
88
133
])
89
134
in