this repo has no description
1{{ define "title" }}{{ .Issue.Title }} &middot; issue #{{ .Issue.IssueId }} &middot; {{ .RepoInfo.FullName }}{{ end }} 2 3 4{{ define "extrameta" }} 5 {{ $title := printf "%s &middot; issue #%d &middot; %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/picHandle" $owner }} 37 <span class="select-none before:content-['\00B7']"></span> 38 <time title="{{ .Issue.Created | longTimeFmt }}"> 39 {{ .Issue.Created | timeFmt }} 40 </time> 41 </span> 42 </div> 43 44 {{ if .Issue.Body }} 45 <article id="body" class="mt-8 prose dark:prose-invert"> 46 {{ .Issue.Body | markdown }} 47 </article> 48 {{ end }} 49 50 <div class="flex items-center gap-2 mt-2"> 51 {{ template "repo/fragments/reactionsPopUp" .OrderedReactionKinds }} 52 {{ range $kind := .OrderedReactionKinds }} 53 {{ 54 template "repo/fragments/reaction" 55 (dict 56 "Kind" $kind 57 "Count" (index $.Reactions $kind) 58 "IsReacted" (index $.UserReacted $kind) 59 "ThreadAt" $.Issue.IssueAt) 60 }} 61 {{ end }} 62 </div> 63 </section> 64{{ end }} 65 66{{ define "repoAfter" }} 67 <section id="comments" class="my-2 mt-2 space-y-2 relative"> 68 {{ range $index, $comment := .Comments }} 69 <div 70 id="comment-{{ .CommentId }}" 71 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"> 72 {{ if gt $index 0 }} 73 <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 74 {{ end }} 75 {{ template "repo/issues/fragments/issueComment" (dict "RepoInfo" $.RepoInfo "LoggedInUser" $.LoggedInUser "DidHandleMap" $.DidHandleMap "Issue" $.Issue "Comment" .)}} 76 </div> 77 {{ end }} 78 </section> 79 80 {{ block "newComment" . }} {{ end }} 81 82{{ end }} 83 84{{ define "newComment" }} 85 {{ if .LoggedInUser }} 86 <form 87 id="comment-form" 88 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 89 hx-on::after-request="if(event.detail.successful) this.reset()" 90 > 91 <div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full md:w-3/5"> 92 <div class="text-sm pb-2 text-gray-500 dark:text-gray-400"> 93 {{ didOrHandle .LoggedInUser.Did .LoggedInUser.Handle }} 94 </div> 95 <textarea 96 id="comment-textarea" 97 name="body" 98 class="w-full p-2 rounded border border-gray-200 dark:border-gray-700" 99 placeholder="Add to the discussion. Markdown is supported." 100 onkeyup="updateCommentForm()" 101 ></textarea> 102 <div id="issue-comment"></div> 103 <div id="issue-action" class="error"></div> 104 </div> 105 106 <div class="flex gap-2 mt-2"> 107 <button 108 id="comment-button" 109 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 110 type="submit" 111 hx-disabled-elt="#comment-button" 112 class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group" 113 disabled 114 > 115 {{ i "message-square-plus" "w-4 h-4" }} 116 comment 117 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 118 </button> 119 120 {{ $isIssueAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Issue.OwnerDid) }} 121 {{ $isRepoCollaborator := .RepoInfo.Roles.IsCollaborator }} 122 {{ $isRepoOwner := .RepoInfo.Roles.IsOwner }} 123 {{ if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "open") }} 124 <button 125 id="close-button" 126 type="button" 127 class="btn flex items-center gap-2" 128 hx-indicator="#close-spinner" 129 hx-trigger="click" 130 > 131 {{ i "ban" "w-4 h-4" }} 132 close 133 <span id="close-spinner" class="group"> 134 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 135 </span> 136 </button> 137 <div 138 id="close-with-comment" 139 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment" 140 hx-trigger="click from:#close-button" 141 hx-disabled-elt="#close-with-comment" 142 hx-target="#issue-comment" 143 hx-indicator="#close-spinner" 144 hx-vals="js:{body: document.getElementById('comment-textarea').value.trim() !== '' ? document.getElementById('comment-textarea').value : ''}" 145 hx-swap="none" 146 > 147 </div> 148 <div 149 id="close-issue" 150 hx-disabled-elt="#close-issue" 151 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/close" 152 hx-trigger="click from:#close-button" 153 hx-target="#issue-action" 154 hx-indicator="#close-spinner" 155 hx-swap="none" 156 > 157 </div> 158 <script> 159 document.addEventListener('htmx:configRequest', function(evt) { 160 if (evt.target.id === 'close-with-comment') { 161 const commentText = document.getElementById('comment-textarea').value.trim(); 162 if (commentText === '') { 163 evt.detail.parameters = {}; 164 evt.preventDefault(); 165 } 166 } 167 }); 168 </script> 169 {{ else if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "closed") }} 170 <button 171 type="button" 172 class="btn flex items-center gap-2" 173 hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/reopen" 174 hx-indicator="#reopen-spinner" 175 hx-swap="none" 176 > 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 class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-fit"> 224 <a href="/login" class="underline">login</a> to join the discussion 225 </div> 226 {{ end }} 227{{ end }}