; feed/page — pagination. Offset/limit for indexed access, and cursor-based
; (by :at) for recency feeds, which is stable under inserts: a cursor is the
; :at of the last item seen, and the next page is the newest items older than it.
;
; Requires: lib/feed/stream.sx (feed/recent, feed/take, feed/filter).

; --- offset / limit ---------------------------------------------------------

(define
  feed/page
  (fn
    (stream offset limit)
    (feed/stream (take (drop (feed/items stream) offset) limit))))

(define
  feed/page-count
  (fn (stream limit) (ceil (/ (feed/count stream) limit))))

; --- cursor (recency feeds) -------------------------------------------------

; activities strictly older than cursor (scroll down / load older)
(define
  feed/before
  (fn
    (stream cursor)
    (feed/filter stream (fn (a) (< (get a :at) cursor)))))

; activities strictly newer than cursor (load newer / "N new posts")
(define
  feed/after
  (fn
    (stream cursor)
    (feed/filter stream (fn (a) (> (get a :at) cursor)))))

; one page: the `limit` newest activities older than cursor, newest first
(define
  feed/page-before
  (fn
    (stream cursor limit)
    (feed/take (feed/recent (feed/before stream cursor)) limit)))

; cursor to fetch the next (older) page: :at of the last item of a page,
; or nil when the page is empty (end of feed)
(define
  feed/next-cursor
  (fn
    (page)
    (let
      ((items (feed/items page)))
      (if (= (len items) 0) nil (get (last items) :at)))))
