Fix ranking pagination: sliding ±2 window around current page
rankingPageNums now takes a current page parameter and always renders first 2, last 2, and current±2 — so navigating to page 3 shows 1 2 3 4 5 … 80 81 instead of only the fixed quarter-mark anchors.
This commit is contained in:
@@ -881,47 +881,38 @@ type pageNum struct {
|
||||
Num int
|
||||
}
|
||||
|
||||
// rankingPageNums builds the dynamic pagination list for 100 pages with
|
||||
// smart ellipsis: always show the first 3, last 3, and a sliding window of
|
||||
// 3 around the ends — compressed with "…" separators between runs.
|
||||
//
|
||||
// For a flat 100-page list it produces:
|
||||
//
|
||||
// 1 2 3 … 6 7 8 … 93 94 95 … 98 99 100
|
||||
//
|
||||
// (The middle range is omitted intentionally; users click individual pages.)
|
||||
func rankingPageNums(total int) []pageNum {
|
||||
// rankingPageNums builds a pagination list with smart ellipsis.
|
||||
// It always shows: first 2, last 2, and a ±2 window around current.
|
||||
// Gaps between non-consecutive runs are filled with a sentinel (Num==0) for "…".
|
||||
// Pass current=0 when there is no concept of a current page (e.g. fetch bar).
|
||||
func rankingPageNums(total, current int) []pageNum {
|
||||
if total <= 0 {
|
||||
return nil
|
||||
}
|
||||
// Build the set of visible page numbers using a sliding-window approach.
|
||||
show := make(map[int]bool)
|
||||
// Always show first 3 and last 3.
|
||||
for i := 1; i <= 3 && i <= total; i++ {
|
||||
// First 2 and last 2.
|
||||
for i := 1; i <= 2 && i <= total; i++ {
|
||||
show[i] = true
|
||||
}
|
||||
for i := total - 2; i <= total; i++ {
|
||||
for i := total - 1; i <= total; i++ {
|
||||
if i >= 1 {
|
||||
show[i] = true
|
||||
}
|
||||
}
|
||||
// For large ranges, show a few pages near the 1/4 and 3/4 marks.
|
||||
if total > 12 {
|
||||
q1 := total / 4
|
||||
q3 := total * 3 / 4
|
||||
for _, p := range []int{q1 - 1, q1, q1 + 1, q3 - 1, q3, q3 + 1} {
|
||||
if p >= 1 && p <= total {
|
||||
show[p] = true
|
||||
// ±2 window around current page.
|
||||
if current > 0 {
|
||||
for i := current - 2; i <= current+2; i++ {
|
||||
if i >= 1 && i <= total {
|
||||
show[i] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect sorted visible pages.
|
||||
// Collect and sort.
|
||||
pages := make([]int, 0, len(show))
|
||||
for p := range show {
|
||||
pages = append(pages, p)
|
||||
}
|
||||
// Sort pages slice.
|
||||
for i := 0; i < len(pages); i++ {
|
||||
for j := i + 1; j < len(pages); j++ {
|
||||
if pages[j] < pages[i] {
|
||||
@@ -930,11 +921,11 @@ func rankingPageNums(total int) []pageNum {
|
||||
}
|
||||
}
|
||||
|
||||
// Build output with ellipsis sentinels (Num==0) between non-consecutive pages.
|
||||
// Build output with ellipsis sentinels between non-consecutive pages.
|
||||
out := make([]pageNum, 0, len(pages)*2)
|
||||
for i, p := range pages {
|
||||
if i > 0 && p > pages[i-1]+1 {
|
||||
out = append(out, pageNum{0}) // ellipsis
|
||||
out = append(out, pageNum{0})
|
||||
}
|
||||
out = append(out, pageNum{p})
|
||||
}
|
||||
@@ -1015,8 +1006,8 @@ func (s *Server) handleRanking(w http.ResponseWriter, r *http.Request) {
|
||||
}{
|
||||
Books: toRankingViewItems(pageItems, s.writer.LocalSlugs()),
|
||||
CachedAt: cachedAt,
|
||||
FetchNums: rankingPageNums(100),
|
||||
DisplayNums: rankingPageNums(totalPages),
|
||||
FetchNums: rankingPageNums(100, 0),
|
||||
DisplayNums: rankingPageNums(totalPages, currentPage),
|
||||
CurrentPage: currentPage,
|
||||
TotalPages: totalPages,
|
||||
TotalItems: totalItems,
|
||||
|
||||
Reference in New Issue
Block a user