defmodule PostlandWeb.TimelineLive do use PostlandWeb, :live_view alias Postland.Activities alias Postland.Objects def render(assigns) do ~H"""
<.post_form draft={@draft} upload={@uploads.files} />
<.post_card post={post} post_dom_id={id} draft_reply={dbg(@draft_replies[post.id])} upload={@uploads.files} />
""" 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