[OCaml] Mobile-friendly clone of cgit.
feat rank repositories by recency on root page
Sort repositories by most recent HEAD commit date. Display a right-aligned relative time span (identical style to the commits page) next to each repository name. Repos without a resolvable HEAD appear last.
Changed files
lib/handlers.ml
@@ -18,8 +18,29 @@
18
18
let root config _request =
19
19
match Resolvers.repositories config with
20
20
| Ok repositories ->
21
Removed:
Views.root ~user:config.Config.user ~root_title:(root_title config)
22
Removed:
repositories
21
Added:
let open Lwt.Syntax in
22
Added:
let* repos_with_dates =
23
Added:
Lwt_list.map_p
24
Added:
(fun name ->
25
Added:
Lwt.bind (Resolvers.open_repository config name) @@ function
26
Added:
| Error _ -> Lwt.return (name, None)
27
Added:
| Ok repository ->
28
Added:
let* date = Resolvers.head_commit_date repository in
29
Added:
let* () = Resolvers.close_repository repository in
30
Added:
Lwt.return (name, date))
31
Added:
repositories
32
Added:
in
33
Added:
let sorted =
34
Added:
List.sort
35
Added:
(fun (_, a) (_, b) ->
36
Added:
match (a, b) with
37
Added:
| None, None -> 0
38
Added:
| None, Some _ -> 1
39
Added:
| Some _, None -> -1
40
Added:
| Some (ta, _), Some (tb, _) -> Int64.compare tb ta)
41
Added:
repos_with_dates
42
Added:
in
43
Added:
Views.root ~user:config.Config.user ~root_title:(root_title config) sorted
23
44
| Error error -> error_response error
24
45
25
46
module Repo = struct
lib/resolvers.ml
@@ -210,6 +210,21 @@
210
210
| Error error -> Lwt_result.fail (Store_error error)
211
211
| Ok value -> Lwt_result.return value
212
212
213
Added:
let head_commit_date repository =
214
Added:
let open Lwt.Syntax in
215
Added:
let* result =
216
Added:
Lwt_result.bind (resolve_head_hash repository) @@ fun hash ->
217
Added:
Lwt.bind (Store.read repository.store hash) @@ function
218
Added:
| Error _ -> Lwt_result.return None
219
Added:
| Ok value -> (
220
Added:
match value with
221
Added:
| Git.Value.Commit commit ->
222
Added:
let author = Store.Value.Commit.author commit in
223
Added:
Lwt_result.return (Some author.Git.User.date)
224
Added:
| _ -> Lwt_result.return None)
225
Added:
in
226
Added:
Lwt.return (Result.value result ~default:None)
227
Added:
213
228
module Commit = struct
214
229
type user = Git.User.t
215
230
lib/resolvers.mli
@@ -30,6 +30,9 @@
30
30
val repository_description : repository -> string
31
31
val close_repository : repository -> unit Lwt.t
32
32
33
Added:
val head_commit_date :
34
Added:
repository -> (int64 * Git.User.tz_offset option) option Lwt.t
35
Added:
33
36
(** {1 Repository metadata} *)
34
37
35
38
val default_repo_description : string
lib/views/root.ml
@@ -2,9 +2,40 @@
2
2
3
3
open Dream_html
4
4
5
Added:
let relative_time (date, _) =
6
Added:
let seconds = Unix.time () -. Int64.to_float date |> int_of_float in
7
Added:
let minutes = seconds / 60 in
8
Added:
let hours = minutes / 60 in
9
Added:
let days = hours / 24 in
10
Added:
let months = days / 30 in
11
Added:
let years = months / 12 in
12
Added:
let quantity value singular =
13
Added:
Printf.sprintf "%d %s%s ago" value singular (if value = 1 then "" else "s")
14
Added:
in
15
Added:
match seconds with
16
Added:
| s when s < 60 -> "just now"
17
Added:
| _ when minutes < 60 -> quantity minutes "minute"
18
Added:
| _ when hours < 24 -> quantity hours "hour"
19
Added:
| _ when days < 30 -> quantity days "day"
20
Added:
| _ when months < 12 -> quantity months "month"
21
Added:
| _ -> quantity years "year"
22
Added:
5
23
let render ~user ~root_title repositories =
6
Removed:
let li_of_repo repo =
7
Removed:
HTML.li [] [ Routes.link_to (Routes.Repo repo) (txt "%s" repo) ]
24
Added:
let li_of_repo (repo_name, date) =
25
Added:
let ago_span =
26
Added:
match date with
27
Added:
| None -> HTML.null []
28
Added:
| Some d ->
29
Added:
HTML.(span [ class_ "commit-ago" ] [ txt "%s" (relative_time d) ])
30
Added:
in
31
Added:
HTML.(
32
Added:
li []
33
Added:
[
34
Added:
span
35
Added:
[ class_ "commit-left" ]
36
Added:
[ Routes.link_to (Routes.Repo repo_name) (txt "%s" repo_name) ];
37
Added:
ago_span;
38
Added:
])
8
39
in
9
40
let all_repositories =
10
41
HTML.(