Hide muted theads from home/public timelines unless `with_muted` is set
authorrinpatch <rinpatch@sdf.org>
Thu, 15 Aug 2019 14:37:30 +0000 (17:37 +0300)
committerrinpatch <rinpatch@sdf.org>
Thu, 15 Aug 2019 14:37:30 +0000 (17:37 +0300)
lib/pleroma/activity.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/streamer.ex
test/web/activity_pub/activity_pub_test.exs
test/web/streamer_test.exs

index baf1e7722bb2ae710e13ecc3c72ca9ea7d9e2be1..35612c882017bb1302015d81a4a70cb49dc0ee1e 100644 (file)
@@ -96,6 +96,7 @@ defmodule Pleroma.Activity do
     from([a] in query,
       left_join: tm in ThreadMute,
       on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data),
+      as: :thread_mute,
       select: %Activity{a | thread_muted?: not is_nil(tm.id)}
     )
   end
index cf55c95203fc2b7cd119f8774567464ccacb96f6..defccade86540c41e040aa3629e48539518d6abc 100644 (file)
@@ -790,14 +790,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
 
-  defp restrict_muted(query, %{"muting_user" => %User{info: info}}) do
+  defp restrict_muted(query, %{"muting_user" => %User{info: info}} = opts) do
     mutes = info.mutes
 
-    from(
-      activity in query,
-      where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
-      where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
-    )
+    query =
+      from([activity] in query,
+        where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
+        where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
+      )
+
+    unless opts["skip_preload"] do
+      from([thread_mute: tm] in query, where: is_nil(tm))
+    else
+      query
+    end
   end
 
   defp restrict_muted(query, _), do: query
@@ -898,7 +904,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp maybe_set_thread_muted_field(query, opts) do
     query
-    |> Activity.with_set_thread_muted_field(opts["user"])
+    |> Activity.with_set_thread_muted_field(opts["muting_user"] || opts["user"])
   end
 
   defp maybe_order(query, %{order: :desc}) do
index bbaddd8529f530e22b1fea21103541a27e7e50fb..826be2f9a8b4cbf9e516ec7da9cbb4ff26285363 100644 (file)
@@ -113,8 +113,7 @@ defmodule Pleroma.Web.Streamer do
     |> Map.get("#{topic}:#{item.user_id}", [])
     |> Enum.each(fn socket ->
       with %User{} = user <- User.get_cached_by_ap_id(socket.assigns[:user].ap_id),
-           true <- should_send?(user, item),
-           false <- CommonAPI.thread_muted?(user, item.activity) do
+           true <- should_send?(user, item) do
         send(
           socket.transport_pid,
           {:text, represent_notification(socket.assigns[:user], item)}
@@ -236,7 +235,8 @@ defmodule Pleroma.Web.Streamer do
          %{host: parent_host} <- URI.parse(parent.data["actor"]),
          false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, item_host),
          false <- Pleroma.Web.ActivityPub.MRF.subdomain_match?(domain_blocks, parent_host),
-         true <- thread_containment(item, user) do
+         true <- thread_containment(item, user),
+         false <- CommonAPI.thread_muted?(user, item) do
       true
     else
       _ -> false
index d723f331f1f4f121b4c3f82adadb2d7408ddb835..0377d29f6bb89c910834bada031904d66a510b38 100644 (file)
@@ -538,6 +538,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_one)
   end
 
+  test "doesn't return thread muted activities" do
+    user = insert(:user)
+    activity_one = insert(:note_activity)
+    note_two = insert(:note, data: %{"context" => "suya.."})
+    activity_two = insert(:note_activity, note: note_two)
+
+    {:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
+
+    assert [activity_one] = ActivityPub.fetch_activities([], %{"muting_user" => user})
+  end
+
+  test "returns thread muted activities when with_muted is set" do
+    user = insert(:user)
+    activity_one = insert(:note_activity)
+    note_two = insert(:note, data: %{"context" => "suya.."})
+    activity_two = insert(:note_activity, note: note_two)
+
+    {:ok, activity_two} = CommonAPI.add_mute(user, activity_two)
+
+    assert [activity_two, activity_one] =
+             ActivityPub.fetch_activities([], %{"muting_user" => user, "with_muted" => true})
+  end
+
   test "does include announces on request" do
     activity_three = insert(:note_activity)
     user = insert(:user)
index d47b37efb9815ca9142da160d3eca94b7703978c..5b7fe44d44a69793c745f0607b72bd44983ea19a 100644 (file)
@@ -414,6 +414,26 @@ defmodule Pleroma.Web.StreamerTest do
     Task.await(task)
   end
 
+  test "it doesn't send posts from muted threads" do
+    user = insert(:user)
+    user2 = insert(:user)
+    {:ok, user2, user, _activity} = CommonAPI.follow(user2, user)
+
+    {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
+
+    {:ok, activity} = CommonAPI.add_mute(user2, activity)
+
+    task = Task.async(fn -> refute_receive {:text, _}, 4_000 end)
+
+    Streamer.add_socket(
+      "user",
+      %{transport_pid: task.pid, assigns: %{user: user2}}
+    )
+
+    Streamer.stream("user", activity)
+    Task.await(task)
+  end
+
   describe "direct streams" do
     setup do
       GenServer.start(Streamer, %{}, name: Streamer)