Skip to content

Commit b95fb6f

Browse files
committed
Add a way to mark Conversation (code comment) resolved
mark Conversation is a way to mark a Conversation is stale or be solved. when it's marked as stale, will be hided like stale. all Pull Request writer , Offical Reviewers and poster can add or remove Conversation resolved mark. Signed-off-by: a1012112796 <[email protected]>
1 parent 7430221 commit b95fb6f

File tree

11 files changed

+254
-8
lines changed

11 files changed

+254
-8
lines changed

models/issue_comment.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,13 @@ func fetchCodeCommentsByReview(e Engine, issue *Issue, currentUser *User, review
942942
return nil, err
943943
}
944944
for _, comment := range comments {
945+
// use assignee as Conversation doer
946+
if comment.AssigneeID != 0 {
947+
if err := comment.LoadAssigneeUser(); err != nil {
948+
return nil, err
949+
}
950+
}
951+
945952
if re, ok := reviews[comment.ReviewID]; ok && re != nil {
946953
// If the review is pending only the author can see the comments (except the review is set)
947954
if review.ID == 0 {

models/review.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package models
66

77
import (
8+
"fmt"
89
"strings"
910

1011
"code.gitea.io/gitea/modules/timeutil"
@@ -590,3 +591,59 @@ func RemoveRewiewRequest(issue *Issue, reviewer *User, doer *User) (comment *Com
590591

591592
return comment, sess.Commit()
592593
}
594+
595+
// MarkConversation Add or remove Conversation mark for a code comment
596+
func MarkConversation(comment *Comment, doer *User, isResolve bool) (err error) {
597+
if comment.Type != CommentTypeCode {
598+
return nil
599+
}
600+
601+
if isResolve {
602+
if comment.AssigneeID != 0 {
603+
return nil
604+
}
605+
606+
if _, err = x.Exec("UPDATE `comment` SET assignee_id=? WHERE id=?", doer.ID, comment.ID); err != nil {
607+
return err
608+
}
609+
} else {
610+
if comment.AssigneeID == 0 {
611+
return nil
612+
}
613+
614+
if _, err = x.Exec("UPDATE `comment` SET assignee_id=? WHERE id=?", 0, comment.ID); err != nil {
615+
return err
616+
}
617+
}
618+
619+
return nil
620+
}
621+
622+
// CanMarkConversation Add or remove Conversation mark for a code comment permission check
623+
// the PR writer , offfical reviewer and poster can do it
624+
func CanMarkConversation(issue *Issue, doer *User) (permResult bool, err error) {
625+
if doer == nil || issue == nil {
626+
return false, fmt.Errorf("issue or doer is nil")
627+
}
628+
629+
if doer.ID != issue.PosterID {
630+
perm, err := GetUserRepoPermission(issue.Repo, doer)
631+
if err != nil {
632+
return false, err
633+
}
634+
635+
permResult = perm.CanAccess(AccessModeWrite, UnitTypePullRequests)
636+
if !permResult {
637+
permResult, err = IsOfficialReviewer(issue, doer)
638+
if err != nil {
639+
return false, err
640+
}
641+
}
642+
643+
if !permResult {
644+
return false, nil
645+
}
646+
}
647+
648+
return true, nil
649+
}

options/locale/locale_en-US.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,11 @@ issues.review.review = Review
10641064
issues.review.reviewers = Reviewers
10651065
issues.review.show_outdated = Show outdated
10661066
issues.review.hide_outdated = Hide outdated
1067+
issues.review.show_resolved = Show resolved
1068+
issues.review.hide_resolved = Hide resolved
1069+
issues.review.resolve_conversation = Resolve conversation
1070+
issues.review.un_resolve_conversation = Unresolve conversation
1071+
issues.review.resolved_by = marked this conversation as resolved
10671072
issues.assignee.error = Not all assignees was added due to an unexpected error.
10681073

10691074
pulls.desc = Enable pull requests and code reviews.

routers/repo/issue.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,14 @@ func ViewIssue(ctx *context.Context) {
990990
ctx.ServerError("Review.LoadCodeComments", err)
991991
return
992992
}
993+
994+
// use assignee as Mark Conversation doer
995+
if comment.Type == models.CommentTypeCode && comment.AssigneeID != 0 {
996+
if err = comment.LoadAssigneeUser(); err != nil {
997+
ctx.ServerError("LoadAssigneeUser", err)
998+
return
999+
}
1000+
}
9931001
}
9941002
}
9951003

@@ -1033,6 +1041,11 @@ func ViewIssue(ctx *context.Context) {
10331041
ctx.ServerError("IsUserAllowedToMerge", err)
10341042
return
10351043
}
1044+
1045+
if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.User); err != nil {
1046+
ctx.ServerError("CanMarkConversation", err)
1047+
return
1048+
}
10361049
}
10371050

