From 274ed544842fe81fe9fa3a901022d3d5968d7330 Mon Sep 17 00:00:00 2001 From: Rajesh Jonnalagadda Date: Mon, 11 Nov 2024 07:03:55 +0530 Subject: [PATCH] feat: phase 1 changes: add comments feat to unchanged lines in the pull request. --- routers/web/repo/compare.go | 113 ++++++++++++++++++++--- routers/web/web.go | 5 + services/gitdiff/gitdiff.go | 73 +++++++++++---- services/repository/files/diff_test.go | 17 ++-- templates/repo/diff/blob_excerpt.tmpl | 98 +++++++++++++++----- templates/repo/diff/section_split.tmpl | 41 ++++---- templates/repo/diff/section_unified.tmpl | 20 +++- web_src/css/base.css | 7 ++ 8 files changed, 292 insertions(+), 82 deletions(-) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 39279728375..eaea91b5849 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -14,6 +14,7 @@ import ( "net/http" "net/url" "path/filepath" + "sort" "strings" "code.gitea.io/gitea/models/db" @@ -39,6 +40,7 @@ import ( "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/gitdiff" + user_service "code.gitea.io/gitea/services/user" ) const ( @@ -864,6 +866,14 @@ func ExcerptBlob(ctx *context.Context) { direction := ctx.FormString("direction") filePath := ctx.FormString("path") gitRepo := ctx.Repo.GitRepo + lastRightCommentIdx := ctx.FormInt("last_left_comment_idx") + rightCommentIdx := ctx.FormInt("left_comment_idx") + fileName := ctx.FormString("file_name") + + if ctx.FormBool("pull") { + ctx.Data["PageIsPullFiles"] = true + } + if ctx.FormBool("wiki") { var err error gitRepo, err = gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) @@ -873,6 +883,17 @@ func ExcerptBlob(ctx *context.Context) { } defer gitRepo.Close() } + + issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, int64(2)) + + if err != nil { + ctx.ServerError("GetIssueByIndex", err) + return + } + + allComments, err := issues_model.FetchCodeComments(ctx, issue, ctx.Doer, false) + lineCommits := allComments[fileName] + chunkSize := gitdiff.BlobExcerptChunkSize commit, err := gitRepo.GetCommit(commitID) if err != nil { @@ -882,15 +903,16 @@ func ExcerptBlob(ctx *context.Context) { section := &gitdiff.DiffSection{ FileName: filePath, Name: filePath, + Lines: []*gitdiff.DiffLine{}, } if direction == "up" && (idxLeft-lastLeft) > chunkSize { idxLeft -= chunkSize idxRight -= chunkSize leftHunkSize += chunkSize rightHunkSize += chunkSize - section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize) + section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize, lastRightCommentIdx, rightCommentIdx) } else if direction == "down" && (idxLeft-lastLeft) > chunkSize { - section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize) + section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize, lastRightCommentIdx, rightCommentIdx) lastLeft += chunkSize lastRight += chunkSize } else { @@ -898,7 +920,7 @@ func ExcerptBlob(ctx *context.Context) { if direction == "down" { offset = 0 } - section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight+offset) + section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight+offset, lastRightCommentIdx, rightCommentIdx) leftHunkSize = 0 rightHunkSize = 0 idxLeft = lastLeft @@ -918,14 +940,18 @@ func ExcerptBlob(ctx *context.Context) { Type: gitdiff.DiffLineSection, Content: lineText, SectionInfo: &gitdiff.DiffLineSectionInfo{ - Path: filePath, - LastLeftIdx: lastLeft, - LastRightIdx: lastRight, - LeftIdx: idxLeft, - RightIdx: idxRight, - LeftHunkSize: leftHunkSize, - RightHunkSize: rightHunkSize, + Path: filePath, + LastLeftIdx: lastLeft, + LastRightIdx: lastRight, + LeftIdx: idxLeft, + RightIdx: idxRight, + LeftHunkSize: leftHunkSize, + RightHunkSize: rightHunkSize, + HasComments: false, + LastRightCommentIdx: 0, + RightCommentIdx: 0, }, + Comments: nil, } if direction == "up" { section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...) @@ -933,14 +959,74 @@ func ExcerptBlob(ctx *context.Context) { section.Lines = append(section.Lines, lineSection) } } + + for _, line := range section.Lines { + if line.SectionInfo != nil { + //for now considerign only right side. + start := int64(line.SectionInfo.LastRightIdx + 1) + end := int64(line.SectionInfo.RightIdx - 1) + + //to check section has comments or not. + //1. we can use binary search + //2. we can LastRightCommentIdx, RightCommentIdx, LastLeftCommentIdx, LeftCommentIdx(little complex but fast) + //3. for demo using linear search + for start <= end { + if _, ok := lineCommits[start]; ok { + if !line.SectionInfo.HasComments { + // line.SectionInfo.LastRightCommentIdx = int(start) + // line.SectionInfo.RightCommentIdx = int(start) + line.SectionInfo.HasComments = true + break + } + + } + start += 1 + } + + } + if comments, ok := lineCommits[int64(line.LeftIdx*-1)]; ok { + line.Comments = append(line.Comments, comments...) + } + if comments, ok := lineCommits[int64(line.RightIdx)]; ok { + line.Comments = append(line.Comments, comments...) + } + + sort.SliceStable(line.Comments, func(i, j int) bool { + return line.Comments[i].CreatedUnix < line.Comments[j].CreatedUnix + }) + } + + for _, line := range section.Lines { + for _, comment := range line.Comments { + if err := comment.LoadAttachments(ctx); err != nil { + ctx.ServerError("LoadAttachments", err) + return + } + } + } + ctx.Data["section"] = section ctx.Data["FileNameHash"] = git.HashFilePathForWebUI(filePath) ctx.Data["AfterCommitID"] = commitID ctx.Data["Anchor"] = anchor + ctx.Data["Issue"] = issue + ctx.Data["issue"] = issue.Index + ctx.Data["SignedUserID"] = ctx.Data["SignedUserID"] + ctx.Data["CanBlockUser"] = func(blocker, blockee *user_model.User) bool { + return user_service.CanBlockUser(ctx, ctx.Doer, blocker, blockee) + } + + if ctx.Data["SignedUserID"] == nil { + ctx.Data["SignedUserID"] = ctx.Doer.ID + } + ctx.Data["SignedUser"] = ctx.Doer + ctx.Data["IsSigned"] = ctx.Doer != nil + ctx.Data["Repository"] = ctx.Repo.Repository + ctx.Data["Permission"] = &ctx.Repo.Permission ctx.HTML(http.StatusOK, tplBlobExcerpt) } -func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chunkSize int) ([]*gitdiff.DiffLine, error) { +func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chunkSize, lastRightCommentIdx, rightCommentIdx int) ([]*gitdiff.DiffLine, error) { blob, err := commit.Tree.GetBlobByPath(filePath) if err != nil { return nil, err @@ -965,7 +1051,12 @@ func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chu RightIdx: line + 1, Type: gitdiff.DiffLinePlain, Content: " " + lineText, + Comments: []*issues_model.Comment{}, } + // if diffLine.SectionInfo != nil { + // diffLine.SectionInfo.LastRightCommentIdx = lastRightCommentIdx + // diffLine.SectionInfo.RightCommentIdx = rightCommentIdx + // } diffLines = append(diffLines, diffLine) } if err = scanner.Err(); err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index 29dd8a8edcb..7573724134a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1511,6 +1511,11 @@ func registerRoutes(m *web.Router) { m.Get("/{sha}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob) }, func(ctx *context.Context) gocontext.CancelFunc { // FIXME: refactor this function, use separate routes for wiki/code + if ctx.FormBool("pull") { + ctx.Data["PageIsPullFiles"] = true + + } + if ctx.FormBool("wiki") { ctx.Data["PageIsWiki"] = true repo.MustEnableWiki(ctx) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index bb1722039e1..1954be760ad 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -86,13 +86,16 @@ type DiffLine struct { // DiffLineSectionInfo represents diff line section meta data type DiffLineSectionInfo struct { - Path string - LastLeftIdx int - LastRightIdx int - LeftIdx int - RightIdx int - LeftHunkSize int - RightHunkSize int + Path string + LastLeftIdx int + LastRightIdx int + LeftIdx int + RightIdx int + LeftHunkSize int + RightHunkSize int + HasComments bool + LastRightCommentIdx int + RightCommentIdx int } // BlobExcerptChunkSize represent max lines of excerpt @@ -118,7 +121,7 @@ func (d *DiffLine) GetHTMLDiffLineType() string { // CanComment returns whether a line can get commented func (d *DiffLine) CanComment() bool { - return len(d.Comments) == 0 && d.Type != DiffLineSection + return len(d.Comments) == 0 } // GetCommentSide returns the comment side of the first comment, if not set returns empty string @@ -143,10 +146,12 @@ func (d *DiffLine) GetBlobExcerptQuery() string { "last_left=%d&last_right=%d&"+ "left=%d&right=%d&"+ "left_hunk_size=%d&right_hunk_size=%d&"+ + "last_rightt_comment_idx=%d&right_comment_idx=%d&"+ "path=%s", d.SectionInfo.LastLeftIdx, d.SectionInfo.LastRightIdx, d.SectionInfo.LeftIdx, d.SectionInfo.RightIdx, d.SectionInfo.LeftHunkSize, d.SectionInfo.RightHunkSize, + d.SectionInfo.LastRightCommentIdx, d.SectionInfo.RightCommentIdx, url.QueryEscape(d.SectionInfo.Path)) return query } @@ -170,13 +175,16 @@ func getDiffLineSectionInfo(treePath, line string, lastLeftIdx, lastRightIdx int leftLine, leftHunk, rightLine, righHunk := git.ParseDiffHunkString(line) return &DiffLineSectionInfo{ - Path: treePath, - LastLeftIdx: lastLeftIdx, - LastRightIdx: lastRightIdx, - LeftIdx: leftLine, - RightIdx: rightLine, - LeftHunkSize: leftHunk, - RightHunkSize: righHunk, + Path: treePath, + LastLeftIdx: lastLeftIdx, + LastRightIdx: lastRightIdx, + LeftIdx: leftLine, + RightIdx: rightLine, + LeftHunkSize: leftHunk, + RightHunkSize: righHunk, + HasComments: false, + LastRightCommentIdx: 0, + RightCommentIdx: 0, } } @@ -396,11 +404,14 @@ func (diffFile *DiffFile) GetTailSection(gitRepo *git.Repository, leftCommit, ri Type: DiffLineSection, Content: " ", SectionInfo: &DiffLineSectionInfo{ - Path: diffFile.Name, - LastLeftIdx: lastLine.LeftIdx, - LastRightIdx: lastLine.RightIdx, - LeftIdx: leftLineCount, - RightIdx: rightLineCount, + Path: diffFile.Name, + LastLeftIdx: lastLine.LeftIdx, + LastRightIdx: lastLine.RightIdx, + LeftIdx: leftLineCount, + RightIdx: rightLineCount, + HasComments: false, + LastRightCommentIdx: 0, + RightCommentIdx: 0, }, } tailSection := &DiffSection{FileName: diffFile.Name, Lines: []*DiffLine{tailDiffLine}} @@ -458,16 +469,38 @@ type Diff struct { NumViewedFiles int // user-specific } +// function (section *DiffSection) GetType() int { + // LoadComments loads comments into each line func (diff *Diff) LoadComments(ctx context.Context, issue *issues_model.Issue, currentUser *user_model.User, showOutdatedComments bool) error { allComments, err := issues_model.FetchCodeComments(ctx, issue, currentUser, showOutdatedComments) if err != nil { return err } + for _, file := range diff.Files { if lineCommits, ok := allComments[file.Name]; ok { for _, section := range file.Sections { for _, line := range section.Lines { + if line.SectionInfo != nil { + start := int64(line.SectionInfo.LastRightIdx + 1) + end := int64(line.SectionInfo.RightIdx - 1) + + for start <= end { + if _, ok := lineCommits[start]; ok { + if line.SectionInfo.LastRightCommentIdx == 0 { + // line.SectionInfo.LastRightCommentIdx = int(start) + // line.SectionInfo.RightCommentIdx = int(start) + line.SectionInfo.HasComments = true + + break + } + + } + start += 1 + + } + } if comments, ok := lineCommits[int64(line.LeftIdx*-1)]; ok { line.Comments = append(line.Comments, comments...) } diff --git a/services/repository/files/diff_test.go b/services/repository/files/diff_test.go index ea6ffe60c3f..7b98886358b 100644 --- a/services/repository/files/diff_test.go +++ b/services/repository/files/diff_test.go @@ -59,13 +59,16 @@ func TestGetDiffPreview(t *testing.T) { Content: "@@ -1,3 +1,4 @@", Comments: nil, SectionInfo: &gitdiff.DiffLineSectionInfo{ - Path: "README.md", - LastLeftIdx: 0, - LastRightIdx: 0, - LeftIdx: 1, - RightIdx: 1, - LeftHunkSize: 3, - RightHunkSize: 4, + Path: "README.md", + LastLeftIdx: 0, + LastRightIdx: 0, + LeftIdx: 1, + RightIdx: 1, + LeftHunkSize: 3, + RightHunkSize: 4, + HasComments: false, + LastRightCommentIdx: 0, + RightCommentIdx: 0, }, }, { diff --git a/templates/repo/diff/blob_excerpt.tmpl b/templates/repo/diff/blob_excerpt.tmpl index cc2237029bd..63d6f970b64 100644 --- a/templates/repo/diff/blob_excerpt.tmpl +++ b/templates/repo/diff/blob_excerpt.tmpl @@ -1,35 +1,49 @@ {{if $.IsSplitStyle}} {{range $k, $line := $.section.Lines}} + {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}} {{if eq .GetType 4}} {{$expandDirection := $line.GetExpandDirection}} -
- {{if or (eq $expandDirection 3) (eq $expandDirection 5)}} - - {{end}} - {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} - - {{end}} - {{if eq $expandDirection 2}} - - {{end}} -
- +
+
+ {{if $line.SectionInfo.HasComments}} + + {{end}} +
+
+ {{if or (eq $expandDirection 3) (eq $expandDirection 5)}} + + {{end}} + {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} + + {{end}} + {{if eq $expandDirection 2}} + + {{end}} +
+
+ {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}}{{/* */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}} {{else}} - {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}} {{if and $line.LeftIdx $inlineDiff.EscapeStatus.Escaped}}{{end}} {{if $line.LeftIdx}}{{end}} {{/* + */}}{{if and $.SignedUserID $.PageIsPullFiles}}{{/* + */}}{{/* + */}}{{end}}{{/* */}}{{if $line.LeftIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/* */}}{{/* */}}{{end}}{{/* @@ -38,45 +52,81 @@ {{if and $line.RightIdx $inlineDiff.EscapeStatus.Escaped}}{{end}} {{if $line.RightIdx}}{{end}} {{/* + */}}{{if and $.SignedUserID $.PageIsPullFiles}}{{/* + */}}{{/* + */}}{{end}}{{/* */}}{{if $line.RightIdx}}{{template "repo/diff/section_code" dict "diff" $inlineDiff}}{{else}}{{/* */}}{{/* */}}{{end}}{{/* */}} {{end}} + {{if $line.Comments}} + + + {{template "repo/diff/conversation" dict "." $ "comments" $line.Comments}}} + + + {{end}} {{end}} {{else}} {{range $k, $line := $.section.Lines}} + {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}} {{if eq .GetType 4}} {{$expandDirection := $line.GetExpandDirection}} +
+
+ {{if $line.SectionInfo.HasComments}} + + {{end}} +
{{if or (eq $expandDirection 3) (eq $expandDirection 5)}} - + test else down blob {{$line.SectionInfo.HasComments}} {{end}} {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} - + test else up blob {{end}} {{if eq $expandDirection 2}} - + test else both blob {{end}}
+
{{else}} {{end}} - {{$inlineDiff := $.section.GetComputedInlineDiffFor $line ctx.Locale}} {{if $inlineDiff.EscapeStatus.Escaped}}{{end}} - {{$inlineDiff.Content}} + + {{if and $.SignedUserID $.PageIsPullFiles}} + + {{end}} + {{$inlineDiff.Content}} + {{if $line.Comments}} + + + {{template "repo/diff/conversation" dict "." $ "comments" $line.Comments}} + + + {{end}} {{end}} {{end}} diff --git a/templates/repo/diff/section_split.tmpl b/templates/repo/diff/section_split.tmpl index 37b42bcb376..fb432bf4ff5 100644 --- a/templates/repo/diff/section_split.tmpl +++ b/templates/repo/diff/section_split.tmpl @@ -18,22 +18,31 @@ {{if eq .GetType 4}} {{$expandDirection := $line.GetExpandDirection}} -
- {{if or (eq $expandDirection 3) (eq $expandDirection 5)}} - - {{end}} - {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} - - {{end}} - {{if eq $expandDirection 2}} - - {{end}} +
+
+ {{if $line.SectionInfo.HasComments}} + + {{end}} +
+
+ {{if or (eq $expandDirection 3) (eq $expandDirection 5)}} + + {{end}} + {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} + + {{end}} + {{if eq $expandDirection 2}} + + {{end}} +
{{$inlineDiff := $section.GetComputedInlineDiffFor $line ctx.Locale}} {{if $inlineDiff.EscapeStatus.Escaped}}{{end}} diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl index 708b3332916..5c90d79459b 100644 --- a/templates/repo/diff/section_unified.tmpl +++ b/templates/repo/diff/section_unified.tmpl @@ -13,24 +13,36 @@ {{if eq .GetType 4}} {{if $.root.AfterCommitID}} {{$expandDirection := $line.GetExpandDirection}} - + +
+
+ {{if $line.SectionInfo.HasComments}} + + {{end}} +
{{if or (eq $expandDirection 3) (eq $expandDirection 5)}} - + test down {{end}} {{if or (eq $expandDirection 3) (eq $expandDirection 4)}} - + test up {{end}} {{if eq $expandDirection 2}} - + test fold {{end}}
+
{{else}} {{/* for code file preview page or comment diffs on pull comment pages, do not show the expansion arrows */}} diff --git a/web_src/css/base.css b/web_src/css/base.css index 8d9f810ef8f..9589e501cc7 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -1141,6 +1141,13 @@ overflow-menu .ui.label { font-family: var(--fonts-regular); } +.lines-comment { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1px; +} + .lines-commit .blame-info .blame-data .blame-message { flex-grow: 2; overflow: hidden;