Merge branch 'develop' into 'remove-twitter-api'
[akkoma] / lib / pleroma / conversation / participation.ex
index 176b82a2092e46cd48745c719a5f4c6fd4dd206d..51bb1bda94d43e85043d3c930896f4462565a2ca 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Conversation.Participation do
@@ -64,11 +64,13 @@ defmodule Pleroma.Conversation.Participation do
   end
 
   def mark_as_read(participation) do
-    participation
-    |> read_cng(%{read: true})
-    |> Repo.update()
+    __MODULE__
+    |> where(id: ^participation.id)
+    |> update(set: [read: true])
+    |> select([p], p)
+    |> Repo.update_all([])
     |> case do
-      {:ok, participation} ->
+      {1, [participation]} ->
         participation = Repo.preload(participation, :user)
         User.set_unread_conversation_count(participation.user)
         {:ok, participation}
@@ -122,9 +124,32 @@ defmodule Pleroma.Conversation.Participation do
       order_by: [desc: p.updated_at],
       preload: [conversation: [:users]]
     )
+    |> restrict_recipients(user, params)
     |> Pleroma.Pagination.fetch_paginated(params)
   end
 
+  def restrict_recipients(query, user, %{recipients: user_ids}) do
+    user_binary_ids =
+      [user.id | user_ids]
+      |> Enum.uniq()
+      |> User.binary_id()
+
+    conversation_subquery =
+      __MODULE__
+      |> group_by([p], p.conversation_id)
+      |> having(
+        [p],
+        count(p.user_id) == ^length(user_binary_ids) and
+          fragment("array_agg(?) @> ?", p.user_id, ^user_binary_ids)
+      )
+      |> select([p], %{id: p.conversation_id})
+
+    query
+    |> join(:inner, [p], c in subquery(conversation_subquery), on: p.conversation_id == c.id)
+  end
+
+  def restrict_recipients(query, _, _), do: query
+
   def for_user_and_conversation(user, conversation) do
     from(p in __MODULE__,
       where: p.user_id == ^user.id,
@@ -147,7 +172,7 @@ defmodule Pleroma.Conversation.Participation do
         | last_activity_id: activity_id
       }
     end)
-    |> Enum.filter(& &1.last_activity_id)
+    |> Enum.reject(&is_nil(&1.last_activity_id))
   end
 
   def get(_, _ \\ [])