e18ea9e349
* Apache `ProxyPassReverse` only works for Location, Content-Location and URI headers on HTTP redirect responses, it causes more problems than it resolves. Now all URLs generated by Gitee have the correct prefix AppSubURL. We do not need to set `ProxyPassReverse`. * fix url param * use AppSubURL instead of AppURL in api/v1 Co-authored-by: techknowlogick <techknowlogick@gitea.io>
194 lines
4.9 KiB
Go
194 lines
4.9 KiB
Go
// 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, 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
|
|
}
|
|
|
|
url := fmt.Sprintf("%s/notifications", setting.AppSubURL)
|
|
c.Redirect(url, http.StatusSeeOther)
|
|
}
|