10381051
prUnit, err := repo.GetUnit(models.UnitTypePullRequests)

routers/repo/pull.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,13 @@ func ViewPullFiles(ctx *context.Context) {
635635
return
636636
}
637637

638+
if ctx.IsSigned && ctx.User != nil {
639+
if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.User); err != nil {
640+
ctx.ServerError("CanMarkConversation", err)
641+
return
642+
}
643+
}
644+
638645
setImageCompareContext(ctx, baseCommit, commit)
639646
setPathsCompareContext(ctx, baseCommit, commit, headTarget)
640647

routers/repo/pull_review.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,44 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) {
6161
ctx.Redirect(comment.HTMLURL())
6262
}
6363

64+
// UpdateResolveConversation add or remove an Conversation resolved mark
65+
func UpdateResolveConversation(ctx *context.Context) {
66+
action := ctx.Query("action")
67+
issueID := ctx.QueryInt64("issue_id")
68+
commentID := ctx.QueryInt64("comment_id")
69+
70+
issue, err := models.GetIssueByID(issueID)
71+
if err != nil {
72+
ctx.ServerError("GetIssueByID", err)
73+
return
74+
}
75+
76+
if !issue.IsPull {
77+
return
78+
}
79+
80+
comment, err := models.GetCommentByID(commentID)
81+
if err != nil {
82+
ctx.ServerError("GetCommentByID", err)
83+
return
84+
}
85+
86+
if action == "Resolve" || action == "UnResolve" {
87+
err = models.MarkConversation(comment, ctx.User, action == "Resolve")
88+
if err != nil {
89+
ctx.ServerError("MarkConversation", err)
90+
return
91+
}
92+
} else {
93+
ctx.ServerError("UpdateResolveConversation", fmt.Errorf("error action : %s", action))
94+
return
95+
}
96+
97+
ctx.JSON(200, map[string]interface{}{
98+
"ok": true,
99+
})
100+
}
101+
64102
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
65103
func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) {
66104
issue := GetActionIssue(ctx)

routers/routes/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ func RegisterRoutes(m *macaron.Macaron) {
739739
m.Post("/assignee", reqRepoIssuesOrPullsWriter, repo.UpdateIssueAssignee)
740740
m.Post("/request_review", reqRepoIssuesOrPullsReader, repo.UpdatePullReviewRequest)
741741
m.Post("/status", reqRepoIssuesOrPullsWriter, repo.UpdateIssueStatus)
742+
m.Post("/resolve_conversation", reqRepoIssuesOrPullsReader, repo.UpdateResolveConversation)
742743
}, context.RepoMustNotBeArchived())
743744
m.Group("/comments/:id", func() {
744745
m.Post("", repo.UpdateCommentContent)

templates/repo/diff/box.tmpl

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,32 +147,82 @@
147147
{{end}}
148148
</tr>
149149
{{if gt (len $line.Comments) 0}}
150+
{{$assigneeid := (index $line.Comments 0).AssigneeID}}
151+
{{$assignee := (index $line.Comments 0).Assignee}}
150152
<tr class="add-code-comment">
151153
<td class="lines-num"></td>
152154
<td class="lines-type-marker"></td>
153155
<td class="add-comment-left">
156+
<div class="ui segment">
157+
{{if and (not (eq $assigneeid 0)) (eq $line.GetCommentSide "previous")}}
158+
<span class="ui grey text left"><b>{{$assignee.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
159+
<button id="show-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="ui compact right labeled button show-outdated">
160+
{{svg "octicon-fold" 16}}
161+
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
162+
</button>
163+
<button id="hide-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="hide ui compact right labeled button hide-outdated">
164+
{{svg "octicon-fold" 16}}
165+
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
166+
</button>
167+
{{end}}
168+
</div>
154169
{{if eq $line.GetCommentSide "previous"}}
155-
<div class="field comment-code-cloud">
170+
<div id="code-comments-{{(index $line.Comments 0).ID}}" class="field comment-code-cloud {{if not (eq $assigneeid 0)}}hide{{end}}">
156171
<div class="comment-list">
157172
<ui class="ui comments">
158173
{{ template "repo/diff/comments" dict "root" $ "comments" $line.Comments}}
159174
</ui>
160175
</div>
161176
{{template "repo/diff/comment_form_datahandler" dict "reply" (index $line.Comments 0).ReviewID "hidden" true "root" $ "comment" (index $line.Comments 0)}}
177+
{{if $.CanMarkConversation }}
178+
<button class="ui green icon tiny button resolve-conversation" data-action="{{if eq $assigneeid 0}}Resolve{{else}}UnResolve{{end}}" data-issue-id="{{$.Issue.ID}}" data-comment-id="{{(index $line.Comments 0).ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation" >
179+
{{if not (eq $assigneeid 0)}}
180+
{{$.i18n.Tr "repo.issues.review.un_resolve_conversation"}}
181+
{{else}}
182+
{{$.i18n.Tr "repo.issues.review.resolve_conversation"}}
183+
{{end}}
184+
</button>
185+
{{end}}
186+
{{if not (eq $assigneeid 0)}}
187+
<span class="ui grey text"><b>{{$assignee.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
188+
{{end}}
162189
</div>
163190
{{end}}
164191
</td>
165192
<td class="lines-num"></td>
166193
<td class="lines-type-marker"></td>
167194
<td class="add-comment-right">
195+
{{if and (not (eq $assigneeid 0)) (eq $line.GetCommentSide "proposed")}}
196+
<span class="ui grey text left"><b>{{$assignee.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
197+
<button id="show-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="ui compact right labeled button show-outdated">
198+
{{svg "octicon-fold" 16}}
199+
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
200+
</button>
201+
<button id="hide-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="hide ui compact right labeled button hide-outdated">
202+
{{svg "octicon-fold" 16}}
203+
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
204+
</button>
205+
{{end}}
168206
{{if eq $line.GetCommentSide "proposed"}}
169-
<div class="field comment-code-cloud">
207+
<div id="code-comments-{{(index $line.Comments 0).ID}}" class="field comment-code-cloud {{if not (eq $assigneeid 0)}}hide{{end}}">
170208
<div class="comment-list">
171209
<ui class="ui comments">
172210
{{ template "repo/diff/comments" dict "root" $ "comments" $line.Comments}}
173211
</ui>
174212
</div>
175213
{{template "repo/diff/comment_form_datahandler" dict "reply" (index $line.Comments 0).ReviewID "hidden" true "root" $ "comment" (index $line.Comments 0)}}
214+
{{if $.CanMarkConversation}}
215+
<button class="ui green icon tiny button resolve-conversation" data-action="{{if eq $assigneeid 0}}Resolve{{else}}UnResolve{{end}}" data-issue-id="{{$.Issue.ID}}" data-comment-id="{{(index $line.Comments 0).ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation" >
216+
{{if not (eq $assigneeid 0)}}
217+
{{$.i18n.Tr "repo.issues.review.un_resolve_conversation"}}
218+
{{else}}
219+
{{$.i18n.Tr "repo.issues.review.resolve_conversation"}}
220+
{{end}}
221+
</button>
222+
{{end}}
223+
{{if not (eq $assigneeid 0)}}
224+
<span class="ui grey text"><b>{{$assignee.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
225+
{{end}}
176226
</div>
177227
{{end}}
178228
</td>

templates/repo/diff/section_unified.tmpl

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,45 @@
2323
<td class="lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</span></td>
2424
</tr>
2525
{{if gt (len $line.Comments) 0}}
26+
{{$assigneeid := (index $line.Comments 0).AssigneeID}}
27+
{{$assignee := (index $line.Comments 0).Assignee}}
2628
<tr>
2729
<td colspan="2" class="lines-num"></td>
2830
<td class="lines-type-marker"></td>
2931
<td class="add-comment-left add-comment-right">
30-
<div class="field comment-code-cloud">
32+
<div class = "ui segment">
33+
{{if not (eq $assigneeid 0)}}
34+
<span class="ui grey text left"><b>{{$assignee.Name}}</b> {{$.root.i18n.Tr "repo.issues.review.resolved_by"}}</span>
35+
<button id="show-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="ui compact right labeled button show-outdated">
36+
{{svg "octicon-fold" 16}}
37+
{{$.root.i18n.Tr "repo.issues.review.show_resolved"}}
38+
</button>
39+
<button id="hide-outdated-{{(index $line.Comments 0).ID}}" data-comment="{{(index $line.Comments 0).ID}}" class="hide ui compact right labeled button hide-outdated">
40+
{{svg "octicon-fold" 16}}
41+
{{$.root.i18n.Tr "repo.issues.review.hide_resolved"}}
42+
</button>
43+
{{end}}
44+
</div>
45+
<div id="code-comments-{{(index $line.Comments 0).ID}}" class="field comment-code-cloud {{if not (eq $assigneeid 0)}}hide{{end}}">
3146
<div class="comment-list">
3247
<ui class="ui comments">
3348
{{ template "repo/diff/comments" dict "root" $.root "comments" $line.Comments}}
3449
</ui>
3550
</div>
3651
{{template "repo/diff/comment_form_datahandler" dict "hidden" true "reply" (index $line.Comments 0).ReviewID "root" $.root "comment" (index $line.Comments 0)}}
52+
{{if $.root.CanMarkConversation}}
53+
<button class="ui green icon tiny button resolve-conversation" data-action="{{if eq $assigneeid 0}}Resolve{{else}}UnResolve{{end}}" data-issue-id="{{$.root.Issue.ID}}" data-comment-id="{{(index $line.Comments 0).ID}}" data-update-url="{{$.root.RepoLink}}/issues/resolve_conversation" >
54+
{{if not (eq $assigneeid 0)}}
55+
{{$.root.i18n.Tr "repo.issues.review.un_resolve_conversation"}}
56+
{{else}}
57+
{{$.root.i18n.Tr "repo.issues.review.resolve_conversation"}}
58+
{{end}}
59+
</button>
60+
{{end}}
61+
62+
{{if not (eq $assigneeid 0)}}
63+
<span class="ui grey text"><b>{{$assignee.Name}}</b> {{$.root.i18n.Tr "repo.issues.review.resolved_by"}}</span>
64+
{{end}}
3765
</div>
3866
</td>
3967
</tr>

templates/repo/issue/view_content/comments.tmpl

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,22 +356,32 @@
356356
<div class="ui segments">
357357
<div class="ui segment">
358358
{{$invalid := (index $comms 0).Invalidated}}
359-
{{if $invalid}}
359+
{{$assigneeid := (index $comms 0).AssigneeID}}
360+
{{$assignee := (index $comms 0).Assignee}}
361+
{{if or $invalid (not (eq $assigneeid 0))}}
360362
<button id="show-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="ui compact right labeled button show-outdated">
361363
{{svg "octicon-fold" 16}}
362-
{{$.i18n.Tr "repo.issues.review.show_outdated"}}
364+
{{if $invalid }}
365+
{{$.i18n.Tr "repo.issues.review.show_outdated"}}
366+
{{else}}
367+
{{$.i18n.Tr "repo.issues.review.show_resolved"}}
368+
{{end}}
363369
</button>
364370
<button id="hide-outdated-{{(index $comms 0).ID}}" data-comment="{{(index $comms 0).ID}}" class="hide ui compact right labeled button hide-outdated">
365371
{{svg "octicon-fold" 16}}
366-
{{$.i18n.Tr "repo.issues.review.hide_outdated"}}
372+
{{if $invalid}}
373+
{{$.i18n.Tr "repo.issues.review.hide_outdated"}}
374+
{{else}}
375+
{{$.i18n.Tr "repo.issues.review.hide_resolved"}}
376+
{{end}}
367377
</button>
368378
{{end}}
369379
<a href="{{(index $comms 0).CodeCommentURL}}" class="file-comment">{{$filename}}</a>
370380
</div>
371381
{{$diff := (CommentMustAsDiff (index $comms 0))}}
372382
{{if $diff}}
373383
{{$file := (index $diff.Files 0)}}
374-
<div id="code-preview-{{(index $comms 0).ID}}" class="ui table segment{{if $invalid}} hide{{end}}">
384+
<div id="code-preview-{{(index $comms 0).ID}}" class="ui table segment{{if or $invalid (not (eq $assigneeid 0))}} hide{{end}}">
375385
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}">
376386
<div class="file-body file-code code-view code-diff code-diff-unified">
377387
<table>
@@ -383,7 +393,7 @@
383393
</div>
384394
</div>
385395
{{end}}
386-
<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if $invalid}} hide{{end}}">
396+
<div id="code-comments-{{(index $comms 0).ID}}" class="ui segment{{if or $invalid (not (eq $assigneeid 0))}} hide{{end}}">
387397
<div class="ui comments">
388398
{{range $comms}}
389399
{{ $createdSubStr:= TimeSinceUnix .CreatedUnix $.Lang }}
@@ -413,6 +423,20 @@
413423
{{end}}
414424
</div>
415425
{{template "repo/diff/comment_form_datahandler" dict "hidden" true "reply" (index $comms 0).ReviewID "root" $ "comment" (index $comms 0)}}
426+
427+
{{if $.CanMarkConversation}}
428+
<button class="ui green icon tiny button resolve-conversation" data-action="{{if eq $assigneeid 0}}Resolve{{else}}UnResolve{{end}}" data-issue-id="{{$.Issue.ID}}" data-comment-id="{{(index $comms 0).ID}}" data-update-url="{{$.RepoLink}}/issues/resolve_conversation" >
429+
{{if not (eq $assigneeid 0)}}
430+
{{$.i18n.Tr "repo.issues.review.un_resolve_conversation"}}
431+
{{else}}
432+
{{$.i18n.Tr "repo.issues.review.resolve_conversation"}}
433+
{{end}}
434+
</button>
435+
{{end}}
436+
437+
{{if not (eq $assigneeid 0)}}
438+
<span class="ui grey text"><b>{{$assignee.Name}}</b> {{$.i18n.Tr "repo.issues.review.resolved_by"}}</span>
439+
{{end}}
416440
</div>
417441
</div>
418442
{{end}}

0 commit comments

Comments
 (0)