This repository has no description
1{{ define "title" }}{{ .RepoInfo.FullName }} at {{ .Ref }} · Tangled{{ end }}
2
3
4{{ define "extrameta" }}
5 {{ template "repo/fragments/meta" . }}
6
7 {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }}
8{{ end }}
9
10{{ define "repoContent" }}
11 <main>
12 {{ if .Languages }}
13 {{ block "repoLanguages" . }}{{ end }}
14 {{ end }}
15 <div class="flex flex-wrap items-center justify-between gap-3 pb-5">
16 {{ block "branchSelector" . }}{{ end }}
17 <form id="search-form" class="relative flex items-center h-[32px] order-last w-full md:order-none md:w-64" method="GET" action="/{{ .RepoInfo.FullName }}/search">
18 <span class="absolute left-2 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none">
19 {{ i "search-code" "w-4 h-4" }}
20 </span>
21 <input
22 id="search-q"
23 class="w-full h-full py-1 pl-8 pr-8 peer"
24 type="text"
25 name="q"
26 placeholder="Find files or code..."
27 >
28 <button
29 type="button"
30 onclick="const i=document.getElementById('search-q');i.value='';i.focus();"
31 class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hidden peer-[:not(:placeholder-shown)]:block"
32 >
33 {{ i "x" "w-4 h-4" }}
34 </button>
35 </form>
36 <div class="flex items-center gap-3">
37 <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
38 {{ i "git-commit-horizontal" "w-4" "h-4" }} {{ scaleFmt .TotalCommits }}
39 </a>
40 <a href="/{{ .RepoInfo.FullName }}/branches" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
41 {{ i "git-branch" "w-4" "h-4" }} {{ scaleFmt (len .Branches) }}
42 </a>
43 <a href="/{{ .RepoInfo.FullName }}/tags" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
44 {{ i "tags" "w-4" "h-4" }} {{ scaleFmt (len .Tags) }}
45 </a>
46 {{ template "repo/fragments/cloneDropdown" . }}
47 </div>
48 </div>
49 <div class="grid grid-cols-1 md:grid-cols-2 gap-2">
50 {{ block "fileTree" . }}{{ end }}
51 {{ block "rightInfo" . }}{{ end }}
52 </div>
53 </main>
54{{ end }}
55
56{{ define "repoLanguages" }}
57 <details class="group -my-4 -m-6 mb-4">
58 <summary class="flex gap-[1px] h-4 scale-y-50 hover:scale-y-100 origin-top group-open:scale-y-100 transition-all hover:cursor-pointer overflow-hidden rounded-t">
59 {{ range $value := .Languages }}
60 <div
61 title='{{ or $value.Name "Other" }} {{ printf "%.1f" $value.Percentage }}%'
62 style="background-color: {{ $value.Color }}; width: {{ $value.Percentage }}%"
63 ></div>
64 {{ end }}
65 </summary>
66 <div class="px-4 py-2 border-b border-gray-200 dark:border-gray-600 flex items-center gap-4 flex-wrap">
67 {{ range $value := .Languages }}
68 <div
69 class="flex flex-grow items-center gap-2 text-xs align-items-center justify-center"
70 >
71 {{ template "repo/fragments/colorBall" (dict "color" (langColor $value.Name)) }}
72 <div>{{ or $value.Name "Other" }}
73 <span class="text-gray-500 dark:text-gray-400">
74 {{ if lt $value.Percentage 0.05 }}
75 0.1%
76 {{ else }}
77 {{ printf "%.1f" $value.Percentage }}%
78 {{ end }}
79 </span></div>
80 </div>
81 {{ end }}
82 </div>
83 </details>
84{{ end }}
85
86{{ define "branchSelector" }}
87 <div class="flex gap-2 items-center justify-between flex-1 min-w-0">
88 <div class="flex gap-2 items-stretch">
89 <select
90 onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)"
91 class="max-w-32 sm:max-w-64"
92 >
93 <optgroup label="Branches ({{len .Branches}})" class="bold text-sm">
94 {{ range .Branches }}
95 <option
96 value="{{ .Reference.Name }}"
97 class="py-1"
98 {{ if eq .Reference.Name $.Ref }}
99 selected
100 {{ end }}
101 >
102 {{ .Reference.Name }}
103 </option>
104 {{ end }}
105 </optgroup>
106 <optgroup label="Tags ({{len .Tags}})" class="bold text-sm">
107 {{ range .Tags }}
108 <option
109 value="{{ .Reference.Name }}"
110 class="py-1"
111 {{ if eq .Reference.Name $.Ref }}
112 selected
113 {{ end }}
114 >
115 {{ .Reference.Name }}
116 </option>
117 {{ else }}
118 <option class="py-1" disabled>No tags found</option>
119 {{ end }}
120 </optgroup>
121 </select>
122 <div class="flex items-center gap-2">
123 <a
124 href="/{{ .RepoInfo.FullName }}/compare?base={{ $.Ref | urlquery }}"
125 class="btn flex items-center gap-2 no-underline hover:no-underline"
126 title="Compare branches or tags"
127 >
128 {{ i "git-compare" "w-4 h-4" }}
129 </a>
130 </div>
131 </div>
132 </div>
133{{ end }}
134
135{{ define "fileTree" }}
136 <div id="file-tree" class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700" >
137 {{ $linkstyle := "no-underline hover:underline dark:text-white" }}
138
139 {{ range .Files }}
140 <div class="grid grid-cols-3 gap-4 items-center py-1">
141 <div class="col-span-2">
142 {{ $link := printf "/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) .Name }}
143 {{ $icon := "folder" }}
144 {{ $iconStyle := "size-4 fill-current" }}
145
146 {{ if .IsSubmodule }}
147 {{ $link = printf "/%s/%s/%s/%s" $.RepoInfo.FullName "blob" (urlquery $.Ref) .Name }}
148 {{ $icon = "folder-input" }}
149 {{ $iconStyle = "size-4" }}
150 {{ end }}
151
152 {{ if .IsFile }}
153 {{ $link = printf "/%s/%s/%s/%s" $.RepoInfo.FullName "blob" (urlquery $.Ref) .Name }}
154 {{ $icon = "file" }}
155 {{ $iconStyle = "size-4" }}
156 {{ end }}
157
158 <a href="{{ $link }}" class="{{ $linkstyle }}">
159 <div class="flex items-center gap-2">
160 {{ i $icon $iconStyle "flex-shrink-0" }}
161 <span class="truncate">{{ .Name }}</span>
162 </div>
163 </a>
164 </div>
165
166 <div class="text-sm col-span-1 text-right">
167 {{ with .LastCommit }}
168 <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a>
169 {{ end }}
170 </div>
171 </div>
172 {{ end }}
173 </div>
174{{ end }}
175
176{{ define "rightInfo" }}
177 <div id="right-info" class="hidden md:block col-span-1">
178 {{ block "commitLog" . }} {{ end }}
179 {{ block "branchList" . }} {{ end }}
180 {{ block "tagList" . }} {{ end }}
181 </div>
182{{ end }}
183
184{{ define "commitLog" }}
185<div id="commit-log" class="md:col-span-1 px-2 pb-4">
186 <div class="flex justify-between items-center">
187 <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
188 {{ i "logs" "w-4 h-4" }} Commits
189 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt .TotalCommits }}</span>
190 </a>
191 </div>
192 <div class="flex flex-col gap-6">
193 {{ range .CommitsTrunc }}
194 <div>
195 <div id="commit-message">
196 {{ $messageParts := splitN .Message "\n\n" 2 }}
197 <div class="text-base cursor-pointer">
198 <div>
199 <div>
200 <a
201 href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"
202 class="inline no-underline hover:underline dark:text-white"
203 >{{ index $messageParts 0 }}</a
204 >
205 {{ if gt (len $messageParts) 1 }}
206
207 <button
208 class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
209 hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"
210 >
211 {{ i "ellipsis" "w-3 h-3" }}
212 </button>
213 {{ end }}
214 </div>
215 {{ if gt (len $messageParts) 1 }}
216 <p
217 class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300"
218 >
219 {{ nl2br (index $messageParts 1) }}
220 </p>
221 {{ end }}
222 </div>
223 </div>
224 </div>
225
226 <!-- commit info bar -->
227 <div class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center flex-wrap">
228 {{ $verified := $.VerifiedCommits.IsVerified .Hash.String }}
229 {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }}
230 {{ if $verified }}
231 {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }}
232 {{ end }}
233 <span class="font-mono">
234 <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"
235 {{ if .ChangeId }}title="jj change id: {{ .ChangeId }}"{{ end }}
236 class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2">
237 {{ slice .Hash.String 0 8 }}
238 {{ if $verified }}
239 {{ i "shield-check" "w-3 h-3" }}
240 {{ end }}
241 </a>
242 </span>
243 <span
244 class="mx-1 before:content-['·'] before:select-none"
245 ></span>
246 {{ template "attribution" (list . $.EmailToDid) }}
247 <div class="inline-block px-1 select-none after:content-['·']"></div>
248 {{ template "repo/fragments/time" .Committer.When }}
249
250 <!-- tags/branches -->
251 {{ $tagsForCommit := index $.TagMap .Hash.String }}
252 {{ if gt (len $tagsForCommit) 0 }}
253 <div class="inline-block px-1 select-none after:content-['·']"></div>
254 {{ end }}
255 {{ range $tagsForCommit }}
256 <span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-[2px] inline-flex items-center">
257 {{ . }}
258 </span>
259 {{ end }}
260
261 <!-- ci status -->
262 {{ $pipeline := index $.Pipelines .Hash.String }}
263 {{ if $pipeline }}
264 {{ if gt (len $pipeline.Statuses) 0 }}
265 <div class="inline-block px-1 select-none after:content-['·']"></div>
266 {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "RepoInfo" $.RepoInfo "Pipeline" $pipeline) }}
267 {{ end }}
268 {{ end }}
269 </div>
270 </div>
271 {{ end }}
272 </div>
273</div>
274{{ end }}
275
276{{ define "attribution" }}
277 {{ $commit := index . 0 }}
278 {{ $map := index . 1 }}
279 <span class="flex items-center gap-1">
280 {{ $author := index $map $commit.Author.Email }}
281 {{ $coauthors := $commit.CoAuthors }}
282 {{ $all := list }}
283
284 {{ if $author }}
285 {{ $all = append $all $author }}
286 {{ end }}
287 {{ range $coauthors }}
288 {{ $co := index $map .Email }}
289 {{ if $co }}
290 {{ $all = append $all $co }}
291 {{ end }}
292 {{ end }}
293
294 {{ if $author }}
295 {{ template "fragments/tinyAvatarList" (dict "all" $all "classes" "size-6") }}
296 {{ else }}
297 {{ placeholderAvatar "tiny" }}
298 {{ end }}
299 <a href="{{ if $author }}/{{ $author }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}"
300 class="no-underline hover:underline">
301 {{ if $author }}{{ resolve $author }}{{ else }}{{ $commit.Author.Name }}{{ end }}
302 {{ if $coauthors }} +{{ length $coauthors }}{{ end }}
303 </a>
304 </span>
305{{ end }}
306
307{{ define "branchList" }}
308 {{ if gt (len .BranchesTrunc) 0 }}
309 <div id="branches" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700">
310 <a href="/{{ .RepoInfo.FullName }}/branches" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
311 {{ i "git-branch" "w-4 h-4" }} Branches
312 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt (len .Branches) }}</span>
313 </a>
314 <div class="flex flex-col gap-1">
315 {{ range .BranchesTrunc }}
316 <div class="text-base flex items-center justify-between overflow-hidden">
317 <div class="flex items-center gap-2 min-w-0 flex-1">
318 <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}"
319 class="inline-block truncate no-underline hover:underline dark:text-white">
320 {{ .Reference.Name }}
321 </a>
322 {{ if .Commit }}
323 <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span>
324 <span class="whitespace-nowrap text-xs text-gray-500 dark:text-gray-400 shrink-0">{{ template "repo/fragments/time" .Commit.Committer.When }}</span>
325 {{ end }}
326 {{ if .IsDefault }}
327 <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span>
328 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono shrink-0">Default</span>
329 {{ end }}
330 </div>
331 {{ if ne $.Ref .Reference.Name }}
332 <a href="/{{ $.RepoInfo.FullName }}/compare/{{ $.Ref | urlquery }}...{{ .Reference.Name | urlquery }}"
333 class="text-xs flex gap-2 items-center shrink-0 ml-2"
334 title="Compare branches or tags">
335 {{ i "git-compare" "w-3 h-3" }} Compare
336 </a>
337 {{ end }}
338 </div>
339 {{ end }}
340 </div>
341 </div>
342 {{ end }}
343{{ end }}
344
345{{ define "tagList" }}
346 {{ if gt (len .TagsTrunc) 0 }}
347 <div id="tags" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700">
348 <div class="flex justify-between items-center">
349 <a href="/{{ .RepoInfo.FullName }}/tags" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
350 {{ i "tags" "w-4 h-4" }} Tags
351 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt (len .Tags) }}</span>
352 </a>
353 </div>
354 <div class="flex flex-col gap-1">
355 {{ range $idx, $tag := .TagsTrunc }}
356 {{ with $tag }}
357 <div>
358 <div class="text-base flex items-center gap-2">
359 <a href="/{{ $.RepoInfo.FullName }}/tags/{{ .Reference.Name | urlquery }}"
360 class="inline no-underline hover:underline dark:text-white">
361 {{ .Reference.Name }}
362 </a>
363 </div>
364 <div>
365 {{ with .Tag }}
366 <span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .Tagger.When }}</span>
367 {{ end }}
368 {{ if eq $idx 0 }}
369 {{ with .Tag }}<span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·']"></span>{{ end }}
370 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono">Latest</span>
371 {{ end }}
372 </div>
373 </div>
374 {{ end }}
375 {{ end }}
376 </div>
377 </div>
378 {{ end }}
379{{ end }}
380
381{{ define "repoAfter" }}
382 {{- if or .HTMLReadme .Readme -}}
383 {{ template "repo/fragments/readme" . }}
384 {{- end -}}
385{{ end }}