28d1e284ab
* The "Newest" tab of the forum is updated with new filter options. * Which forums: All, Official, Community, My List * Show: By threads, All posts * The option for "Which forums" is saved in the user's preferences and set as their default on future visits, similar to the Site Gallery "Whose photos" option. * So users can subscribe to their favorite forums and always get their latest posts easily while filtering out the rest. * Forum Moderators * Add the ability to add and remove moderators for your forum. * Users are notified when they are added as a moderator. * Moderators can opt themselves out by unfollowing the forum. * ForumMembership: add unique constraint on user_id,forum_id.
141 lines
3.8 KiB
Go
141 lines
3.8 KiB
Go
package forum
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/log"
|
|
"code.nonshy.com/nonshy/website/pkg/models"
|
|
"code.nonshy.com/nonshy/website/pkg/session"
|
|
"code.nonshy.com/nonshy/website/pkg/templates"
|
|
)
|
|
|
|
// ManageModerators controller (/forum/admin/moderators) to appoint moderators to your (user) forum.
|
|
func ManageModerators() http.HandlerFunc {
|
|
// Reuse the upload page but with an EditPhoto variable.
|
|
tmpl := templates.Must("forum/moderators.html")
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
intent = r.FormValue("intent")
|
|
stringID = r.FormValue("forum_id")
|
|
)
|
|
|
|
// Parse forum_id query parameter.
|
|
var forumID uint64
|
|
if stringID != "" {
|
|
if i, err := strconv.Atoi(stringID); err == nil {
|
|
forumID = uint64(i)
|
|
} else {
|
|
session.FlashError(w, r, "Edit parameter: forum_id was not an integer")
|
|
templates.Redirect(w, "/forum/admin")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Redirect URLs
|
|
var (
|
|
next = fmt.Sprintf("%s?forum_id=%d", r.URL.Path, forumID)
|
|
nextFinished = fmt.Sprintf("/forum/admin/edit?id=%d", forumID)
|
|
)
|
|
|
|
// Load the current user.
|
|
currentUser, err := session.CurrentUser(r)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Unexpected error: could not get currentUser.")
|
|
templates.Redirect(w, "/")
|
|
return
|
|
}
|
|
|
|
// Are we adding/removing a user as moderator?
|
|
var (
|
|
username = r.FormValue("to")
|
|
user *models.User
|
|
)
|
|
if username != "" {
|
|
if found, err := models.FindUser(username); err != nil {
|
|
templates.NotFoundPage(w, r)
|
|
return
|
|
} else {
|
|
user = found
|
|
}
|
|
}
|
|
|
|
// Look up the forum by its fragment.
|
|
forum, err := models.GetForum(forumID)
|
|
if err != nil {
|
|
templates.NotFoundPage(w, r)
|
|
return
|
|
}
|
|
|
|
// User must be the owner of this forum, or a privileged admin.
|
|
if !forum.CanEdit(currentUser) {
|
|
templates.ForbiddenPage(w, r)
|
|
return
|
|
}
|
|
|
|
// The forum owner can not add themself.
|
|
if user != nil && forum.OwnerID == user.ID {
|
|
session.FlashError(w, r, "You can not add the forum owner to its moderators list.")
|
|
templates.Redirect(w, next)
|
|
return
|
|
}
|
|
|
|
// POSTing?
|
|
if r.Method == http.MethodPost {
|
|
switch intent {
|
|
case "submit":
|
|
// Confirmed adding a moderator.
|
|
if _, err := forum.AddModerator(user); err != nil {
|
|
session.FlashError(w, r, "Error adding the moderator: %s", err)
|
|
templates.Redirect(w, next)
|
|
return
|
|
}
|
|
|
|
// Create a notification for this.
|
|
notif := &models.Notification{
|
|
UserID: user.ID,
|
|
AboutUser: *currentUser,
|
|
Type: models.NotificationForumModerator,
|
|
TableName: "forums",
|
|
TableID: forum.ID,
|
|
Link: fmt.Sprintf("/f/%s", forum.Fragment),
|
|
}
|
|
if err := models.CreateNotification(notif); err != nil {
|
|
log.Error("Couldn't create PrivatePhoto notification: %s", err)
|
|
}
|
|
|
|
session.Flash(w, r, "%s has been added to the moderators list!", user.Username)
|
|
templates.Redirect(w, nextFinished)
|
|
return
|
|
case "confirm-remove":
|
|
// Confirm removing a moderator.
|
|
if _, err := forum.RemoveModerator(user); err != nil {
|
|
session.FlashError(w, r, "Error removing the moderator: %s", err)
|
|
templates.Redirect(w, next)
|
|
return
|
|
}
|
|
|
|
// Revoke any past notifications they had about being added as moderator.
|
|
if err := models.RemoveSpecificNotification(user.ID, models.NotificationForumModerator, "forums", forum.ID); err != nil {
|
|
log.Error("Couldn't revoke the forum moderator notification: %s", err)
|
|
}
|
|
|
|
session.Flash(w, r, "%s has been removed from the moderators list.", user.Username)
|
|
templates.Redirect(w, nextFinished)
|
|
return
|
|
}
|
|
}
|
|
|
|
var vars = map[string]interface{}{
|
|
"Forum": forum,
|
|
"User": user,
|
|
"IsRemoving": intent == "remove",
|
|
}
|
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
})
|
|
}
|