Marker: added unread_count field

This commit is contained in:
Maksim Pechnikov 2019-10-22 13:42:59 +03:00
parent 6281e4795a
commit d4270397dc
5 changed files with 61 additions and 5 deletions

View file

@ -18,6 +18,7 @@ defmodule Pleroma.Marker do
field(:last_read_id, :string, default: "") field(:last_read_id, :string, default: "")
field(:timeline, :string, default: "") field(:timeline, :string, default: "")
field(:lock_version, :integer, default: 0) field(:lock_version, :integer, default: 0)
field(:unread_count, :integer, default: 0)
belongs_to(:user, User, type: FlakeId.Ecto.CompatType) belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
timestamps() timestamps()
@ -38,7 +39,7 @@ def upsert(%User{} = user, attrs) do
Multi.insert(multi, timeline, marker, Multi.insert(multi, timeline, marker,
returning: true, returning: true,
on_conflict: {:replace, [:last_read_id]}, on_conflict: {:replace, [:last_read_id, :unread_count]},
conflict_target: [:user_id, :timeline] conflict_target: [:user_id, :timeline]
) )
end) end)
@ -55,7 +56,7 @@ defp get_marker(user, timeline) do
@doc false @doc false
defp changeset(marker, attrs) do defp changeset(marker, attrs) do
marker marker
|> cast(attrs, [:last_read_id]) |> cast(attrs, [:last_read_id, :unread_count])
|> validate_required([:user_id, :timeline, :last_read_id]) |> validate_required([:user_id, :timeline, :last_read_id])
|> validate_inclusion(:timeline, @timelines) |> validate_inclusion(:timeline, @timelines)
end end

View file

@ -10,6 +10,7 @@ def render("markers.json", %{markers: markers}) do
Map.put_new(acc, m.timeline, %{ Map.put_new(acc, m.timeline, %{
last_read_id: m.last_read_id, last_read_id: m.last_read_id,
version: m.lock_version, version: m.lock_version,
unread_count: m.unread_count,
updated_at: NaiveDateTime.to_iso8601(m.updated_at) updated_at: NaiveDateTime.to_iso8601(m.updated_at)
}) })
end) end)

View file

@ -0,0 +1,49 @@
defmodule Pleroma.Repo.Migrations.AddUnreadToMarker do
use Ecto.Migration
import Ecto.Query
alias Pleroma.Repo
alias Pleroma.Notification
def up do
alter table(:markers) do
add_if_not_exists(:unread_count, :integer, default: 0)
end
flush()
update_markers()
end
def down do
alter table(:markers) do
remove_if_exists(:unread_count, :integer)
end
end
def update_markers do
from(q in Notification,
select: %{
timeline: "notifications",
user_id: q.user_id,
unread_count: fragment("COUNT(*) FILTER (WHERE seen = false) as unread_count"),
last_read_id: fragment("(MAX(id) FILTER (WHERE seen = true)::text) as last_read_id ")
},
group_by: [q.user_id]
)
|> Repo.all()
|> Enum.reduce(Ecto.Multi.new(), fn attrs, multi ->
marker =
Pleroma.Marker
|> struct(attrs)
|> Ecto.Changeset.change()
multi
|> Ecto.Multi.insert(attrs[:user_id], marker,
returning: true,
on_conflict: {:replace, [:last_read_id, :unread_count]},
conflict_target: [:user_id, :timeline]
)
end)
|> Pleroma.Repo.transaction()
end
end

View file

@ -15,7 +15,7 @@ test "gets markers with correct scopes", %{conn: conn} do
{:ok, %{"notifications" => marker}} = {:ok, %{"notifications" => marker}} =
Pleroma.Marker.upsert( Pleroma.Marker.upsert(
user, user,
%{"notifications" => %{"last_read_id" => "69420"}} %{"notifications" => %{"last_read_id" => "69420", "unread_count" => 7}}
) )
response = response =
@ -28,6 +28,7 @@ test "gets markers with correct scopes", %{conn: conn} do
assert response == %{ assert response == %{
"notifications" => %{ "notifications" => %{
"last_read_id" => "69420", "last_read_id" => "69420",
"unread_count" => 7,
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at), "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
"version" => 0 "version" => 0
} }
@ -70,7 +71,8 @@ test "creates a marker with correct scopes", %{conn: conn} do
"notifications" => %{ "notifications" => %{
"last_read_id" => "69420", "last_read_id" => "69420",
"updated_at" => _, "updated_at" => _,
"version" => 0 "version" => 0,
"unread_count" => 0
} }
} = response } = response
end end
@ -98,6 +100,7 @@ test "updates exist marker", %{conn: conn} do
assert response == %{ assert response == %{
"notifications" => %{ "notifications" => %{
"last_read_id" => "69888", "last_read_id" => "69888",
"unread_count" => 0,
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at), "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
"version" => 0 "version" => 0
} }

View file

@ -8,17 +8,19 @@ defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do
import Pleroma.Factory import Pleroma.Factory
test "returns markers" do test "returns markers" do
marker1 = insert(:marker, timeline: "notifications", last_read_id: "17") marker1 = insert(:marker, timeline: "notifications", last_read_id: "17", unread_count: 5)
marker2 = insert(:marker, timeline: "home", last_read_id: "42") marker2 = insert(:marker, timeline: "home", last_read_id: "42")
assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{ assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{
"home" => %{ "home" => %{
last_read_id: "42", last_read_id: "42",
unread_count: 0,
updated_at: NaiveDateTime.to_iso8601(marker2.updated_at), updated_at: NaiveDateTime.to_iso8601(marker2.updated_at),
version: 0 version: 0
}, },
"notifications" => %{ "notifications" => %{
last_read_id: "17", last_read_id: "17",
unread_count: 5,
updated_at: NaiveDateTime.to_iso8601(marker1.updated_at), updated_at: NaiveDateTime.to_iso8601(marker1.updated_at),
version: 0 version: 0
} }