Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
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.
193 lines
4.9 KiB
193 lines
4.9 KiB
// Copyright 2019 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 user |
|
|
|
import ( |
|
"errors" |
|
"fmt" |
|
"net/http" |
|
"net/url" |
|
"strings" |
|
|
|
"code.gitea.io/gitea/models" |
|
"code.gitea.io/gitea/modules/base" |
|
"code.gitea.io/gitea/modules/context" |
|
"code.gitea.io/gitea/modules/setting" |
|
) |
|
|
|
const ( |
|
tplNotification base.TplName = "user/notification/notification" |
|
tplNotificationDiv base.TplName = "user/notification/notification_div" |
|
) |
|
|
|
// GetNotificationCount is the middleware that sets the notification count in the context |
|
func GetNotificationCount(c *context.Context) { |
|
if strings.HasPrefix(c.Req.URL.Path, "/api") { |
|
return |
|
} |
|
|
|
if !c.IsSigned { |
|
return |
|
} |
|
|
|
c.Data["NotificationUnreadCount"] = func() int64 { |
|
count, err := models.GetNotificationCount(c.User, models.NotificationStatusUnread) |
|
if err != nil { |
|
c.ServerError("GetNotificationCount", err) |
|
return -1 |
|
} |
|
|
|
return count |
|
} |
|
} |
|
|
|
// Notifications is the notifications page |
|
func Notifications(c *context.Context) { |
|
getNotifications(c) |
|
if c.Written() { |
|
return |
|
} |
|
if c.FormBool("div-only") { |
|
c.Data["SequenceNumber"] = c.FormString("sequence-number") |
|
c.HTML(http.StatusOK, tplNotificationDiv) |
|
return |
|
} |
|
c.HTML(http.StatusOK, tplNotification) |
|
} |
|
|
|
func getNotifications(c *context.Context) { |
|
var ( |
|
keyword = c.FormTrim("q") |
|
status models.NotificationStatus |
|
page = c.FormInt("page") |
|
perPage = c.FormInt("perPage") |
|
) |
|
if page < 1 { |
|
page = 1 |
|
} |
|
if perPage < 1 { |
|
perPage = 20 |
|
} |
|
|
|
switch keyword { |
|
case "read": |
|
status = models.NotificationStatusRead |
|
default: |
|
status = models.NotificationStatusUnread |
|
} |
|
|
|
total, err := models.GetNotificationCount(c.User, status) |
|
if err != nil { |
|
c.ServerError("ErrGetNotificationCount", err) |
|
return |
|
} |
|
|
|
// redirect to last page if request page is more than total pages |
|
pager := context.NewPagination(int(total), perPage, page, 5) |
|
if pager.Paginater.Current() < page { |
|
c.Redirect(fmt.Sprintf("%s/notifications?q=%s&page=%d", setting.AppSubURL, url.QueryEscape(c.FormString("q")), pager.Paginater.Current())) |
|
return |
|
} |
|
|
|
statuses := []models.NotificationStatus{status, models.NotificationStatusPinned} |
|
notifications, err := models.NotificationsForUser(c.User, statuses, page, perPage) |
|
if err != nil { |
|
c.ServerError("ErrNotificationsForUser", err) |
|
return |
|
} |
|
|
|
failCount := 0 |
|
|
|
repos, failures, err := notifications.LoadRepos() |
|
if err != nil { |
|
c.ServerError("LoadRepos", err) |
|
return |
|
} |
|
notifications = notifications.Without(failures) |
|
if err := repos.LoadAttributes(); err != nil { |
|
c.ServerError("LoadAttributes", err) |
|
return |
|
} |
|
failCount += len(failures) |
|
|
|
failures, err = notifications.LoadIssues() |
|
if err != nil { |
|
c.ServerError("LoadIssues", err) |
|
return |
|
} |
|
notifications = notifications.Without(failures) |
|
failCount += len(failures) |
|
|
|
failures, err = notifications.LoadComments() |
|
if err != nil { |
|
c.ServerError("LoadComments", err) |
|
return |
|
} |
|
notifications = notifications.Without(failures) |
|
failCount += len(failures) |
|
|
|
if failCount > 0 { |
|
c.Flash.Error(fmt.Sprintf("ERROR: %d notifications were removed due to missing parts - check the logs", failCount)) |
|
} |
|
|
|
c.Data["Title"] = c.Tr("notifications") |
|
c.Data["Keyword"] = keyword |
|
c.Data["Status"] = status |
|
c.Data["Notifications"] = notifications |
|
|
|
pager.SetDefaultParams(c) |
|
c.Data["Page"] = pager |
|
} |
|
|
|
// NotificationStatusPost is a route for changing the status of a notification |
|
func NotificationStatusPost(c *context.Context) { |
|
var ( |
|
notificationID = c.FormInt64("notification_id") |
|
statusStr = c.FormString("status") |
|
status models.NotificationStatus |
|
) |
|
|
|
switch statusStr { |
|
case "read": |
|
status = models.NotificationStatusRead |
|
case "unread": |
|
status = models.NotificationStatusUnread |
|
case "pinned": |
|
status = models.NotificationStatusPinned |
|
default: |
|
c.ServerError("InvalidNotificationStatus", errors.New("Invalid notification status")) |
|
return |
|
} |
|
|
|
if _, err := models.SetNotificationStatus(notificationID, c.User, status); err != nil { |
|
c.ServerError("SetNotificationStatus", err) |
|
return |
|
} |
|
|
|
if !c.FormBool("noredirect") { |
|
url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, url.QueryEscape(c.FormString("page"))) |
|
c.Redirect(url, http.StatusSeeOther) |
|
} |
|
|
|
getNotifications(c) |
|
if c.Written() { |
|
return |
|
} |
|
c.Data["Link"] = setting.AppURL + "notifications" |
|
c.Data["SequenceNumber"] = c.Req.PostFormValue("sequence-number") |
|
|
|
c.HTML(http.StatusOK, tplNotificationDiv) |
|
} |
|
|
|
// NotificationPurgePost is a route for 'purging' the list of notifications - marking all unread as read |
|
func NotificationPurgePost(c *context.Context) { |
|
err := models.UpdateNotificationStatuses(c.User, models.NotificationStatusUnread, models.NotificationStatusRead) |
|
if err != nil { |
|
c.ServerError("ErrUpdateNotificationStatuses", err) |
|
return |
|
} |
|
|
|
c.Redirect(setting.AppSubURL+"/notifications", http.StatusSeeOther) |
|
}
|
|
|