implement Move activities (#45)
[akkoma] / lib / pleroma / following_relationship.ex
index 83b366dd406fc1fe8b6af93190268ff6d4694c4f..b101b9ee7d81e04499e274b2e4a265e2372aed6f 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.FollowingRelationship do
@@ -62,23 +62,47 @@ defmodule Pleroma.FollowingRelationship do
         follow(follower, following, state)
 
       following_relationship ->
-        following_relationship
-        |> cast(%{state: state}, [:state])
-        |> validate_required([:state])
-        |> Repo.update()
+        with {:ok, _following_relationship} <-
+               following_relationship
+               |> cast(%{state: state}, [:state])
+               |> validate_required([:state])
+               |> Repo.update() do
+          after_update(state, follower, following)
+        end
     end
   end
 
   def follow(%User{} = follower, %User{} = following, state \\ :follow_accept) do
-    %__MODULE__{}
-    |> changeset(%{follower: follower, following: following, state: state})
-    |> Repo.insert(on_conflict: :nothing)
+    with {:ok, _following_relationship} <-
+           %__MODULE__{}
+           |> changeset(%{follower: follower, following: following, state: state})
+           |> Repo.insert(on_conflict: :nothing) do
+      after_update(state, follower, following)
+    end
   end
 
   def unfollow(%User{} = follower, %User{} = following) do
     case get(follower, following) do
-      %__MODULE__{} = following_relationship -> Repo.delete(following_relationship)
-      _ -> {:ok, nil}
+      %__MODULE__{} = following_relationship ->
+        with {:ok, _following_relationship} <- Repo.delete(following_relationship) do
+          after_update(:unfollow, follower, following)
+        end
+
+      _ ->
+        {:ok, nil}
+    end
+  end
+
+  defp after_update(state, %User{} = follower, %User{} = following) do
+    with {:ok, following} <- User.update_follower_count(following),
+         {:ok, follower} <- User.update_following_count(follower) do
+      Pleroma.Web.Streamer.stream("follow_relationship", %{
+        state: state,
+        following: following,
+        follower: follower
+      })
+
+      {:ok, follower, following}
     end
   end
 
@@ -128,7 +152,7 @@ defmodule Pleroma.FollowingRelationship do
     |> join(:inner, [r], f in assoc(r, :follower))
     |> where([r], r.state == ^:follow_pending)
     |> where([r], r.following_id == ^id)
-    |> where([r, f], f.deactivated != true)
+    |> where([r, f], f.is_active == true)
     |> select([r, f], f)
     |> Repo.all()
   end
@@ -170,12 +194,13 @@ defmodule Pleroma.FollowingRelationship do
     |> join(:inner, [r], f in assoc(r, :follower))
     |> where(following_id: ^origin.id)
     |> where([r, f], f.allow_following_move == true)
+    |> where([r, f], f.local == true)
     |> limit(50)
     |> preload([:follower])
     |> Repo.all()
     |> Enum.map(fn following_relationship ->
-      Repo.delete(following_relationship)
       Pleroma.Web.CommonAPI.follow(following_relationship.follower, target)
+      Pleroma.Web.CommonAPI.unfollow(following_relationship.follower, origin)
     end)
     |> case do
       [] ->
@@ -264,4 +289,12 @@ defmodule Pleroma.FollowingRelationship do
       end
     end)
   end
+
+  @spec following_ap_ids(User.t()) :: [String.t()]
+  def following_ap_ids(%User{} = user) do
+    user
+    |> following_query()
+    |> select([r, u], u.ap_id)
+    |> Repo.all()
+  end
 end