diff options
author | Marius Peter <marius.peter@tutanota.com> | 2025-03-15 19:17:14 +0100 |
---|---|---|
committer | Marius Peter <marius.peter@tutanota.com> | 2025-03-15 19:17:14 +0100 |
commit | 346d17a1f4c78a05fb1fe010eb1a9e646c8b04a3 (patch) | |
tree | f1151c0e5bb1649158735a219e0744e11f3015b3 /lib/views.ml | |
parent | 55993c4d0857aec8a372aee989aaeef61ea37b3c (diff) |
Great work today, again!
Diffstat (limited to 'lib/views.ml')
-rw-r--r-- | lib/views.ml | 121 |
1 files changed, 67 insertions, 54 deletions
diff --git a/lib/views.ml b/lib/views.ml index 2d11674..d09892b 100644 --- a/lib/views.ml +++ b/lib/views.ml @@ -29,6 +29,7 @@ module Layout = struct [ 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 [] [ @@ -68,30 +69,6 @@ module Topnav = struct ("diff", "diff"); ]; ] - - (* let li_of_a (path, text) = *) - (* let is_active = path = current_path in *) - (* li (if is_active then [ id "active" ] else []) in *) - (* let link_of_path = *) - (* if String.length path = 0 then Printf.sprintf "/%s" repo_path *) - (* else Printf.sprintf "/%s/%s" repo_path path *) - (* in *) - (* li [ id "active" ] [ a [ href "%s" link_of_path ] [ txt text ] ] *) - (* in *) - (* nav *) - (* [ id "top" ] *) - (* [ *) - (* ul [] *) - (* @@ List.map li_of_a *) - (* [ *) - (* ("", "summary"); *) - (* ("refs", "refs"); *) - (* ("log", "log"); *) - (* ("tree", "tree"); *) - (* ("commit", "commit"); *) - (* ("diff", "diff"); *) - (* ]; *) - (* ] *) end module Ogit_root = struct @@ -123,13 +100,6 @@ module Repo_root = struct open Dream_html open HTML - (* let href_for_git_object kind identifier = *) - (* let open Printf in *) - (* href "%s" @@ *) - (* match kind with *) - (* | `Branch -> sprintf "/tree/%s" identifier *) - (* | `Commit -> sprintf "/commit/%s" identifier *) - let render repo_path = let title = repo_path in let subtitle = Filename.concat Config.git_directory repo_path in @@ -159,41 +129,84 @@ module Repo_tree = struct open Dream_html open HTML - let full_path repo_path = Filename.concat Config.git_directory repo_path + let full_path repo_path dir_path = + Filename.concat (Filename.concat Config.git_directory repo_path) dir_path - (* Helper function to list top-level files and directories *) - let ls_repo repo_path = + (* Helper function to list contents of a given directory *) + let ls_dir repo_path dir_path = + let dir_full_path = full_path repo_path dir_path in try - Sys.readdir (full_path repo_path) + Sys.readdir dir_full_path |> Array.to_list |> List.filter (fun name -> name <> ".git") (* Exclude .git *) - |> List.sort String.compare + |> List.map (fun entry -> + let entry_rel_path = Filename.concat dir_path entry in + let full_entry_path = Filename.concat dir_full_path entry in + (entry, entry_rel_path, Sys.is_directory full_entry_path)) + |> List.sort (fun (a, _, is_dir_a) (b, _, is_dir_b) -> + match (is_dir_a, is_dir_b) with + | true, false -> -1 (* Directories first *) + | false, true -> 1 + | _ -> String.compare a b) with Sys_error _ -> [] (* Function to create a link based on file type *) - let link_for_entry repo_path entry = - let entry_path = Filename.concat (full_path repo_path) entry in - if Sys.is_directory entry_path then - a - [ href "%s" @@ Printf.sprintf "/%s/tree/%s" repo_path entry ] - [ txt "%s" (entry ^ "/") ] - else - a - [ href "%s" @@ Printf.sprintf "/%s/blob/%s" repo_path entry ] - [ txt "%s" entry ] - - let li_of_entry repo_path entry = li [] [ link_for_entry repo_path entry ] + let link_for_entry repo_path (entry, entry_rel_path, is_dir) = + let link = + if is_dir then Printf.sprintf "/%s/tree/%s" repo_path entry_rel_path + else Printf.sprintf "/%s/blob/%s" repo_path entry_rel_path + in + li [] [ a [ href "%s" link ] [ txt "%s" entry ] ] - (* Render function *) - let render repo_path = - let title = repo_path in - let subtitle = "Files" in + (* Render function, now supporting nested directories *) + let render repo_path dir_path = + let title = Filename.concat repo_path dir_path in + let subtitle = "Repository Files" in - let repo_entries = ls_repo repo_path in - let content = [ ul [] (List.map (li_of_entry repo_path) repo_entries) ] in + let repo_entries = ls_dir repo_path dir_path in + let content = + [ + h3 [] [ txt "%s" (Printf.sprintf "Contents of /%s" dir_path) ]; + ul [] (List.map (link_for_entry repo_path) repo_entries); + ] + in let body_data = { title; subtitle; topnav = Topnav.repo repo_path "tree"; content } in Layout.application body_data end + +module Repo_blob = struct + open Dream_html + open HTML + + let full_path repo_path = Filename.concat Config.git_directory repo_path + + (* Read the contents of a file *) + let read_blob repo_path blob_name = + let file_path = Filename.concat (full_path repo_path) blob_name in + try Some (In_channel.with_open_text file_path In_channel.input_all) + with _ -> None (* Handle cases where the file doesn't exist or can't be read *) + + (* Render function *) + let render repo_path blob_name = + let title = blob_name in + let subtitle = "File Contents" in + + match read_blob repo_path blob_name with + | Some content -> + let content_display = + pre [] [ code [] [ txt "%s" content ] ] (* Render as code block *) + in + let body_data = + { title; subtitle; topnav = Topnav.repo repo_path "blob"; content = [content_display] } + in + Layout.application body_data + | None -> + let error_message = p [] [ txt "Error: Unable to read file." ] in + let body_data = + { title; subtitle; topnav = Topnav.repo repo_path "blob"; content = [error_message] } + in + Layout.application body_data +end |