home73k/lib/home73k_web/live/blog_live.ex

102 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