From 9cf249b0d3b5f2f2e933e547e50954db180d880a Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Thu, 10 Dec 2020 21:32:44 +0100 Subject: [PATCH 1/4] #8861 use ajax on PR review page --- models/issue_comment.go | 62 +++++++++- modules/auth/repo_form.go | 1 + routers/repo/pull_review.go | 81 ++++++++++++- routers/routes/macaron.go | 1 + templates/repo/diff/box.tmpl | 37 +++--- templates/repo/diff/comment_form.tmpl | 3 +- templates/repo/diff/conversation.tmpl | 4 +- templates/repo/diff/new_comment.tmpl | 6 +- templates/repo/diff/section_split.tmpl | 8 +- templates/repo/diff/section_unified.tmpl | 6 +- .../repo/issue/view_content/comments.tmpl | 2 +- web_src/js/index.js | 114 ++++++++++++------ 12 files changed, 248 insertions(+), 77 deletions(-) diff --git a/models/issue_comment.go b/models/issue_comment.go index 7bcea40b93006..e1aa4e977afbb 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -980,7 +980,7 @@ func (opts *FindCommentsOptions) toConds() builder.Cond { if opts.Type != CommentTypeUnknown { cond = cond.And(builder.Eq{"comment.type": opts.Type}) } - if opts.Line > 0 { + if opts.Line != 0 { cond = cond.And(builder.Eq{"comment.line": opts.Line}) } if len(opts.TreePath) > 0 { @@ -1148,6 +1148,66 @@ func fetchCodeCommentsByReview(e Engine, issue *Issue, currentUser *User, review return pathToLineToComment, nil } +// FetchCodeCommentsByLine fetches the code comments for a given treePath and line number +func FetchCodeCommentsByLine(issue *Issue, currentUser *User, treePath string, line int64) ([]*Comment, error) { + opts := FindCommentsOptions{ + Type: CommentTypeCode, + IssueID: issue.ID, + TreePath: treePath, + Line: line, + } + var comments []*Comment + if err := x.Where(opts.toConds()). + Asc("comment.created_unix"). + Asc("comment.id"). + Find(&comments); err != nil { + return nil, err + } + + if err := issue.loadRepo(x); err != nil { + return nil, err + } + + if err := CommentList(comments).loadPosters(x); err != nil { + return nil, err + } + + // Find all reviews by ReviewID + reviews := make(map[int64]*Review) + var ids = make([]int64, 0, len(comments)) + for _, comment := range comments { + if comment.ReviewID != 0 { + ids = append(ids, comment.ReviewID) + } + } + if err := x.In("id", ids).Find(&reviews); err != nil { + return nil, err + } + + for _, comment := range comments { + if err := comment.LoadResolveDoer(); err != nil { + return nil, err + } + + if err := comment.LoadReactions(issue.Repo); err != nil { + return nil, err + } + + if re, ok := reviews[comment.ReviewID]; ok && re != nil { + // If the review is pending only the author can see the comments (except the review is set) + if re.Type == ReviewTypePending && + (currentUser == nil || currentUser.ID != re.ReviewerID) { + continue + } + comment.Review = re + } + + comment.RenderedContent = string(markdown.Render([]byte(comment.Content), issue.Repo.Link(), + issue.Repo.ComposeMetas())) + } + return comments, nil +} + // FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line func FetchCodeComments(issue *Issue, currentUser *User) (CodeComments, error) { return fetchCodeComments(x, issue, currentUser) diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 24c2478fa4ef3..7082392b3b65e 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -547,6 +547,7 @@ func (f *MergePullRequestForm) Validate(ctx *macaron.Context, errs binding.Error // CodeCommentForm form for adding code comments for PRs type CodeCommentForm struct { + Origin string `binding:"Required;In(timeline,diff)"` Content string `binding:"Required"` Side string `binding:"Required;In(previous,proposed)"` Line int64 diff --git a/routers/repo/pull_review.go b/routers/repo/pull_review.go index 730074b7f3f08..5c75c5a434703 100644 --- a/routers/repo/pull_review.go +++ b/routers/repo/pull_review.go @@ -9,11 +9,40 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" pull_service "code.gitea.io/gitea/services/pull" ) +const ( + tplConversation base.TplName = "repo/diff/conversation" + tplNewComment base.TplName = "repo/diff/new_comment" +) + +// RenderNewCodeCommentForm will render the form for creating a new review comment +func RenderNewCodeCommentForm(ctx *context.Context) { + issue := GetActionIssue(ctx) + if !issue.IsPull { + return + } + currentReview, err := models.GetCurrentReview(ctx.User, issue) + if err != nil && !models.IsErrReviewNotExist(err) { + ctx.ServerError("GetCurrentReview", err) + return + } + ctx.Data["PageIsPullFiles"] = true + ctx.Data["Issue"] = issue + ctx.Data["CurrentReview"] = currentReview + pullHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(issue.PullRequest.GetGitRefName()) + if err != nil { + ctx.ServerError("GetRefCommitID", err) + return + } + ctx.Data["AfterCommitID"] = pullHeadCommitID + ctx.HTML(200, tplNewComment) +} + // CreateCodeComment will create a code comment including an pending review if required func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) { issue := GetActionIssue(ctx) @@ -58,11 +87,32 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) { } log.Trace("Comment created: %-v #%d[%d] Comment[%d]", ctx.Repo.Repository, issue.Index, issue.ID, comment.ID) - ctx.Redirect(comment.HTMLURL()) + + if form.Origin == "diff" { + comments, err := models.FetchCodeCommentsByLine(issue, ctx.User, comment.TreePath, comment.Line) + if err != nil { + ctx.ServerError("FetchCodeCommentsByLine", err) + return + } + ctx.Data["PageIsPullFiles"] = true + ctx.Data["comments"] = comments + ctx.Data["CanMarkConversation"] = true + ctx.Data["Issue"] = issue + pullHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(issue.PullRequest.GetGitRefName()) + if err != nil { + ctx.ServerError("GetRefCommitID", err) + return + } + ctx.Data["AfterCommitID"] = pullHeadCommitID + ctx.HTML(200, tplConversation) + } else { + ctx.Redirect(comment.HTMLURL()) + } } // UpdateResolveConversation add or remove an Conversation resolved mark func UpdateResolveConversation(ctx *context.Context) { + origin := ctx.Query("origin") action := ctx.Query("action") commentID := ctx.QueryInt64("comment_id") @@ -103,9 +153,32 @@ func UpdateResolveConversation(ctx *context.Context) { return } - ctx.JSON(200, map[string]interface{}{ - "ok": true, - }) + if origin == "diff" { + comments, err := models.FetchCodeCommentsByLine(comment.Issue, ctx.User, comment.TreePath, comment.Line) + if err != nil { + ctx.ServerError("FetchCodeCommentsByLine", err) + return + } + ctx.Data["PageIsPullFiles"] = true + ctx.Data["comments"] = comments + ctx.Data["CanMarkConversation"] = true + ctx.Data["Issue"] = comment.Issue + if err = comment.Issue.LoadPullRequest(); err != nil { + ctx.ServerError("comment.Issue.LoadPullReqiest", err) + return + } + pullHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(comment.Issue.PullRequest.GetGitRefName()) + if err != nil { + ctx.ServerError("GetRefCommitID", err) + return + } + ctx.Data["AfterCommitID"] = pullHeadCommitID + ctx.HTML(200, tplConversation) + } else { + ctx.JSON(200, map[string]interface{}{ + "ok": true, + }) + } } // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist diff --git a/routers/routes/macaron.go b/routers/routes/macaron.go index 170bc7d493dff..897f4eecb1ddc 100644 --- a/routers/routes/macaron.go +++ b/routers/routes/macaron.go @@ -854,6 +854,7 @@ func RegisterMacaronRoutes(m *macaron.Macaron) { m.Group("/files", func() { m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.ViewPullFiles) m.Group("/reviews", func() { + m.Post("/new_comment", repo.RenderNewCodeCommentForm) m.Post("/comments", bindIgnErr(auth.CodeCommentForm{}), repo.CreateCodeComment) m.Post("/submit", bindIgnErr(auth.SubmitReviewForm{}), repo.SubmitReview) }, context.RepoMustNotBeArchived()) diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 275dc51501a86..6bb41f114199c 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -142,28 +142,25 @@ {{end}} {{if not $.Repository.IsArchived}} -
- {{template "repo/diff/new_comment" dict "root" .}} +
+
+ -
-
- -
- -
-
- {{$.i18n.Tr "loading"}} -
-
-
{{.i18n.Tr "repo.issues.cancel"}}
-
{{.i18n.Tr "repo.issues.save"}}
-
-
+
+ +
+
+ {{$.i18n.Tr "loading"}} +
+
+
{{.i18n.Tr "repo.issues.cancel"}}
+
{{.i18n.Tr "repo.issues.save"}}
- {{end}} +
+
+ {{end}} {{if .IsSplitStyle}}