157 lines
4.1 KiB
Elixir
157 lines
4.1 KiB
Elixir
defmodule PostlandWeb.TimelineLive do
|
|
use PostlandWeb, :live_view
|
|
|
|
alias Postland.Activities
|
|
alias Postland.Objects
|
|
|
|
def render(assigns) do
|
|
~H"""
|
|
<div id="timeline">
|
|
<.post_form post_content={@post} attachments={@attachments} upload={@uploads.files} cw={@cw} />
|
|
<div id="timeline-posts" phx-update="stream">
|
|
<div :for={{id, post} <- @streams.posts} id={id} class="mt-10">
|
|
<.post_card post={post} post_dom_id={id} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
def mount(_params, _session, socket) do
|
|
socket =
|
|
socket
|
|
|> assign(:post, "")
|
|
|> assign(:attachments, [])
|
|
|> assign(:cw, nil)
|
|
|> stream(:posts, Postland.Timeline.timeline())
|
|
|> allow_upload(:files,
|
|
accept: ["image/*"],
|
|
auto_upload: true,
|
|
progress: &handle_progress/3
|
|
)
|
|
|
|
{:ok, socket}
|
|
end
|
|
|
|
def handle_event("create_post", %{"post" => post}, socket) do
|
|
{:ok, results} =
|
|
Postland.Activities.record_markdown_post(
|
|
post,
|
|
socket.assigns.cw,
|
|
socket.assigns.attachments
|
|
)
|
|
|
|
new_posts =
|
|
results
|
|
|> Enum.filter(fn {_key, value} ->
|
|
is_struct(value, Postland.Object)
|
|
end)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:post, "")
|
|
|> assign(:attachments, [])
|
|
|> assign(:cw, nil)
|
|
|> then(fn socket ->
|
|
Enum.reduce(new_posts, socket, fn {_id, post}, socket ->
|
|
stream_insert(socket, :posts, post, at: 0)
|
|
end)
|
|
end)
|
|
|
|
{:noreply, socket}
|
|
end
|
|
|
|
def handle_event("delete_post", %{"post-id" => id, "post-dom-id" => dom_id}, socket) do
|
|
post = Objects.get_by_id(id)
|
|
|
|
case Activities.delete_post(post) do
|
|
{:ok, _} ->
|
|
{:noreply, socket |> stream_delete_by_dom_id(:posts, dom_id)}
|
|
|
|
_ ->
|
|
{:noreply, socket |> put_flash(:error, "An unexpected error has occurred.")}
|
|
end
|
|
end
|
|
|
|
def handle_event("like_post", %{"post-id" => id, "post-dom-id" => dom_id}, socket) do
|
|
post = Objects.get_by_id(id)
|
|
|
|
case Activities.like_post(post) do
|
|
{:ok, _} ->
|
|
post = Objects.get_by_id(id)
|
|
{:noreply, socket |> stream_insert(:posts, post)}
|
|
|
|
_ ->
|
|
{:noreply, socket |> put_flash(:error, "An unexpected error has occurred.")}
|
|
end
|
|
end
|
|
|
|
def handle_event("unlike_post", %{"post-id" => id, "post-dom-id" => dom_id}, socket) do
|
|
post = Objects.get_by_id(id)
|
|
|
|
case Activities.unlike_post(post) do
|
|
{:ok, _} ->
|
|
post = Objects.get_by_id(id)
|
|
{:noreply, socket |> stream_insert(:posts, post)}
|
|
|
|
_ ->
|
|
{:noreply, socket |> put_flash(:error, "An unexpected error has occurred.")}
|
|
end
|
|
end
|
|
|
|
def handle_event("change_post", %{"post" => post} = params, socket) do
|
|
cw = Map.get(params, "cw")
|
|
{:noreply, socket |> assign(post: post, cw: cw)}
|
|
end
|
|
|
|
def handle_event("remove_attachment", %{"url" => url}, socket) do
|
|
attachments =
|
|
socket.assigns.attachments
|
|
|> Enum.reject(fn %{"url" => attachment_url} -> attachment_url == url end)
|
|
|
|
{:noreply, assign(socket, attachments: attachments)}
|
|
end
|
|
|
|
def handle_event("change_alt_text", %{"alt" => value, "url" => url}, socket) do
|
|
attachments =
|
|
socket.assigns.attachments
|
|
|> Enum.map(fn
|
|
%{"url" => ^url} = attachment ->
|
|
Map.put(attachment, "name", value)
|
|
|
|
other ->
|
|
other
|
|
end)
|
|
|
|
{:noreply, assign(socket, attachments: attachments)}
|
|
end
|
|
|
|
def handle_event("add_cw", _, socket) do
|
|
{:noreply, assign(socket, cw: "")}
|
|
end
|
|
|
|
def handle_event("remove_cw", _, socket) do
|
|
{:noreply, assign(socket, cw: nil)}
|
|
end
|
|
|
|
def handle_progress(:files, entry, socket) do
|
|
if entry.done? do
|
|
uploaded_file =
|
|
consume_uploaded_entry(socket, entry, fn meta ->
|
|
Postland.Uploads.handle_upload(entry, meta)
|
|
end)
|
|
|
|
attachment = %{
|
|
"type" => "Document",
|
|
"mediaType" => entry.client_type,
|
|
"url" => unverified_url(PostlandWeb.Endpoint, uploaded_file),
|
|
"name" => nil
|
|
}
|
|
|
|
attachments = socket.assigns.attachments ++ [attachment]
|
|
{:noreply, assign(socket, attachments: attachments)}
|
|
else
|
|
{:noreply, socket}
|
|
end
|
|
end
|
|
end
|