Платформа ЦРНП "Мирокод" для разработки проектов
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.
192 lines
4.8 KiB
192 lines
4.8 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" |
|
"strconv" |
|
"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.QueryBool("div-only") { |
|
c.HTML(http.StatusOK, tplNotificationDiv) |
|
return |
|
} |
|
c.HTML(http.StatusOK, tplNotification) |
|
} |
|
|
|
func getNotifications(c *context.Context) { |
|
var ( |
|
keyword = strings.Trim(c.Query("q"), " ") |
|
status models.NotificationStatus |
|
page = c.QueryInt("page") |
|
perPage = c.QueryInt("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("/notifications?q=%s&page=%d", c.Query("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, _ = strconv.ParseInt(c.Req.PostFormValue("notification_id"), 10, 64) |
|
statusStr = c.Req.PostFormValue("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.QueryBool("noredirect") { |
|
url := fmt.Sprintf("%s/notifications?page=%s", setting.AppSubURL, c.Query("page")) |
|
c.Redirect(url, http.StatusSeeOther) |
|
} |
|
|
|
getNotifications(c) |
|
if c.Written() { |
|
return |
|
} |
|
c.Data["Link"] = setting.AppURL + "notifications" |
|
|
|
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 |
|
} |
|
|
|
url := fmt.Sprintf("%s/notifications", setting.AppSubURL) |
|
c.Redirect(url, http.StatusSeeOther) |
|
}
|
|
|