fix: Draft replies
This commit is contained in:
parent
34de8792c0
commit
ec6b728611
6 changed files with 101 additions and 38 deletions
15
README.md
15
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
|
||||
|
|
|
|||
3
lib/postland/draft.ex
Normal file
3
lib/postland/draft.ex
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
defmodule Postland.Draft do
|
||||
defstruct text: "", cw: nil, attachments: []
|
||||
end
|
||||
|
|
@ -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
|
|||
<div class="min-w-0 flex-1 relative">
|
||||
<div class="overflow-hidden bg-white relative rounded-lg shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-violet-600">
|
||||
<.form phx-submit="create_post" phx-change="change_post" id="create-post-form">
|
||||
<div :if={@cw} class="px-3 pt-2 text-orange-700">
|
||||
<div :if={@draft.cw} class="px-3 pt-2 text-orange-700">
|
||||
<.icon name="hero-exclamation-triangle" />
|
||||
<input
|
||||
id="cw-input"
|
||||
name="cw"
|
||||
value={@cw}
|
||||
value={@draft.cw}
|
||||
placeholder="add content warning"
|
||||
class="border-0 bg-transparent py-1.5 text-orange-700 placeholder:text-gray-400 focus:ring-0 outline-none sm:text-sm sm:leading-6"
|
||||
/>
|
||||
|
|
@ -132,14 +135,14 @@ defmodule PostlandWeb.CoreComponents do
|
|||
<label for="post-body" class="sr-only">post body</label>
|
||||
<textarea
|
||||
rows="3"
|
||||
name="post"
|
||||
id="post-body"
|
||||
name="draft_body"
|
||||
id="draft-body"
|
||||
class="block w-full resize-none border-0 bg-transparent py-1.5 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
|
||||
placeholder="post body"
|
||||
><%= @post_content %></textarea>
|
||||
><%= @draft.text %></textarea>
|
||||
</.form>
|
||||
<div class="flex">
|
||||
<div :for={attachment <- @attachments} class="m-2 w-1/2">
|
||||
<div :for={attachment <- @draft.attachments} class="m-2 w-1/2">
|
||||
<.attachment_edit attachment={attachment} id={attachment["url"]} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -160,7 +163,7 @@ defmodule PostlandWeb.CoreComponents do
|
|||
</div>
|
||||
<div
|
||||
class="h-9 flex items-center text-gray-500"
|
||||
phx-click={if @cw, do: "remove_cw", else: "add_cw"}
|
||||
phx-click={if @draft.cw, do: "remove_cw", else: "add_cw"}
|
||||
>
|
||||
<.icon name="hero-exclamation-triangle" class="relative top-0.5" />
|
||||
</div>
|
||||
|
|
@ -294,6 +297,16 @@ defmodule PostlandWeb.CoreComponents do
|
|||
>
|
||||
<.icon name="hero-star" />
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
phx-click="show_reply_form"
|
||||
phx-value-post-dom-id={@post_dom_id}
|
||||
phx-value-post-id={@post.id}
|
||||
class="text-gray-500"
|
||||
>
|
||||
<.icon name="hero-arrow-turn-up-left" />
|
||||
</a>
|
||||
<.post_form :if={@draft_reply} draft={@draft_reply} upload={@upload} />
|
||||
<!-- Content goes here -->
|
||||
<!-- We use less vertical padding on card footers at all sizes than on headers or body sections -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,15 @@ defmodule PostlandWeb.TimelineLive do
|
|||
def render(assigns) do
|
||||
~H"""
|
||||
<div id="timeline">
|
||||
<.post_form post_content={@post} attachments={@attachments} upload={@uploads.files} cw={@cw} />
|
||||
<.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} />
|
||||
<.post_card
|
||||
post={post}
|
||||
post_dom_id={id}
|
||||
draft_reply={dbg(@draft_replies[post.id])}
|
||||
upload={@uploads.files}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
2
mix.exs
2
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,
|
||||
|
|
|
|||
2
mix.lock
2
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"},
|
||||
|
|
|
|||
Loading…
Reference in a new issue