ChatController: Add function to mark single message as read.
authorlain <lain@soykaf.club>
Wed, 3 Jun 2020 17:21:23 +0000 (19:21 +0200)
committerlain <lain@soykaf.club>
Wed, 3 Jun 2020 17:21:23 +0000 (19:21 +0200)
lib/pleroma/chat_message_reference.ex
lib/pleroma/web/api_spec/operations/chat_operation.ex
lib/pleroma/web/pleroma_api/controllers/chat_controller.ex
lib/pleroma/web/router.ex
test/web/pleroma_api/controllers/chat_controller_test.exs

index ad174b29451f27a0ecb9291c5b245c75fe2cd9b4..9b00443f51540c8dc20d07ca8df84889b86662a9 100644 (file)
@@ -92,6 +92,12 @@ defmodule Pleroma.ChatMessageReference do
     |> Repo.aggregate(:count)
   end
 
+  def mark_as_read(cm_ref) do
+    cm_ref
+    |> changeset(%{seen: true})
+    |> Repo.update()
+  end
+
   def set_all_seen_for_chat(chat) do
     chat
     |> for_chat_query()
index a1c5db5dcd283569592d62a23da78069d9e30470..6ad325113a70bf1a15ba020a406ef13e99a8505e 100644 (file)
@@ -39,6 +39,31 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
     }
   end
 
+  def mark_message_as_read_operation do
+    %Operation{
+      tags: ["chat"],
+      summary: "Mark one message in the chat as read",
+      operationId: "ChatController.mark_message_as_read",
+      parameters: [
+        Operation.parameter(:id, :path, :string, "The ID of the Chat"),
+        Operation.parameter(:message_id, :path, :string, "The ID of the message")
+      ],
+      responses: %{
+        200 =>
+          Operation.response(
+            "The read ChatMessage",
+            "application/json",
+            ChatMessage
+          )
+      },
+      security: [
+        %{
+          "oAuth" => ["write"]
+        }
+      ]
+    }
+  end
+
   def show_operation do
     %Operation{
       tags: ["chat"],
@@ -274,7 +299,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
           "content" => "Check this out :firefox:",
           "id" => "13",
           "chat_id" => "1",
-          "actor_id" => "someflakeid"
+          "actor_id" => "someflakeid",
+          "unread" => false
         },
         %{
           "actor_id" => "someflakeid",
@@ -282,7 +308,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do
           "id" => "12",
           "chat_id" => "1",
           "emojis" => [],
-          "created_at" => "2020-04-21T15:06:45.000Z"
+          "created_at" => "2020-04-21T15:06:45.000Z",
+          "unread" => false
         }
       ]
     }
index 29922da999dfdb109eff3c345d572ff988291b9b..01d47045dfac466e07cce8bcaa919bc610cacaaa 100644 (file)
@@ -24,7 +24,13 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
   plug(
     OAuthScopesPlug,
     %{scopes: ["write:statuses"]}
-    when action in [:post_chat_message, :create, :mark_as_read, :delete_message]
+    when action in [
+           :post_chat_message,
+           :create,
+           :mark_as_read,
+           :mark_message_as_read,
+           :delete_message
+         ]
   )
 
   plug(
@@ -88,6 +94,21 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
     end
   end
 
+  def mark_message_as_read(%{assigns: %{user: %{id: user_id} = user}} = conn, %{
+        id: chat_id,
+        message_id: message_id
+      }) do
+    with %ChatMessageReference{} = cm_ref <-
+           ChatMessageReference.get_by_id(message_id),
+         ^chat_id <- cm_ref.chat_id |> to_string(),
+         %Chat{user_id: ^user_id} <- Chat.get_by_id(chat_id),
+         {:ok, cm_ref} <- ChatMessageReference.mark_as_read(cm_ref) do
+      conn
+      |> put_view(ChatMessageReferenceView)
+      |> render("show.json", for: user, chat_message_reference: cm_ref)
+    end
+  end
+
   def mark_as_read(%{assigns: %{user: %{id: user_id}}} = conn, %{id: id}) do
     with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id),
          {_n, _} <- ChatMessageReference.set_all_seen_for_chat(chat) do
index fef277ac6c839b473474eee5286cebfe08ad67e6..fd2dc82ca27a1f2edb9633fc8058482c4ed12327 100644 (file)
@@ -313,6 +313,7 @@ defmodule Pleroma.Web.Router do
       post("/chats/:id/messages", ChatController, :post_chat_message)
       delete("/chats/:id/messages/:message_id", ChatController, :delete_message)
       post("/chats/:id/read", ChatController, :mark_as_read)
+      post("/chats/:id/messages/:message_id/read", ChatController, :mark_message_as_read)
 
       get("/conversations/:id/statuses", ConversationController, :statuses)
       get("/conversations/:id", ConversationController, :show)
index e62b717995c941f7c4d4457fee7b32dd986a1aaf..e7892142a3cfce7dc05c9c8eca163122c928c5b5 100644 (file)
@@ -13,6 +13,33 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
 
   import Pleroma.Factory
 
+  describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do
+    setup do: oauth_access(["write:statuses"])
+
+    test "it marks one message as read", %{conn: conn, user: user} do
+      other_user = insert(:user)
+
+      {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
+      {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
+      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
+      object = Object.normalize(create, false)
+      cm_ref = ChatMessageReference.for_chat_and_object(chat, object)
+
+      assert cm_ref.seen == false
+
+      result =
+        conn
+        |> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read")
+        |> json_response_and_validate_schema(200)
+
+      assert result["unread"] == false
+
+      cm_ref = ChatMessageReference.for_chat_and_object(chat, object)
+
+      assert cm_ref.seen == true
+    end
+  end
+
   describe "POST /api/v1/pleroma/chats/:id/read" do
     setup do: oauth_access(["write:statuses"])
 
@@ -20,6 +47,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
       other_user = insert(:user)
 
       {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
+      {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
       {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
       object = Object.normalize(create, false)
       cm_ref = ChatMessageReference.for_chat_and_object(chat, object)