Merge remote-tracking branch 'remotes/origin/develop' into relations-preloading-for...
[akkoma] / lib / pleroma / web / mastodon_api / views / account_view.ex
index 341dc2c91e2f059a7ced3c4c50d4aca387796138..2fe46158b305d1e8dce2922aca2134f61705fd04 100644 (file)
@@ -6,10 +6,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
   use Pleroma.Web, :view
 
   alias Pleroma.User
+  alias Pleroma.UserRelationship
   alias Pleroma.Web.CommonAPI.Utils
   alias Pleroma.Web.MastodonAPI.AccountView
   alias Pleroma.Web.MediaProxy
 
+  defp find_following_rel(following_relationships, follower, following) do
+    Enum.find(following_relationships, fn
+      fr -> fr.follower_id == follower.id and fr.following_id == following.id
+    end)
+  end
+
   def render("index.json", %{users: users} = opts) do
     users
     |> render_many(AccountView, "show.json", opts)
@@ -35,28 +42,90 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
     %{}
   end
 
-  def render("relationship.json", %{user: %User{} = user, target: %User{} = target}) do
-    follow_state = User.get_cached_follow_state(user, target)
+  def render(
+        "relationship.json",
+        %{user: %User{} = reading_user, target: %User{} = target} = opts
+      ) do
+    user_relationships = Map.get(opts, :user_relationships)
+    following_relationships = opts[:following_relationships]
+
+    follow_state =
+      if following_relationships do
+        user_to_target_following_relation =
+          find_following_rel(following_relationships, reading_user, target)
+
+        User.get_follow_state(reading_user, target, user_to_target_following_relation)
+      else
+        User.get_follow_state(reading_user, target)
+      end
 
-    requested =
-      if follow_state && !User.following?(user, target) do
-        follow_state == "pending"
+    followed_by =
+      if following_relationships do
+        with %{state: "accept"} <-
+               find_following_rel(following_relationships, target, reading_user) do
+          true
+        else
+          _ -> false
+        end
       else
-        false
+        User.following?(target, reading_user)
       end
 
+    # TODO: add a note on adjusting StatusView.user_relationships_opt/1 re: preloading of user relations
     %{
       id: to_string(target.id),
-      following: User.following?(user, target),
-      followed_by: User.following?(target, user),
-      blocking: User.blocks_user?(user, target),
-      blocked_by: User.blocks_user?(target, user),
-      muting: User.mutes?(user, target),
-      muting_notifications: User.muted_notifications?(user, target),
-      subscribing: User.subscribed_to?(user, target),
-      requested: requested,
-      domain_blocking: User.blocks_domain?(user, target),
-      showing_reblogs: User.showing_reblogs?(user, target),
+      following: follow_state == "accept",
+      followed_by: followed_by,
+      blocking:
+        UserRelationship.exists?(
+          user_relationships,
+          :block,
+          reading_user,
+          target,
+          &User.blocks_user?(&1, &2)
+        ),
+      blocked_by:
+        UserRelationship.exists?(
+          user_relationships,
+          :block,
+          target,
+          reading_user,
+          &User.blocks_user?(&1, &2)
+        ),
+      muting:
+        UserRelationship.exists?(
+          user_relationships,
+          :mute,
+          reading_user,
+          target,
+          &User.mutes?(&1, &2)
+        ),
+      muting_notifications:
+        UserRelationship.exists?(
+          user_relationships,
+          :notification_mute,
+          reading_user,
+          target,
+          &User.muted_notifications?(&1, &2)
+        ),
+      subscribing:
+        UserRelationship.exists?(
+          user_relationships,
+          :inverse_subscription,
+          target,
+          reading_user,
+          &User.subscribed_to?(&2, &1)
+        ),
+      requested: follow_state == "pending",
+      domain_blocking: User.blocks_domain?(reading_user, target),
+      showing_reblogs:
+        not UserRelationship.exists?(
+          user_relationships,
+          :reblog_mute,
+          reading_user,
+          target,
+          &User.muting_reblogs?(&1, &2)
+        ),
       endorsed: false
     }
   end
@@ -100,7 +169,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
         }
       end)
 
-    relationship = render("relationship.json", %{user: opts[:for], target: user})
+    relationship =
+      render("relationship.json", %{
+        user: opts[:for],
+        target: user,
+        user_relationships: opts[:user_relationships],
+        following_relationships: opts[:following_relationships]
+      })
 
     %{
       id: to_string(user.id),