A vibe coded tangled fork which supports pijul.
1{{ define "title" }}
2 {{ .Pull.Title }} · pull #{{ .Pull.PullId }} · {{ .RepoInfo.FullName }}
3{{ end }}
4
5{{ define "extrameta" }}
6 {{ template "repo/pulls/fragments/og" (dict "RepoInfo" .RepoInfo "Pull" .Pull) }}
7{{ end }}
8
9{{ define "mainLayout" }}
10 <div class="px-1 flex-grow flex flex-col gap-4">
11 <div class="max-w-full md:max-w-screen-lg mx-auto">
12 {{ block "contentLayout" . }}
13 {{ block "content" . }}{{ end }}
14 {{ end }}
15 </div>
16 {{ block "contentAfterLayout" . }}
17 <main>
18 {{ block "contentAfter" . }}{{ end }}
19 </main>
20 {{ end }}
21 </div>
22 <script>
23 (function() {
24 const details = document.getElementById('bottomSheet');
25 const backdrop = document.getElementById('bottomSheetBackdrop');
26 const isDesktop = () => window.matchMedia('(min-width: 768px)').matches;
27
28 // function to update backdrop
29 const updateBackdrop = () => {
30 if (backdrop) {
31 if (details.open && !isDesktop()) {
32 backdrop.classList.remove('opacity-0', 'pointer-events-none');
33 backdrop.classList.add('opacity-100', 'pointer-events-auto');
34 } else {
35 backdrop.classList.remove('opacity-100', 'pointer-events-auto');
36 backdrop.classList.add('opacity-0', 'pointer-events-none');
37 }
38 }
39 };
40
41 // close on mobile initially
42 if (!isDesktop()) {
43 details.open = false;
44 }
45 updateBackdrop(); // initialize backdrop
46
47 // prevent closing on desktop
48 details.addEventListener('toggle', function(e) {
49 if (isDesktop() && !this.open) {
50 this.open = true;
51 }
52 updateBackdrop();
53 });
54
55 const mediaQuery = window.matchMedia('(min-width: 768px)');
56 mediaQuery.addEventListener('change', function(e) {
57 if (e.matches) {
58 // switched to desktop - keep open
59 details.open = true;
60 } else {
61 // switched to mobile - close
62 details.open = false;
63 }
64 updateBackdrop();
65 });
66
67 // close when clicking backdrop
68 if (backdrop) {
69 backdrop.addEventListener('click', () => {
70 if (!isDesktop()) {
71 details.open = false;
72 }
73 });
74 }
75 })();
76 </script>
77{{ end }}
78
79{{ define "repoContentLayout" }}
80 <div class="grid grid-cols-1 md:grid-cols-10 gap-4 w-full">
81 <section class="bg-white col-span-1 md:col-span-8 dark:bg-gray-800 p-6 rounded relative w-full mx-auto dark:text-white h-full flex-shrink">
82 {{ block "repoContent" . }}{{ end }}
83 </section>
84 <div class="flex flex-col gap-6 col-span-1 md:col-span-2">
85 {{ template "repo/fragments/labelPanel"
86 (dict "RepoInfo" $.RepoInfo
87 "Defs" $.LabelDefs
88 "Subject" $.Pull.AtUri
89 "State" $.Pull.Labels) }}
90 {{ template "repo/fragments/participants" $.Pull.Participants }}
91 {{ template "repo/fragments/backlinks"
92 (dict "RepoInfo" $.RepoInfo
93 "Backlinks" $.Backlinks) }}
94 {{ template "repo/fragments/externalLinkPanel" $.Pull.AtUri }}
95 </div>
96 </div>
97{{ end }}
98
99{{ define "contentAfter" }}
100 {{ template "repo/fragments/diff" (list .Diff .DiffOpts $) }}
101{{ end }}
102
103{{ define "repoContent" }}
104 {{ template "repo/pulls/fragments/pullHeader" . }}
105 {{ if .Pull.IsStacked }}
106 <div class="mt-8">
107 {{ template "repo/pulls/fragments/pullStack" . }}
108 </div>
109 {{ end }}
110{{ end }}
111
112{{ define "diffLayout" }}
113 {{ $diff := index . 0 }}
114 {{ $opts := index . 1 }}
115 {{ $root := index . 2 }}
116
117 <div class="flex col-span-full">
118 <!-- left panel -->
119 <div id="files" class="w-0 hidden md:block overflow-hidden sticky top-12 max-h-screen overflow-y-auto pb-12">
120 <section class="overflow-x-auto text-sm px-6 py-2 border-b border-x border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded-b rounded-t-none bg-white dark:bg-gray-800 drop-shadow-sm">
121 {{ template "repo/fragments/fileTree" $diff.FileTree }}
122 </section>
123 </div>
124
125 <!-- main content -->
126 <div class="flex-1 min-w-0 sticky top-12 pb-12">
127 {{ template "diffFiles" (list $diff $opts) }}
128 </div>
129
130 <!-- right panel -->
131 {{ template "subsPanel" $ }}
132 </div>
133{{ end }}
134
135{{ define "subsPanel" }}
136 {{ $root := index . 2 }}
137 {{ $pull := $root.Pull }}
138 <!-- backdrop overlay - only visible on mobile when open -->
139 <div id="bottomSheetBackdrop" class="fixed inset-0 bg-black/50 md:hidden opacity-0 pointer-events-none transition-opacity duration-300 z-40"></div>
140 <!-- right panel - bottom sheet on mobile, side panel on desktop -->
141 <div id="subs" class="fixed bottom-0 left-0 right-0 z-50 w-full md:static md:z-auto md:max-h-screen md:sticky md:top-12 overflow-hidden">
142 <details open id="bottomSheet" class="rounded-t-2xl md:rounded-t drop-shadow-lg md:drop-shadow-none group/panel">
143 <summary class="
144 flex gap-4 items-center justify-between
145 rounded-t-2xl md:rounded-t cursor-pointer list-none p-4 md:h-12
146 text-white md:text-black md:dark:text-white
147 bg-green-600 dark:bg-green-700
148 md:bg-white md:dark:bg-gray-800
149 drop-shadow-sm
150 border-t md:border-x md:border-t-0 border-gray-200 dark:border-gray-700">
151 <h2 class="">Comments</h2>
152 {{ template "subsPanelSummary" $ }}
153 </summary>
154 <div class="max-h-[85vh] md:max-h-[calc(100vh-3rem-3rem)] w-full flex flex-col-reverse gap-4 overflow-y-auto bg-slate-100 dark:bg-gray-900 md:bg-transparent">
155 {{ template "submissions" $root }}
156 </div>
157 </details>
158 </div>
159{{ end }}
160
161{{ define "subsPanelSummary" }}
162 {{ $root := index . 2 }}
163 {{ $pull := $root.Pull }}
164 {{ $latest := $pull.LastRoundNumber }}
165 <div class="flex items-center gap-2 text-sm">
166 <span class="md:hidden inline">
167 <span class="inline group-open/panel:hidden">{{ i "chevron-up" "size-4" }}</span>
168 <span class="hidden group-open/panel:inline">{{ i "chevron-down" "size-4" }}</span>
169 </span>
170 </div>
171{{ end }}
172
173{{ define "subsCheckbox" }}
174 <input type="checkbox" id="subsToggle" class="peer/subs hidden" checked/>
175{{ end }}
176
177{{ define "subsToggle" }}
178 <style>
179 /* Mobile: full width */
180 #subsToggle:checked ~ div div#subs {
181 width: 100%;
182 margin-left: 0;
183 }
184 #subsToggle:checked ~ div label[for="subsToggle"] .show-toggle { display: none; }
185 #subsToggle:checked ~ div label[for="subsToggle"] .hide-toggle { display: flex; }
186 #subsToggle:not(:checked) ~ div label[for="subsToggle"] .hide-toggle { display: none; }
187
188 /* Desktop: 25vw with left margin */
189 @media (min-width: 768px) {
190 #subsToggle:checked ~ div div#subs {
191 width: 25vw;
192 margin-left: 1rem;
193 }
194 /* Unchecked state */
195 #subsToggle:not(:checked) ~ div div#subs {
196 width: 0;
197 display: none;
198 margin-left: 0;
199 }
200 }
201 </style>
202 <label title="Toggle review panel" for="subsToggle" class="hidden md:flex items-center justify-end rounded cursor-pointer">
203 <span class="show-toggle">{{ i "message-square-more" "size-4" }}</span>
204 <span class="hide-toggle w-[25vw] flex justify-end">{{ i "message-square" "size-4" }}</span>
205 </label>
206{{ end }}
207
208
209{{ define "submissions" }}
210 {{ $lastIdx := sub (len .Pull.Submissions) 1 }}
211 {{ if not .LoggedInUser }}
212 {{ template "loginPrompt" $ }}
213 {{ end }}
214 {{ range $ridx, $item := reverse .Pull.Submissions }}
215 {{ $idx := sub $lastIdx $ridx }}
216 {{ template "submission" (list $item $idx $lastIdx $) }}
217 {{ end }}
218{{ end }}
219
220{{ define "submission" }}
221 {{ $item := index . 0 }}
222 {{ $idx := index . 1 }}
223 {{ $lastIdx := index . 2 }}
224 {{ $root := index . 3 }}
225 <div class="{{ if eq $item.RoundNumber 0 }}rounded-b border-t-0{{ else }}rounded{{ end }} border border-gray-200 dark:border-gray-700 w-full shadow-sm bg-gray-50 dark:bg-gray-900">
226 {{ template "submissionHeader" $ }}
227 {{ template "submissionComments" $ }}
228 </div>
229{{ end }}
230
231{{ define "submissionHeader" }}
232 {{ $item := index . 0 }}
233 {{ $lastIdx := index . 2 }}
234 {{ $root := index . 3 }}
235 {{ $round := $item.RoundNumber }}
236 <div class="
237 {{ if eq $round 0 }}rounded-b{{ else }}rounded{{ end }}
238 px-6 py-4 pr-2 pt-2
239 {{ if eq $root.ActiveRound $round }}
240 bg-blue-100 dark:bg-blue-900 border-b border-blue-200 dark:border-blue-700
241 {{ else }}
242 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700
243 {{ end }}
244 flex gap-2 sticky top-0 z-20">
245 <!-- left column: just profile picture -->
246 <div class="flex-shrink-0 pt-2">
247 <img
248 src="{{ tinyAvatar $root.Pull.OwnerDid }}"
249 alt=""
250 class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900"
251 />
252 </div>
253 <!-- right column -->
254 <div class="flex-1 min-w-0 flex flex-col gap-1">
255 {{ template "submissionInfo" $ }}
256 {{ template "submissionCommits" $ }}
257 {{ template "submissionPipeline" $ }}
258 {{ if eq $lastIdx $round }}
259 {{ block "mergeCheck" $root }} {{ end }}
260 {{ end }}
261 </div>
262 </div>
263{{ end }}
264
265{{ define "submissionInfo" }}
266 {{ $item := index . 0 }}
267 {{ $idx := index . 1 }}
268 {{ $root := index . 3 }}
269 {{ $round := $item.RoundNumber }}
270 <div class="flex gap-2 items-center justify-between mb-1">
271 <span class="inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 pt-2">
272 {{ resolve $root.Pull.OwnerDid }} submitted
273 <span class="px-2 py-0.5 {{ if eq $root.ActiveRound $round }}text-white bg-blue-600 dark:bg-blue-500 border-blue-700 dark:border-blue-600{{ else }}text-black dark:text-white bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600{{ end }} rounded font-mono text-xs border">
274 #{{ $round }}
275 </span>
276 <span class="select-none before:content-['\00B7']"></span>
277 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500" href="#round-#{{ $round }}">
278 {{ template "repo/fragments/shortTime" $item.Created }}
279 </a>
280 </span>
281 <div class="flex gap-2 items-center">
282 {{ if ne $root.ActiveRound $round }}
283 <a class="btn-flat flex items-center gap-2 no-underline hover:no-underline text-sm"
284 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $round }}?{{ safeUrl $root.DiffOpts.Encode }}#round-#{{ $round }}">
285 {{ i "diff" "w-4 h-4" }}
286 diff
287 </a>
288 {{ end }}
289 {{ if ne $idx 0 }}
290 <a class="btn-flat flex items-center gap-2 no-underline hover:no-underline text-sm"
291 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $round }}/interdiff?{{ safeUrl $root.DiffOpts.Encode }}">
292 {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }}
293 interdiff
294 </a>
295 {{ end }}
296 </div>
297 </div>
298{{ end }}
299
300{{ define "submissionCommits" }}
301 {{ $item := index . 0 }}
302 {{ $root := index . 3 }}
303 {{ $round := $item.RoundNumber }}
304 {{ $patches := $item.AsFormatPatch }}
305 {{ if $patches }}
306 <details class="group/commit">
307 <summary class="list-none cursor-pointer flex items-center gap-2">
308 <span>{{ i "git-commit-horizontal" "w-4 h-4" }}</span>
309 {{ len $patches }} commit{{ if ne (len $patches) 1 }}s{{ end }}
310 <div class="text-sm text-gray-500 dark:text-gray-400">
311 <span class="group-open/commit:hidden inline">expand</span>
312 <span class="hidden group-open/commit:inline">collapse</span>
313 </div>
314 </summary>
315 {{ range $patches }}
316 {{ template "submissionCommit" (list . $item $root) }}
317 {{ end }}
318 </details>
319 {{ end }}
320{{ end }}
321
322{{ define "submissionCommit" }}
323 {{ $patch := index . 0 }}
324 {{ $item := index . 1 }}
325 {{ $root := index . 2 }}
326 {{ $round := $item.RoundNumber }}
327 {{ with $patch }}
328 <div id="commit-{{.SHA}}" class="py-1 relative w-full md:max-w-3/5 md:w-fit flex flex-col text-gray-600 dark:text-gray-300">
329 <div class="flex items-baseline gap-2">
330 <div class="text-xs">
331 <!-- attempt to resolve $fullRepo: this is possible only on non-deleted forks and branches -->
332 {{ $fullRepo := "" }}
333 {{ if and $root.Pull.IsForkBased $root.Pull.PullSource.Repo }}
334 {{ $fullRepo = printf "%s/%s" $root.Pull.OwnerDid $root.Pull.PullSource.Repo.Name }}
335 {{ else if $root.Pull.IsBranchBased }}
336 {{ $fullRepo = $root.RepoInfo.FullName }}
337 {{ end }}
338
339 <!-- if $fullRepo was resolved, link to it, otherwise just span without a link -->
340 {{ if $fullRepo }}
341 <a href="/{{ $fullRepo }}/commit/{{ .SHA }}" class="font-mono text-gray-600 dark:text-gray-300">{{ slice .SHA 0 8 }}</a>
342 {{ else }}
343 <span class="font-mono">{{ slice .SHA 0 8 }}</span>
344 {{ end }}
345 </div>
346
347 <div>
348 <span>{{ .Title | description }}</span>
349 {{ if gt (len .Body) 0 }}
350 <button
351 class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
352 hx-on:click="document.getElementById('body-{{$round}}-{{.SHA}}').classList.toggle('hidden')"
353 >
354 {{ i "ellipsis" "w-3 h-3" }}
355 </button>
356 {{ end }}
357 {{ if gt (len .Body) 0 }}
358 <p id="body-{{$round}}-{{.SHA}}" class="hidden mt-1 pb-2">{{ nl2br .Body }}</p>
359 {{ end }}
360 </div>
361 </div>
362 </div>
363 {{ end }}
364{{ end }}
365
366{{ define "mergeCheck" }}
367 {{ $isOpen := .Pull.State.IsOpen }}
368 {{ if and $isOpen .MergeCheck .MergeCheck.Error }}
369 <div class="flex items-center gap-2">
370 {{ i "triangle-alert" "w-4 h-4 text-red-600 dark:text-red-500" }}
371 {{ .MergeCheck.Error }}
372 </div>
373 {{ else if and $isOpen .MergeCheck .MergeCheck.IsConflicted }}
374 <details class="group/conflict">
375 <summary class="flex items-center justify-between cursor-pointer list-none">
376 <div class="flex items-center gap-2 ">
377 {{ i "triangle-alert" "text-red-600 dark:text-red-500 w-4 h-4" }}
378 <span class="font-medium">merge conflicts detected</span>
379 <div class="text-sm text-gray-500 dark:text-gray-400">
380 <span class="group-open/conflict:hidden inline">expand</span>
381 <span class="hidden group-open/conflict:inline">collapse</span>
382 </div>
383 </div>
384 </summary>
385 {{ if gt (len .MergeCheck.Conflicts) 0 }}
386 <ul class="space-y-1 mt-2 overflow-x-auto">
387 {{ range .MergeCheck.Conflicts }}
388 {{ if .Filename }}
389 <li class="flex items-center whitespace-nowrap">
390 {{ i "file-warning" "inline-flex w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 flex-shrink-0" }}
391 <span class="font-mono">{{ .Filename }}</span>
392 </li>
393 {{ else if .Reason }}
394 <li class="flex items-center whitespace-nowrap">
395 {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 " }}
396 <span>{{.Reason}}</span>
397 </li>
398 {{ end }}
399 {{ end }}
400 </ul>
401 {{ end }}
402 </details>
403 {{ else if and $isOpen .MergeCheck }}
404 <div class="flex items-center gap-2">
405 {{ i "check" "w-4 h-4 text-green-600 dark:text-green-500" }}
406 <span>no conflicts, ready to merge</span>
407 </div>
408 {{ end }}
409{{ end }}
410
411{{ define "mergeStatus" }}
412 {{ if .Pull.State.IsClosed }}
413 <div class="bg-gray-50 dark:bg-gray-700 border border-black dark:border-gray-500 rounded drop-shadow-sm px-6 py-2 relative">
414 <div class="flex items-center gap-2 text-black dark:text-white">
415 {{ i "ban" "w-4 h-4" }}
416 <span class="font-medium">closed without merging</span
417 >
418 </div>
419 </div>
420 {{ else if .Pull.State.IsMerged }}
421 <div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative">
422 <div class="flex items-center gap-2 text-purple-500 dark:text-purple-300">
423 {{ i "git-merge" "w-4 h-4" }}
424 <span class="font-medium">pull request successfully merged</span
425 >
426 </div>
427 </div>
428 {{ else if .Pull.State.IsDeleted }}
429 <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative">
430 <div class="flex items-center gap-2 text-red-500 dark:text-red-300">
431 {{ i "git-pull-request-closed" "w-4 h-4" }}
432 <span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span>
433 </div>
434 </div>
435 {{ end }}
436{{ end }}
437
438{{ define "resubmitStatus" }}
439 {{ if .ResubmitCheck.Yes }}
440 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative">
441 <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
442 {{ i "triangle-alert" "w-4 h-4" }}
443 <span class="font-medium">this branch has been updated, consider resubmitting</span>
444 </div>
445 </div>
446 {{ end }}
447{{ end }}
448
449{{ define "submissionPipeline" }}
450 {{ $item := index . 0 }}
451 {{ $root := index . 3 }}
452 {{ $pipeline := index $root.Pipelines $item.SourceRev }}
453 {{ with $pipeline }}
454 {{ $id := .Id }}
455 {{ if .Statuses }}
456 <details class="group/pipeline">
457 <summary class="cursor-pointer list-none flex items-center gap-2">
458 {{ template "repo/pipelines/fragments/pipelineSymbol" (dict "Pipeline" $pipeline "ShortSummary" false) }}
459 <div class="text-sm text-gray-500 dark:text-gray-400">
460 <span class="group-open/pipeline:hidden inline">expand</span>
461 <span class="hidden group-open/pipeline:inline">collapse</span>
462 </div>
463 </summary>
464 <div class="my-2 grid grid-cols-1 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700">
465 {{ range $name, $all := .Statuses }}
466 <a href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25">
467 <div
468 class="flex gap-2 items-center justify-between p-2">
469 {{ $lastStatus := $all.Latest }}
470 {{ $kind := $lastStatus.Status.String }}
471
472 <div id="left" class="flex items-center gap-2 flex-shrink-0">
473 {{ template "repo/pipelines/fragments/workflowSymbol" $all }}
474 {{ $name }}
475 </div>
476 <div id="right" class="flex items-center gap-2 flex-shrink-0">
477 <span class="font-bold">{{ $kind }}</span>
478 {{ if .TimeTaken }}
479 {{ template "repo/fragments/duration" .TimeTaken }}
480 {{ else }}
481 {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }}
482 {{ end }}
483 </div>
484 </div>
485 </a>
486 {{ end }}
487 </div>
488 </details>
489 {{ end }}
490 {{ end }}
491{{ end }}
492
493{{ define "submissionComments" }}
494 {{ $item := index . 0 }}
495 {{ $idx := index . 1 }}
496 {{ $lastIdx := index . 2 }}
497 {{ $root := index . 3 }}
498 {{ $c := len $item.Comments }}
499 <details class="relative ml-10 group/comments" open>
500 <summary class="cursor-pointer list-none">
501 <div class="hidden group-open/comments:block absolute -left-8 top-0 bottom-0 w-16 transition-colors flex items-center justify-center group/border z-4">
502 <div class="absolute left-1/2 -translate-x-1/2 top-0 bottom-0 w-0.5 group-open/comments:bg-gray-200 dark:group-open/comments:bg-gray-700 group-hover/border:bg-gray-400 dark:group-hover/border:bg-gray-500 transition-colors"> </div>
503 </div>
504 <div class="group-open/comments:hidden block relative group/summary py-4">
505 <div class="absolute -left-8 top-0 bottom-0 w-16 transition-colors flex items-center justify-center z-4">
506 <div class="absolute left-1/2 -translate-x-1/2 h-1/3 top-0 bottom-0 w-0.5 bg-gray-200 dark:bg-gray-700 group-hover/summary:bg-gray-400 dark:group-hover/summary:bg-gray-500 transition-colors"></div>
507 </div>
508 <span class="text-gray-500 dark:text-gray-400 text-sm group-hover/summary:text-gray-600 dark:group-hover/summary:text-gray-300 transition-colors flex items-center gap-2 -ml-2 relative">
509 {{ i "circle-plus" "size-4 z-5" }}
510 expand {{ $c }} comment{{ if ne $c 1 }}s{{ end }}
511 </span>
512 </div>
513 </summary>
514 <div>
515 {{ range $item.Comments }}
516 {{ template "submissionComment" . }}
517 {{ end }}
518 </div>
519
520 <div class="relative -ml-10">
521 {{ if eq $lastIdx $item.RoundNumber }}
522 {{ block "mergeStatus" $root }} {{ end }}
523 {{ block "resubmitStatus" $root }} {{ end }}
524 {{ end }}
525 </div>
526 <div class="relative -ml-10 bg-gray-50 dark:bg-gray-900">
527 {{ if $root.LoggedInUser }}
528 {{ template "repo/pulls/fragments/pullActions"
529 (dict
530 "LoggedInUser" $root.LoggedInUser
531 "Pull" $root.Pull
532 "RepoInfo" $root.RepoInfo
533 "RoundNumber" $item.RoundNumber
534 "MergeCheck" $root.MergeCheck
535 "ResubmitCheck" $root.ResubmitCheck
536 "BranchDeleteStatus" $root.BranchDeleteStatus
537 "Stack" $root.Stack) }}
538 {{ end }}
539 </div>
540 </details>
541{{ end }}
542
543{{ define "submissionComment" }}
544 <div id="comment-{{.ID}}" class="flex gap-2 -ml-4 py-4 w-full mx-auto">
545 <!-- left column: profile picture -->
546 <div class="flex-shrink-0 h-fit relative">
547 <img
548 src="{{ tinyAvatar .OwnerDid }}"
549 alt=""
550 class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900 z-5"
551 />
552 </div>
553 <!-- right column: name and body in two rows -->
554 <div class="flex-1 min-w-0">
555 <!-- Row 1: Author and timestamp -->
556 <div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
557 <span>{{ resolve .OwnerDid }}</span>
558 <span class="before:content-['·']"></span>
559 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.ID}}">
560 {{ template "repo/fragments/time" .Created }}
561 </a>
562 </div>
563 <!-- Row 2: Body text -->
564 <div class="prose dark:prose-invert mt-1">
565 {{ .Body | markdown }}
566 </div>
567 </div>
568 </div>
569{{ end }}
570
571{{ define "loginPrompt" }}
572 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm p-2 relative flex gap-2 items-center">
573 <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
574 sign up
575 </a>
576 <span class="text-gray-500 dark:text-gray-400">or</span>
577 <a href="/login" class="underline">login</a>
578 to add to the discussion
579 </div>
580{{ end }}