type head_data = { page_title : string } type body_data = { title : string; subtitle : string; content : Dream_html.node list; } module Components = struct open Dream_html let topnav current_path = let open HTML in let li_of_a (path, text) = let is_active = path = current_path in let attrs = if is_active then [ id "active" ] else [] in let url = if String.equal path "/" then Printf.sprintf "/%s/" current_path else Printf.sprintf "/%s/%s" current_path path in li attrs [ a [ href "%s" url ] [ txt text ] ] in nav [ id "top" ] [ ul [] @@ List.map li_of_a [ ("/", "summary"); ("refs/", "refs"); ("log/", "log"); ("tree/", "tree"); ("commit/", "commit"); ]; ] end module Page = struct open Dream_html open HTML let header title subtitle = null [ h1 [] [ txt "%s" title ]; h2 [] [ txt "%s" subtitle ] ] let footer () = let today = Unix.localtime (Unix.time ()) in let year = string_of_int (today.Unix.tm_year + 1900) in let footer_text = Printf.sprintf "Copyright %s %s" year Config.author in footer [] [ txt "%s" footer_text ] let default_head_data = { page_title = "Ogit" } let render ?(head_data = default_head_data) body_data = html [] [ head [] [ title [] "%s" head_data.page_title; link [ rel "stylesheet"; href "/static/styles.css" ]; link [ rel "icon"; type_ "image/x-icon"; href "/static/git_icon.svg" ]; ]; body [] [ header body_data.title body_data.subtitle; Components.topnav body_data.title; div [ id "main" ] body_data.content; footer (); ]; ] end let root () = let open Dream_html in let repositories_in directory = let repos = Sys.readdir directory |> Array.to_list |> List.sort String.compare in let li_of_repo repo = HTML.(li [] [ a [ href "%s/" repo ] [ txt "%s" repo ] ]) in HTML.(div [ id "repositories" ] [ ul [] @@ List.map li_of_repo repos ]) in let body_data = { title = "Ogit"; subtitle = "Repositories for " ^ Config.author; content = [ repositories_in Config.git_directory ]; } in Page.render body_data module Repo = struct let summary repo_path branches commits authors = let open Dream_html in let li_of_branch branch = HTML.(li [] [ a [ href "%s" branch ] [ txt "%s" branch ] ]) in let li_of_commit (commit : Git_helpers.Commit.t) = match commit.message with | Some msg -> HTML.( li [] [ a [ href "commit/?id=%s" commit.hash ] [ txt "%s %s" (Git_helpers.short_hash commit.hash) msg ]; ]) | None -> HTML.(li [] [ a [ href "" ] [ txt "caca!!" ] ]) in let li_of_author author = HTML.(li [] [ a [ href "" ] [ txt "%s" author ] ]) in let content = HTML. [ h3 [] [ txt "Branches" ]; ul [] (List.map li_of_branch branches); h3 [] [ txt "Recent commits" ]; ul [] (List.map li_of_commit commits); h3 [] [ txt "Authors" ]; ul [] (List.map li_of_author authors); ] in Page.render { title = repo_path; subtitle = Git_helpers.repo_description repo_path; content; } let refs repo_path = let open Dream_html in Page.render HTML. { title = repo_path; subtitle = Git_helpers.repo_description repo_path; content = [ null [] ]; } let log repo_path = let open Dream_html in Page.render HTML. { title = repo_path; subtitle = Git_helpers.repo_description repo_path; content = [ null [] ]; } let tree repo_path = let open Dream_html in Page.render HTML. { title = repo_path; subtitle = Git_helpers.repo_description repo_path; content = [ null [] ]; } let commit repo_path (commit : Git_helpers.Commit.t) = let open Dream_html in let open Git_helpers in let message = match commit.message with Some msg -> msg | None -> "" in let content = HTML.[ h3 [] [ txt "%s" message ] ] in let title = Printf.sprintf "%s : %s" repo_path (short_hash commit.hash) in Page.render { title; subtitle = ""; content } end let error_page message = let open Dream_html in HTML.( html [] [ head [] [ title [] "Fatal Error"; link [ rel "stylesheet"; href "/static/styles.css" ]; link [ rel "icon"; type_ "image/x-icon"; href "/static/git_icon.svg" ]; ]; body [] [ h1 [] [ txt "Fatal Error" ]; div [ id "main" ] [ p [] [ b [] [ txt "%s" message ] ]; p [] [ txt "Your best course of action is to press the 'back' \ button in your browser."; ]; ]; ]; ])