RepoHome.tsx
⎇
Raw
1import config from "../../config.ts";
2import type { RepositoryRow } from "../../db/index.ts";
3import type { SessionUser } from "../../middleware/session.ts";
4import type { TreeEntry } from "../../services/git.ts";
5import { Layout } from "../layout.tsx";
6import { BranchSelector } from "./BranchSelector.tsx";
7import { FileTreeTable } from "./FileTreeTable.tsx";
8import { RepoHeader } from "./RepoHeader.tsx";
9import { RepoNav } from "./RepoNav.tsx";
10
11interface RepoHomeProps {
12 user: SessionUser | null;
13 repo: RepositoryRow;
14 entries: TreeEntry[];
15 readmeHtml: string | null;
16 readmePath?: string;
17 hasContent: boolean;
18 branches: string[];
19 tags?: string[];
20}
21
22export function RepoHome({
23 user,
24 repo,
25 entries,
26 readmeHtml,
27 readmePath,
28 hasContent,
29 branches,
30 tags,
31}: RepoHomeProps) {
32 return (
33 <Layout user={user} title={repo.name}>
34 <div class="container">
35 <RepoHeader repo={repo} />
36 {!!repo.description && (
37 <p class="repo-description" safe>
38 {repo.description}
39 </p>
40 )}
41 <RepoNav repo={repo} active="code" user={user} />
42 {!hasContent ? (
43 <div class="empty-state">
44 <h2>This repository is empty.</h2>
45 <p>Push your first commit to get started:</p>
46 <pre class="code-setup">
47 <code safe>{`git clone ${httpUrl(repo.name)}${
48 config.SSH_DISABLED
49 ? ""
50 : `\n# or: git clone ${sshUrl(repo.name)}`
51 }
52cd ${repo.name}
53echo "# ${repo.name}" > README.md
54git add .
55git commit -m "Initial commit"
56git push origin main`}</code>
57 </pre>
58 </div>
59 ) : (
60 <>
61 <div class="tree-toolbar">
62 <BranchSelector
63 repoName={repo.name}
64 branches={branches}
65 tags={tags}
66 currentRef={repo.default_branch}
67 view="tree"
68 />
69 <div class="tree-toolbar-actions">
70 {branches.includes(repo.default_branch) &&
71 user?.isAdmin && (
72 <a
73 href={`/${repo.name}/new-file/${repo.default_branch}`}
74 class="btn btn-sm btn-primary"
75 >
76 New file
77 </a>
78 )}
79 <details class="clone-popup-details">
80 <summary class="btn btn-sm btn-primary">
81 Clone
82 </summary>
83 <div class="clone-popup">
84 <div class="clone-url-row">
85 <span class="clone-url-label">
86 HTTP
87 </span>
88 <input
89 type="text"
90 readonly
91 value={httpUrl(repo.name)}
92 class="clone-url-input"
93 />
94 </div>
95 {!config.SSH_DISABLED && (
96 <div class="clone-url-row">
97 <span class="clone-url-label">
98 SSH
99 </span>
100 <input
101 type="text"
102 readonly
103 value={sshUrl(repo.name)}
104 class="clone-url-input"
105 />
106 </div>
107 )}
108 </div>
109 </details>
110 </div>
111 </div>
112 <FileTreeTable
113 repoName={repo.name}
114 treeRef={repo.default_branch}
115 subpath=""
116 entries={entries}
117 />
118 {!!readmeHtml && (
119 <div class="readme-section">
120 <div class="readme-header">
121 <span>README</span>
122 {!!readmePath && (
123 <a
124 href={`/${repo.name}/raw/${repo.default_branch}/${readmePath}`}
125 class="btn btn-sm"
126 >
127 Raw
128 </a>
129 )}
130 </div>
131 <div class="markdown-body">
132 {readmeHtml as "safe"}
133 </div>
134 </div>
135 )}
136 </>
137 )}
138 </div>
139 </Layout>
140 );
141}
142
143function httpUrl(name: string) {
144 return `${config.BASE_URL}/${name}.git`;
145}
146
147function sshUrl(name: string) {
148 const host = new URL(config.BASE_URL).hostname;
149 return `ssh://git@${host}:${config.SSH_PORT}/${name}.git`;
150}
151