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

notification.go 4.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2019 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 user
  5. import (
  6. "errors"
  7. "fmt"
  8. "strconv"
  9. "strings"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/base"
  12. "code.gitea.io/gitea/modules/context"
  13. "code.gitea.io/gitea/modules/setting"
  14. )
  15. const (
  16. tplNotification base.TplName = "user/notification/notification"
  17. )
  18. // GetNotificationCount is the middleware that sets the notification count in the context
  19. func GetNotificationCount(c *context.Context) {
  20. if strings.HasPrefix(c.Req.URL.Path, "/api") {
  21. return
  22. }
  23. if !c.IsSigned {
  24. return
  25. }
  26. count, err := models.GetNotificationCount(c.User, models.NotificationStatusUnread)
  27. if err != nil {
  28. c.ServerError("GetNotificationCount", err)
  29. return
  30. }
  31. c.Data["NotificationUnreadCount"] = count
  32. }
  33. // Notifications is the notifications page
  34. func Notifications(c *context.Context) {
  35. var (
  36. keyword = strings.Trim(c.Query("q"), " ")
  37. status models.NotificationStatus
  38. page = c.QueryInt("page")
  39. perPage = c.QueryInt("perPage")
  40. )
  41. if page < 1 {
  42. page = 1
  43. }
  44. if perPage < 1 {
  45. perPage = 20
  46. }
  47. switch keyword {
  48. case "read":
  49. status = models.NotificationStatusRead
  50. default:
  51. status = models.NotificationStatusUnread
  52. }
  53. total, err := models.GetNotificationCount(c.User, status)
  54. if err != nil {
  55. c.ServerError("ErrGetNotificationCount", err)
  56. return
  57. }
  58. // redirect to last page if request page is more than total pages
  59. pager := context.NewPagination(int(total), perPage, page, 5)
  60. if pager.Paginater.Current() < page {
  61. c.Redirect(fmt.Sprintf("/notifications?q=%s&page=%d", c.Query("q"), pager.Paginater.Current()))
  62. return
  63. }
  64. statuses := []models.NotificationStatus{status, models.NotificationStatusPinned}
  65. notifications, err := models.NotificationsForUser(c.User, statuses, page, perPage)
  66. if err != nil {
  67. c.ServerError("ErrNotificationsForUser", err)
  68. return
  69. }
  70. repos, err := notifications.LoadRepos()
  71. if err != nil {
  72. c.ServerError("LoadRepos", err)
  73. return
  74. }
  75. if err := repos.LoadAttributes(); err != nil {
  76. c.ServerError("LoadAttributes", err)
  77. return
  78. }
  79. if err := notifications.LoadIssues(); err != nil {
  80. c.ServerError("LoadIssues", err)
  81. return
  82. }
  83. if err := notifications.LoadComments(); err != nil {
  84. c.ServerError("LoadComments", err)
  85. return
  86. }
  87. title := c.Tr("notifications")
  88. if status == models.NotificationStatusUnread && total > 0 {
  89. title = fmt.Sprintf("(%d) %s", total, title)
  90. }
  91. c.Data["Title"] = title
  92. c.Data["Keyword"] = keyword
  93. c.Data["Status"] = status
  94. c.Data["Notifications"] = notifications
  95. pager.SetDefaultParams(c)
  96. c.Data["Page"] = pager
  97. c.HTML(200, tplNotification)
  98. }
  99. // NotificationStatusPost is a route for changing the status of a notification
  100. func NotificationStatusPost(c *context.Context) {
  101. var (
  102. notificationID, _ = strconv.ParseInt(c.Req.PostFormValue("notification_id"), 10, 64)
  103. statusStr = c.Req.PostFormValue("status")
  104. status models.NotificationStatus
  105. )
  106. switch statusStr {
  107. case "read":
  108. status = models.NotificationStatusRead
  109. case "unread":
  110. status = models.NotificationStatusUnread
  111. case "pinned":
  112. status = models.NotificationStatusPinned
  113. default:
  114. c.ServerError("InvalidNotificationStatus", errors.New("Invalid notification status"))
  115. return
  116. }
  117. if err := models.SetNotificationStatus(notificationID, c.User, status); err != nil {
  118. c.ServerError("SetNotificationStatus", err)
  119. return
  120. }
  121. url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page"))
  122. c.Redirect(url, 303)
  123. }
  124. // NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read
  125. func NotificationPurgePost(c *context.Context) {
  126. err := models.UpdateNotificationStatuses(c.User, models.NotificationStatusUnread, models.NotificationStatusRead)
  127. if err != nil {
  128. c.ServerError("ErrUpdateNotificationStatuses", err)
  129. return
  130. }
  131. url := fmt.Sprintf("%s/notifications", setting.AppSubURL)
  132. c.Redirect(url, 303)
  133. }