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