You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
2.9 KiB

  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "fmt"
  7. "github.com/go-xorm/xorm"
  8. )
  9. // IssueUser represents an issue-user relation.
  10. type IssueUser struct {
  11. ID int64 `xorm:"pk autoincr"`
  12. UID int64 `xorm:"INDEX"` // User ID.
  13. IssueID int64
  14. IsRead bool
  15. IsMentioned bool
  16. }
  17. func newIssueUsers(e Engine, repo *Repository, issue *Issue) error {
  18. assignees, err := repo.getAssignees(e)
  19. if err != nil {
  20. return fmt.Errorf("getAssignees: %v", err)
  21. }
  22. // Poster can be anyone, append later if not one of assignees.
  23. isPosterAssignee := false
  24. // Leave a seat for poster itself to append later, but if poster is one of assignee
  25. // and just waste 1 unit is cheaper than re-allocate memory once.
  26. issueUsers := make([]*IssueUser, 0, len(assignees)+1)
  27. for _, assignee := range assignees {
  28. issueUsers = append(issueUsers, &IssueUser{
  29. IssueID: issue.ID,
  30. UID: assignee.ID,
  31. })
  32. isPosterAssignee = isPosterAssignee || assignee.ID == issue.PosterID
  33. }
  34. if !isPosterAssignee {
  35. issueUsers = append(issueUsers, &IssueUser{
  36. IssueID: issue.ID,
  37. UID: issue.PosterID,
  38. })
  39. }
  40. if _, err = e.Insert(issueUsers); err != nil {
  41. return err
  42. }
  43. return nil
  44. }
  45. func updateIssueAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) {
  46. // Check if the user exists
  47. assignee, err := GetUserByID(assigneeID)
  48. if err != nil {
  49. return false, err
  50. }
  51. // Check if the submitted user is already assigne, if yes delete him otherwise add him
  52. var i int
  53. for i = 0; i < len(issue.Assignees); i++ {
  54. if issue.Assignees[i].ID == assigneeID {
  55. break
  56. }
  57. }
  58. assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID}
  59. toBeDeleted := i < len(issue.Assignees)
  60. if toBeDeleted {
  61. issue.Assignees = append(issue.Assignees[:i], issue.Assignees[i:]...)
  62. _, err = e.Delete(assigneeIn)
  63. if err != nil {
  64. return toBeDeleted, err
  65. }
  66. } else {
  67. issue.Assignees = append(issue.Assignees, assignee)
  68. _, err = e.Insert(assigneeIn)
  69. if err != nil {
  70. return toBeDeleted, err
  71. }
  72. }
  73. return toBeDeleted, nil
  74. }
  75. // UpdateIssueUserByRead updates issue-user relation for reading.
  76. func UpdateIssueUserByRead(uid, issueID int64) error {
  77. _, err := x.Exec("UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=?", true, uid, issueID)
  78. return err
  79. }
  80. // UpdateIssueUsersByMentions updates issue-user pairs by mentioning.
  81. func UpdateIssueUsersByMentions(e Engine, issueID int64, uids []int64) error {
  82. for _, uid := range uids {
  83. iu := &IssueUser{
  84. UID: uid,
  85. IssueID: issueID,
  86. }
  87. has, err := e.Get(iu)
  88. if err != nil {
  89. return err
  90. }
  91. iu.IsMentioned = true
  92. if has {
  93. _, err = e.ID(iu.ID).Cols("is_mentioned").Update(iu)
  94. } else {
  95. _, err = e.Insert(iu)
  96. }
  97. if err != nil {
  98. return err
  99. }
  100. }
  101. return nil
  102. }