diff --git a/lib/annot_at/publishing.ex b/lib/annot_at/publishing.ex index 9b9bb47..f0c8b2d 100644 --- a/lib/annot_at/publishing.ex +++ b/lib/annot_at/publishing.ex @@ -10,6 +10,7 @@ defmodule AnnotAt.Publishing do alias AnnotAt.Accounts.Scope alias AnnotAt.Accounts.User alias AnnotAt.Atproto.TID + alias AnnotAt.Feeds.Entry alias AnnotAt.Publishing.Post alias AnnotAt.Publishing.Site alias AnnotAt.Repo @@ -98,6 +99,18 @@ defmodule AnnotAt.Publishing do |> Repo.update() end + def adopt(%Site{} = site, entries) do + tracked = MapSet.new(list_posts(site), & &1.guid) + + entries + |> Enum.filter(fn entry -> is_binary(entry.rkey) and entry.id not in tracked end) + |> Enum.each(fn entry -> + create_post(site, %{guid: entry.id, rkey: entry.rkey, content_hash: Entry.hash(entry)}) + end) + + Map.new(list_posts(site), &{&1.guid, &1}) + end + defp verify_user_ownership!(%Site{user_id: user_id}, user_id), do: :ok defp verify_user_ownership!(%Site{}, _user_id), do: raise(Ecto.NoResultsError, queryable: Site) end diff --git a/lib/annot_at_web/controllers/live/posts_live.ex b/lib/annot_at_web/controllers/live/posts_live.ex index 611e517..66d6914 100644 --- a/lib/annot_at_web/controllers/live/posts_live.ex +++ b/lib/annot_at_web/controllers/live/posts_live.ex @@ -307,14 +307,30 @@ defmodule AnnotAtWeb.PostsLive do {:noreply, socket} end + def handle_async(:load_feed, {:ok, {:ok, %{feed: feed, posts: posts}}}, socket) do + {:noreply, + assign(socket, + feed: AsyncResult.ok(socket.assigns.feed, feed), + posts: posts + )} + end + + def handle_async(:load_feed, {:ok, reason}, socket) do + Logger.warning("PostsLive: failed to load feed", reason: inspect(reason)) + {:noreply, assign(socket, feed: AsyncResult.failed(socket.assigns.feed, reason))} + end + defp load_feed(socket, site) do if connected?(socket) do user_did = socket.assigns.current_scope.user.did - assign_async(socket, :feed, fn -> + socket + |> assign(feed: AsyncResult.loading()) + |> start_async(:load_feed, fn -> with {:ok, feed} <- Client.load(site.feed_url) do feed = Client.resolve_documents(feed, user_did) - {:ok, %{feed: feed}} + posts = Publishing.adopt(site, feed.entries) + {:ok, %{feed: feed, posts: posts}} end end) else