From 801e668a97adff4a33451dd7bb48799562ed8796 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 7 Jun 2020 15:38:33 +0200 Subject: [PATCH] ChatController: Add `last_read_id` option to mark_as_read. --- lib/pleroma/chat/message_reference.ex | 20 +++++++++++----- .../web/api_spec/operations/chat_operation.ex | 18 ++++++++++++++ .../controllers/chat_controller.ex | 3 ++- .../controllers/chat_controller_test.exs | 24 +++++++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/chat/message_reference.ex b/lib/pleroma/chat/message_reference.ex index 7ee7508ca..131ae0186 100644 --- a/lib/pleroma/chat/message_reference.ex +++ b/lib/pleroma/chat/message_reference.ex @@ -98,12 +98,20 @@ def mark_as_read(cm_ref) do |> Repo.update() end - def set_all_seen_for_chat(chat) do - chat - |> for_chat_query() - |> exclude(:order_by) - |> exclude(:preload) - |> where([cmr], cmr.unread == true) + def set_all_seen_for_chat(chat, last_read_id \\ nil) do + query = + chat + |> for_chat_query() + |> exclude(:order_by) + |> exclude(:preload) + |> where([cmr], cmr.unread == true) + + if last_read_id do + query + |> where([cmr], cmr.id <= ^last_read_id) + else + query + end |> Repo.update_all(set: [unread: false]) end end diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex index 74c3ad0bd..45fbad311 100644 --- a/lib/pleroma/web/api_spec/operations/chat_operation.ex +++ b/lib/pleroma/web/api_spec/operations/chat_operation.ex @@ -23,6 +23,7 @@ def mark_as_read_operation do summary: "Mark all messages in the chat as read", operationId: "ChatController.mark_as_read", parameters: [Operation.parameter(:id, :path, :string, "The ID of the Chat")], + requestBody: request_body("Parameters", mark_as_read()), responses: %{ 200 => Operation.response( @@ -333,4 +334,21 @@ def chat_message_create do } } end + + def mark_as_read do + %Schema{ + title: "MarkAsReadRequest", + description: "POST body for marking a number of chat messages as read", + type: :object, + properties: %{ + last_read_id: %Schema{ + type: :string, + description: "The content of your message. Optional." + } + }, + example: %{ + "last_read_id" => "abcdef12456" + } + } + end end diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex index 983550b13..002b75082 100644 --- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex @@ -111,7 +111,8 @@ def mark_message_as_read(%{assigns: %{user: %{id: user_id} = user}} = conn, %{ 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, _} <- MessageReference.set_all_seen_for_chat(chat) do + {_n, _} <- + MessageReference.set_all_seen_for_chat(chat, conn.body_params[:last_read_id]) do conn |> put_view(ChatView) |> render("show.json", chat: chat) diff --git a/test/web/pleroma_api/controllers/chat_controller_test.exs b/test/web/pleroma_api/controllers/chat_controller_test.exs index 2128fd9dd..63cd89c73 100644 --- a/test/web/pleroma_api/controllers/chat_controller_test.exs +++ b/test/web/pleroma_api/controllers/chat_controller_test.exs @@ -65,6 +65,30 @@ test "it marks all messages in a chat as read", %{conn: conn, user: user} do assert cm_ref.unread == false end + + test "it given a `last_read_id` ", %{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 = MessageReference.for_chat_and_object(chat, object) + + assert cm_ref.unread == true + + result = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id}) + |> json_response_and_validate_schema(200) + + assert result["unread"] == 1 + + cm_ref = MessageReference.for_chat_and_object(chat, object) + + assert cm_ref.unread == false + end end describe "POST /api/v1/pleroma/chats/:id/messages" do