+9
appview/pages/templates/repo/issues/fragments/issueCommentBody.html
+9
appview/pages/templates/repo/issues/fragments/issueCommentBody.html
···
1
+
{{ define "repo/issues/fragments/issueCommentBody" }}
2
+
<div id="comment-body-{{.Comment.Id}}">
3
+
{{ if not .Comment.Deleted }}
4
+
<div class="prose dark:prose-invert">{{ .Comment.Body | markdown }}</div>
5
+
{{ else }}
6
+
<div class="prose dark:prose-invert italic text-gray-500 dark:text-gray-400">[deleted by author]</div>
7
+
{{ end }}
8
+
</div>
9
+
{{ end }}
+56
appview/pages/templates/repo/issues/fragments/issueCommentHeader.html
+56
appview/pages/templates/repo/issues/fragments/issueCommentHeader.html
···
1
+
{{ define "repo/issues/fragments/issueCommentHeader" }}
2
+
<div class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-400 ">
3
+
{{ template "user/fragments/picHandleLink" .Comment.Did }}
4
+
{{ template "hats" $ }}
5
+
{{ template "timestamp" . }}
6
+
{{ $isCommentOwner := and .LoggedInUser (eq .LoggedInUser.Did .Comment.Did) }}
7
+
{{ if and $isCommentOwner (not .Comment.Deleted) }}
8
+
{{ template "edit" . }}
9
+
{{ template "delete" . }}
10
+
{{ end }}
11
+
</div>
12
+
{{ end }}
13
+
14
+
{{ define "hats" }}
15
+
{{ $isIssueAuthor := eq .Comment.Did .Issue.Did }}
16
+
{{ if $isIssueAuthor }}
17
+
(author)
18
+
{{ end }}
19
+
{{ end }}
20
+
21
+
{{ define "timestamp" }}
22
+
<a href="#{{ .Comment.Id }}"
23
+
class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-400 hover:underline no-underline"
24
+
id="{{ .Comment.Id }}">
25
+
{{ if .Comment.Deleted }}
26
+
{{ template "repo/fragments/shortTimeAgo" .Comment.Deleted }}
27
+
{{ else if .Comment.Edited }}
28
+
edited {{ template "repo/fragments/shortTimeAgo" .Comment.Edited }}
29
+
{{ else }}
30
+
{{ template "repo/fragments/shortTimeAgo" .Comment.Created }}
31
+
{{ end }}
32
+
</a>
33
+
{{ end }}
34
+
35
+
{{ define "edit" }}
36
+
<a
37
+
class="text-gray-500 dark:text-gray-400 flex gap-1 items-center group"
38
+
hx-get="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.Id }}/comment/{{ .Comment.Id }}/edit"
39
+
hx-swap="outerHTML"
40
+
hx-target="#comment-body-{{.Comment.Id}}">
41
+
{{ i "pencil" "size-3" }}
42
+
</a>
43
+
{{ end }}
44
+
45
+
{{ define "delete" }}
46
+
<a
47
+
class="text-gray-500 dark:text-gray-400 flex gap-1 items-center group"
48
+
hx-delete="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.Id }}/comment/{{ .Comment.Id }}/"
49
+
hx-confirm="Are you sure you want to delete your comment?"
50
+
hx-swap="outerHTML"
51
+
hx-target="#comment-body-{{.Comment.Id}}"
52
+
>
53
+
{{ i "trash-2" "size-3" }}
54
+
{{ i "loader-circle" "size-3 animate-spin hidden group-[.htmx-request]:inline" }}
55
+
</a>
56
+
{{ end }}
+145
appview/pages/templates/repo/issues/fragments/newComment.html
+145
appview/pages/templates/repo/issues/fragments/newComment.html
···
1
+
{{ define "repo/issues/fragments/newComment" }}
2
+
{{ if .LoggedInUser }}
3
+
<form
4
+
id="comment-form"
5
+
hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
6
+
hx-on::after-request="if(event.detail.successful) this.reset()"
7
+
>
8
+
<div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full">
9
+
<div class="text-sm pb-2 text-gray-500 dark:text-gray-400">
10
+
{{ template "user/fragments/picHandleLink" .LoggedInUser.Did }}
11
+
</div>
12
+
<textarea
13
+
id="comment-textarea"
14
+
name="body"
15
+
class="w-full p-2 rounded border border-gray-200 dark:border-gray-700"
16
+
placeholder="Add to the discussion. Markdown is supported."
17
+
onkeyup="updateCommentForm()"
18
+
rows="5"
19
+
></textarea>
20
+
<div id="issue-comment"></div>
21
+
<div id="issue-action" class="error"></div>
22
+
</div>
23
+
24
+
<div class="flex gap-2 mt-2">
25
+
<button
26
+
id="comment-button"
27
+
hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
28
+
type="submit"
29
+
hx-disabled-elt="#comment-button"
30
+
class="btn-create p-2 flex items-center gap-2 no-underline hover:no-underline group"
31
+
disabled
32
+
>
33
+
{{ i "message-square-plus" "w-4 h-4" }}
34
+
comment
35
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
36
+
</button>
37
+
38
+
{{ $isIssueAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Issue.Did) }}
39
+
{{ $isRepoCollaborator := .RepoInfo.Roles.IsCollaborator }}
40
+
{{ $isRepoOwner := .RepoInfo.Roles.IsOwner }}
41
+
{{ if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "open") }}
42
+
<button
43
+
id="close-button"
44
+
type="button"
45
+
class="btn flex items-center gap-2"
46
+
hx-indicator="#close-spinner"
47
+
hx-trigger="click"
48
+
>
49
+
{{ i "ban" "w-4 h-4" }}
50
+
close
51
+
<span id="close-spinner" class="group">
52
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
53
+
</span>
54
+
</button>
55
+
<div
56
+
id="close-with-comment"
57
+
hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment"
58
+
hx-trigger="click from:#close-button"
59
+
hx-disabled-elt="#close-with-comment"
60
+
hx-target="#issue-comment"
61
+
hx-indicator="#close-spinner"
62
+
hx-vals="js:{body: document.getElementById('comment-textarea').value.trim() !== '' ? document.getElementById('comment-textarea').value : ''}"
63
+
hx-swap="none"
64
+
>
65
+
</div>
66
+
<div
67
+
id="close-issue"
68
+
hx-disabled-elt="#close-issue"
69
+
hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/close"
70
+
hx-trigger="click from:#close-button"
71
+
hx-target="#issue-action"
72
+
hx-indicator="#close-spinner"
73
+
hx-swap="none"
74
+
>
75
+
</div>
76
+
<script>
77
+
document.addEventListener('htmx:configRequest', function(evt) {
78
+
if (evt.target.id === 'close-with-comment') {
79
+
const commentText = document.getElementById('comment-textarea').value.trim();
80
+
if (commentText === '') {
81
+
evt.detail.parameters = {};
82
+
evt.preventDefault();
83
+
}
84
+
}
85
+
});
86
+
</script>
87
+
{{ else if and (or $isIssueAuthor $isRepoCollaborator $isRepoOwner) (eq .State "closed") }}
88
+
<button
89
+
type="button"
90
+
class="btn flex items-center gap-2"
91
+
hx-post="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/reopen"
92
+
hx-indicator="#reopen-spinner"
93
+
hx-swap="none"
94
+
>
95
+
{{ i "refresh-ccw-dot" "w-4 h-4" }}
96
+
reopen
97
+
<span id="reopen-spinner" class="group">
98
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
99
+
</span>
100
+
</button>
101
+
{{ end }}
102
+
103
+
<script>
104
+
function updateCommentForm() {
105
+
const textarea = document.getElementById('comment-textarea');
106
+
const commentButton = document.getElementById('comment-button');
107
+
const closeButton = document.getElementById('close-button');
108
+
109
+
if (textarea.value.trim() !== '') {
110
+
commentButton.removeAttribute('disabled');
111
+
} else {
112
+
commentButton.setAttribute('disabled', '');
113
+
}
114
+
115
+
if (closeButton) {
116
+
if (textarea.value.trim() !== '') {
117
+
closeButton.innerHTML = `
118
+
{{ i "ban" "w-4 h-4" }}
119
+
<span>close with comment</span>
120
+
<span id="close-spinner" class="group">
121
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
122
+
</span>`;
123
+
} else {
124
+
closeButton.innerHTML = `
125
+
{{ i "ban" "w-4 h-4" }}
126
+
<span>close</span>
127
+
<span id="close-spinner" class="group">
128
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
129
+
</span>`;
130
+
}
131
+
}
132
+
}
133
+
134
+
document.addEventListener('DOMContentLoaded', function() {
135
+
updateCommentForm();
136
+
});
137
+
</script>
138
+
</div>
139
+
</form>
140
+
{{ else }}
141
+
<div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-fit">
142
+
<a href="/login" class="underline">login</a> to join the discussion
143
+
</div>
144
+
{{ end }}
145
+
{{ end }}