added recount unread notifications to markers
authorMaksim Pechnikov <parallel588@gmail.com>
Fri, 15 Nov 2019 19:10:41 +0000 (22:10 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Fri, 15 Nov 2019 19:46:58 +0000 (22:46 +0300)
lib/pleroma/marker.ex
lib/pleroma/web/mastodon_api/controllers/marker_controller.ex
test/marker_test.exs
test/web/mastodon_api/controllers/marker_controller_test.exs

index a3254609488cfc3136b1d2b9ecad3c335be6a4fa..2d217a0b7a7a83e580fe2cecfa837a25fff58fff 100644 (file)
@@ -15,6 +15,7 @@ defmodule Pleroma.Marker do
   alias __MODULE__
 
   @timelines ["notifications"]
+  @type t :: %__MODULE__{}
 
   schema "markers" do
     field(:last_read_id, :string, default: "")
@@ -26,8 +27,18 @@ defmodule Pleroma.Marker do
     timestamps()
   end
 
-  def get_markers(user, timelines \\ []) do
-    Repo.all(get_query(user, timelines))
+  @doc """
+  Gets markers by user and timeline.
+
+  opts:
+  `recount_unread` - run force recount unread notifications for `true` value
+  """
+  @spec get_markers(User.t(), list(String), map()) :: list(t())
+  def get_markers(user, timelines \\ [], opts \\ %{}) do
+    user
+    |> get_query(timelines)
+    |> recount_unread_notifications(opts[:recount_unread])
+    |> Repo.all()
   end
 
   def upsert(%User{} = user, attrs) do
@@ -99,4 +110,18 @@ defmodule Pleroma.Marker do
     |> by_user_id(user.id)
     |> by_timeline(timelines)
   end
+
+  defp recount_unread_notifications(query, true) do
+    from(
+      q in query,
+      left_join: n in "notifications",
+      on: n.user_id == q.user_id and n.seen == false,
+      group_by: [:id],
+      select_merge: %{
+        unread_count: fragment("count(?)", n.id)
+      }
+    )
+  end
+
+  defp recount_unread_notifications(query, _), do: query
 end
index ce025624d3f0d8ca1997d8d0a72ff6149e146757..6649ffbda106eb5b1f0401f115f957075d9657c6 100644 (file)
@@ -18,7 +18,13 @@ defmodule Pleroma.Web.MastodonAPI.MarkerController do
 
   # GET /api/v1/markers
   def index(%{assigns: %{user: user}} = conn, params) do
-    markers = Pleroma.Marker.get_markers(user, params["timeline"])
+    markers =
+      Pleroma.Marker.get_markers(
+        user,
+        params["timeline"],
+        %{recount_unread: true}
+      )
+
     render(conn, "markers.json", %{markers: markers})
   end
 
index 5d03db48ef1c7b42ec83ee08d8f2df37419012e5..7b1d2218ab0f57c566a70e61472450d1d41f5069 100644 (file)
@@ -36,6 +36,20 @@ defmodule Pleroma.MarkerTest do
       insert(:marker, timeline: "home", user: user)
       assert Marker.get_markers(user, ["notifications"]) == [refresh_record(marker)]
     end
+
+    test "returns user markers with recount unread notifications" do
+      user = insert(:user)
+      marker = insert(:marker, user: user)
+      insert(:notification, user: user)
+      insert(:notification, user: user)
+      insert(:marker, timeline: "home", user: user)
+
+      assert Marker.get_markers(
+               user,
+               ["notifications"],
+               %{recount_unread: true}
+             ) == [%Marker{refresh_record(marker) | unread_count: 2}]
+    end
   end
 
   describe "upsert/2" do
index 8bcfcb7e1303f3ef205906314a187477e7a8cd7b..64bf79bb1e482508e97cf374b7bcfaac8316da68 100644 (file)
@@ -11,11 +11,12 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
     test "gets markers with correct scopes", %{conn: conn} do
       user = insert(:user)
       token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
+      insert_list(7, :notification, user: user)
 
       {:ok, %{"notifications" => marker}} =
         Pleroma.Marker.upsert(
           user,
-          %{"notifications" => %{"last_read_id" => "69420", "unread_count" => 7}}
+          %{"notifications" => %{"last_read_id" => "69420"}}
         )
 
       response =