diff options
-rw-r--r-- | system/admin/handlers.go | 40 | ||||
-rw-r--r-- | system/api/handlers.go | 2 | ||||
-rw-r--r-- | system/db/content.go | 40 |
3 files changed, 67 insertions, 15 deletions
diff --git a/system/admin/handlers.go b/system/admin/handlers.go index 39e93fc..d9f6ce6 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -823,7 +823,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { Order: order, } - posts := db.Query(t+"_sorted", opts) + total, posts := db.Query(t+"_sorted", opts) b := &bytes.Buffer{} html := `<div class="col s9 card"> @@ -874,6 +874,10 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { q.Add("status", "public") } + // always start from top of results when changing public/pending + q.Del("count") + q.Del("offset") + q.Set("status", "public") publicURL := req.URL.Path + "?" + q.Encode() @@ -905,7 +909,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { case "pending": // get _pending posts of type t from the db - posts = db.Query(t+"_pending", opts) + _, posts = db.Query(t+"_pending", opts) html += `<div class="row externalable"> <span class="description">Status:</span> @@ -949,17 +953,29 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { b.Write([]byte(`</ul>`)) - pagination := ` - <ul class="pagination"> - <li class="disabled"><a href="#!"><i class="material-icons">chevron_left</i></a></li> - <li class="active"><a href="#!">1</a></li> - <li class="waves-effect"><a href="#!">2</a></li> - <li class="waves-effect"><a href="#!">3</a></li> - <li class="waves-effect"><a href="#!">4</a></li> - <li class="waves-effect"><a href="#!">5</a></li> - <li class="waves-effect"><a href="#!"><i class="material-icons">chevron_right</i></a></li> + statusDisabled := "disabled" + prevStatus := "" + nextStatus := "" + if offset == 0 { + prevStatus = statusDisabled + } + + if offset*count >= total { + nextStatus = statusDisabled + } + + urlFmt := req.URL.Path + "/admin/posts?count=%d&offset=%d&status=%s&type=%s" + prevURL := fmt.Sprintf(urlFmt, count, offset-1, status, t) + nextURL := fmt.Sprintf(urlFmt, count, offset+1, status, t) + start := 1 + count*offset + end := start + count + pagination := fmt.Sprintf(` + <ul class="pagination row"> + <li class="waves-effect col s4 %s"><a href="%s"><i class="material-icons">chevron_left</i></a></li> + <li class="col s4">%d to %d of %d</li> + <li class="waves-effect col s4 %s"><a href="%s"><i class="material-icons">chevron_right</i></a></li> </ul> - ` + `, prevStatus, prevURL, start, end, total, nextStatus, nextURL) b.Write([]byte(pagination + `</div></div>`)) diff --git a/system/api/handlers.go b/system/api/handlers.go index afe5819..1d7dc8f 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -72,7 +72,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { Order: order, } - bb := db.Query(t+"_sorted", opts) + _, bb := db.Query(t+"_sorted", opts) var result = []json.RawMessage{} for i := range bb { result = append(result, bb[i]) diff --git a/system/db/content.go b/system/db/content.go index 0cfadf4..76d95c5 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -215,8 +215,21 @@ type QueryOptions struct { } // Query retrieves a set of content from the db based on options -func Query(namespace string, opts QueryOptions) [][]byte { +// and returns the total number of content in the namespace and the content +func Query(namespace string, opts QueryOptions) (int, [][]byte) { var posts [][]byte + var total int + + // correct bad input rather than return nil or error + // similar to default case for opts.Order switch below + if opts.Count < 0 { + opts.Count = 0 + } + + if opts.Offset < 0 { + opts.Offset = 0 + } + store.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(namespace)) if b == nil { @@ -225,6 +238,12 @@ func Query(namespace string, opts QueryOptions) [][]byte { c := b.Cursor() n := b.Stats().KeyN + total = n + + // return nil if no content + if n == 0 { + return nil + } var start, end int switch opts.Count { @@ -279,12 +298,29 @@ func Query(namespace string, opts QueryOptions) [][]byte { i++ cur++ } + + default: + // results for DESC order + for k, v := c.First(); k != nil; k, v = c.Next() { + if cur < start { + cur++ + continue + } + + if cur >= end { + break + } + + posts = append(posts, v) + i++ + cur++ + } } return nil }) - return posts + return total, posts } // SortContent sorts all content of the type supplied as the namespace by time, |