Skip to content

Commit

Permalink
Merge pull request #59 from recoilme/43-all_posts
Browse files Browse the repository at this point in the history
pagination
  • Loading branch information
recoilme committed Dec 1, 2022
2 parents ef48584 + 206f66d commit cf8e8c1
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 12 deletions.
138 changes: 138 additions & 0 deletions internal/pagination/pagination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package pagination

import (
"math"
)

// Pagination is a general purpose pagination type, it knows how to calculate
// offset and number of pages. It also contains some utility functions
// that helps common tasks. One special utility is the PagesStream method
// that returns a channel to range over for presenting a list of all pages
// without adding them all to a slice.
type Pagination struct {
itemsPerPage int
numberOfItems int
currentPage int
}

// New returns a new Pagination with the provided values.
// The current page is normalized to be inside the bounds
// of the available pages. So if the current page supplied
// is less than 1 the current page is normalized as 1, and if
// it is larger than the number of pages needed its normalized
// as the last available page.
func New(numberOfItems, itemsPerPage, currentPage int) *Pagination {
if currentPage == 0 {
currentPage = 1
}

n := int(math.Ceil(float64(numberOfItems) / float64(itemsPerPage)))
if currentPage > n {
currentPage = n
}

return &Pagination{
itemsPerPage: itemsPerPage,
numberOfItems: numberOfItems,
currentPage: currentPage,
}
}

// PagesStream returns a channel that will be incremented to
// the available number of pages. Useful to range over when
// building a list of pages.
func (p *Pagination) PagesStream() chan int {
stream := make(chan int)
go func() {
for i := 1; i <= p.NumberOfPages(); i++ {
stream <- i
}
close(stream)
}()
return stream
}

// Offset calculates the offset into the collection the current page represents.
func (p *Pagination) Offset() int {
return (p.CurrentPage() - 1) * p.ItemsPerPage()
}

// NumberOfPages calculates the number of pages needed
// based on number of items and items per page.
func (p *Pagination) NumberOfPages() int {
return int(math.Ceil(float64(p.NumberOfItems()) / float64(p.ItemsPerPage())))
}

// PreviousPage returns the page number of the page before current page.
// If current page is the first in the list of pages, 1 is returned.
func (p *Pagination) PreviousPage() int {
if p.CurrentPage() <= 1 {
return 1
}

return p.CurrentPage() - 1
}

func (p *Pagination) IsFirstPage() bool {
if p.CurrentPage() <= 1 {
return true
}

return false
}

func (p *Pagination) IsLastPage() bool {
if p.CurrentPage() >= p.NumberOfPages() {
return true
}

return false
}

// NextPage returns the page number of the page after current page.
// If current page is the last in the list of pages, the last page number is returned.
func (p *Pagination) NextPage() int {
if p.CurrentPage() >= p.NumberOfPages() {
return p.NumberOfPages()
}

return p.CurrentPage() + 1
}

// IsCurrentPage checks a number to see if it matches the current page.
func (p *Pagination) IsCurrentPage(page int) bool {
return p.CurrentPage() == page
}

// Pages returns a list with all page numbers.
// Eg. [1 2 3 4 5]
func (p *Pagination) Pages() []int {
s := make([]int, 0, p.NumberOfPages())

for i := 1; i <= p.NumberOfPages(); i++ {
s = append(s, i)
}

return s
}

// Show returns true if the pagination should be used.
// Ie. if there is more than one page.
func (p *Pagination) Show() bool {
return p.NumberOfPages() > 1
}

// CurrentPage returns the current page.
func (p *Pagination) CurrentPage() int {
return p.currentPage
}

// NumberOfItems returns the number of items.
func (p *Pagination) NumberOfItems() int {
return p.numberOfItems
}

// ItemsPerPage returns the number of items to show per page.
func (p *Pagination) ItemsPerPage() int {
return p.itemsPerPage
}
22 changes: 15 additions & 7 deletions internal/vsd/vsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func UsrFeeds(app core.App, userId string) (*search.Result, error) {
return pbapi.RecordList(app, "usr_feed", fmt.Sprintf("filter=(user_id='%s')", userId), "feed_id,feed_id.domain_id")
}

