package models import ( "math" "net/http" "strconv" "code.nonshy.com/nonshy/website/pkg/config" ) // Pagination result object. type Pagination struct { Page int // provide <0 to mean "last page" PerPage int Total int64 Sort string // privates lastPage bool } // Page for Iter. type Page struct { Page int IsCurrent bool } // Load the page from form or query parameters. func (p *Pagination) ParsePage(r *http.Request) { raw := r.FormValue("page") a, err := strconv.Atoi(raw) if err == nil { if a <= 0 { p.lastPage = true a = 1 } p.Page = a } else { p.Page = 1 } } // Iter the pages, for templates. func (p *Pagination) Iter() []Page { var ( pages = []Page{} pageIdx int total = p.Pages() ) for i := 1; i <= total; i++ { pages = append(pages, Page{ Page: i, IsCurrent: i == p.Page, }) if i == p.Page { pageIdx = i } } // Do we have A LOT of pages? if len(pages) > config.PagerButtonLimit { // We return a slide only N pages long. Where is our current page in the offset? if pageIdx <= config.PagerButtonLimit/2 { // We are near the front, return the first N pages. return pages[:config.PagerButtonLimit+1] } // Are we near the end? if pageIdx > len(pages)-(config.PagerButtonLimit/2) { // We are near the end, return the last N pages. return pages[len(pages)-config.PagerButtonLimit-1:] } // We are somewhere in the middle. var result = []Page{} for i := pageIdx - (config.PagerButtonLimit / 2) - 1; i < pageIdx+(config.PagerButtonLimit/2); i++ { if i >= 0 && i < len(pages) { result = append(result, pages[i]) } } return result } return pages } func (p *Pagination) Pages() int { return int(math.Ceil(float64(p.Total) / float64(p.PerPage))) } func (p *Pagination) GetOffset() int { // Are we looking for the FINAL page? if p.lastPage && p.Pages() >= 1 { p.Page = p.Pages() } return (p.Page - 1) * p.PerPage } func (p *Pagination) HasNext() bool { return p.Page < p.Pages() } func (p *Pagination) HasPrevious() bool { return p.Page > 1 } func (p *Pagination) Next() int { if p.Page >= p.Pages() { return p.Pages() } return p.Page + 1 } func (p *Pagination) Previous() int { if p.Page > 1 { return p.Page - 1 } return 1 }