User Forums: Sort options and pagination
* The Explore tab can now sort forums by their: * Most recently updated thread * Topics, Posts or Users (counts) * Show owner information in forum cards * Passive pagination support for the "My List" on forum home page. * Only visible when there are >20 favorited Forums.
This commit is contained in:
parent
3921691319
commit
56a6190ce9
|
@ -24,6 +24,7 @@ var (
|
|||
PageSizeInboxThread = 10 // conversation view
|
||||
PageSizeBrowseForums = 20
|
||||
PageSizeForums = 100 // TODO: for main category index view
|
||||
PageSizeMyListForums = 20 // "My List" pager on forum home (categories) page.
|
||||
PageSizeThreadList = 20 // 20 threads per board, 20 posts per thread
|
||||
PageSizeForumAdmin = 20
|
||||
PageSizeDashboardNotifications = 50
|
||||
|
|
|
@ -20,6 +20,13 @@ func Explore() http.HandlerFunc {
|
|||
"created_at asc",
|
||||
"title asc",
|
||||
"title desc",
|
||||
|
||||
// Special sort handlers.
|
||||
// See PaginateForums for expanded handlers for these.
|
||||
"by_latest",
|
||||
"by_threads",
|
||||
"by_posts",
|
||||
"by_users",
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -33,14 +33,13 @@ func Landing() http.HandlerFunc {
|
|||
|
||||
// Get all the categorized index forums.
|
||||
// XXX: we get a large page size to get ALL official forums
|
||||
var pager = &models.Pagination{
|
||||
// This pager is hardcoded and doesn't parse from ?page= params.
|
||||
var indexPager = &models.Pagination{
|
||||
Page: 1,
|
||||
PerPage: config.PageSizeForums,
|
||||
Sort: "title asc",
|
||||
}
|
||||
pager.ParsePage(r)
|
||||
|
||||
forums, err := models.PaginateForums(currentUser, config.ForumCategories, nil, false, pager)
|
||||
forums, err := models.PaginateForums(currentUser, config.ForumCategories, nil, false, indexPager)
|
||||
if err != nil {
|
||||
session.FlashError(w, r, "Couldn't paginate forums: %s", err)
|
||||
templates.Redirect(w, "/")
|
||||
|
@ -51,6 +50,12 @@ func Landing() http.HandlerFunc {
|
|||
categorized := models.CategorizeForums(forums, config.ForumCategories)
|
||||
|
||||
// Inject the "My List" Category if the user subscribes to forums.
|
||||
var pager = &models.Pagination{
|
||||
Page: 1,
|
||||
PerPage: config.PageSizeMyListForums,
|
||||
Sort: "by_latest",
|
||||
}
|
||||
pager.ParsePage(r)
|
||||
if config.UserForumsEnabled {
|
||||
myList, err := models.PaginateForums(currentUser, nil, nil, true, pager)
|
||||
if err != nil {
|
||||
|
|
|
@ -85,6 +85,13 @@ Parameters:
|
|||
- userID: of who is looking
|
||||
- categories: optional, filter within categories
|
||||
- pager
|
||||
|
||||
The pager Sort accepts a couple of custom values for more advanced sorting:
|
||||
|
||||
- by_latest: recently updated posts
|
||||
- by_threads: thread count
|
||||
- by_posts: post count
|
||||
- by_users: user count
|
||||
*/
|
||||
func PaginateForums(user *User, categories []string, search *Search, subscribed bool, pager *Pagination) ([]*Forum, error) {
|
||||
var (
|
||||
|
@ -159,6 +166,37 @@ func PaginateForums(user *User, categories []string, search *Search, subscribed
|
|||
)
|
||||
}
|
||||
|
||||
// Custom SORT parameters.
|
||||
switch pager.Sort {
|
||||
case "by_latest":
|
||||
pager.Sort = `(
|
||||
SELECT MAX(threads.updated_at)
|
||||
FROM threads
|
||||
WHERE threads.forum_id = forums.id
|
||||
) DESC NULLS LAST`
|
||||
case "by_threads":
|
||||
pager.Sort = `(
|
||||
SELECT count(threads.id)
|
||||
FROM threads
|
||||
WHERE threads.forum_id = forums.id
|
||||
) DESC`
|
||||
case "by_posts":
|
||||
pager.Sort = `(
|
||||
SELECT count(comments.id)
|
||||
FROM threads
|
||||
JOIN comments ON comments.table_name='threads' AND comments.table_id=threads.id
|
||||
WHERE threads.forum_id = forums.id
|
||||
) DESC`
|
||||
case "by_users":
|
||||
pager.Sort = `(
|
||||
SELECT count(distinct(users.id))
|
||||
FROM threads
|
||||
JOIN comments ON comments.table_name='threads' AND comments.table_id=threads.id
|
||||
JOIN users ON comments.user_id=users.id
|
||||
WHERE threads.forum_id = forums.id
|
||||
) DESC`
|
||||
}
|
||||
|
||||
query = query.Order(pager.Sort)
|
||||
query.Model(&Forum{}).Count(&pager.Total)
|
||||
result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&fs)
|
||||
|
|
|
@ -87,9 +87,17 @@
|
|||
<label class="label" for="sort">Sort by:</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select id="sort" name="sort">
|
||||
<option value="title asc"{{if eq .Sort "title asc"}} selected{{end}}>Title (A-Z)</option>
|
||||
<option value="title desc"{{if eq .Sort "title desc"}} selected{{end}}>Title (Z-A)</option>
|
||||
<option value="created_at desc"{{if eq .Sort "created_at desc"}} selected{{end}}>Recently created</option>
|
||||
<optgroup label="Forum">
|
||||
<option value="title asc"{{if eq .Sort "title asc"}} selected{{end}}>Title (A-Z)</option>
|
||||
<option value="title desc"{{if eq .Sort "title desc"}} selected{{end}}>Title (Z-A)</option>
|
||||
<option value="created_at desc"{{if eq .Sort "created_at desc"}} selected{{end}}>Recently created</option>
|
||||
</optgroup>
|
||||
<optgroup label="Contents">
|
||||
<option value="by_latest"{{if eq .Sort "by_latest"}} selected{{end}}>Latest post</option>
|
||||
<option value="by_threads"{{if eq .Sort "by_threads"}} selected{{end}}>Topic count</option>
|
||||
<option value="by_posts"{{if eq .Sort "by_posts"}} selected{{end}}>Post count</option>
|
||||
<option value="by_users"{{if eq .Sort "by_users"}} selected{{end}}>User count</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -121,16 +129,22 @@
|
|||
{{end}}
|
||||
|
||||
{{range .Categories}}
|
||||
{{$IsMyList := eq .Category "My List"}}
|
||||
<div class="block p-4">
|
||||
{{if .Category}}
|
||||
<h1 class="title">
|
||||
{{.Category}}
|
||||
{{if eq .Category "My List"}}
|
||||
{{if $IsMyList}}
|
||||
<i class="fa fa-book-bookmark ml-2"></i>
|
||||
{{end}}
|
||||
</h1>
|
||||
{{end}}
|
||||
|
||||
<!-- My List: show pagers if needed -->
|
||||
{{if and $IsMyList (gt $Root.Pager.Pages 1)}}
|
||||
{{SimplePager $Root.Pager}}
|
||||
{{end}}
|
||||
|
||||
{{if eq (len .Forums) 0}}
|
||||
<em>
|
||||
There are no forums under this category.
|
||||
|
@ -159,7 +173,7 @@
|
|||
{{end}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="mb-3">
|
||||
{{if .Explicit}}
|
||||
<span class="tag is-danger is-light">
|
||||
<span class="icon"><i class="fa fa-fire"></i></span>
|
||||
|
@ -189,6 +203,25 @@
|
|||
{{end}}
|
||||
</div>
|
||||
|
||||
<!-- Owner line -->
|
||||
{{if .Category}}
|
||||
<div class="mt-2 has-text-grey" style="font-size: smaller">
|
||||
by <a href="/f/{{.Fragment}}">{{PrettyTitle}}</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="mt-2 has-text-grey" style="font-size: smaller">
|
||||
by
|
||||
{{template "avatar-16x16" .Owner}}
|
||||
{{if .Owner.Username}}
|
||||
<a href="/u/{{.Owner.Username}}" class="has-text-grey">
|
||||
<strong>{{or .Owner.Username "[unavailable]"}}</strong>
|
||||
</a>
|
||||
{{else}}
|
||||
[unavailable]
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
<div class="column py-1">
|
||||
<div class="box has-background-success-light has-text-dark">
|
||||
|
@ -251,6 +284,12 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<!-- My List: show pagers -->
|
||||
{{if and $IsMyList (gt $Root.Pager.Pages 1)}}
|
||||
{{SimplePager $Root.Pager}}
|
||||
<hr class="mb-0">
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}<!-- range .Categories -->
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user