From ca63a9d3f1120d8c76eb83ff1fd07e0992a683a8 Mon Sep 17 00:00:00 2001
From: Lauris BH <lauris@nix.lv>
Date: Sun, 17 Jan 2021 19:29:10 +0200
Subject: [PATCH] Add edit, delete and reaction support to code review comments
 on issue page (#14339)

---
 routers/repo/issue.go                         | 19 ++++++
 templates/repo/diff/comments.tmpl             |  2 +-
 .../repo/issue/view_content/comments.tmpl     | 63 ++++++++++++++-----
 .../repo/issue/view_content/context_menu.tmpl |  6 +-
 web_src/less/_repository.less                 | 31 +++++++++
 5 files changed, 101 insertions(+), 20 deletions(-)

diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 7b4044ac7..6a532dc12 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -1377,7 +1377,26 @@ func ViewIssue(ctx *context.Context) {
 				ctx.ServerError("Review.LoadCodeComments", err)
 				return
 			}
+			for _, codeComments := range comment.Review.CodeComments {
+				for _, lineComments := range codeComments {
+					for _, c := range lineComments {
+						// Check tag.
+						tag, ok = marked[c.PosterID]
+						if ok {
+							c.ShowTag = tag
+							continue
+						}
 
+						c.ShowTag, err = commentTag(repo, c.Poster, issue)
+						if err != nil {
+							ctx.ServerError("commentTag", err)
+							return
+						}
+						marked[c.PosterID] = c.ShowTag
+						participants = addParticipant(c.Poster, participants)
+					}
+				}
+			}
 			if err = comment.LoadResolveDoer(); err != nil {
 				ctx.ServerError("LoadResolveDoer", err)
 				return
diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl
index 59bc89b79..36e725936 100644
--- a/templates/repo/diff/comments.tmpl
+++ b/templates/repo/diff/comments.tmpl
@@ -47,7 +47,7 @@
 					{{end}}
 				{{end}}
 				{{template "repo/issue/view_content/add_reaction" Dict "ctx" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }}
-				{{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
+				{{template "repo/issue/view_content/context_menu" Dict "ctx" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
 			</div>
 		</div>
 		<div class="ui attached segment comment-body">
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl
index 8f5426b83..abf5792a9 100644
--- a/templates/repo/issue/view_content/comments.tmpl
+++ b/templates/repo/issue/view_content/comments.tmpl
@@ -58,7 +58,7 @@
 								</div>
 							{{end}}
 							{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
-							{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
+							{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
 						{{end}}
 					</div>
 				</div>
@@ -494,25 +494,49 @@
 										</div>
 									</div>
 								{{end}}
-								<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if $resolved}} hide{{end}} py-3">
+								<div id="code-comments-{{(index $comms 0).ID}}" class="comment-code-cloud ui segment{{if $resolved}} hide{{end}} py-3">
 									<div class="ui comments mb-0">
 										{{range $comms}}
 											{{ $createdSubStr:= TimeSinceUnix .CreatedUnix $.Lang }}
 											<div class="comment code-comment" id="{{.HashTag}}">
-												{{if not .OriginalAuthor }}
-													<a class="avatar">
-														{{avatar .Poster}}
-													</a>
-												{{end}}
 												<div class="content">
-													<span class="text grey">
-														{{if .OriginalAuthor }}
-															<span class="text black"><i class="fa {{MigrationIcon $.Repository.GetOriginalURLHostname}}" aria-hidden="true"></i> {{ .OriginalAuthor }}</span><span class="text grey"> {{if $.Repository.OriginalURL}}</span><span class="text migrate">({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}}</span>
-														{{else}}
-															<a class="author"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.GetDisplayName}}</a>
-														{{end}}
-														{{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}}
-													</span>
+													<div class="header comment-header">
+														<div class="comment-header-left df ac">
+															{{if not .OriginalAuthor }}
+																<a class="avatar">
+																	{{avatar .Poster}}
+																</a>
+															{{end}}
+															<span class="text grey">
+																{{if .OriginalAuthor }}
+																	<span class="text black"><i class="fa {{MigrationIcon $.Repository.GetOriginalURLHostname}}" aria-hidden="true"></i> {{ .OriginalAuthor }}</span><span class="text grey"> {{if $.Repository.OriginalURL}}</span><span class="text migrate">({{$.i18n.Tr "repo.migrated_from" $.Repository.OriginalURL $.Repository.GetOriginalURLHostname | Safe }}){{end}}</span>
+																{{else}}
+																	<a class="author"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.GetDisplayName}}</a>
+																{{end}}
+																{{$.i18n.Tr "repo.issues.commented_at" .HashTag $createdSubStr | Safe}}
+															</span>
+														</div>
+														<div class="comment-header-right actions df ac">
+															{{if not $.Repository.IsArchived}}
+																{{if or (and (eq .PosterID $.Issue.PosterID) (eq $.Issue.OriginalAuthorID 0)) (eq $.Issue.OriginalAuthorID .OriginalAuthorID) }}
+																	<div class="ui basic label">
+																		{{$.i18n.Tr "repo.issues.poster"}}
+																	</div>
+																{{end}}
+																{{if gt .ShowTag 0}}
+																	<div class="ui basic label">
+																		{{if eq .ShowTag 2}}
+																			{{$.i18n.Tr "repo.issues.collaborator"}}
+																		{{else if eq .ShowTag 3}}
+																			{{$.i18n.Tr "repo.issues.owner"}}
+																		{{end}}
+																	</div>
+																{{end}}
+																{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
+																{{template "repo/issue/view_content/context_menu" Dict "ctx" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
+															{{end}}
+														</div>
+													</div>
 													<div class="text comment-content">
 														<div class="render-content markdown">
 														{{if .RenderedContent}}
@@ -521,8 +545,15 @@
 															<span class="no-content">{{$.i18n.Tr "repo.issues.no_content"}}</span>
 														{{end}}
 														</div>
-														<div class="raw-content hide">{{.Content}}</div>
+														<div id="comment-{{.ID}}" class="raw-content hide">{{.Content}}</div>
+														<div class="edit-content-zone hide" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div>
 													</div>
+													{{$reactions := .Reactions.GroupByType}}
+													{{if $reactions}}
+														<div class="ui attached segment reactions">
+															{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
+														</div>
+													{{end}}
 												</div>
 											</div>
 										{{end}}
diff --git a/templates/repo/issue/view_content/context_menu.tmpl b/templates/repo/issue/view_content/context_menu.tmpl
index 744821cb3..0b8b84e9f 100644
--- a/templates/repo/issue/view_content/context_menu.tmpl
+++ b/templates/repo/issue/view_content/context_menu.tmpl
@@ -4,10 +4,10 @@
 		{{svg "octicon-kebab-horizontal"}}
 	</a>
 	<div class="menu">
-		{{if .diff}}
-			<div class="item context clipboard" data-clipboard-text="{{Printf "%s%s/pulls/%d/files#%s" AppUrl .ctx.Repository.FullName .ctx.Issue.Index .item.HashTag}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
-		{{else}}
+		{{if .issue}}
 			<div class="item context clipboard" data-clipboard-text="{{Printf "%s%s/issues/%d#%s" AppUrl .ctx.Repository.FullName .ctx.Issue.Index .item.HashTag}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
+		{{else}}
+			<div class="item context clipboard" data-clipboard-text="{{Printf "%s%s/pulls/%d/files#%s" AppUrl .ctx.Repository.FullName .ctx.Issue.Index .item.HashTag}}">{{.ctx.i18n.Tr "repo.issues.context.copy_link"}}</div>
 		{{end}}
 		<div class="item context quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.ID}}">{{.ctx.i18n.Tr "repo.issues.context.quote_reply"}}</div>
 		{{if or .ctx.Permission.IsAdmin .IsCommentPoster .ctx.HasIssuesOrPullsWritePermission}}
diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less
index 6c7de7507..fa6ea4467 100644
--- a/web_src/less/_repository.less
+++ b/web_src/less/_repository.less
@@ -939,6 +939,10 @@
         }
       }
 
+      .ui.comments {
+        max-width: 100%;
+      }
+
       .comment {
         > .content {
           > div:first-child {
@@ -1048,12 +1052,39 @@
           border: none !important;
         }
 
+        .comment-header {
+          background: transparent;
+          border-bottom: 0 !important;
+          padding: 0 !important;
+
+          &::after,
+          &::before {
+            display: none;
+          }
+        }
+
         .avatar.image {
           width: 28px;
           height: 28px;
         }
       }
 
+      .comment-code-cloud {
+        .segment.reactions {
+          border-top: none !important;
+
+          .ui.label {
+            border: 1px solid;
+            padding: 6px !important;
+            border-radius: var(--border-radius);
+          }
+        }
+
+        button.comment-form-reply {
+          margin-left: 0;
+        }
+      }
+
       .event {
         padding-left: 15px;