mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Fix "Dashboard shows deleted comments" (#1995)
This commit is contained in:
		
				
					committed by
					
						
						Kim "BKC" Carlbäcker
					
				
			
			
				
	
			
			
			
						parent
						
							735676267e
						
					
				
				
					commit
					441986a473
				
			@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
	"unicode"
 | 
						"unicode"
 | 
				
			||||||
@@ -77,6 +78,9 @@ type Action struct {
 | 
				
			|||||||
	ActUser     *User       `xorm:"-"`
 | 
						ActUser     *User       `xorm:"-"`
 | 
				
			||||||
	RepoID      int64       `xorm:"INDEX"`
 | 
						RepoID      int64       `xorm:"INDEX"`
 | 
				
			||||||
	Repo        *Repository `xorm:"-"`
 | 
						Repo        *Repository `xorm:"-"`
 | 
				
			||||||
 | 
						CommentID   int64       `xorm:"INDEX"`
 | 
				
			||||||
 | 
						Comment     *Comment    `xorm:"-"`
 | 
				
			||||||
 | 
						IsDeleted   bool        `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
				
			||||||
	RefName     string
 | 
						RefName     string
 | 
				
			||||||
	IsPrivate   bool      `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
						IsPrivate   bool      `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
				
			||||||
	Content     string    `xorm:"TEXT"`
 | 
						Content     string    `xorm:"TEXT"`
 | 
				
			||||||
@@ -191,6 +195,35 @@ func (a *Action) GetRepoLink() string {
 | 
				
			|||||||
	return "/" + a.GetRepoPath()
 | 
						return "/" + a.GetRepoPath()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetCommentLink returns link to action comment.
 | 
				
			||||||
 | 
					func (a *Action) GetCommentLink() string {
 | 
				
			||||||
 | 
						if a == nil {
 | 
				
			||||||
 | 
							return "#"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if a.Comment == nil && a.CommentID != 0 {
 | 
				
			||||||
 | 
							a.Comment, _ = GetCommentByID(a.CommentID)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if a.Comment != nil {
 | 
				
			||||||
 | 
							return a.Comment.HTMLURL()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(a.GetIssueInfos()) == 0 {
 | 
				
			||||||
 | 
							return "#"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//Return link to issue
 | 
				
			||||||
 | 
						issueIDString := a.GetIssueInfos()[0]
 | 
				
			||||||
 | 
						issueID, err := strconv.ParseInt(issueIDString, 10, 64)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "#"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						issue, err := GetIssueByID(issueID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "#"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return issue.HTMLURL()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetBranch returns the action's repository branch.
 | 
					// GetBranch returns the action's repository branch.
 | 
				
			||||||
func (a *Action) GetBranch() string {
 | 
					func (a *Action) GetBranch() string {
 | 
				
			||||||
	return a.RefName
 | 
						return a.RefName
 | 
				
			||||||
@@ -678,6 +711,7 @@ type GetFeedsOptions struct {
 | 
				
			|||||||
	RequestingUserID int64
 | 
						RequestingUserID int64
 | 
				
			||||||
	IncludePrivate   bool // include private actions
 | 
						IncludePrivate   bool // include private actions
 | 
				
			||||||
	OnlyPerformedBy  bool // only actions performed by requested user
 | 
						OnlyPerformedBy  bool // only actions performed by requested user
 | 
				
			||||||
 | 
						IncludeDeleted   bool // include deleted actions
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetFeeds returns actions according to the provided options
 | 
					// GetFeeds returns actions according to the provided options
 | 
				
			||||||
@@ -706,5 +740,11 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
 | 
				
			|||||||
	if opts.RequestedUser.IsOrganization() {
 | 
						if opts.RequestedUser.IsOrganization() {
 | 
				
			||||||
		sess.In("repo_id", repoIDs)
 | 
							sess.In("repo_id", repoIDs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !opts.IncludeDeleted {
 | 
				
			||||||
 | 
							sess.And("is_deleted = ?", false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return actions, sess.Find(&actions)
 | 
						return actions, sess.Find(&actions)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -310,6 +310,7 @@ func TestGetFeeds(t *testing.T) {
 | 
				
			|||||||
		RequestingUserID: user.ID,
 | 
							RequestingUserID: user.ID,
 | 
				
			||||||
		IncludePrivate:   true,
 | 
							IncludePrivate:   true,
 | 
				
			||||||
		OnlyPerformedBy:  false,
 | 
							OnlyPerformedBy:  false,
 | 
				
			||||||
 | 
							IncludeDeleted:   true,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Len(t, actions, 1)
 | 
						assert.Len(t, actions, 1)
 | 
				
			||||||
@@ -337,6 +338,7 @@ func TestGetFeeds2(t *testing.T) {
 | 
				
			|||||||
		RequestingUserID: userID,
 | 
							RequestingUserID: userID,
 | 
				
			||||||
		IncludePrivate:   true,
 | 
							IncludePrivate:   true,
 | 
				
			||||||
		OnlyPerformedBy:  false,
 | 
							OnlyPerformedBy:  false,
 | 
				
			||||||
 | 
							IncludeDeleted:   true,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Len(t, actions, 1)
 | 
						assert.Len(t, actions, 1)
 | 
				
			||||||
@@ -348,6 +350,7 @@ func TestGetFeeds2(t *testing.T) {
 | 
				
			|||||||
		RequestingUserID: userID,
 | 
							RequestingUserID: userID,
 | 
				
			||||||
		IncludePrivate:   false,
 | 
							IncludePrivate:   false,
 | 
				
			||||||
		OnlyPerformedBy:  false,
 | 
							OnlyPerformedBy:  false,
 | 
				
			||||||
 | 
							IncludeDeleted:   true,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Len(t, actions, 0)
 | 
						assert.Len(t, actions, 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -334,6 +334,8 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
 | 
				
			|||||||
		Content:   fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
 | 
							Content:   fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
 | 
				
			||||||
		RepoID:    opts.Repo.ID,
 | 
							RepoID:    opts.Repo.ID,
 | 
				
			||||||
		Repo:      opts.Repo,
 | 
							Repo:      opts.Repo,
 | 
				
			||||||
 | 
							Comment:   comment,
 | 
				
			||||||
 | 
							CommentID: comment.ID,
 | 
				
			||||||
		IsPrivate: opts.Repo.IsPrivate,
 | 
							IsPrivate: opts.Repo.IsPrivate,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -666,6 +668,7 @@ func DeleteComment(comment *Comment) error {
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						sess.Where("comment_id = ?", comment.ID).Cols("is_deleted").Update(&Action{IsDeleted: true})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sess.Commit()
 | 
						return sess.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,6 +118,8 @@ var migrations = []Migration{
 | 
				
			|||||||
	NewMigration("remove columns from action", removeActionColumns),
 | 
						NewMigration("remove columns from action", removeActionColumns),
 | 
				
			||||||
	// v34 -> v35
 | 
						// v34 -> v35
 | 
				
			||||||
	NewMigration("give all units to owner teams", giveAllUnitsToOwnerTeams),
 | 
						NewMigration("give all units to owner teams", giveAllUnitsToOwnerTeams),
 | 
				
			||||||
 | 
						// v35 -> v36
 | 
				
			||||||
 | 
						NewMigration("adds comment to an action", addCommentIDToAction),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Migrate database to current version
 | 
					// Migrate database to current version
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								models/migrations/v35.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								models/migrations/v35.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					// Copyright 2017 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/go-xorm/xorm"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addCommentIDToAction(x *xorm.Engine) error {
 | 
				
			||||||
 | 
						// Action see models/action.go
 | 
				
			||||||
 | 
						type Action struct {
 | 
				
			||||||
 | 
							CommentID int64 `xorm:"INDEX"`
 | 
				
			||||||
 | 
							IsDeleted bool  `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := x.Sync2(new(Action)); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Sync2: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -54,7 +54,7 @@ func getDashboardContextUser(ctx *context.Context) *models.User {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// retrieveFeeds loads feeds for the specified user
 | 
					// retrieveFeeds loads feeds for the specified user
 | 
				
			||||||
func retrieveFeeds(ctx *context.Context, user *models.User, includePrivate, isProfile bool) {
 | 
					func retrieveFeeds(ctx *context.Context, user *models.User, includePrivate, isProfile bool, includeDeletedComments bool) {
 | 
				
			||||||
	var requestingID int64
 | 
						var requestingID int64
 | 
				
			||||||
	if ctx.User != nil {
 | 
						if ctx.User != nil {
 | 
				
			||||||
		requestingID = ctx.User.ID
 | 
							requestingID = ctx.User.ID
 | 
				
			||||||
@@ -64,6 +64,7 @@ func retrieveFeeds(ctx *context.Context, user *models.User, includePrivate, isPr
 | 
				
			|||||||
		RequestingUserID: requestingID,
 | 
							RequestingUserID: requestingID,
 | 
				
			||||||
		IncludePrivate:   includePrivate,
 | 
							IncludePrivate:   includePrivate,
 | 
				
			||||||
		OnlyPerformedBy:  isProfile,
 | 
							OnlyPerformedBy:  isProfile,
 | 
				
			||||||
 | 
							IncludeDeleted:   includeDeletedComments,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.Handle(500, "GetFeeds", err)
 | 
							ctx.Handle(500, "GetFeeds", err)
 | 
				
			||||||
@@ -186,7 +187,7 @@ func Dashboard(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["MirrorCount"] = len(mirrors)
 | 
						ctx.Data["MirrorCount"] = len(mirrors)
 | 
				
			||||||
	ctx.Data["Mirrors"] = mirrors
 | 
						ctx.Data["Mirrors"] = mirrors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	retrieveFeeds(ctx, ctxUser, true, false)
 | 
						retrieveFeeds(ctx, ctxUser, true, false, false)
 | 
				
			||||||
	if ctx.Written() {
 | 
						if ctx.Written() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,7 +138,7 @@ func Profile(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Keyword"] = keyword
 | 
						ctx.Data["Keyword"] = keyword
 | 
				
			||||||
	switch tab {
 | 
						switch tab {
 | 
				
			||||||
	case "activity":
 | 
						case "activity":
 | 
				
			||||||
		retrieveFeeds(ctx, ctxUser, showPrivate, true)
 | 
							retrieveFeeds(ctx, ctxUser, showPrivate, true, false)
 | 
				
			||||||
		if ctx.Written() {
 | 
							if ctx.Written() {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,7 @@
 | 
				
			|||||||
					{{else if eq .GetOpType 7}}
 | 
										{{else if eq .GetOpType 7}}
 | 
				
			||||||
						<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
 | 
											<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
 | 
				
			||||||
					{{else if eq .GetOpType 10}}
 | 
										{{else if eq .GetOpType 10}}
 | 
				
			||||||
						<span class="text truncate issue title has-emoji">{{.GetIssueTitle}}</span>
 | 
											<a href="{{.GetCommentLink}}" class="text truncate issue title has-emoji">{{.GetIssueTitle}}</a>
 | 
				
			||||||
						<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
 | 
											<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
 | 
				
			||||||
					{{else if eq .GetOpType 11}}
 | 
										{{else if eq .GetOpType 11}}
 | 
				
			||||||
						<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
 | 
											<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user