Add item pagination
This commit is contained in:
parent
3eeef799ad
commit
2a3c085fef
|
@ -0,0 +1,28 @@
|
|||
defmodule Frenzy.Paginator do
|
||||
import Ecto.Query
|
||||
alias Frenzy.{Repo, Item}
|
||||
|
||||
@spec paginate(query :: Ecto.Queryable.t(), params :: map()) :: Ecto.Query.t()
|
||||
|
||||
def paginate(query, %{"before" => before_id}) do
|
||||
before = Repo.get(Item, before_id)
|
||||
|
||||
query
|
||||
# |> where([o], o.id < ^before_id)
|
||||
|> where([i], i.date < ^before.date)
|
||||
|> order_by(desc: :date)
|
||||
end
|
||||
|
||||
def paginate(query, %{"after" => after_id}) do
|
||||
after_item = Repo.get(Item, after_id)
|
||||
|
||||
query
|
||||
|> where([i], i.date > ^after_item.date)
|
||||
|> order_by(asc: :date)
|
||||
end
|
||||
|
||||
def paginate(query, _) do
|
||||
query
|
||||
|> order_by(desc: :date)
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
defmodule FrenzyWeb.FeedController do
|
||||
use FrenzyWeb, :controller
|
||||
alias Frenzy.{Repo, Group, Feed, Item, Pipeline}
|
||||
alias Frenzy.{Repo, Group, Feed, Item, Pipeline, Paginator}
|
||||
alias FrenzyWeb.Router.Helpers, as: Routes
|
||||
alias FrenzyWeb.Endpoint
|
||||
import Ecto.Query
|
||||
|
@ -25,9 +25,18 @@ defmodule FrenzyWeb.FeedController do
|
|||
|
||||
defp user_owns_feed(conn, _opts), do: conn
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
def show(conn, %{"id" => id} = params) do
|
||||
feed = conn.assigns[:feed]
|
||||
items = Repo.all(from Item, where: [feed_id: ^id, tombstone: false], order_by: [desc: :date])
|
||||
|
||||
items =
|
||||
Item
|
||||
|> where([i], i.feed_id == ^id)
|
||||
|> Paginator.paginate(params)
|
||||
|> limit(50)
|
||||
|> Repo.all()
|
||||
|> Enum.sort_by(fn item -> item.date end, fn a, b ->
|
||||
DateTime.compare(a, b) == :gt
|
||||
end)
|
||||
|
||||
render(conn, "show.html", %{
|
||||
feed: feed,
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
<h3 class="mt-4">Items</h3>
|
||||
|
||||
<%= unless is_nil(prev_page_path(@conn, @items)) do %>
|
||||
<p class="text-center">
|
||||
<a href="<%= prev_page_path(@conn, @items) %>" class="pagination-link">Newer</a>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<%= for item <- @items do %>
|
||||
|
@ -34,3 +40,9 @@
|
|||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= unless is_nil(next_page_path(@conn, @items)) do %>
|
||||
<p class="text-center">
|
||||
<a href="<%= next_page_path(@conn, @items) %>" class="pagination-link">Older</a>
|
||||
</p>
|
||||
<% end %>
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
defmodule FrenzyWeb.FeedView do
|
||||
use FrenzyWeb, :view
|
||||
alias Frenzy.{Repo, Item}
|
||||
import Ecto.Query
|
||||
|
||||
@spec next_page_path(Plug.Conn.t(), [Frenzy.Item.t()]) :: String.t()
|
||||
defp next_page_path(conn, items) do
|
||||
%Item{id: id, date: date} = List.last(items)
|
||||
has_older = Repo.exists?(from i in Item, where: i.date < ^date)
|
||||
|
||||
if has_older do
|
||||
Phoenix.Controller.current_path(conn, %{before: id})
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@spec prev_page_path(Plug.Conn.t(), [Frenzy.Item.t()]) :: String.t()
|
||||
defp prev_page_path(conn, [%Item{id: id, date: date} | _]) do
|
||||
has_newer = Repo.exists?(from i in Item, where: i.date > ^date)
|
||||
|
||||
if has_newer do
|
||||
Phoenix.Controller.current_path(conn, %{after: id})
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue