diff --git a/README.md b/README.md index fb426fc..deb1df6 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,15 @@ # Roadmap +## Individual Post Page + +- [ ] Show post +- [~] Reply to post + - [ ] Allow drafting replies + - [ ] CW on reply + - [ ] Upload attachments on replies +- [ ] Show replies to post (chronological order) + ## Posting - [ ] Making polls @@ -51,12 +60,6 @@ - [ ] Displaying polls - [ ] Voting in polls -## Individual Post Page - -- [ ] Show post -- [ ] Reply to post -- [ ] Show replies to post (chronological order) - ## DMs - [ ] Receiving DMs diff --git a/lib/postland/draft.ex b/lib/postland/draft.ex new file mode 100644 index 0000000..7be8320 --- /dev/null +++ b/lib/postland/draft.ex @@ -0,0 +1,3 @@ +defmodule Postland.Draft do + defstruct text: "", cw: nil, attachments: [] +end diff --git a/lib/postland_web/components/core_components.ex b/lib/postland_web/components/core_components.ex index af1693f..bdff031 100644 --- a/lib/postland_web/components/core_components.ex +++ b/lib/postland_web/components/core_components.ex @@ -98,6 +98,9 @@ defmodule PostlandWeb.CoreComponents do """ end + attr :draft, :any, required: true + attr :upload, :any, required: true + def post_form(assigns) do user = Postland.Accounts.solo_user() @@ -119,12 +122,12 @@ defmodule PostlandWeb.CoreComponents do
<.form phx-submit="create_post" phx-change="change_post" id="create-post-form"> -
+
<.icon name="hero-exclamation-triangle" /> @@ -132,14 +135,14 @@ defmodule PostlandWeb.CoreComponents do + ><%= @draft.text %>
-
+
<.attachment_edit attachment={attachment} id={attachment["url"]} />
@@ -160,7 +163,7 @@ defmodule PostlandWeb.CoreComponents do
<.icon name="hero-exclamation-triangle" class="relative top-0.5" />
@@ -294,6 +297,16 @@ defmodule PostlandWeb.CoreComponents do > <.icon name="hero-star" /> + + <.icon name="hero-arrow-turn-up-left" /> + + <.post_form :if={@draft_reply} draft={@draft_reply} upload={@upload} />
diff --git a/lib/postland_web/live/timeline_live.ex b/lib/postland_web/live/timeline_live.ex index 8795dcd..7879237 100644 --- a/lib/postland_web/live/timeline_live.ex +++ b/lib/postland_web/live/timeline_live.ex @@ -7,10 +7,15 @@ defmodule PostlandWeb.TimelineLive do def render(assigns) do ~H"""
- <.post_form post_content={@post} attachments={@attachments} upload={@uploads.files} cw={@cw} /> + <.post_form draft={@draft} upload={@uploads.files} />
- <.post_card post={post} post_dom_id={id} /> + <.post_card + post={post} + post_dom_id={id} + draft_reply={dbg(@draft_replies[post.id])} + upload={@uploads.files} + />
@@ -20,9 +25,8 @@ defmodule PostlandWeb.TimelineLive do def mount(_params, _session, socket) do socket = socket - |> assign(:post, "") - |> assign(:attachments, []) - |> assign(:cw, nil) + |> assign(:draft, %Postland.Draft{}) + |> assign(:draft_replies, %{}) |> stream(:posts, Postland.Timeline.timeline()) |> allow_upload(:files, accept: ["image/*"], @@ -33,12 +37,12 @@ defmodule PostlandWeb.TimelineLive do {:ok, socket} end - def handle_event("create_post", %{"post" => post}, socket) do + def handle_event("create_post", %{"draft_body" => draft_body}, socket) do {:ok, results} = Postland.Activities.record_markdown_post( - post, - socket.assigns.cw, - socket.assigns.attachments + draft_body, + socket.assigns.draft.cw, + socket.assigns.draft.attachments ) new_posts = @@ -49,9 +53,7 @@ defmodule PostlandWeb.TimelineLive do socket = socket - |> assign(:post, "") - |> assign(:attachments, []) - |> assign(:cw, nil) + |> assign(:draft, %Postland.Draft{}) |> then(fn socket -> Enum.reduce(new_posts, socket, fn {_id, post}, socket -> stream_insert(socket, :posts, post, at: 0) @@ -86,7 +88,7 @@ defmodule PostlandWeb.TimelineLive do end end - def handle_event("unlike_post", %{"post-id" => id, "post-dom-id" => dom_id}, socket) do + def handle_event("unlike_post", %{"post-id" => id}, socket) do post = Objects.get_by_id(id) case Activities.unlike_post(post) do @@ -99,22 +101,47 @@ defmodule PostlandWeb.TimelineLive do end end - def handle_event("change_post", %{"post" => post} = params, socket) do + 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") - {:noreply, socket |> assign(post: post, cw: 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.attachments + socket.assigns.draft.attachments |> Enum.reject(fn %{"url" => attachment_url} -> attachment_url == url end) - {:noreply, assign(socket, attachments: attachments)} + 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.attachments + socket.assigns.draft.attachments |> Enum.map(fn %{"url" => ^url} = attachment -> Map.put(attachment, "name", value) @@ -123,15 +150,27 @@ defmodule PostlandWeb.TimelineLive do other end) - {:noreply, assign(socket, attachments: attachments)} + draft = + socket.assigns.draft + |> Map.put(:attachments, attachments) + + {:noreply, assign(socket, draft: draft)} end def handle_event("add_cw", _, socket) do - {:noreply, assign(socket, cw: "")} + draft = + socket.assigns.draft + |> Map.put(:cw, "") + + {:noreply, assign(socket, draft: draft)} end def handle_event("remove_cw", _, socket) do - {:noreply, assign(socket, cw: nil)} + draft = + socket.assigns.draft + |> Map.put(:cw, nil) + + {:noreply, assign(socket, draft: draft)} end def handle_progress(:files, entry, socket) do @@ -148,8 +187,13 @@ defmodule PostlandWeb.TimelineLive do "name" => nil } - attachments = socket.assigns.attachments ++ [attachment] - {:noreply, assign(socket, attachments: attachments)} + attachments = socket.assigns.draft.attachments ++ [attachment] + + draft = + socket.assigns.draft + |> Map.put(:attachments, attachments) + + {:noreply, assign(socket, draft: draft)} else {:noreply, socket} end diff --git a/mix.exs b/mix.exs index fc77233..0bd5ef6 100644 --- a/mix.exs +++ b/mix.exs @@ -46,7 +46,7 @@ defmodule Postland.MixProject do {:tailwind, "~> 0.2", runtime: Mix.env() == :dev}, {:heroicons, github: "tailwindlabs/heroicons", - tag: "v2.1.1", + tag: "v2.1.5", sparse: "optimized", app: false, compile: false, diff --git a/mix.lock b/mix.lock index 3a8da0b..a5cee8c 100644 --- a/mix.lock +++ b/mix.lock @@ -22,7 +22,7 @@ "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "floki": {:hex, :floki, "0.37.0", "b83e0280bbc6372f2a403b2848013650b16640cd2470aea6701f0632223d719e", [:mix], [], "hexpm", "516a0c15a69f78c47dc8e0b9b3724b29608aa6619379f91b1ffa47109b5d0dd3"}, "gettext": {:hex, :gettext, "0.26.1", "38e14ea5dcf962d1fc9f361b63ea07c0ce715a8ef1f9e82d3dfb8e67e0416715", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "01ce56f188b9dc28780a52783d6529ad2bc7124f9744e571e1ee4ea88bf08734"}, - "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]}, + "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "ad0ad1f6d51bd64dcd67e363d2b2833a8de25154", [tag: "v2.1.5", sparse: "optimized"]}, "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jumper": {:hex, :jumper, "1.0.2", "68cdcd84472a00ac596b4e6459a41b3062d4427cbd4f1e8c8793c5b54f1406a7", [:mix], [], "hexpm", "9b7782409021e01ab3c08270e26f36eb62976a38c1aa64b2eaf6348422f165e1"},