Add virtual :thread_muted? field
authorAaron Tinio <aptinio@gmail.com>
Mon, 20 May 2019 16:35:46 +0000 (00:35 +0800)
committerAaron Tinio <aptinio@gmail.com>
Mon, 20 May 2019 16:35:46 +0000 (00:35 +0800)
that may be set when fetching activities

lib/pleroma/activity.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
lib/pleroma/web/twitter_api/views/activity_view.ex
test/activity_test.exs
test/user_test.exs

index 4e54b15baf072d35a233fb069014c0abe65391af..99589590c1b3bddba86134e849d3935adf26145a 100644 (file)
@@ -10,6 +10,7 @@ defmodule Pleroma.Activity do
   alias Pleroma.Notification
   alias Pleroma.Object
   alias Pleroma.Repo
+  alias Pleroma.ThreadMute
   alias Pleroma.User
 
   import Ecto.Changeset
@@ -37,6 +38,7 @@ defmodule Pleroma.Activity do
     field(:local, :boolean, default: true)
     field(:actor, :string)
     field(:recipients, {:array, :string}, default: [])
+    field(:thread_muted?, :boolean, virtual: true)
     # This is a fake relation, do not use outside of with_preloaded_bookmark/get_bookmark
     has_one(:bookmark, Bookmark)
     has_many(:notifications, Notification, on_delete: :delete_all)
@@ -90,6 +92,16 @@ defmodule Pleroma.Activity do
 
   def with_preloaded_bookmark(query, _), do: query
 
+  def with_set_thread_muted_field(query, %User{} = user) do
+    from([a] in query,
+      left_join: tm in ThreadMute,
+      on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data),
+      select: %Activity{a | thread_muted?: not is_nil(tm.id)}
+    )
+  end
+
+  def with_set_thread_muted_field(query, _), do: query
+
   def get_by_ap_id(ap_id) do
     Repo.one(
       from(
index 5c315697858537ea505f8d4611fc139657f848bb..3d9679ec0d03728f7606c6fcd6875bf5996d0795 100644 (file)
@@ -834,6 +834,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> Activity.with_preloaded_bookmark(opts["user"])
   end
 
+  defp maybe_set_thread_muted_field(query, %{"skip_preload" => true}), do: query
+
+  defp maybe_set_thread_muted_field(query, opts) do
+    query
+    |> Activity.with_set_thread_muted_field(opts["user"])
+  end
+
   defp maybe_order(query, %{order: :desc}) do
     query
     |> order_by(desc: :id)
@@ -852,6 +859,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     base_query
     |> maybe_preload_objects(opts)
     |> maybe_preload_bookmarks(opts)
+    |> maybe_set_thread_muted_field(opts)
     |> maybe_order(opts)
     |> restrict_recipients(recipients, opts["user"])
     |> restrict_tag(opts)
index c93d915e5aa851e8fa27084fec1e682a58137d9d..e55f9b96e5aa4a11dce6ebecdd1191ac42896213 100644 (file)
@@ -157,6 +157,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
 
     bookmarked = Activity.get_bookmark(activity, opts[:for]) != nil
 
+    thread_muted? =
+      case activity.thread_muted? do
+        thread_muted? when is_boolean(thread_muted?) -> thread_muted?
+        nil -> CommonAPI.thread_muted?(user, activity)
+      end
+
     attachment_data = object.data["attachment"] || []
     attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
 
@@ -228,7 +234,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       reblogged: reblogged?(activity, opts[:for]),
       favourited: present?(favorited),
       bookmarked: present?(bookmarked),
-      muted: CommonAPI.thread_muted?(user, activity) || User.mutes?(opts[:for], user),
+      muted: thread_muted? || User.mutes?(opts[:for], user),
       pinned: pinned?(activity, user),
       sensitive: sensitive,
       spoiler_text: summary_html,
index 44bcafe0e2e35f98d5017ae6706a10abccfa9082..e84af84dc6932a01f4d353f4f122e910812753a8 100644 (file)
@@ -284,6 +284,12 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
         Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
       )
 
+    thread_muted? =
+      case activity.thread_muted? do
+        thread_muted? when is_boolean(thread_muted?) -> thread_muted?
+        nil -> CommonAPI.thread_muted?(user, activity)
+      end
+
     %{
       "id" => activity.id,
       "uri" => object.data["id"],
@@ -314,7 +320,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
       "summary" => summary,
       "summary_html" => summary |> Formatter.emojify(object.data["emoji"]),
       "card" => card,
-      "muted" => CommonAPI.thread_muted?(user, activity) || User.mutes?(opts[:for], user)
+      "muted" => thread_muted? || User.mutes?(opts[:for], user)
     }
   end
 
index 7e91d534b4b391d2654621a3dc27cf1c3a3152c5..15c95502ab4af78beae377dac861439a57977e0d 100644 (file)
@@ -6,6 +6,7 @@ defmodule Pleroma.ActivityTest do
   use Pleroma.DataCase
   alias Pleroma.Activity
   alias Pleroma.Bookmark
+  alias Pleroma.ThreadMute
   import Pleroma.Factory
 
   test "returns an activity by it's AP id" do
@@ -47,6 +48,31 @@ defmodule Pleroma.ActivityTest do
     assert queried_activity.bookmark == bookmark3
   end
 
+  test "setting thread_muted?" do
+    activity = insert(:note_activity)
+    user = insert(:user)
+    annoyed_user = insert(:user)
+    {:ok, _} = ThreadMute.add_mute(annoyed_user.id, activity.data["context"])
+
+    activity_with_unset_thread_muted_field =
+      Ecto.Query.from(Activity)
+      |> Repo.one()
+
+    activity_for_user =
+      Ecto.Query.from(Activity)
+      |> Activity.with_set_thread_muted_field(user)
+      |> Repo.one()
+
+    activity_for_annoyed_user =
+      Ecto.Query.from(Activity)
+      |> Activity.with_set_thread_muted_field(annoyed_user)
+      |> Repo.one()
+
+    assert activity_with_unset_thread_muted_field.thread_muted? == nil
+    assert activity_for_user.thread_muted? == false
+    assert activity_for_annoyed_user.thread_muted? == true
+  end
+
   describe "getting a bookmark" do
     test "when association is loaded" do
       user = insert(:user)
index 10e463ff847a6c3e7d100bc2e340d10510a29822..cb6afbe07352cde5f1d7a7844c3c8c7853a71b8c 100644 (file)
@@ -902,7 +902,7 @@ defmodule Pleroma.UserTest do
 
       assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
 
-      assert [activity] ==
+      assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
                ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2})
 
       {:ok, _user} = User.deactivate(user)