8a321eb8d2
* Private forums: CanBeSeenBy moderators, approved followers, its owner and admin users. * Note: the endpoint to subscribe to the forum won't allow users to follow the private forum, so approved followers can not be created at this time, except by adding them as moderators. * Admins: when creating a forum they can choose "no category" to create it as an unofficial community forum. * Code cleanup * More feature flag checking
117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
package forum
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/config"
|
|
"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"
|
|
)
|
|
|
|
// Thread view for the comment thread body of a forum post.
|
|
func Thread() http.HandlerFunc {
|
|
tmpl := templates.Must("forum/thread.html")
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Parse the path parameters
|
|
var (
|
|
idStr = r.PathValue("id")
|
|
forum *models.Forum
|
|
thread *models.Thread
|
|
)
|
|
|
|
if idStr == "" {
|
|
templates.NotFoundPage(w, r)
|
|
return
|
|
} else {
|
|
if threadID, err := strconv.Atoi(idStr); err != nil {
|
|
session.FlashError(w, r, "Invalid thread ID in the address bar.")
|
|
templates.Redirect(w, "/forum")
|
|
return
|
|
} else {
|
|
// Load the thread.
|
|
if found, err := models.GetThread(uint64(threadID)); err != nil {
|
|
session.FlashError(w, r, "That thread does not exist.")
|
|
templates.Redirect(w, "/forum")
|
|
return
|
|
} else {
|
|
thread = found
|
|
forum = &thread.Forum
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get the current user.
|
|
currentUser, err := session.CurrentUser(r)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Couldn't get current user: %s", err)
|
|
templates.Redirect(w, "/")
|
|
return
|
|
}
|
|
|
|
// Is it a private forum?
|
|
if !forum.CanBeSeenBy(currentUser) {
|
|
templates.NotFoundPage(w, r)
|
|
return
|
|
}
|
|
|
|
// Can we moderate this forum? (from a user-owned forum perspective,
|
|
// e.g. can we delete threads and posts, not edit them)
|
|
var canModerate = forum.CanBeModeratedBy(currentUser)
|
|
|
|
// Ping the view count on this thread.
|
|
if err := thread.View(currentUser.ID); err != nil {
|
|
log.Error("Couldn't ping view count on thread %d: %s", thread.ID, err)
|
|
}
|
|
|
|
// Paginate the comments on this thread.
|
|
var pager = &models.Pagination{
|
|
Page: 1,
|
|
PerPage: config.PageSizeThreadList,
|
|
Sort: "created_at asc",
|
|
}
|
|
pager.ParsePage(r)
|
|
|
|
comments, err := models.PaginateComments(currentUser, "threads", thread.ID, pager)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Couldn't paginate comments: %s", err)
|
|
templates.Redirect(w, "/")
|
|
return
|
|
}
|
|
|
|
// Get the like map for these comments.
|
|
commentIDs := []uint64{}
|
|
for _, com := range comments {
|
|
commentIDs = append(commentIDs, com.ID)
|
|
}
|
|
commentLikeMap := models.MapLikes(currentUser, "comments", commentIDs)
|
|
|
|
// Get any photo attachments for these comments.
|
|
photos, err := models.MapCommentPhotos(comments)
|
|
if err != nil {
|
|
log.Error("Couldn't MapCommentPhotos: %s", err)
|
|
}
|
|
|
|
// Is the current user subscribed to notifications on this thread?
|
|
_, isSubscribed := models.IsSubscribed(currentUser, "threads", thread.ID)
|
|
|
|
var vars = map[string]interface{}{
|
|
"Forum": forum,
|
|
"Thread": thread,
|
|
"Comments": comments,
|
|
"LikeMap": commentLikeMap,
|
|
"PhotoMap": photos,
|
|
"Pager": pager,
|
|
"CanModerate": canModerate,
|
|
"IsSubscribed": isSubscribed,
|
|
"IsForumSubscribed": models.IsForumSubscribed(currentUser, forum),
|
|
}
|
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
})
|
|
}
|