SideEffects / ChatView: Add an unread cache.
authorlain <lain@soykaf.club>
Fri, 5 Jun 2020 10:01:33 +0000 (12:01 +0200)
committerlain <lain@soykaf.club>
Fri, 5 Jun 2020 10:01:33 +0000 (12:01 +0200)
This is to prevent wrong values in the stream.

lib/pleroma/web/activity_pub/side_effects.ex
lib/pleroma/web/pleroma_api/views/chat_view.ex
lib/pleroma/web/streamer/streamer.ex
lib/pleroma/web/views/streamer_view.ex
test/web/pleroma_api/views/chat_view_test.exs

index e9f109d8012004fe39eb40d9ab1b41fac2b77129..992c04ac131fb5c30c557599121b80661a693d74 100644 (file)
@@ -142,6 +142,11 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
           {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
           {:ok, cm_ref} = ChatMessageReference.create(chat, object, user.ap_id != actor.ap_id)
 
+          # We add a cache of the unread value here so that it doesn't change when being streamed out
+          chat =
+            chat
+            |> Map.put(:unread, ChatMessageReference.unread_count_for_chat(chat))
+
           Streamer.stream(
             ["user", "user:pleroma_chat"],
             {user, %{cm_ref | chat: chat, object: object}}
index c903a71fde3d6f2bcd5642a5b049135469eeee5e..91d50dd1e4e94984097cd1c9e2a705a898e9e91b 100644 (file)
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatView do
     %{
       id: chat.id |> to_string(),
       account: AccountView.render("show.json", Map.put(opts, :user, recipient)),
-      unread: ChatMessageReference.unread_count_for_chat(chat),
+      unread: Map.get(chat, :unread) || ChatMessageReference.unread_count_for_chat(chat),
       last_message:
         last_message &&
           ChatMessageReferenceView.render("show.json", chat_message_reference: last_message),
index 5e37e2cf2d80c2299cff77a75f2bcb1dd2e43b87..b22297955f084931875268eba9c568bf5b2fe61e 100644 (file)
@@ -90,34 +90,20 @@ defmodule Pleroma.Web.Streamer do
     if should_env_send?(), do: Registry.unregister(@registry, topic)
   end
 
-  def stream(topics, item) when is_list(topics) do
+  def stream(topics, items) do
     if should_env_send?() do
-      Enum.each(topics, fn t ->
-        spawn(fn -> do_stream(t, item) end)
+      List.wrap(topics)
+      |> Enum.each(fn topic ->
+        List.wrap(items)
+        |> Enum.each(fn item ->
+          spawn(fn -> do_stream(topic, item) end)
+        end)
       end)
     end
 
     :ok
   end
 
-  def stream(topic, items) when is_list(items) do
-    if should_env_send?() do
-      Enum.each(items, fn i ->
-        spawn(fn -> do_stream(topic, i) end)
-      end)
-
-      :ok
-    end
-  end
-
-  def stream(topic, item) do
-    if should_env_send?() do
-      spawn(fn -> do_stream(topic, item) end)
-    end
-
-    :ok
-  end
-
   def filtered_by_user?(%User{} = user, %Activity{} = item) do
     %{block: blocked_ap_ids, mute: muted_ap_ids, reblog_mute: reblog_muted_ap_ids} =
       User.outgoing_relationships_ap_ids(user, [:block, :mute, :reblog_mute])
index a6efd01090d9fced2d3b0e8dd49fc358ef12bbf5..b000e7ce03ea90a8803e06683a7f7c431d9f3c46 100644 (file)
@@ -55,6 +55,8 @@ defmodule Pleroma.Web.StreamerView do
     # Explicitly giving the cmr for the object here, so we don't accidentally
     # send a later 'last_message' that was inserted between inserting this and
     # streaming it out
+    # 
+    # It also contains the chat with a cache of the correct unread count
     Logger.debug("Trying to stream out #{inspect(cm_ref)}")
 
     representation =
index f3bd12616a5063a2d0ba60c4ae73b3d6d54af4ff..f77584dd1f7c2a99ff10e555fc001d03476664ad 100644 (file)
@@ -16,6 +16,21 @@ defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
 
   import Pleroma.Factory
 
+  test "giving a chat with an 'unread' field, it uses that" do
+    user = insert(:user)
+    recipient = insert(:user)
+
+    {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
+
+    chat =
+      chat
+      |> Map.put(:unread, 5)
+
+    represented_chat = ChatView.render("show.json", chat: chat)
+
+    assert represented_chat[:unread] == 5
+  end
+
   test "it represents a chat" do
     user = insert(:user)
     recipient = insert(:user)