website/pkg/controller/forum/forum.go
Noah Petherbridge 8a321eb8d2 User-owned Forum Improvements
* 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
2024-08-23 22:56:40 -07:00

95 lines
2.4 KiB
Go

package forum
import (
"net/http"
"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"
)
// Forum view for a specific board index.
func Forum() http.HandlerFunc {
tmpl := templates.Must("forum/board_index.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Parse the path parameters
var (
fragment = r.PathValue("fragment")
forum *models.Forum
)
// Look up the forum by its fragment.
if found, err := models.ForumByFragment(fragment); err != nil {
templates.NotFoundPage(w, r)
return
} else {
forum = found
}
// 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
}
// Get the pinned threads.
pinned, err := models.PinnedThreads(forum)
if err != nil {
session.FlashError(w, r, "Couldn't get pinned threads: %s", err)
templates.Redirect(w, "/")
return
}
// Get all the categorized index forums.
// XXX: we get a large page size to get ALL official forums
var pager = &models.Pagination{
Page: 1,
PerPage: config.PageSizeThreadList,
Sort: "updated_at desc",
}
pager.ParsePage(r)
threads, err := models.PaginateThreads(currentUser, forum, pager)
if err != nil {
session.FlashError(w, r, "Couldn't paginate threads: %s", err)
templates.Redirect(w, "/")
return
}
// Inject pinned threads on top.
threads = append(pinned, threads...)
// Map the statistics (replies, views) of these threads.
threadMap := models.MapThreadStatistics(threads)
// Load the forum's moderators.
mods, err := forum.GetModerators()
if err != nil {
log.Error("Getting forum moderators: %s", err)
}
var vars = map[string]interface{}{
"Forum": forum,
"ForumModerators": mods,
"IsForumSubscribed": models.IsForumSubscribed(currentUser, forum),
"Threads": threads,
"ThreadMap": threadMap,
"Pager": pager,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}