From c56e3d4f3bfb090d19bdbe93dac6cede7616cc4d Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Tue, 8 Sep 2020 13:26:44 +0300 Subject: [PATCH 1/8] Add expires_in param for account mutes --- config/config.exs | 5 ++- lib/pleroma/user.ex | 45 ++++++++++--------- .../api_spec/operations/account_operation.ex | 15 ++++++- .../controllers/account_controller.ex | 2 +- lib/pleroma/workers/mute_expire_worker.ex | 22 +++++++++ test/notification_test.exs | 4 +- test/user_test.exs | 2 +- .../notification_controller_test.exs | 2 +- .../mastodon_api/views/account_view_test.exs | 2 +- 9 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 lib/pleroma/workers/mute_expire_worker.ex diff --git a/config/config.exs b/config/config.exs index ed37b93c0..0649f3078 100644 --- a/config/config.exs +++ b/config/config.exs @@ -541,7 +541,8 @@ background: 5, remote_fetcher: 2, attachments_cleanup: 5, - new_users_digest: 1 + new_users_digest: 1, + mute_expire: 5 ], plugins: [Oban.Plugins.Pruner], crontab: [ @@ -672,7 +673,7 @@ # With no frontend configuration, the bundled files from the `static` directory will # be used. # -# config :pleroma, :frontends, +# config :pleroma, :frontends, # primary: %{"name" => "pleroma-fe", "ref" => "develop"}, # admin: %{"name" => "admin-fe", "ref" => "stable"}, # available: %{...} diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 94c96de8d..040db8d80 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1356,14 +1356,34 @@ def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do |> Repo.all() end - @spec mute(User.t(), User.t(), boolean()) :: + @spec mute(User.t(), User.t(), map()) :: {:ok, list(UserRelationship.t())} | {:error, String.t()} - def mute(%User{} = muter, %User{} = mutee, notifications? \\ true) do - add_to_mutes(muter, mutee, notifications?) + def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do + notifications? = Map.get(params, :notifications, true) + expires_in = Map.get(params, :expires_in, 0) + + with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee), + {:ok, user_notification_mute} <- + (notifications? && UserRelationship.create_notification_mute(muter, mutee)) || + {:ok, nil} do + with seconds when seconds > 0 <- expires_in do + Pleroma.Workers.MuteExpireWorker.enqueue( + "unmute", + %{"muter" => muter.id, "mutee" => mutee.id}, + schedule_in: expires_in + ) + end + + {:ok, Enum.filter([user_mute, user_notification_mute], & &1)} + end end def unmute(%User{} = muter, %User{} = mutee) do - remove_from_mutes(muter, mutee) + with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee), + {:ok, user_notification_mute} <- + UserRelationship.delete_notification_mute(muter, mutee) do + {:ok, [user_mute, user_notification_mute]} + end end def subscribe(%User{} = subscriber, %User{} = target) do @@ -2379,23 +2399,6 @@ defp remove_from_block(%User{} = user, %User{} = blocked) do UserRelationship.delete_block(user, blocked) end - defp add_to_mutes(%User{} = user, %User{} = muted_user, notifications?) do - with {:ok, user_mute} <- UserRelationship.create_mute(user, muted_user), - {:ok, user_notification_mute} <- - (notifications? && UserRelationship.create_notification_mute(user, muted_user)) || - {:ok, nil} do - {:ok, Enum.filter([user_mute, user_notification_mute], & &1)} - end - end - - defp remove_from_mutes(user, %User{} = muted_user) do - with {:ok, user_mute} <- UserRelationship.delete_mute(user, muted_user), - {:ok, user_notification_mute} <- - UserRelationship.delete_notification_mute(user, muted_user) do - {:ok, [user_mute, user_notification_mute]} - end - end - def set_invisible(user, invisible) do params = %{invisible: invisible} diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index aaebc9b5c..de715a077 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -262,6 +262,12 @@ def mute_operation do :query, %Schema{allOf: [BooleanLike], default: true}, "Mute notifications in addition to statuses? Defaults to `true`." + ), + Operation.parameter( + :expires_in, + :query, + %Schema{type: :integer, default: 0}, + "Expire the mute in `expires_in` seconds. Default 0 for infinity" ) ], responses: %{ @@ -718,10 +724,17 @@ defp mute_request do nullable: true, description: "Mute notifications in addition to statuses? Defaults to true.", default: true + }, + expires_in: %Schema{ + type: :integer, + nullable: true, + description: "Expire the mute in `expires_in` seconds. Default 0 for infinity", + default: 0 } }, example: %{ - "notifications" => true + "notifications" => true, + "expires_in" => 86_400 } } end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 95d8452df..ca1a79f5e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -394,7 +394,7 @@ def unfollow(%{assigns: %{user: follower, account: followed}} = conn, _params) d @doc "POST /api/v1/accounts/:id/mute" def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do - with {:ok, _user_relationships} <- User.mute(muter, muted, params.notifications) do + with {:ok, _user_relationships} <- User.mute(muter, muted, params) do render(conn, "relationship.json", user: muter, target: muted) else {:error, message} -> json_response(conn, :forbidden, %{error: message}) diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex new file mode 100644 index 000000000..b8ec939a9 --- /dev/null +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -0,0 +1,22 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Workers.MuteExpireWorker do + use Pleroma.Workers.WorkerHelper, queue: "mute_expire" + + require Logger + + @impl Oban.Worker + def perform(%Job{args: %{"op" => "unmute", "muter" => muter_id, "mutee" => mutee_id}}) do + muter = Pleroma.User.get_by_id(muter_id) + mutee = Pleroma.User.get_by_id(mutee_id) + Pleroma.User.unmute(muter, mutee) + :ok + end + + def perform(any) do + Logger.error("Got call to perform(#{inspect(any)})") + :ok + end +end diff --git a/test/notification_test.exs b/test/notification_test.exs index a09b08675..ffd737969 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -227,7 +227,7 @@ test "notification created if user is muted without notifications" do muter = insert(:user) muted = insert(:user) - {:ok, _user_relationships} = User.mute(muter, muted, false) + {:ok, _user_relationships} = User.mute(muter, muted, %{notifications: false}) {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"}) @@ -1013,7 +1013,7 @@ test "move activity generates a notification" do test "it returns notifications for muted user without notifications", %{user: user} do muted = insert(:user) - {:ok, _user_relationships} = User.mute(user, muted, false) + {:ok, _user_relationships} = User.mute(user, muted, %{notifications: false}) {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"}) diff --git a/test/user_test.exs b/test/user_test.exs index 50f72549e..b23e36be3 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -981,7 +981,7 @@ test "it mutes user without notifications" do refute User.mutes?(user, muted_user) refute User.muted_notifications?(user, muted_user) - {:ok, _user_relationships} = User.mute(user, muted_user, false) + {:ok, _user_relationships} = User.mute(user, muted_user, %{notifications: false}) assert User.mutes?(user, muted_user) refute User.muted_notifications?(user, muted_user) diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index 70ef0e8b5..5fd518c60 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -502,7 +502,7 @@ test "see notifications after muting user without notifications" do assert length(json_response_and_validate_schema(ret_conn, 200)) == 1 - {:ok, _user_relationships} = User.mute(user, user2, false) + {:ok, _user_relationships} = User.mute(user, user2, %{notifications: false}) conn = get(conn, "/api/v1/notifications") diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index 8f37efa3c..c34cbcfc1 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -277,7 +277,7 @@ test "represent a relationship for the following and followed user" do {:ok, user} = User.follow(user, other_user) {:ok, other_user} = User.follow(other_user, user) {:ok, _subscription} = User.subscribe(user, other_user) - {:ok, _user_relationships} = User.mute(user, other_user, true) + {:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true}) {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user) expected = From f6b250fb8d13f6788c1ecc6c1287e76febbfd888 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Tue, 8 Sep 2020 14:11:00 +0300 Subject: [PATCH 2/8] Add test for expiring mutes --- test/user_test.exs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/user_test.exs b/test/user_test.exs index b23e36be3..83c017ec5 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -963,6 +963,19 @@ test "it mutes people" do assert User.muted_notifications?(user, muted_user) end + test "expiring" do + user = insert(:user) + muted_user = insert(:user) + + {:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60}) + assert User.mutes?(user, muted_user) + + assert_enqueued( + worker: Pleroma.Workers.MuteExpireWorker, + args: %{"op" => "unmute", "muter" => user.id, "mutee" => muted_user.id} + ) + end + test "it unmutes users" do user = insert(:user) muted_user = insert(:user) From e3f845b24363cd867ab85b7297f2d34bfa16b13f Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Tue, 8 Sep 2020 15:13:50 +0300 Subject: [PATCH 3/8] Add expiring mutes for activities --- lib/pleroma/user.ex | 6 ++--- .../api_spec/operations/status_operation.ex | 22 ++++++++++++++++++- lib/pleroma/web/common_api/common_api.ex | 12 +++++++++- lib/pleroma/workers/mute_expire_worker.ex | 10 ++++++--- test/user_test.exs | 12 ++++++++-- test/web/common_api/common_api_test.exs | 18 +++++++++++++++ 6 files changed, 70 insertions(+), 10 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 040db8d80..46e03553c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1366,10 +1366,10 @@ def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do {:ok, user_notification_mute} <- (notifications? && UserRelationship.create_notification_mute(muter, mutee)) || {:ok, nil} do - with seconds when seconds > 0 <- expires_in do + if expires_in > 0 do Pleroma.Workers.MuteExpireWorker.enqueue( - "unmute", - %{"muter" => muter.id, "mutee" => mutee.id}, + "unmute_user", + %{"muter_id" => muter.id, "mutee_id" => mutee.id}, schedule_in: expires_in ) end diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex index 5bd4619d5..6589a16f3 100644 --- a/lib/pleroma/web/api_spec/operations/status_operation.ex +++ b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -223,7 +223,27 @@ def mute_conversation_operation do security: [%{"oAuth" => ["write:mutes"]}], description: "Do not receive notifications for the thread that this status is part of.", operationId: "StatusController.mute_conversation", - parameters: [id_param()], + requestBody: + request_body("Parameters", %Schema{ + type: :object, + properties: %{ + expires_in: %Schema{ + type: :integer, + nullable: true, + description: "Expire the mute in `expires_in` seconds. Default 0 for infinity", + default: 0 + } + } + }), + parameters: [ + id_param(), + Operation.parameter( + :expires_in, + :query, + %Schema{type: :integer, default: 0}, + "Expire the mute in `expires_in` seconds. Default 0 for infinity" + ) + ], responses: %{ 200 => status_response(), 400 => Operation.response("Error", "application/json", ApiError) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 4ab533658..b217c4d10 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -451,9 +451,19 @@ def unpin(id, user) do end end - def add_mute(user, activity) do + def add_mute(user, activity, params \\ %{}) do + expires_in = Map.get(params, :expires_in, 0) + with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]), _ <- Pleroma.Notification.mark_context_as_read(user, activity.data["context"]) do + if expires_in > 0 do + Pleroma.Workers.MuteExpireWorker.enqueue( + "unmute_conversation", + %{"user_id" => user.id, "activity_id" => activity.id}, + schedule_in: expires_in + ) + end + {:ok, activity} else {:error, _} -> {:error, dgettext("errors", "conversation is already muted")} diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index b8ec939a9..622fdbadd 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -8,15 +8,19 @@ defmodule Pleroma.Workers.MuteExpireWorker do require Logger @impl Oban.Worker - def perform(%Job{args: %{"op" => "unmute", "muter" => muter_id, "mutee" => mutee_id}}) do + def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do muter = Pleroma.User.get_by_id(muter_id) mutee = Pleroma.User.get_by_id(mutee_id) Pleroma.User.unmute(muter, mutee) :ok end - def perform(any) do - Logger.error("Got call to perform(#{inspect(any)})") + def perform(%Job{ + args: %{"op" => "unmute_conversation", "user_id" => user_id, "activity_id" => activity_id} + }) do + user = Pleroma.User.get_by_id(user_id) + activity = Pleroma.Activity.get_by_id(activity_id) + Pleroma.Web.CommonAPI.remove_mute(user, activity) :ok end end diff --git a/test/user_test.exs b/test/user_test.exs index 83c017ec5..d49afb35a 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -970,10 +970,18 @@ test "expiring" do {:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60}) assert User.mutes?(user, muted_user) + worker = Pleroma.Workers.MuteExpireWorker + args = %{"op" => "unmute_user", "muter_id" => user.id, "mutee_id" => muted_user.id} + assert_enqueued( - worker: Pleroma.Workers.MuteExpireWorker, - args: %{"op" => "unmute", "muter" => user.id, "mutee" => muted_user.id} + worker: worker, + args: args ) + + assert :ok = perform_job(worker, args) + + refute User.mutes?(user, muted_user) + refute User.muted_notifications?(user, muted_user) end test "it unmutes users" do diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index 800db9a20..7ceb7ec7f 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -3,7 +3,9 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.CommonAPITest do + use Oban.Testing, repo: Pleroma.Repo use Pleroma.DataCase + alias Pleroma.Activity alias Pleroma.Chat alias Pleroma.Conversation.Participation @@ -878,6 +880,22 @@ test "add mute", %{user: user, activity: activity} do assert CommonAPI.thread_muted?(user, activity) end + test "add expiring mute", %{user: user, activity: activity} do + {:ok, _} = CommonAPI.add_mute(user, activity, %{expires_in: 60}) + assert CommonAPI.thread_muted?(user, activity) + + worker = Pleroma.Workers.MuteExpireWorker + args = %{"op" => "unmute_conversation", "user_id" => user.id, "activity_id" => activity.id} + + assert_enqueued( + worker: worker, + args: args + ) + + assert :ok = perform_job(worker, args) + refute CommonAPI.thread_muted?(user, activity) + end + test "remove mute", %{user: user, activity: activity} do CommonAPI.add_mute(user, activity) {:ok, _} = CommonAPI.remove_mute(user, activity) From 91b9985e1c0ef1766eb1705364e1aebe69d9b9bd Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Tue, 8 Sep 2020 15:26:06 +0300 Subject: [PATCH 4/8] Pass expires_in param from status controller --- lib/pleroma/web/mastodon_api/controllers/status_controller.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index ecfa38489..da14c0b6c 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -285,9 +285,9 @@ def unbookmark(%{assigns: %{user: user}} = conn, %{id: id}) do end @doc "POST /api/v1/statuses/:id/mute" - def mute_conversation(%{assigns: %{user: user}} = conn, %{id: id}) do + def mute_conversation(%{assigns: %{user: user}, body_params: params} = conn, %{id: id}) do with %Activity{} = activity <- Activity.get_by_id(id), - {:ok, activity} <- CommonAPI.add_mute(user, activity) do + {:ok, activity} <- CommonAPI.add_mute(user, activity, params) do try_render(conn, "show.json", activity: activity, for: user, as: :activity) end end From 527afb813af6c64337d02ddf1a2f159fe557acbc Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sun, 13 Sep 2020 12:23:45 +0300 Subject: [PATCH 5/8] Remove unused require --- lib/pleroma/workers/mute_expire_worker.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index 622fdbadd..c8b44894e 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -5,8 +5,6 @@ defmodule Pleroma.Workers.MuteExpireWorker do use Pleroma.Workers.WorkerHelper, queue: "mute_expire" - require Logger - @impl Oban.Worker def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do muter = Pleroma.User.get_by_id(muter_id) From 28d0986f839651df7d305da8932f7b5c48a4fbfb Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sun, 20 Sep 2020 20:51:20 +0300 Subject: [PATCH 6/8] Refactor mutes removing in CommonAPI and User --- lib/pleroma/user.ex | 14 ++++++++++++++ lib/pleroma/web/common_api/common_api.ex | 18 +++++++++++++++++- lib/pleroma/workers/mute_expire_worker.ex | 8 ++------ test/user_test.exs | 11 +++++++++++ test/web/common_api/common_api_test.exs | 6 ++++++ 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 83eb4d5ff..83e89a12c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1385,6 +1385,20 @@ def unmute(%User{} = muter, %User{} = mutee) do end end + def unmute(muter_id, mutee_id) do + with {:muter, %User{} = muter} <- {:muter, User.get_by_id(muter_id)}, + {:mutee, %User{} = mutee} <- {:mutee, User.get_by_id(mutee_id)} do + unmute(muter, mutee) + else + {who, result} = error -> + Logger.warn( + "User.unmute/2 failed. #{who}: #{result}, muter_id: #{muter_id}, mutee_id: #{mutee_id}" + ) + + {:error, error} + end + end + def subscribe(%User{} = subscriber, %User{} = target) do deny_follow_blocked = Config.get([:user, :deny_follow_blocked]) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index fca9246a5..aa4c6ddab 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -472,11 +472,27 @@ def add_mute(user, activity, params \\ %{}) do end end - def remove_mute(user, activity) do + def remove_mute(%User{} = user, %Activity{} = activity) do ThreadMute.remove_mute(user.id, activity.data["context"]) {:ok, activity} end + def remove_mute(user_id, activity_id) do + with {:user, %User{} = user} <- {:user, User.get_by_id(user_id)}, + {:activity, %Activity{} = activity} <- {:activity, Activity.get_by_id(activity_id)} do + remove_mute(user, activity) + else + {what, result} = error -> + Logger.warn( + "CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{ + activity_id + }" + ) + + {:error, error} + end + end + def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}}) when is_binary(context) do ThreadMute.exists?(user_id, context) diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index c8b44894e..32a12ba85 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -7,18 +7,14 @@ defmodule Pleroma.Workers.MuteExpireWorker do @impl Oban.Worker def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do - muter = Pleroma.User.get_by_id(muter_id) - mutee = Pleroma.User.get_by_id(mutee_id) - Pleroma.User.unmute(muter, mutee) + Pleroma.User.unmute(muter_id, mutee_id) :ok end def perform(%Job{ args: %{"op" => "unmute_conversation", "user_id" => user_id, "activity_id" => activity_id} }) do - user = Pleroma.User.get_by_id(user_id) - activity = Pleroma.Activity.get_by_id(activity_id) - Pleroma.Web.CommonAPI.remove_mute(user, activity) + Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id) :ok end end diff --git a/test/user_test.exs b/test/user_test.exs index ce0d4d38b..79c8b76b8 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1034,6 +1034,17 @@ test "it unmutes users" do refute User.muted_notifications?(user, muted_user) end + test "it unmutes users by id" do + user = insert(:user) + muted_user = insert(:user) + + {:ok, _user_relationships} = User.mute(user, muted_user) + {:ok, _user_mute} = User.unmute(user.id, muted_user.id) + + refute User.mutes?(user, muted_user) + refute User.muted_notifications?(user, muted_user) + end + test "it mutes user without notifications" do user = insert(:user) muted_user = insert(:user) diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index bf4353a57..45ab1e0bd 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -913,6 +913,12 @@ test "remove mute", %{user: user, activity: activity} do refute CommonAPI.thread_muted?(user, activity) end + test "remove mute by ids", %{user: user, activity: activity} do + CommonAPI.add_mute(user, activity) + {:ok, _} = CommonAPI.remove_mute(user.id, activity.id) + refute CommonAPI.thread_muted?(user, activity) + end + test "check that mutes can't be duplicate", %{user: user, activity: activity} do CommonAPI.add_mute(user, activity) {:error, _} = CommonAPI.add_mute(user, activity) From b0bd81ef7187ddf5b4e6cfbc1780fc60b65798c6 Mon Sep 17 00:00:00 2001 From: Roman Chvanikov Date: Sun, 20 Sep 2020 20:58:32 +0300 Subject: [PATCH 7/8] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a7e27fd3..9fd5f9efe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Experimental websocket-based federation between Pleroma instances. +- User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute. ### Changed From 9b2ed1427725cd8c5e8d81e39cc5bbc73a2140bc Mon Sep 17 00:00:00 2001 From: lain Date: Thu, 5 Nov 2020 13:23:58 +0100 Subject: [PATCH 8/8] Docs: Add info about expiring mutes. --- docs/API/differences_in_mastoapi_responses.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md index bb1000b0b..3075b6b86 100644 --- a/docs/API/differences_in_mastoapi_responses.md +++ b/docs/API/differences_in_mastoapi_responses.md @@ -255,6 +255,10 @@ There is an additional `user:pleroma_chat` stream. Incoming chat messages will m For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`. +## User muting and thread muting + +Both user muting and thread muting can be done for only a certain time by adding an `expires_in` parameter to the API calls and giving the expiration time in seconds. + ## Not implemented Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.