101 lines
2.5 KiB
Elixir
101 lines
2.5 KiB
Elixir
defmodule Home73kWeb.BlogLive do
|
|
@moduledoc """
|
|
LiveView engine for Blog navigation
|
|
"""
|
|
use Home73kWeb, :live_view
|
|
|
|
alias Home73k.Blog
|
|
|
|
@page_size 7
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
{:ok, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_params(params, _url, socket) do
|
|
socket.assigns.live_action
|
|
|> init_per_live_action(socket, params)
|
|
|> live_noreply()
|
|
end
|
|
|
|
defp page_param_as_int(page) do
|
|
try do
|
|
String.to_integer(page)
|
|
rescue
|
|
_ -> nil
|
|
end
|
|
end
|
|
|
|
defp raise_not_found(msg), do: raise Home73k.Blog.NotFoundError, msg
|
|
|
|
defp init_per_live_action(:index, socket, _params) do
|
|
socket
|
|
|> assign(:page_title, "Blog")
|
|
|> assign(:posts, get_posts_for_page!(1))
|
|
|> assign(:page_count, get_page_count())
|
|
|> assign_prev_next(1)
|
|
end
|
|
|
|
defp init_per_live_action(:page, socket, %{"page" => page}) do
|
|
page_int = page_param_as_int(page)
|
|
page_count = get_page_count()
|
|
|
|
cond do
|
|
is_nil(page_int) || page_int <= 1 ->
|
|
push_patch(socket, to: Routes.blog_path(socket, :index))
|
|
|
|
page_int > page_count ->
|
|
raise_not_found("there are only #{page_count} pages of posts")
|
|
|
|
true ->
|
|
posts = get_posts_for_page!(page_int)
|
|
|
|
socket
|
|
|> assign(:page_title, "Blog \\ Page #{page}")
|
|
|> assign(:posts, posts)
|
|
|> assign(:page_count, page_count)
|
|
|> assign_prev_next(page_int)
|
|
end
|
|
end
|
|
|
|
defp init_per_live_action(:show, socket, %{"id" => id}) do
|
|
post = Blog.get_post_by_id!(id)
|
|
socket
|
|
|> assign(:page_title, "Blog \\ #{post.title}")
|
|
|> assign(:posts, [post])
|
|
|> assign(:page_count, nil)
|
|
|> assign_prev_next(0)
|
|
end
|
|
|
|
defp init_per_live_action(:tag, socket, %{"tag" => tag}) do
|
|
socket
|
|
|> assign(:page_title, "Blog \\ ##{tag}")
|
|
|> assign(:posts, Blog.get_posts_by_tag!(tag))
|
|
|> assign(:page_count, get_page_count())
|
|
|> assign_prev_next(1)
|
|
end
|
|
|
|
|
|
defp get_posts_for_page!(1), do: Blog.list_posts() |> Enum.take(@page_size)
|
|
|
|
defp get_posts_for_page!(page_int) do
|
|
Blog.list_posts()
|
|
|> Stream.chunk_every(@page_size)
|
|
|> Enum.at(page_int - 1)
|
|
end
|
|
|
|
defp get_page_count, do: Kernel.ceil(Blog.post_count() / @page_size)
|
|
|
|
defp assign_prev_next(socket, page_int) do
|
|
socket
|
|
|> assign(:page_prev, page_int < socket.assigns.page_count && page_int + 1 || nil)
|
|
|> assign(:page_next, page_int > 1 && page_int - 1 || nil)
|
|
end
|
|
|
|
|
|
def format_date(date) do
|
|
Calendar.strftime(date, "%B %-d, %Y")
|
|
end
|
|
end
|