From b49925b830594ac598e3111aea5f1995735e7ee3 Mon Sep 17 00:00:00 2001 From: Ro Date: Fri, 1 Nov 2024 19:07:40 -0500 Subject: [PATCH] feat: Deleting posts --- README.md | 3 ++- lib/postland/activities.ex | 17 +++++++++++++++-- lib/postland/objects.ex | 11 +++++++++++ lib/postland_web/components/core_components.ex | 9 +++++++++ lib/postland_web/live/timeline_live.ex | 17 ++++++++++++++++- 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 lib/postland/objects.ex diff --git a/README.md b/README.md index 9fc494e..27eb1c6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - [x] My posts - [x] Posts from accounts you follow - [x] Show the actor avatar and display name -- [ ] Deleting posts +- [x] Deleting posts - [x] Profile - [x] Name field (for display name) - [x] Bust actor cache when you update your profile @@ -31,6 +31,7 @@ - [ ] DMs - [ ] Support authenticated fetch of outbox (by allowed domains / servers) - [ ] Followers-only posts (or maybe this is handled because we only send posts to followers? but we also include public in the TO field?) +- [ ] Check the domain of the public key against the domain of the object being CRUDed ## UX diff --git a/lib/postland/activities.ex b/lib/postland/activities.ex index 9aa63fa..7079ec8 100644 --- a/lib/postland/activities.ex +++ b/lib/postland/activities.ex @@ -58,6 +58,21 @@ defmodule Postland.Activities do |> broadcast_to_followers(activity) end + def delete_post(post) do + activity = + %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => url(~p"/activities/#{Ecto.UUID.autogenerate()}"), + "type" => "Delete", + "actor" => Postland.my_actor_id(), + "object" => post.id + } + + post + |> Repo.delete() + |> broadcast_to_followers(activity) + end + def broadcast_to_followers({:ok, _} = result, activity) do my_actor_id = Postland.my_actor_id() private_key = Postland.Accounts.solo_user().private_key @@ -65,8 +80,6 @@ defmodule Postland.Activities do Postland.Follows.all_followers() |> Enum.map(fn %{follower: follower} -> inbox = Postland.Actors.inbox(follower) - dbg(follower) - dbg(inbox) case inbox do nil -> diff --git a/lib/postland/objects.ex b/lib/postland/objects.ex new file mode 100644 index 0000000..8841be1 --- /dev/null +++ b/lib/postland/objects.ex @@ -0,0 +1,11 @@ +defmodule Postland.Objects do + alias Postland.Object + alias Postland.Repo + + import Ecto.Query + + def get_by_id(id) do + from(o in Object, where: o.id == ^id) + |> Repo.one() + end +end diff --git a/lib/postland_web/components/core_components.ex b/lib/postland_web/components/core_components.ex index 221b547..692d786 100644 --- a/lib/postland_web/components/core_components.ex +++ b/lib/postland_web/components/core_components.ex @@ -115,6 +115,15 @@ defmodule PostlandWeb.CoreComponents do <%= {:safe, Postland.Timeline.html_content(@post)} %>
+ + <.icon name="hero-trash" /> +
diff --git a/lib/postland_web/live/timeline_live.ex b/lib/postland_web/live/timeline_live.ex index 57c4dc8..6a45e2e 100644 --- a/lib/postland_web/live/timeline_live.ex +++ b/lib/postland_web/live/timeline_live.ex @@ -1,12 +1,15 @@ defmodule PostlandWeb.TimelineLive do use PostlandWeb, :live_view + alias Postland.Activities + alias Postland.Objects + def render(assigns) do ~H""" <.post_form post_content={@post} />
- <.post_card post={post} /> + <.post_card post={post} post_dom_id={id} />
""" @@ -37,6 +40,18 @@ defmodule PostlandWeb.TimelineLive do {: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("change_post", %{"post" => post}, socket) do {:noreply, socket |> assign(:post, post)} end