From f310ff2fa084cc40af493769577e7a280101f817 Mon Sep 17 00:00:00 2001 From: Alexei Bezborodov Date: Sat, 25 Jun 2022 21:15:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=20=D1=80=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1=8F=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D1=8F=D0=BC=D0=B8=20#31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/issue_comment.go | 22 ++++++-- models/issue_comment_list.go | 67 +++++++++++++++++++++++++ modules/convert/issue_comment.go | 10 ++++ modules/structs/issue_comment.go | 2 + routers/web/repo/issue.go | 7 +++ templates/repo/issue/view_content/comments.tmpl | 50 ++++++++++++++++++ 6 files changed, 154 insertions(+), 4 deletions(-) diff --git a/models/issue_comment.go b/models/issue_comment.go index 8b6b204008..e3dc31233f 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -82,10 +82,6 @@ const ( CommentTypeAddDependency // 20 Dependency removed CommentTypeRemoveDependency - // 19 Parent added - CommentTypeAddParent - // 20 Parent removed - CommentTypeRemoveParent // 21 Comment a line of code CommentTypeCode // 22 Reviews a pull request by giving general feedback @@ -112,6 +108,10 @@ const ( CommentTypeDismissReview // 33 Change issue ref CommentTypeChangeIssueRef + // 34 Parent added + CommentTypeAddParent + // 35 Parent removed + CommentTypeRemoveParent ) var commentStrings = []string{ @@ -149,6 +149,8 @@ var commentStrings = []string{ "project_board", "dismiss_review", "change_issue_ref", + "add_parent", + "remove_parent", } func (t CommentType) String() string { @@ -228,6 +230,8 @@ type Comment struct { NewRef string DependentIssueID int64 DependentIssue *Issue `xorm:"-"` + ParentIssueID int64 + ParentIssue *Issue `xorm:"-"` CommitID int64 Line int64 // - previous line / + proposed line @@ -623,6 +627,15 @@ func (c *Comment) LoadDepIssueDetails() (err error) { return err } +// LoadParentIssueDetails loads Parent Issue Details +func (c *Comment) LoadParentIssueDetails() (err error) { + if c.ParentIssueID <= 0 || c.ParentIssue != nil { + return nil + } + c.ParentIssue, err = getIssueByID(db.GetEngine(db.DefaultContext), c.ParentIssueID) + return err +} + // LoadTime loads the associated time for a CommentTypeAddTimeManual func (c *Comment) LoadTime() error { if c.Time != nil || c.TimeID == 0 { @@ -793,6 +806,7 @@ func createComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, OldRef: opts.OldRef, NewRef: opts.NewRef, DependentIssueID: opts.DependentIssueID, + ParentIssueID: opts.ParentIssueID, TreePath: opts.TreePath, ReviewID: opts.ReviewID, Patch: opts.Patch, diff --git a/models/issue_comment_list.go b/models/issue_comment_list.go index 23a2756dcf..c614535f84 100644 --- a/models/issue_comment_list.go +++ b/models/issue_comment_list.go @@ -395,6 +395,69 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error { return nil } +func (comments CommentList) getParentIssueIDs() []int64 { + ids := make(map[int64]struct{}, len(comments)) + for _, comment := range comments { + if comment.ParentIssue != nil { + continue + } + if _, ok := ids[comment.ParentIssueID]; !ok { + ids[comment.ParentIssueID] = struct{}{} + } + } + return keysInt64(ids) +} + +func (comments CommentList) loadParentIssues(ctx context.Context) error { + if len(comments) == 0 { + return nil + } + + e := db.GetEngine(ctx) + issueIDs := comments.getParentIssueIDs() + issues := make(map[int64]*Issue, len(issueIDs)) + left := len(issueIDs) + for left > 0 { + limit := defaultMaxInSize + if left < limit { + limit = left + } + rows, err := e. + In("id", issueIDs[:limit]). + Rows(new(Issue)) + if err != nil { + return err + } + + for rows.Next() { + var issue Issue + err = rows.Scan(&issue) + if err != nil { + _ = rows.Close() + return err + } + + issues[issue.ID] = &issue + } + _ = rows.Close() + + left -= limit + issueIDs = issueIDs[limit:] + } + + for _, comment := range comments { + if comment.ParentIssue == nil { + comment.ParentIssue = issues[comment.ParentIssueID] + if comment.ParentIssue != nil { + if err := comment.ParentIssue.loadRepo(ctx); err != nil { + return err + } + } + } + } + return nil +} + func (comments CommentList) loadAttachments(e db.Engine) (err error) { if len(comments) == 0 { return nil @@ -528,6 +591,10 @@ func (comments CommentList) loadAttributes(ctx context.Context) (err error) { return } + if err = comments.loadParentIssues(ctx); err != nil { + return + } + return nil } diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index caba2b506e..061fe59142 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -52,6 +52,12 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo return nil } + err = c.LoadParentIssueDetails() + if err != nil { + log.Error("LoadParentIssueDetails: %v", err) + return nil + } + err = c.LoadTime() if err != nil { log.Error("LoadTime: %v", err) @@ -163,5 +169,9 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo comment.DependentIssue = ToAPIIssue(c.DependentIssue) } + if c.ParentIssue != nil { + comment.ParentIssue = ToAPIIssue(c.ParentIssue) + } + return comment } diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index e13ec05d01..d6bf5ef887 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -79,4 +79,6 @@ type TimelineComment struct { ResolveDoer *User `json:"resolve_doer"` DependentIssue *Issue `json:"dependent_issue"` + + ParentIssue *Issue `json:"parent_issue"` } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 7ec1af728f..1bb9d9fc7f 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1473,6 +1473,13 @@ func ViewIssue(ctx *context.Context) { return } } + } else if comment.Type == models.CommentTypeRemoveParent || comment.Type == models.CommentTypeAddParent { + if err = comment.LoadParentIssueDetails(); err != nil { + if !models.IsErrIssueNotExist(err) { + ctx.ServerError("LoadParentIssueDetails", err) + return + } + } } else if comment.Type == models.CommentTypeCode || comment.Type == models.CommentTypeReview || comment.Type == models.CommentTypeDismissReview { comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{ URLPrefix: ctx.Repo.RepoLink, diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index a0ab487a5b..65b214c407 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -831,5 +831,55 @@ {{end}} + {{else if eq .Type 34}} +
+ {{svg "octicon-package-parents"}} + + {{avatar .Poster}} + + + {{.Poster.GetDisplayName}} + {{$.i18n.Tr "repo.issues.parent.added_parent" $createdStr | Safe}} + + {{if .ParentIssue}} + + {{end}} +
+ {{else if eq .Type 35}} +
+ {{svg "octicon-package-parents"}} + + {{avatar .Poster}} + + + {{.Poster.GetDisplayName}} + {{$.i18n.Tr "repo.issues.parent.removed_parent" $createdStr | Safe}} + + {{if .ParentIssue}} + + {{end}} +
{{end}} {{end}}