Pleroma API: `POST /api/v1/pleroma/conversations/read` to mark all user's conversatio...
authoreugenijm <eugenijm@protonmail.com>
Fri, 11 Oct 2019 03:40:58 +0000 (06:40 +0300)
committereugenijm <eugenijm@protonmail.com>
Sat, 19 Oct 2019 12:24:06 +0000 (15:24 +0300)
CHANGELOG.md
docs/API/pleroma_api.md
lib/pleroma/conversation/participation.ex
lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
lib/pleroma/web/router.ex
test/conversation/participation_test.exs
test/web/pleroma_api/controllers/pleroma_api_controller_test.exs

index d516080b44f43db503e08ef15a57a9f3a5e09bc6..19cd1e53990f471c7bb9c6854f655f5db477eb50 100644 (file)
@@ -50,6 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Admin API: `/users/:nickname/toggle_activation` endpoint is now deprecated in favor of: `/users/activate`, `/users/deactivate`, both accept `nicknames` array
 - Admin API: `POST/DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group` are deprecated in favor of: `POST/DELETE /api/pleroma/admin/users/permission_group/:permission_group` (both accept `nicknames` array), `DELETE /api/pleroma/admin/users` (`nickname` query param or `nickname` sent in JSON body) is deprecated in favor of: `DELETE /api/pleroma/admin/users` (`nicknames` query array param or `nicknames` sent in JSON body).
 - Admin API: Add `GET /api/pleroma/admin/relay` endpoint - lists all followed relays
+- Pleroma API: `POST /api/v1/pleroma/conversations/read` to mark all conversations as read
 
 ### Changed
 - **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
index 0517bbdd70ce27febf6af5a33d21041437edc7e6..6c326dc9bc19efea8ef4e063faa6058d47353459 100644 (file)
@@ -367,6 +367,13 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
     * `recipients`: A list of ids of users that should receive posts to this conversation. This will replace the current list of recipients, so submit the full list. The owner of owner of the conversation will always be part of the set of recipients, though.
 * Response: JSON, statuses (200 - healthy, 503 unhealthy)
 
+## `GET /api/v1/pleroma/conversations/read`
+### Marks all user's conversations as read.
+* Method `POST`
+* Authentication: required
+* Params: None
+* Response: JSON, returns a list of Mastodon Conversation entities that were marked as read (200 - healthy, 503 unhealthy).
+
 ## `GET /api/pleroma/emoji/packs`
 ### Lists the custom emoji packs on the server
 * Method `GET`
index e17f49e58da622ec8db706bc2dfad9ca0a2a8f5b..41918fa78e4cd21962c902563b95fa004ebe50d9 100644 (file)
@@ -69,6 +69,19 @@ defmodule Pleroma.Conversation.Participation do
     end
   end
 
+  def mark_all_as_read(user) do
+    {_, participations} =
+      __MODULE__
+      |> where([p], p.user_id == ^user.id)
+      |> where([p], not p.read)
+      |> update([p], set: [read: true])
+      |> select([p], p)
+      |> Repo.update_all([])
+
+    User.set_unread_conversation_count(user)
+    {:ok, participations}
+  end
+
   def mark_as_unread(participation) do
     participation
     |> read_cng(%{read: false})
index 9d50a7ca996c72f61061fa2e708917d1877eb8f6..fc39abf053ee658b90b846e708bebf080636e79e 100644 (file)
@@ -79,6 +79,15 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
     end
   end
 
+  def read_conversations(%{assigns: %{user: user}} = conn, _params) do
+    with {:ok, participations} <- Participation.mark_all_as_read(user) do
+      conn
+      |> add_link_headers(participations)
+      |> put_view(ConversationView)
+      |> render("participations.json", participations: participations, for: user)
+    end
+  end
+
   def read_notification(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do
     with {:ok, notification} <- Notification.read_one(user, notification_id) do
       conn
index d68fb87da21276e1d5ae4d7e6881cf015b3c63f2..66e7a2263d4c50f5772f9d54aaf3a166ae90b2bf 100644 (file)
@@ -266,6 +266,7 @@ defmodule Pleroma.Web.Router do
 
       get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
       get("/conversations/:id", PleromaAPIController, :conversation)
+      post("/conversations/read", PleromaAPIController, :read_conversations)
     end
 
     scope [] do
index a5af0d1b21c2a13f3286d12ac72a4e7b1bb58233..64c350904899bfc203e56ada40ab209c5fa482f7 100644 (file)
@@ -133,6 +133,20 @@ defmodule Pleroma.Conversation.ParticipationTest do
     refute participation.read
   end
 
+  test "it marks all the user's participations as read" do
+    user = insert(:user)
+    other_user = insert(:user)
+    participation1 = insert(:participation, %{read: false, user: user})
+    participation2 = insert(:participation, %{read: false, user: user})
+    participation3 = insert(:participation, %{read: false, user: other_user})
+
+    {:ok, [%{read: true}, %{read: true}]} = Participation.mark_all_as_read(user)
+
+    assert Participation.get(participation1.id).read == true
+    assert Participation.get(participation2.id).read == true
+    assert Participation.get(participation3.id).read == false
+  end
+
   test "gets all the participations for a user, ordered by updated at descending" do
     user = insert(:user)
     {:ok, activity_one} = CommonAPI.post(user, %{"status" => "x", "visibility" => "direct"})
index 8a6528cbb1b5b874a14240cbfa948d115fcb175b..9cccc8c8a0ecb440262f1e0471e07a70a8cc5553 100644 (file)
@@ -95,6 +95,33 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
     assert other_user in participation.recipients
   end
 
+  test "POST /api/v1/pleroma/conversations/read", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, _activity} =
+      CommonAPI.post(user, %{"status" => "Hi @#{other_user.nickname}", "visibility" => "direct"})
+
+    {:ok, _activity} =
+      CommonAPI.post(user, %{"status" => "Hi @#{other_user.nickname}", "visibility" => "direct"})
+
+    [participation2, participation1] = Participation.for_user(other_user)
+    assert Participation.get(participation2.id).read == false
+    assert Participation.get(participation1.id).read == false
+    assert User.get_cached_by_id(other_user.id).info.unread_conversation_count == 2
+
+    [%{"unread" => false}, %{"unread" => false}] =
+      conn
+      |> assign(:user, other_user)
+      |> post("/api/v1/pleroma/conversations/read", %{})
+      |> json_response(200)
+
+    [participation2, participation1] = Participation.for_user(other_user)
+    assert Participation.get(participation2.id).read == true
+    assert Participation.get(participation1.id).read == true
+    assert User.get_cached_by_id(other_user.id).info.unread_conversation_count == 0
+  end
+
   describe "POST /api/v1/pleroma/notifications/read" do
     test "it marks a single notification as read", %{conn: conn} do
       user1 = insert(:user)