diff --git a/lib/pinchflat/utils/number_utils.ex b/lib/pinchflat/utils/number_utils.ex
new file mode 100644
index 0000000..fcfb296
--- /dev/null
+++ b/lib/pinchflat/utils/number_utils.ex
@@ -0,0 +1,12 @@
+defmodule Pinchflat.Utils.NumberUtils do
+ @moduledoc """
+ Utility methods for working with numbers
+ """
+
+ # TODO: test
+ def clamp(num, minimum, maximum) do
+ num
+ |> max(minimum)
+ |> min(maximum)
+ end
+end
diff --git a/lib/pinchflat_web/components/custom_components/table_components.ex b/lib/pinchflat_web/components/custom_components/table_components.ex
index fbe897c..c1bdc09 100644
--- a/lib/pinchflat_web/components/custom_components/table_components.ex
+++ b/lib/pinchflat_web/components/custom_components/table_components.ex
@@ -2,6 +2,8 @@ defmodule PinchflatWeb.CustomComponents.TableComponents do
@moduledoc false
use Phoenix.Component
+ alias PinchflatWeb.CoreComponents
+
@doc """
Renders a table component with the given rows and columns.
@@ -50,4 +52,45 @@ defmodule PinchflatWeb.CustomComponents.TableComponents do
"""
end
+
+ attr :page_number, :integer, default: 1
+ attr :total_pages, :integer, default: 1
+
+ def pagination_controls(assigns) do
+ ~H"""
+
+ """
+ end
end
diff --git a/lib/pinchflat_web/controllers/sources/source_html/pending_table_live.ex b/lib/pinchflat_web/controllers/sources/source_html/pending_table_live.ex
new file mode 100644
index 0000000..bc4512f
--- /dev/null
+++ b/lib/pinchflat_web/controllers/sources/source_html/pending_table_live.ex
@@ -0,0 +1,83 @@
+defmodule Pinchflat.PendingTableLive do
+ use PinchflatWeb, :live_view
+ import Ecto.Query, warn: false
+
+ alias Pinchflat.Repo
+ alias Pinchflat.Sources
+ alias Pinchflat.Media.MediaQuery
+ alias Pinchflat.Utils.NumberUtils
+
+ @limit 10
+
+ def render(%{records: []} = assigns) do
+ ~H"""
+
Nothing Here!
+ """
+ end
+
+ def render(assigns) do
+ ~H"""
+
+
+ Showing <%= length(@records) %> of <%= @total_record_count %>
+
+ <.table rows={@records} table_class="text-black dark:text-white">
+ <:col :let={media_item} label="Title">
+ <.subtle_link href={~p"/sources/#{@source.id}/media/#{media_item.id}"}>
+ <%= StringUtils.truncate(media_item.title, 50) %>
+
+
+ <:col :let={media_item} label="" class="flex place-content-evenly">
+ <.icon_link href={~p"/sources/#{@source.id}/media/#{media_item.id}"} icon="hero-eye" class="mx-1" />
+ <.icon_link href={~p"/sources/#{@source.id}/media/#{media_item.id}/edit"} icon="hero-pencil-square" class="mx-1" />
+
+
+
+ <.pagination_controls page_number={@page} total_pages={@total_pages} />
+
+
+ """
+ end
+
+ def mount(_params, session, socket) do
+ page = 1
+ source = Sources.get_source!(session["source_id"])
+ base_query = generate_base_query(source)
+ pagination_attrs = fetch_pagination_attributes(base_query, page)
+
+ {:ok, assign(socket, Map.merge(pagination_attrs, %{base_query: base_query, source: source}))}
+ end
+
+ def handle_event("page_change", %{"direction" => direction}, %{assigns: assigns} = socket) do
+ direction = if direction == "inc", do: 1, else: -1
+ new_page = assigns.page + direction
+ new_assigns = fetch_pagination_attributes(assigns.base_query, new_page)
+
+ {:noreply, assign(socket, new_assigns)}
+ end
+
+ defp fetch_pagination_attributes(base_query, page) do
+ total_record_count = Repo.aggregate(base_query, :count, :id)
+ total_pages = ceil(total_record_count / @limit)
+ page = NumberUtils.clamp(page, 1, total_pages)
+ records = fetch_records(base_query, page)
+
+ %{page: page, total_pages: total_pages, records: records, total_record_count: total_record_count}
+ end
+
+ defp generate_base_query(source) do
+ MediaQuery.new()
+ |> MediaQuery.for_source(source)
+ |> MediaQuery.where_pending_download()
+ |> order_by(desc: :id)
+ end
+
+ defp fetch_records(base_query, page) do
+ offset = (page - 1) * @limit
+
+ base_query
+ |> limit(^@limit)
+ |> offset(^offset)
+ |> Repo.all()
+ end
+end
diff --git a/lib/pinchflat_web/controllers/sources/source_html/show.html.heex b/lib/pinchflat_web/controllers/sources/source_html/show.html.heex
index d9687a1..3c4bc7f 100644
--- a/lib/pinchflat_web/controllers/sources/source_html/show.html.heex
+++ b/lib/pinchflat_web/controllers/sources/source_html/show.html.heex
@@ -37,26 +37,7 @@
<:tab title="Pending Media">
- <%= if match?([_|_], @pending_media) do %>
- Shows a maximum of 100 media items
- <.table rows={@pending_media} table_class="text-black dark:text-white">
- <:col :let={media_item} label="Title">
- <.subtle_link href={~p"/sources/#{@source.id}/media/#{media_item.id}"}>
- <%= StringUtils.truncate(media_item.title, 50) %>
-
-
- <:col :let={media_item} label="" class="flex place-content-evenly">
- <.icon_link href={~p"/sources/#{@source.id}/media/#{media_item.id}"} icon="hero-eye" class="mx-1" />
- <.icon_link
- href={~p"/sources/#{@source.id}/media/#{media_item.id}/edit"}
- icon="hero-pencil-square"
- class="mx-1"
- />
-
-
- <% else %>
- Nothing Here!
- <% end %>
+ <%= live_render(@conn, Pinchflat.PendingTableLive, session: %{"source_id" => @source.id}) %>
<:tab title="Downloaded Media">
<%= if match?([_|_], @downloaded_media) do %>