+ @doc "Filters out AP IDs domain-blocking and not following the activity's actor"
+ def exclude_domain_blocker_ap_ids(ap_ids, activity, preloaded_users \\ [])
+
+ def exclude_domain_blocker_ap_ids([], _activity, _preloaded_users), do: []
+
+ def exclude_domain_blocker_ap_ids(ap_ids, %Activity{} = activity, preloaded_users) do
+ activity_actor_domain = activity.actor && URI.parse(activity.actor).host
+
+ users =
+ ap_ids
+ |> Enum.map(fn ap_id ->
+ Enum.find(preloaded_users, &(&1.ap_id == ap_id)) ||
+ User.get_cached_by_ap_id(ap_id)
+ end)
+ |> Enum.filter(& &1)
+
+ domain_blocker_ap_ids = for u <- users, activity_actor_domain in u.domain_blocks, do: u.ap_id
+
+ domain_blocker_follower_ap_ids =
+ if Enum.any?(domain_blocker_ap_ids) do
+ activity
+ |> Activity.user_actor()
+ |> FollowingRelationship.followers_ap_ids(domain_blocker_ap_ids)
+ else
+ []
+ end
+
+ ap_ids
+ |> Kernel.--(domain_blocker_ap_ids)
+ |> Kernel.++(domain_blocker_follower_ap_ids)
+ end
+
+ @doc "Filters out AP IDs of users basing on their relationships with activity actor user"
+ def exclude_relationship_restricted_ap_ids([], _activity), do: []
+
+ def exclude_relationship_restricted_ap_ids(ap_ids, %Activity{} = activity) do
+ relationship_restricted_ap_ids =
+ activity
+ |> Activity.user_actor()
+ |> User.incoming_relationships_ungrouped_ap_ids([
+ :block,
+ :notification_mute
+ ])
+
+ Enum.uniq(ap_ids) -- relationship_restricted_ap_ids
+ end
+
+ @doc "Filters out AP IDs of users who mute activity thread"
+ def exclude_thread_muter_ap_ids([], _activity), do: []
+
+ def exclude_thread_muter_ap_ids(ap_ids, %Activity{} = activity) do
+ thread_muter_ap_ids = ThreadMute.muter_ap_ids(activity.data["context"])
+
+ Enum.uniq(ap_ids) -- thread_muter_ap_ids
+ end