201 lines
5.1 KiB
Elixir
201 lines
5.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 draft={@draft} upload={@uploads.files} />
|
|
<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}
|
|
draft_reply={dbg(@draft_replies[post.id])}
|
|
upload={@uploads.files}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
def mount(_params, _session, socket) do
|
|
socket =
|
|
socket
|
|
|> assign(:draft, %Postland.Draft{})
|
|
|> assign(:draft_replies, %{})
|
|
|> 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", %{"draft_body" => draft_body}, socket) do
|
|
{:ok, results} =
|
|
Postland.Activities.record_markdown_post(
|
|
draft_body,
|
|
socket.assigns.draft.cw,
|
|
socket.assigns.draft.attachments
|
|
)
|
|
|
|
new_posts =
|
|
results
|
|
|> Enum.filter(fn {_key, value} ->
|
|
is_struct(value, Postland.Object)
|
|
end)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:draft, %Postland.Draft{})
|
|
|> 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}, 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("show_reply_form", %{"post-id" => id}, socket) do
|
|
post = Objects.get_by_id(id)
|
|
|
|
draft_replies =
|
|
case Map.get(socket.assigns.draft_replies, id) do
|
|
nil ->
|
|
Map.put(socket.assigns.draft_replies, id, %Postland.Draft{})
|
|
|
|
_ ->
|
|
socket.assigns.draft_replies
|
|
end
|
|
|
|
{:noreply, socket |> assign(:draft_replies, draft_replies) |> stream_insert(:posts, post)}
|
|
end
|
|
|
|
def handle_event("change_post", %{"draft_body" => draft_body} = params, socket) do
|
|
cw = Map.get(params, "cw")
|
|
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:text, draft_body)
|
|
|> Map.put(:cw, cw)
|
|
|
|
{:noreply, socket |> assign(draft: draft)}
|
|
end
|
|
|
|
def handle_event("remove_attachment", %{"url" => url}, socket) do
|
|
attachments =
|
|
socket.assigns.draft.attachments
|
|
|> Enum.reject(fn %{"url" => attachment_url} -> attachment_url == url end)
|
|
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:attachments, attachments)
|
|
|
|
{:noreply, assign(socket, draft: draft)}
|
|
end
|
|
|
|
def handle_event("change_alt_text", %{"alt" => value, "url" => url}, socket) do
|
|
attachments =
|
|
socket.assigns.draft.attachments
|
|
|> Enum.map(fn
|
|
%{"url" => ^url} = attachment ->
|
|
Map.put(attachment, "name", value)
|
|
|
|
other ->
|
|
other
|
|
end)
|
|
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:attachments, attachments)
|
|
|
|
{:noreply, assign(socket, draft: draft)}
|
|
end
|
|
|
|
def handle_event("add_cw", _, socket) do
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:cw, "")
|
|
|
|
{:noreply, assign(socket, draft: draft)}
|
|
end
|
|
|
|
def handle_event("remove_cw", _, socket) do
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:cw, nil)
|
|
|
|
{:noreply, assign(socket, draft: draft)}
|
|
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.draft.attachments ++ [attachment]
|
|
|
|
draft =
|
|
socket.assigns.draft
|
|
|> Map.put(:attachments, attachments)
|
|
|
|
{:noreply, assign(socket, draft: draft)}
|
|
else
|
|
{:noreply, socket}
|
|
end
|
|
end
|
|
end
|