2023-03-31 17:00:09 +02:00
|
|
|
defmodule ChiyaWeb.PublicComponents do
|
|
|
|
use Phoenix.Component
|
|
|
|
|
|
|
|
use Phoenix.VerifiedRoutes,
|
|
|
|
endpoint: ChiyaWeb.Endpoint,
|
|
|
|
router: ChiyaWeb.Router,
|
|
|
|
statics: ChiyaWeb.static_paths()
|
|
|
|
|
2023-05-07 10:30:32 +02:00
|
|
|
import ChiyaWeb.Format
|
2023-05-21 09:54:38 +02:00
|
|
|
import ChiyaWeb.Markdown, only: [render: 1]
|
|
|
|
import Phoenix.HTML, only: [raw: 1]
|
2023-05-22 21:05:33 +02:00
|
|
|
import ChiyaWeb.CoreComponents
|
2023-05-07 10:30:32 +02:00
|
|
|
|
2023-05-22 20:05:44 +02:00
|
|
|
@doc """
|
|
|
|
Renders a middot as divider
|
|
|
|
"""
|
2023-05-25 21:23:04 +02:00
|
|
|
def dot(assigns),
|
|
|
|
do: ~H"""
|
2023-05-22 20:05:44 +02:00
|
|
|
<span class="text-theme-primary font-bold">·</span>
|
|
|
|
"""
|
|
|
|
|
2023-03-31 17:00:09 +02:00
|
|
|
@doc """
|
|
|
|
Renders a horizontal line
|
|
|
|
"""
|
2023-05-25 21:23:04 +02:00
|
|
|
def line(assigns),
|
|
|
|
do: ~H"""
|
2023-04-13 23:52:01 +02:00
|
|
|
<hr class="my-6 border-theme-base/20" />
|
|
|
|
"""
|
2023-05-22 20:05:44 +02:00
|
|
|
|
2023-06-03 09:26:45 +02:00
|
|
|
attr :text, :string, default: "⌘"
|
2023-06-03 09:27:43 +02:00
|
|
|
|
2023-06-03 09:26:45 +02:00
|
|
|
def divider(assigns) do
|
|
|
|
~H"""
|
2023-06-03 11:47:55 +02:00
|
|
|
<div class="flex items-center my-8 text-theme-base/75 before:flex-1 after:flex-1 before:content-[''] after:content-[''] before:p-[0.5px] after:p-[0.5px] before:bg-theme-base/25 after:bg-theme-base/25 w-full mx-auto last:hidden">
|
2023-06-03 09:26:45 +02:00
|
|
|
<%= assigns.text %>
|
|
|
|
</div>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
2023-04-13 23:52:01 +02:00
|
|
|
@doc """
|
2023-05-21 22:45:06 +02:00
|
|
|
Renders a note-header with title.
|
2023-04-13 23:52:01 +02:00
|
|
|
"""
|
|
|
|
attr :class, :string, default: nil
|
|
|
|
attr :inline, :boolean, default: false
|
|
|
|
|
|
|
|
slot :inner_block, required: true
|
|
|
|
slot :subtitle
|
|
|
|
slot :actions
|
|
|
|
|
|
|
|
def header(assigns) do
|
|
|
|
~H"""
|
|
|
|
<header class={[@actions != [] && "flex items-center justify-between gap-6", @class]}>
|
|
|
|
<div>
|
|
|
|
<h1 class="text-lg font-semibold leading-8 text-gray-800 dark:text-gray-200">
|
|
|
|
<%= render_slot(@inner_block) %>
|
2023-04-29 09:43:34 +02:00
|
|
|
<span :if={@inline} class="text-sm leading-6 font-normal text-gray-600 dark:text-gray-400">
|
|
|
|
<%= render_slot(@subtitle) %>
|
|
|
|
</span>
|
2023-04-13 23:52:01 +02:00
|
|
|
</h1>
|
2023-04-29 09:43:34 +02:00
|
|
|
<p
|
|
|
|
:if={@subtitle != [] && @inline == false}
|
|
|
|
class="mt-2 text-sm leading-6 text-gray-600 dark:text-gray-400"
|
|
|
|
>
|
2023-04-13 23:52:01 +02:00
|
|
|
<%= render_slot(@subtitle) %>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="flex-none"><%= render_slot(@actions) %></div>
|
|
|
|
</header>
|
2023-03-31 17:00:09 +02:00
|
|
|
"""
|
|
|
|
end
|
2023-05-07 10:30:32 +02:00
|
|
|
|
|
|
|
attr :layout, :atom, default: :list
|
|
|
|
attr :notes, :list, required: true
|
|
|
|
|
|
|
|
def note_list(assigns) do
|
|
|
|
case assigns.layout do
|
|
|
|
:gallery ->
|
|
|
|
~H"""
|
|
|
|
<section class="note-list gallery | mt-6">
|
|
|
|
<%= for note <- assigns.notes do %>
|
|
|
|
<article>
|
|
|
|
<section class="flex flex-wrap justify-start gap-3">
|
|
|
|
<%= for image <- note.images do %>
|
|
|
|
<a
|
2023-06-03 09:26:45 +02:00
|
|
|
href={ChiyaWeb.Helpers.image_url(image, :full)}
|
2023-05-07 10:30:32 +02:00
|
|
|
class="lightbox | w-28"
|
|
|
|
data-gallery={gallery_name(note)}
|
|
|
|
data-description={ChiyaWeb.Markdown.render(image.content)}
|
|
|
|
>
|
2023-06-03 09:27:43 +02:00
|
|
|
<img src={ChiyaWeb.Helpers.image_url(image, :thumb)} loading="lazy" />
|
2023-05-07 10:30:32 +02:00
|
|
|
</a>
|
|
|
|
<% end %>
|
|
|
|
</section>
|
|
|
|
<a
|
2023-06-02 07:07:22 +02:00
|
|
|
href={~p"/note/#{note.slug}"}
|
2023-05-20 23:50:53 +02:00
|
|
|
class="text-theme-secondary text-lg/10 font-semibold rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-secondary/10 transition"
|
2023-05-07 10:30:32 +02:00
|
|
|
>
|
|
|
|
<%= note.name %>
|
2023-05-20 23:50:53 +02:00
|
|
|
<span class="text-theme-base/75 text-sm">
|
2023-05-07 10:30:32 +02:00
|
|
|
<%= pretty_date(note.published_at) %>
|
|
|
|
</span>
|
|
|
|
</a>
|
|
|
|
</article>
|
|
|
|
|
|
|
|
<.line />
|
|
|
|
<% end %>
|
|
|
|
</section>
|
|
|
|
"""
|
|
|
|
|
2023-05-21 09:54:38 +02:00
|
|
|
:microblog ->
|
2023-05-07 10:30:32 +02:00
|
|
|
~H"""
|
2023-05-21 09:54:38 +02:00
|
|
|
<section class="note-list microblog | mt-6 text-theme-base">
|
|
|
|
<%= for note <- assigns.notes do %>
|
2023-06-03 09:26:45 +02:00
|
|
|
<article class="mt-4 first:mt-0">
|
|
|
|
<% image = main_image(note) %>
|
|
|
|
<%= if image do %>
|
|
|
|
<figure class="mb-4">
|
2023-06-03 09:27:43 +02:00
|
|
|
<img
|
|
|
|
src={ChiyaWeb.Helpers.image_url(image, :full)}
|
|
|
|
class="rounded"
|
|
|
|
title={image.content}
|
|
|
|
/>
|
2023-06-03 09:26:45 +02:00
|
|
|
</figure>
|
|
|
|
<% end %>
|
|
|
|
|
2023-05-21 09:54:38 +02:00
|
|
|
<div class="prose prose-gruvbox">
|
2023-05-25 21:23:04 +02:00
|
|
|
<%= raw(render(note.content)) %>
|
2023-05-21 09:54:38 +02:00
|
|
|
</div>
|
2023-05-23 22:19:37 +02:00
|
|
|
<footer class="mt-1">
|
|
|
|
<time class="text-theme-base/75">
|
|
|
|
<%= pretty_datetime(note.published_at) %>
|
|
|
|
</time>
|
2023-05-22 21:05:33 +02:00
|
|
|
<.dot />
|
2023-06-02 07:07:22 +02:00
|
|
|
<a href={~p"/note/#{note.slug}"} class="text-theme-base/75">Permalink</a>
|
2023-05-23 22:19:37 +02:00
|
|
|
<%= if not Enum.empty?(note.images) do %>
|
|
|
|
<.dot />
|
|
|
|
<.icon name="hero-photo" />
|
|
|
|
<% end %>
|
|
|
|
</footer>
|
2023-05-21 09:54:38 +02:00
|
|
|
</article>
|
2023-06-03 09:26:45 +02:00
|
|
|
|
|
|
|
<.divider />
|
2023-05-21 09:54:38 +02:00
|
|
|
<% end %>
|
|
|
|
</section>
|
|
|
|
"""
|
|
|
|
|
2023-05-25 21:23:04 +02:00
|
|
|
# default, show headings only
|
|
|
|
_ ->
|
2023-05-21 09:54:38 +02:00
|
|
|
~H"""
|
|
|
|
<section class="note-list default | mt-6 sm:w-auto flex flex-col gap-1.5">
|
2023-05-07 10:30:32 +02:00
|
|
|
<%= for note <- assigns.notes do %>
|
|
|
|
<a
|
2023-06-02 07:07:22 +02:00
|
|
|
href={~p"/note/#{note.slug}"}
|
2023-05-20 23:50:53 +02:00
|
|
|
class="rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-secondary/10 transition"
|
2023-05-07 10:30:32 +02:00
|
|
|
>
|
2023-05-20 23:50:53 +02:00
|
|
|
<span class="text-theme-secondary text-lg font-semibold leading-8">
|
2023-05-07 10:30:32 +02:00
|
|
|
<%= note.name %>
|
|
|
|
</span>
|
2023-05-20 23:50:53 +02:00
|
|
|
<span class="text-theme-base/75 text-sm"><%= pretty_date(note.published_at) %></span>
|
2023-05-07 10:30:32 +02:00
|
|
|
</a>
|
|
|
|
<% end %>
|
|
|
|
</section>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-06-11 20:49:18 +02:00
|
|
|
def comment_form(assigns) do
|
|
|
|
~H"""
|
2023-06-11 22:22:22 +02:00
|
|
|
<.simple_form :let={f} for={@changeset} action="" class="bg-theme-background -m-3">
|
2023-06-11 20:49:18 +02:00
|
|
|
<.error :if={@changeset.action}>
|
|
|
|
Oops, something went wrong! Please check the errors below.
|
|
|
|
</.error>
|
|
|
|
<.input
|
|
|
|
field={f[:author_name]}
|
|
|
|
type="text"
|
|
|
|
placeholder="Name"
|
|
|
|
class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/40 dark:placeholder-theme-base/60 dark:focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
|
|
|
/>
|
|
|
|
<.input
|
|
|
|
field={f[:content]}
|
|
|
|
type="textarea"
|
|
|
|
placeholder="Content"
|
|
|
|
rows="3"
|
|
|
|
class="bg-theme-background dark:bg-theme-background border-theme-base/20 dark:border-theme-base/20 text-theme-base dark:text-theme-base placeholder-theme-base/60 dark:placeholder-theme-base/60 focus:border-theme-base/60 dark:focus:border-theme-base/60"
|
|
|
|
/>
|
|
|
|
<.input field={f[:note_id]} type="hidden" />
|
|
|
|
<:actions>
|
|
|
|
<.button>Submit Comment</.button>
|
|
|
|
</:actions>
|
|
|
|
</.simple_form>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
|
|
|
def comment_list(assigns) do
|
|
|
|
~H"""
|
|
|
|
<%= if not Enum.empty?(assigns.note.comments) do %>
|
|
|
|
<.line />
|
|
|
|
|
|
|
|
<h2 class="mb-6 text-theme-base"><%= Enum.count(assigns.note.comments) %> Comments</h2>
|
|
|
|
|
|
|
|
<aside id="comments" class="flex flex-col gap-6">
|
|
|
|
<%= for comment <- assigns.note.comments do %>
|
|
|
|
<article class="text-theme-base bg-theme-base/10 p-1">
|
|
|
|
<header class="flex flex-row justify-between">
|
|
|
|
<strong class="text-theme-primary"><%= comment.author_name %></strong>
|
|
|
|
<span class="text-theme-dim"><%= from_now(comment.inserted_at) %></span>
|
|
|
|
</header>
|
|
|
|
<p><%= comment.content %></p>
|
|
|
|
</article>
|
|
|
|
<% end %>
|
|
|
|
</aside>
|
|
|
|
<% else %>
|
|
|
|
<.line />
|
|
|
|
|
|
|
|
<h2 class="mb-6 text-theme-base">No comments yet.</h2>
|
|
|
|
<% end %>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
2023-05-07 10:30:32 +02:00
|
|
|
defp gallery_name(note), do: "gallery-#{note.id}"
|
2023-06-03 09:26:45 +02:00
|
|
|
|
|
|
|
defp main_image(note),
|
|
|
|
do:
|
|
|
|
note.images
|
|
|
|
|> Enum.filter(fn image -> image.featured end)
|
|
|
|
|> List.first()
|
2023-03-31 17:00:09 +02:00
|
|
|
end
|