this repo has no description
1{{ define "title" }} 2 {{ .Issue.Title }} &middot; issue #{{ .Issue.IssueId }} &middot; 3 {{ .RepoInfo.FullName }} 4{{ end }} 5 6{{ define "extrameta" }} 7 {{ $title := printf "%s &middot; issue #%d &middot; %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 }}