Rewrite the pagination algorithm so it works properly.
Shorten a few bits of JS. Get the topic store methods to call BypassGet instead of duplicating logic.
This commit is contained in:
parent
5b5b8339d6
commit
fdd223d9cf
|
@ -1002,18 +1002,20 @@ func CoerceIntString(data string) (res int, length int) {
|
|||
|
||||
// TODO: Write tests for this
|
||||
// Make sure we reflect changes to this in the JS port in /public/global.js
|
||||
func Paginate(count int, perPage int, maxPages int) []int {
|
||||
if count < perPage {
|
||||
return []int{1}
|
||||
func Paginate(currentPage int, lastPage int, maxPages int) (out []int) {
|
||||
diff := lastPage - currentPage
|
||||
pre := 3
|
||||
if diff < 3 {
|
||||
pre = maxPages - diff
|
||||
}
|
||||
var page int
|
||||
var out []int
|
||||
for current := 0; current < count; current += perPage {
|
||||
|
||||
page := currentPage - pre
|
||||
if page < 0 {
|
||||
page = 0
|
||||
}
|
||||
for len(out) < maxPages && page < lastPage {
|
||||
page++
|
||||
out = append(out, page)
|
||||
if len(out) >= maxPages {
|
||||
break
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -527,7 +527,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
|||
|
||||
itemsPerPage := 25
|
||||
_, page, lastPage := PageOffset(20, 1, itemsPerPage)
|
||||
pageList := Paginate(20, itemsPerPage, 5)
|
||||
pageList := Paginate(page, lastPage, 5)
|
||||
tmpls.AddStd("paginator", "common.Paginator", Paginator{pageList, page, lastPage})
|
||||
|
||||
tmpls.AddStd("topic_c_edit_post", "common.TopicCEditPost", TopicCEditPost{ID: 0, Source: "", Ref: ""})
|
||||
|
|
|
@ -365,7 +365,7 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
|
|||
topic.LastUser = userList[topic.LastReplyBy]
|
||||
}
|
||||
|
||||
pageList := Paginate(topicCount, Config.ItemsPerPage, 5)
|
||||
pageList := Paginate(page, lastPage, 5)
|
||||
return topicList, Paginator{pageList, page, lastPage}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -66,44 +66,40 @@ func NewDefaultTopicStore(cache TopicCache) (*DefaultTopicStore, error) {
|
|||
}, acc.FirstError()
|
||||
}
|
||||
|
||||
func (mts *DefaultTopicStore) DirtyGet(id int) *Topic {
|
||||
topic, err := mts.cache.Get(id)
|
||||
func (s *DefaultTopicStore) DirtyGet(id int) *Topic {
|
||||
topic, err := s.cache.Get(id)
|
||||
if err == nil {
|
||||
return topic
|
||||
}
|
||||
|
||||
topic = &Topic{ID: id}
|
||||
err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyBy, &topic.LastReplyAt, &topic.LastReplyID, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
||||
topic, err = s.BypassGet(id)
|
||||
if err == nil {
|
||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||
_ = mts.cache.Set(topic)
|
||||
_ = s.cache.Set(topic)
|
||||
return topic
|
||||
}
|
||||
return BlankTopic()
|
||||
}
|
||||
|
||||
// TODO: Log weird cache errors?
|
||||
func (mts *DefaultTopicStore) Get(id int) (topic *Topic, err error) {
|
||||
topic, err = mts.cache.Get(id)
|
||||
func (s *DefaultTopicStore) Get(id int) (topic *Topic, err error) {
|
||||
topic, err = s.cache.Get(id)
|
||||
if err == nil {
|
||||
return topic, nil
|
||||
}
|
||||
|
||||
topic = &Topic{ID: id}
|
||||
err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyBy, &topic.LastReplyAt, &topic.LastReplyID, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
||||
topic, err = s.BypassGet(id)
|
||||
if err == nil {
|
||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||
_ = mts.cache.Set(topic)
|
||||
_ = s.cache.Set(topic)
|
||||
}
|
||||
return topic, err
|
||||
}
|
||||
|
||||
// BypassGet will always bypass the cache and pull the topic directly from the database
|
||||
func (mts *DefaultTopicStore) BypassGet(id int) (*Topic, error) {
|
||||
topic := &Topic{ID: id}
|
||||
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyBy, &topic.LastReplyAt, &topic.LastReplyID, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||
return topic, err
|
||||
func (s *DefaultTopicStore) BypassGet(id int) (*Topic, error) {
|
||||
t := &Topic{ID: id}
|
||||
err := s.get.QueryRow(id).Scan(&t.Title, &t.Content, &t.CreatedBy, &t.CreatedAt, &t.LastReplyBy, &t.LastReplyAt, &t.LastReplyID, &t.IsClosed, &t.Sticky, &t.ParentID, &t.IPAddress, &t.ViewCount, &t.PostCount, &t.LikeCount, &t.AttachCount, &t.Poll, &t.Data)
|
||||
if err == nil {
|
||||
t.Link = BuildTopicURL(NameToSlug(t.Title), id)
|
||||
}
|
||||
return t, err
|
||||
}
|
||||
|
||||
// TODO: Avoid duplicating much of this logic from user_store.go
|
||||
|
@ -155,14 +151,14 @@ func (s *DefaultTopicStore) BulkGetMap(ids []int) (list map[int]*Topic, err erro
|
|||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
topic := &Topic{}
|
||||
err := rows.Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyBy, &topic.LastReplyAt, &topic.LastReplyID, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
||||
t := &Topic{}
|
||||
err := rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreatedBy, &t.CreatedAt, &t.LastReplyBy, &t.LastReplyAt, &t.LastReplyID, &t.IsClosed, &t.Sticky, &t.ParentID, &t.IPAddress, &t.ViewCount, &t.PostCount, &t.LikeCount, &t.AttachCount, &t.Poll, &t.Data)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), topic.ID)
|
||||
s.cache.Set(topic)
|
||||
list[topic.ID] = topic
|
||||
t.Link = BuildTopicURL(NameToSlug(t.Title), t.ID)
|
||||
s.cache.Set(t)
|
||||
list[t.ID] = t
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
|
@ -187,21 +183,19 @@ func (s *DefaultTopicStore) BulkGetMap(ids []int) (list map[int]*Topic, err erro
|
|||
return list, err
|
||||
}
|
||||
|
||||
func (mts *DefaultTopicStore) Reload(id int) error {
|
||||
topic := &Topic{ID: id}
|
||||
err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyBy, &topic.LastReplyAt, &topic.LastReplyID, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
||||
func (s *DefaultTopicStore) Reload(id int) error {
|
||||
topic, err := s.BypassGet(id)
|
||||
if err == nil {
|
||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), id)
|
||||
_ = mts.cache.Set(topic)
|
||||
_ = s.cache.Set(topic)
|
||||
} else {
|
||||
_ = mts.cache.Remove(id)
|
||||
_ = s.cache.Remove(id)
|
||||
}
|
||||
TopicListThaw.Thaw()
|
||||
return err
|
||||
}
|
||||
|
||||
func (mts *DefaultTopicStore) Exists(id int) bool {
|
||||
return mts.exists.QueryRow(id).Scan(&id) == nil
|
||||
func (s *DefaultTopicStore) Exists(id int) bool {
|
||||
return s.exists.QueryRow(id).Scan(&id) == nil
|
||||
}
|
||||
|
||||
func (mts *DefaultTopicStore) Create(fid int, topicName string, content string, uid int, ipaddress string) (tid int, err error) {
|
||||
|
@ -234,7 +228,7 @@ func (mts *DefaultTopicStore) Create(fid int, topicName string, content string,
|
|||
}
|
||||
|
||||
// ? - What is this? Do we need it? Should it be in the main store interface?
|
||||
func (mts *DefaultTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
func (s *DefaultTopicStore) AddLastTopic(item *Topic, fid int) error {
|
||||
// Coming Soon...
|
||||
return nil
|
||||
}
|
||||
|
@ -248,15 +242,15 @@ func (s *DefaultTopicStore) Count() (count int) {
|
|||
return count
|
||||
}
|
||||
|
||||
func (mts *DefaultTopicStore) SetCache(cache TopicCache) {
|
||||
mts.cache = cache
|
||||
func (s *DefaultTopicStore) SetCache(cache TopicCache) {
|
||||
s.cache = cache
|
||||
}
|
||||
|
||||
// TODO: We're temporarily doing this so that you can do tcache != nil in getTopicUser. Refactor it.
|
||||
func (mts *DefaultTopicStore) GetCache() TopicCache {
|
||||
_, ok := mts.cache.(*NullTopicCache)
|
||||
func (s *DefaultTopicStore) GetCache() TopicCache {
|
||||
_, ok := s.cache.(*NullTopicCache)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return mts.cache
|
||||
}
|
||||
return s.cache
|
||||
}
|
|
@ -386,14 +386,17 @@ function PageOffset(count, page, perPage) {
|
|||
function LastPage(count, perPage) {
|
||||
return (count / perPage) + 1
|
||||
}
|
||||
function Paginate(count, perPage, maxPages) {
|
||||
if(count < perPage) return [1];
|
||||
let page = 0;
|
||||
function Paginate(currentPage, lastPage, maxPages) {
|
||||
let diff = lastPage - currentPage;
|
||||
let pre = 3;
|
||||
if(diff < 3) pre = maxPages - diff;
|
||||
|
||||
let page = currentPage - pre;
|
||||
if(page < 0) page = 0;
|
||||
let out = [];
|
||||
for(let current = 0; current < count; current += perPage){
|
||||
while(out.length < maxPages && page < lastPage){
|
||||
page++;
|
||||
out.push(page);
|
||||
if(out.length >= maxPages) break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -405,9 +408,9 @@ function mainInit(){
|
|||
event.preventDefault();
|
||||
let moreTopicBlocks = document.getElementsByClassName("more_topic_block_active");
|
||||
for(let i = 0; i < moreTopicBlocks.length; i++) {
|
||||
let moreTopicBlock = moreTopicBlocks[i];
|
||||
moreTopicBlock.classList.remove("more_topic_block_active");
|
||||
moreTopicBlock.classList.add("more_topic_block_initial");
|
||||
let block = moreTopicBlocks[i];
|
||||
block.classList.remove("more_topic_block_active");
|
||||
block.classList.add("more_topic_block_initial");
|
||||
}
|
||||
$(".ajax_topic_dupe").fadeOut("slow", function(){
|
||||
$(this).remove();
|
||||
|
@ -437,9 +440,7 @@ function mainInit(){
|
|||
data: { isJs: 1 },
|
||||
error: ajaxError,
|
||||
success: function (data, status, xhr) {
|
||||
if("success" in data) {
|
||||
if(data["success"] == "1") return;
|
||||
}
|
||||
if("success" in data && data["success"] == "1") return;
|
||||
// addNotice("Failed to add a like: {err}")
|
||||
likeButton.classList.add("add_like");
|
||||
likeButton.classList.remove("remove_like");
|
||||
|
@ -465,11 +466,8 @@ function mainInit(){
|
|||
let urlParams = new URLSearchParams(window.location.search);
|
||||
let page = urlParams.get('page');
|
||||
if(page=="") page = 1;
|
||||
let stopAtPage = lastPage;
|
||||
if(stopAtPage>5) stopAtPage = 5;
|
||||
|
||||
let pageList = [];
|
||||
for(let i = 0; i < stopAtPage;i++) pageList.push(i+1);
|
||||
let pageList = Paginate(page,lastPage,5)
|
||||
//$(".pageset").html(Template_paginator({PageList: pageList, Page: page, LastPage: lastPage}));
|
||||
let ok = false;
|
||||
$(".pageset").each(function(){
|
||||
|
@ -804,7 +802,7 @@ function mainInit(){
|
|||
|
||||
// This one's for Tempra Conflux
|
||||
// TODO: We might want to use pure JS here
|
||||
$(".ip_item").each(function(){
|
||||
/*$(".ip_item").each(function(){
|
||||
var ip = this.textContent;
|
||||
if(ip.length > 10){
|
||||
this.innerHTML = "Show IP";
|
||||
|
@ -813,7 +811,7 @@ function mainInit(){
|
|||
this.textContent = ip;
|
||||
};
|
||||
}
|
||||
});
|
||||
});*/
|
||||
|
||||
$(".quote_item").click(function(){
|
||||
event.preventDefault();
|
||||
|
|
|
@ -724,7 +724,7 @@ func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, header *
|
|||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
pageList := c.Paginate(logCount, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.Account{header, "logins", "account_logins", c.AccountLoginsPage{header, logs, c.Paginator{pageList, page, lastPage}}}
|
||||
return renderTemplate("account", w, r, header, pi)
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
return nil
|
||||
}
|
||||
|
||||
pageList := c.Paginate(forum.TopicCount, c.Config.ItemsPerPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.ForumPage{header, topicList, forum, c.Paginator{pageList, page, lastPage}}
|
||||
tmpl := forum.Tmpl
|
||||
if tmpl == "" {
|
||||
|
|
|
@ -57,7 +57,7 @@ func Groups(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
count++
|
||||
}
|
||||
|
||||
pageList := c.Paginate(basePage.Stats.Groups, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelGroupPage{basePage, groupList, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_groups",&pi})
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
|||
llist[index] = c.PageRegLogItem{log, strings.Replace(strings.TrimSuffix(log.FailureReason, "|"), "|", " | ", -1)}
|
||||
}
|
||||
|
||||
pageList := c.Paginate(logCount, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelRegLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_reglogs", pi})
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ func LogsMod(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
llist[index] = c.PageLogItem{Action: template.HTML(action), IPAddress: log.IPAddress, DoneAt: log.DoneAt}
|
||||
}
|
||||
|
||||
pageList := c.Paginate(logCount, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_modlogs", pi})
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func LogsAdmin(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
|||
llist[index] = c.PageLogItem{Action: template.HTML(action), IPAddress: log.IPAddress, DoneAt: log.DoneAt}
|
||||
}
|
||||
|
||||
pageList := c.Paginate(logCount, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_adminlogs", pi})
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ func Pages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
pageList := c.Paginate(pageCount, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelCustomPagesPage{basePage, cPages, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_page_list","","panel_pages",&pi})
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi})
|
||||
}
|
||||
|
||||
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
|
@ -90,7 +90,7 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
|
|||
}
|
||||
|
||||
pi := c.PanelCustomPageEditPage{basePage, page}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"panel_page_edit","","panel_pages_edit",&pi})
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi})
|
||||
}
|
||||
|
||||
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError {
|
||||
|
|
|
@ -23,7 +23,7 @@ func Users(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
pageList := c.Paginate(basePage.Stats.Users, perPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
pi := c.PanelUserPage{basePage, users, c.Paginator{pageList, page, lastPage}}
|
||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage,"","","panel_users",&pi})
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
|
||||
// Calculate the offset
|
||||
offset, page, lastPage := c.PageOffset(topic.PostCount, page, c.Config.ItemsPerPage)
|
||||
pageList := c.Paginate(topic.PostCount, c.Config.ItemsPerPage, 5)
|
||||
pageList := c.Paginate(page, lastPage, 5)
|
||||
tpage := c.TopicPage{header, nil, topic, forum, poll, c.Paginator{pageList, page, lastPage}}
|
||||
|
||||
// Get the replies if we have any...
|
||||
|
|
Loading…
Reference in New Issue