func AllPosts(app core.App, userId string) (*search.Result, error) {
func AllPosts(app core.App, userId, page string) (*search.Result, error) {
td := time.Now().UTC().Add(-24 * time.Hour)
query := fmt.Sprintf(`pub_date>="%s" && (`,
td.Format("2006-01-02 15:04:05"))
Expand All @@ -193,26 +193,34 @@ func AllPosts(app core.App, userId string) (*search.Result, error) {
query += fmt.Sprintf(`feed_id="%s"`, feedId)
}
query += ")"
log.Println("AllPosts", query)
filter := "sort=-pub_date&perPage=100&filter=" + url.QueryEscape(query)
filter := ""
if page != "" {
filter += "page=" + page + "&"
}
//log.Println("filter", filter)
filter += "sort=-pub_date&filter=" + url.QueryEscape(query)
return pbapi.RecordList(app, "post", filter, "feed_id,feed_id.domain_id")
}

func Posts(app core.App, feedId, period string) (*search.Result, error) {
func Posts(app core.App, feedId, period, page string) (*search.Result, error) {
td := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.UTC)
tm := td.Add(24 * time.Hour)
switch period {
case "yesterday":
td = td.Add(-24 * time.Hour)
tm = tm.Add(-24 * time.Hour)
case "week":
td = td.Add(-24 * 7 * time.Hour)
td = td.Add(-24 * 9 * time.Hour)
tm = tm.Add(-24 * 2 * time.Hour)
}
query := fmt.Sprintf(`pub_date>="%s" && pub_date<"%s" && feed_id="%s"`,
td.Format("2006-01-02"), tm.Format("2006-01-02"), feedId)
//log.Println(query)

filter := "sort=-pub_date&perPage=100&filter=" + url.QueryEscape(query)
filter := ""
if page != "" {
filter += "page=" + page + "&"
}
filter += "sort=-pub_date&filter=" + url.QueryEscape(query)
return pbapi.RecordList(app, "post", filter, "feed_id")
}

Expand Down
12 changes: 8 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/tokens"
"github.com/recoilme/verysmartdog/internal/pagination"
"github.com/recoilme/verysmartdog/internal/vsd"
_ "github.com/recoilme/verysmartdog/migrations"
"github.com/recoilme/verysmartdog/pkg/pbapi"
Expand Down Expand Up @@ -73,10 +74,12 @@ func main() {
if authRecord, ok := c.Get(apis.ContextAuthRecordKey).(*models.Record); ok {
userId = authRecord.GetId()
}
result, err := vsd.AllPosts(app, userId)

result, err := vsd.AllPosts(app, userId, c.QueryParam("page"))
if err != nil {
c.Set("err", err.Error())
}
c.Set("pagination", pagination.New(result.TotalItems, result.PerPage, result.Page))
c.Set("posts", toJson(result)["items"])
//c.Set("err", "In development")
return c.Render(http.StatusOK, "main.html", siteData(c))
Expand Down Expand Up @@ -315,7 +318,7 @@ func siteData(c echo.Context) (siteData map[string]interface{}) {
siteData["userId"] = authRecord.GetId()
feedId := c.PathParams().Get("feedid", "-")
if feedId == "-" {
siteData["path"] = c.Request().URL.String()
siteData["path"] = "/" //c.Request().URL.String()
siteData["feedid"] = ""
} else {
siteData["path"] = "/feed"
Expand All @@ -327,7 +330,7 @@ func siteData(c echo.Context) (siteData map[string]interface{}) {
siteData["err"] = c.Get("err")
siteData["usr_feeds"] = c.Get("usr_feeds")
siteData["posts"] = c.Get("posts")

siteData["pagination"] = c.Get("pagination")
//log.Println(fmt.Sprintf("siteData:%+v", siteData))

return siteData
Expand All @@ -348,10 +351,11 @@ func posts(c echo.Context, app *pocketbase.PocketBase) {
feedId := c.PathParams().Get("feedid", "-")
period := c.PathParams().Get("period", "-")
if feedId != "-" {
result, err := vsd.Posts(app, feedId, period)
result, err := vsd.Posts(app, feedId, period, c.QueryParam("page"))
if err != nil {
c.Set("err", err.Error())
}
c.Set("pagination", pagination.New(result.TotalItems, result.PerPage, result.Page))
c.Set("posts", toJson(result)["items"])
}
}
Expand Down
31 changes: 30 additions & 1 deletion web_data/view/center.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,38 @@ <h3 class="text-lg font-bold text-gray-800 dark:text-white">{{.title}}</h3>
</div>
</a>
{{end}}
</div>
</div>
<div class="hidden lg:block w-80">
<!-- Right Page
<div class="p-4 ml-4 md:p-7 flex-auto text-sm text-gray-800 dark:text-gray-400 flex flex-col border rounded-xl">
<span class="p-1">Apps</span><span class="p-1">Erika Brodnock, Johannes Lenhard</span>
<span class="p-1">управление_разработкой управление_разработкой</span>
</div>
-->
</div>
</div>
{{end}}

{{ if .pagination.Show }}
<nav class="flex items-center space-x-2">
<a class="text-gray-400 hover:text-blue-600 p-4 inline-flex items-center gap-2 rounded-md {{if .pagination.IsFirstPage}}pointer-events-none {{end}}" href="?page={{.pagination.PreviousPage}}">
<span aria-hidden="true">«</span>
<span>Previous</span>
</a>
{{ range $page := .pagination.PagesStream }}
{{if $.pagination.IsCurrentPage $page}}
<a class="w-10 h-10 bg-blue-500 text-white p-4 inline-flex items-center text-sm font-medium rounded-full" href="?page={{$page}}" aria-current="page">{{$page}}</a>
{{else}}
<a class="w-10 h-10 text-gray-500 hover:text-blue-600 p-4 inline-flex items-center text-sm font-medium rounded-full" href="?page={{$page}}">{{$page}}</a>
{{end}}
{{end}}
<a class="text-gray-500 hover:text-blue-600 p-4 inline-flex items-center gap-2 rounded-md {{if .pagination.IsLastPage}}pointer-events-none {{end}}" href="?page={{.pagination.NextPage}}">
<span>Next</span>
<span aria-hidden="true">»</span>
</a>
</nav>
{{end}}

<!-- ========== END MAIN CONTENT ========== -->
<div id='sidebar-backdrop' class='hidden transition duration fixed inset-0 z-[47] bg-gray-900 bg-opacity-50 dark:bg-opacity-80'></div>

Expand Down

0 comments on commit cf8e8c1

Please sign in to comment.