this repo has no description
1{{ define "title" }}{{ .Issue.Title }} · issue #{{ .Issue.IssueId }} · {{ .RepoInfo.FullName }}{{ end }}
2
3
4{{ define "extrameta" }}
5 {{ $title := printf "%s · issue #%d · %s" .Issue.Title .Issue.IssueId .RepoInfo.FullName }}
6 {{ $url := printf "https://tangled.sh/%s/issues/%d" .RepoInfo.FullName .Issue.IssueId }}
7
8 {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }}
9{{ end }}
10
11{{ define "repoContent" }}
12 <header class="pb-4">
13 <h1 class="text-2xl">
14 {{ .Issue.Title }}
15 <span class="text-gray-500 dark:text-gray-400">#{{ .Issue.IssueId }}</span>
16 </h1>
17 </header>
18
19 {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }}
20 {{ $icon := "ban" }}
21 {{ if eq .State "open" }}
22 {{ $bgColor = "bg-green-600 dark:bg-green-700" }}
23 {{ $icon = "circle-dot" }}
24 {{ end }}
25
26 <section class="mt-2">
27 <div class="inline-flex items-center gap-2">
28 <div id="state"
29 class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}">
30 {{ i $icon "w-4 h-4 mr-1.5 text-white" }}
31 <span class="text-white">{{ .State }}</span>
32 </div>
33 <span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1">
34 opened by
35 {{ $owner := didOrHandle .Issue.OwnerDid .IssueOwnerHandle }}
36 {{ template "user/fragments/picHandleLink" $owner }}
37 <span class="select-none before:content-['\00B7']"></span>
38 {{ template "repo/fragments/time" .Issue.Created }}
39 </span>
40 </div>
41
42 {{ if .Issue.Body }}
43 <article id="body" class="mt-8 prose dark:prose-invert">
44 {{ .Issue.Body | markdown }}
45 </article>
46 {{ end }}
47
48 <div class="flex items-center gap-2 mt-2">
49 {{ template "repo/fragments/reactionsPopUp" .OrderedReactionKinds }}
50 {{ range $kind := .OrderedReactionKinds }}
51 {{
52 template "repo/fragments/reaction"
53 (dict
54 "Kind" $kind
55 "Count" (index $.Reactions $kind)
56 "IsReacted" (index $.UserReacted $kind)
57 "ThreadAt" $.Issue.AtUri)
58 }}
59 {{ end }}
60 </div>
61 </section>
62{{ end }}
63
64{{ define "repoAfter" }}
65 <section id="comments" class="my-2 mt-2 space-y-2 relative">
66 {{ range $index, $comment := .Comments }}
67 <div
68 id="comment-{{ .CommentId }}"
69 class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit">
70 {{ if gt $index 0 }}
71 <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div>
72 {{ end }}
73 {{ template "repo/issues/fragments/issueComment" (dict "RepoInfo" $.RepoInfo "LoggedInUser" $.LoggedInUser "Issue" $.Issue "Comment" .)}}
74 </div>
75 {{ end }}
76 </section>
77
78 {{ block "newComment" . }} {{ end }}
79
80{{ end }}
81
82{{ define "newComment" }}
83 {{ if .LoggedInUser }}
84 <form
85 id="comment-form"
86 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
87 hx-on::after-request="if(event.detail.successful) this.reset()"
88 >
89 <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full md:w-3/5">
90 <div class="text-sm pb-2 text-gray-500 dark:text-gray-400">
91 {{ template "user/fragments/picHandleLink" (didOrHandle .LoggedInUser.Did .LoggedInUser.Handle) }}
92 </div>
93 <textarea
94 id="comment-textarea"
95 name="body"
96 class="w-full p-2 rounded border border-gray-200 dark:border-gray-700"
97 placeholder="Add to the discussion. Markdown is supported."
98 onkeyup="updateCommentForm()"
99 ></textarea>
100 <div id="issue-comment"></div>
101 <div id="issue-action" class="error"></div>
102 </div>
103
104 <div class="flex gap-2 mt-2">
105 <button
106 id="comment-button"
107 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
108 type="submit"
109 hx-disabled-elt="#comment-button"
110 class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group"
111 disabled
112 >
113 {{ i "message-square-plus" "w-4 h-4" }}
114 comment
115 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
116 </button>
117
118 {{ $isIssueAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Issue.OwnerDid) }}
119 {{ $isRepoCollaborator := .RepoInfo.Roles.IsCollaborator }}
120 {{ $isRepoOwner := .RepoInfo.Roles.IsOwner }}
121 {{ if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "open") }}
122 <button
123 id="close-button"
124 type="button"
125 class="btn flex items-center gap-2"
126 hx-indicator="#close-spinner"
127 hx-trigger="click"
128 >
129 {{ i "ban" "w-4 h-4" }}
130 close
131 <span id="close-spinner" class="group">
132 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
133 </span>
134 </button>
135 <div
136 id="close-with-comment"
137 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
138 hx-trigger="click from:#close-button"
139 hx-disabled-elt="#close-with-comment"
140 hx-target="#issue-comment"
141 hx-indicator="#close-spinner"
142 hx-vals="js:{body: document.getElementById('comment-textarea').value.trim() !== '' ? document.getElementById('comment-textarea').value : ''}"
143 hx-swap="none"
144 >
145 </div>
146 <div
147 id="close-issue"
148 hx-disabled-elt="#close-issue"
149 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/close"
150 hx-trigger="click from:#close-button"
151 hx-target="#issue-action"
152 hx-indicator="#close-spinner"
153 hx-swap="none"
154 >
155 </div>
156 <script>
157 document.addEventListener('htmx:configRequest', function(evt) {
158 if (evt.target.id === 'close-with-comment') {
159 const commentText = document.getElementById('comment-textarea').value.trim();
160 if (commentText === '') {
161 evt.detail.parameters = {};
162 evt.preventDefault();
163 }
164 }
165 });
166 </script>
167 {{ else if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "closed") }}
168 <button
169 type="button"
170 class="btn flex items-center gap-2"
171 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/reopen"
172 hx-indicator="#reopen-spinner"
173 hx-swap="none"
174 >
175 {{ i "refresh-ccw-dot" "w-4 h-4" }}
176 reopen
177 <span id="reopen-spinner" class="group">
178 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
179 </span>
180 </button>
181 {{ end }}
182
183 <script>
184 function updateCommentForm() {
185 const textarea = document.getElementById('comment-textarea');
186 const commentButton = document.getElementById('comment-button');
187 const closeButton = document.getElementById('close-button');
188
189 if (textarea.value.trim() !== '') {
190 commentButton.removeAttribute('disabled');
191 } else {
192 commentButton.setAttribute('disabled', '');
193 }
194
195 if (closeButton) {
196 if (textarea.value.trim() !== '') {
197 closeButton.innerHTML = `
198{{ i "ban" "w-4 h-4" }}
199<span>close with comment</span>
200<span id="close-spinner" class="group">
201 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
202</span>`;
203 } else {
204 closeButton.innerHTML = `
205{{ i "ban" "w-4 h-4" }}
206<span>close</span>
207<span id="close-spinner" class="group">
208 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
209</span>`;
210 }
211 }
212 }
213
214 document.addEventListener('DOMContentLoaded', function() {
215 updateCommentForm();
216 });
217 </script>
218 </div>
219 </form>
220 {{ else }}
221 <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-fit">
222 <a href="/login" class="underline">login</a> to join the discussion
223 </div>
224 {{ end }}
225{{ end }}