mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-18 00:47:48 -04:00
Improved comment rendering in "Files" view by adding Comments to DiffLine
Signed-off-by: Jonas Franz <info@jonasfranz.software>
This commit is contained in:
parent
58fb672d0d
commit
066086c390
@ -30,3 +30,12 @@
|
|||||||
line: 4
|
line: 4
|
||||||
tree_path: "README.md"
|
tree_path: "README.md"
|
||||||
created_unix: 946684812
|
created_unix: 946684812
|
||||||
|
-
|
||||||
|
id: 5
|
||||||
|
type: 19 # code comment
|
||||||
|
poster_id: 1
|
||||||
|
issue_id: 2
|
||||||
|
content: "meh..."
|
||||||
|
line: -4
|
||||||
|
tree_path: "README.md"
|
||||||
|
created_unix: 946684812
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -57,6 +58,7 @@ type DiffLine struct {
|
|||||||
RightIdx int
|
RightIdx int
|
||||||
Type DiffLineType
|
Type DiffLineType
|
||||||
Content string
|
Content string
|
||||||
|
Comments []*Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetType returns the type of a DiffLine.
|
// GetType returns the type of a DiffLine.
|
||||||
@ -225,6 +227,32 @@ type Diff struct {
|
|||||||
IsIncomplete bool
|
IsIncomplete bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadComments loads comments into each line
|
||||||
|
func (diff *Diff) LoadComments(issue *Issue, currentUser *User) error {
|
||||||
|
allComments, err := FetchCodeComments(issue, currentUser)
|
||||||
|
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 comments, ok := lineCommits[int64(line.LeftIdx*-1)]; ok {
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NumFiles returns number of files changes in a diff.
|
// NumFiles returns number of files changes in a diff.
|
||||||
func (diff *Diff) NumFiles() int {
|
func (diff *Diff) NumFiles() int {
|
||||||
return len(diff.Files)
|
return len(diff.Files)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
|
func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
|
||||||
@ -34,3 +35,28 @@ func TestDiffToHTML(t *testing.T) {
|
|||||||
{Type: dmp.DiffEqual, Text: " biz"},
|
{Type: dmp.DiffEqual, Text: " biz"},
|
||||||
}, DiffLineDel))
|
}, DiffLineDel))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDiff_LoadComments(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
issue := AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue)
|
||||||
|
user := AssertExistsAndLoadBean(t, &User{ID: 1}).(*User)
|
||||||
|
diff := &Diff{
|
||||||
|
Files: []*DiffFile{
|
||||||
|
{
|
||||||
|
Name: "README.md",
|
||||||
|
Sections: []*DiffSection{
|
||||||
|
{
|
||||||
|
Lines: []*DiffLine{
|
||||||
|
{
|
||||||
|
LeftIdx: 4,
|
||||||
|
RightIdx: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.NoError(t, diff.LoadComments(issue, user))
|
||||||
|
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2)
|
||||||
|
}
|
||||||
|
@ -761,6 +761,7 @@ issues.review.approve = "approved these changes %s"
|
|||||||
issues.review.comment = "left review comments %s"
|
issues.review.comment = "left review comments %s"
|
||||||
issues.review.reject = "rejected these changes %s"
|
issues.review.reject = "rejected these changes %s"
|
||||||
issues.review.pending = Pending
|
issues.review.pending = Pending
|
||||||
|
issues.review.review = Review
|
||||||
|
|
||||||
pulls.desc = Enable merge requests and code reviews.
|
pulls.desc = Enable merge requests and code reviews.
|
||||||
pulls.new = New Pull Request
|
pulls.new = New Pull Request
|
||||||
|
@ -61,7 +61,7 @@ func GlobalInit() {
|
|||||||
}
|
}
|
||||||
models.HasEngine = true
|
models.HasEngine = true
|
||||||
if err := models.InitOAuth2(); err != nil {
|
if err := models.InitOAuth2(); err != nil {
|
||||||
log.Fatal(4, "Failed to initialize OAuth2 support: %v", err)
|
//log.Fatal(4, "Failed to initialize OAuth2 support: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
models.LoadRepoConfig()
|
models.LoadRepoConfig()
|
||||||
|
@ -456,6 +456,12 @@ func ViewPullFiles(ctx *context.Context) {
|
|||||||
ctx.ServerError("GetDiffRange", err)
|
ctx.ServerError("GetDiffRange", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = diff.LoadComments(issue, ctx.User); err != nil {
|
||||||
|
ctx.ServerError("LoadComments", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Diff"] = diff
|
ctx.Data["Diff"] = diff
|
||||||
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
|
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
|
||||||
|
|
||||||
@ -470,13 +476,6 @@ func ViewPullFiles(ctx *context.Context) {
|
|||||||
ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", startCommitID)
|
ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(headTarget, "src", "commit", startCommitID)
|
||||||
ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", endCommitID)
|
ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(headTarget, "raw", "commit", endCommitID)
|
||||||
ctx.Data["RequireHighlightJS"] = true
|
ctx.Data["RequireHighlightJS"] = true
|
||||||
|
|
||||||
pathToLineToComment, err := models.FetchCodeComments(issue, ctx.User)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("FetchCodeComments", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["CodeComments"] = pathToLineToComment
|
|
||||||
ctx.Data["CurrentReview"], err = models.GetCurrentReview(ctx.User, issue)
|
ctx.Data["CurrentReview"], err = models.GetCurrentReview(ctx.User, issue)
|
||||||
if err != nil && !models.IsErrReviewNotExist(err) {
|
if err != nil && !models.IsErrReviewNotExist(err) {
|
||||||
ctx.ServerError("GetCurrentReview", err)
|
ctx.ServerError("GetCurrentReview", err)
|
||||||
|
@ -114,26 +114,29 @@
|
|||||||
<a class="ui green button add-code-comment add-code-comment-right" data-side="right" data-idx="{{$line.RightIdx}}">+</a>
|
<a class="ui green button add-code-comment add-code-comment-right" data-side="right" data-idx="{{$line.RightIdx}}">+</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
{{if index $.CodeComments $file.Name (mul $line.LeftIdx -1)}}
|
|
||||||
<td class="add-comment-left add-comment-right">
|
<td class="lines-code lines-code-new halfwidth">
|
||||||
|
<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{if gt (len $line.Comments) 0}}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="add-comment-left add-comment-right">
|
||||||
<div class="field comment-code-cloud">
|
<div class="field comment-code-cloud">
|
||||||
<div class="comment-list">
|
<div class="comment-list">
|
||||||
<ui class="ui comments">
|
<ui class="ui comments">
|
||||||
{{ template "repo/diff/comments" dict "root" $ "comments" (index $.CodeComments $file.Name (mul $line.LeftIdx -1))}}
|
{{ template "repo/diff/comments" dict "root" $ "comments" $line.Comments}}
|
||||||
</ui>
|
</ui>
|
||||||
</div>
|
</div>
|
||||||
{{template "repo/diff/comment_form" $}}
|
{{template "repo/diff/comment_form" $}}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{{end}}
|
|
||||||
<td class="lines-code lines-code-new halfwidth">
|
|
||||||
<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{template "repo/diff/section_unified" .}}
|
{{template "repo/diff/section_unified" dict "file" . "root" $}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -9,10 +9,16 @@
|
|||||||
<div class="ui top attached header">
|
<div class="ui top attached header">
|
||||||
<span class="text grey"><a {{if gt .Poster.ID 0}}href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.Name}}</a> {{$.root.i18n.Tr "repo.issues.commented_at" .HashTag $createdStr | Safe}}</span>
|
<span class="text grey"><a {{if gt .Poster.ID 0}}href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.Name}}</a> {{$.root.i18n.Tr "repo.issues.commented_at" .HashTag $createdStr | Safe}}</span>
|
||||||
<div class="ui right actions">
|
<div class="ui right actions">
|
||||||
|
{{if and .Review}}
|
||||||
{{if eq .Review.Type 0}}
|
{{if eq .Review.Type 0}}
|
||||||
<div class="item warning tag">
|
<div class="item tag">
|
||||||
{{$.root.i18n.Tr "repo.issues.review.pending"}}
|
{{$.root.i18n.Tr "repo.issues.review.pending"}}
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="item tag">
|
||||||
|
{{$.root.i18n.Tr "repo.issues.review.review"}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }}
|
{{template "repo/issue/view_content/add_reaction" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) }}
|
||||||
{{if or $.root.IsRepositoryAdmin (eq .Poster.ID $.root.SignedUserID)}}
|
{{if or $.root.IsRepositoryAdmin (eq .Poster.ID $.root.SignedUserID)}}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{{$file := .}}
|
{{$file := .file}}
|
||||||
{{$highlightClass := $file.GetHighlightClass}}
|
{{$highlightClass := $file.GetHighlightClass}}
|
||||||
{{range $j, $section := $file.Sections}}
|
{{range $j, $section := $file.Sections}}
|
||||||
{{range $k, $line := $section.Lines}}
|
{{range $k, $line := $section.Lines}}
|
||||||
@ -20,5 +20,19 @@
|
|||||||
<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</code></pre>
|
<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</code></pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{{if gt (len $line.Comments) 0}}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="add-comment-left add-comment-right">
|
||||||
|
<div class="field comment-code-cloud">
|
||||||
|
<div class="comment-list">
|
||||||
|
<ui class="ui comments">
|
||||||
|
{{ template "repo/diff/comments" dict "root" $.root "comments" $line.Comments}}
|
||||||
|
</ui>
|
||||||
|
</div>
|
||||||
|
{{template "repo/diff/comment_form" $.root }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user