Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/conversation.ex b/lib/conversation.ex
index 3d53e91b7..6eedc72b6 100644
--- a/lib/conversation.ex
+++ b/lib/conversation.ex
@@ -1,70 +1,70 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Conversation do
alias Pleroma.Repo
alias Pleroma.Conversation.Participation
alias Pleroma.User
use Ecto.Schema
import Ecto.Changeset
schema "conversations" do
# This is the context ap id.
field(:ap_id, :string)
has_many(:participations, Participation)
timestamps()
end
def creation_cng(struct, params) do
struct
|> cast(params, [:ap_id])
|> validate_required([:ap_id])
|> unique_constraint(:ap_id)
end
def create_for_ap_id(ap_id) do
%__MODULE__{}
|> creation_cng(%{ap_id: ap_id})
|> Repo.insert(
on_conflict: [set: [updated_at: NaiveDateTime.utc_now()]],
returning: true,
conflict_target: :ap_id
)
end
def get_for_ap_id(ap_id) do
Repo.get_by(__MODULE__, ap_id: ap_id)
end
@doc """
This will
1. Create a conversation if there isn't one already
2. Create a participation for all the people involved who don't have one already
3. Bump all relevant participations to 'unread'
"""
def create_or_bump_for(activity) do
with true <- Pleroma.Web.ActivityPub.Visibility.is_direct?(activity),
"Create" <- activity.data["type"],
"Note" <- activity.data["object"]["type"],
ap_id when is_binary(ap_id) <- activity.data["object"]["context"] do
{:ok, conversation} = create_for_ap_id(ap_id)
- local_users = User.get_users_from_set(activity.recipients, true)
+ users = User.get_users_from_set(activity.recipients)
participations =
- Enum.map(local_users, fn user ->
+ Enum.map(users, fn user ->
{:ok, participation} =
Participation.create_for_user_and_conversation(user, conversation)
participation
end)
%{
conversation
| participations: participations
}
end
end
end
diff --git a/lib/conversation/participation.ex b/lib/conversation/participation.ex
index a58d0ca0d..23e6409f1 100644
--- a/lib/conversation/participation.ex
+++ b/lib/conversation/participation.ex
@@ -1,53 +1,62 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Conversation.Participation do
use Ecto.Schema
alias Pleroma.User
alias Pleroma.Conversation
alias Pleroma.Repo
import Ecto.Changeset
+ import Ecto.Query
schema "conversation_participations" do
belongs_to(:user, User, type: Pleroma.FlakeId)
belongs_to(:conversation, Conversation)
field(:read, :boolean, default: false)
timestamps()
end
def creation_cng(struct, params) do
struct
|> cast(params, [:user_id, :conversation_id])
|> validate_required([:user_id, :conversation_id])
end
def create_for_user_and_conversation(user, conversation) do
%__MODULE__{}
|> creation_cng(%{user_id: user.id, conversation_id: conversation.id})
|> Repo.insert(
on_conflict: [set: [read: false, updated_at: NaiveDateTime.utc_now()]],
returning: true,
conflict_target: [:user_id, :conversation_id]
)
end
def read_cng(struct, params) do
struct
|> cast(params, [:read])
|> validate_required([:read])
end
def mark_as_read(participation) do
participation
|> read_cng(%{read: true})
|> Repo.update()
end
def mark_as_unread(participation) do
participation
|> read_cng(%{read: false})
|> Repo.update()
end
+
+ def for_user(user, params \\ %{}) do
+ from(p in __MODULE__,
+ where: p.user_id == ^user.id,
+ order_by: [desc: p.updated_at]
+ )
+ |> Pleroma.Pagination.fetch_paginated(params)
+ end
end
diff --git a/test/conversation/participation_test.exs b/test/conversation/participation_test.exs
index 4e7d9dc92..c52b4ed88 100644
--- a/test/conversation/participation_test.exs
+++ b/test/conversation/participation_test.exs
@@ -1,54 +1,84 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Conversation.ParticipationTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Conversation.Participation
+ alias Pleroma.Web.CommonAPI
test "it creates a participation for a conversation and a user" do
user = insert(:user)
conversation = insert(:conversation)
{:ok, %Participation{} = participation} =
Participation.create_for_user_and_conversation(user, conversation)
assert participation.user_id == user.id
assert participation.conversation_id == conversation.id
:timer.sleep(1000)
# Creating again returns the same participation
{:ok, %Participation{} = participation_two} =
Participation.create_for_user_and_conversation(user, conversation)
assert participation.id == participation_two.id
refute participation.updated_at == participation_two.updated_at
end
test "recreating an existing participations sets it to unread" do
participation = insert(:participation, %{read: true})
{:ok, participation} =
Participation.create_for_user_and_conversation(
participation.user,
participation.conversation
)
refute participation.read
end
test "it marks a participation as read" do
participation = insert(:participation, %{read: false})
{:ok, participation} = Participation.mark_as_read(participation)
assert participation.read
end
test "it marks a participation as unread" do
participation = insert(:participation, %{read: true})
{:ok, participation} = Participation.mark_as_unread(participation)
refute participation.read
end
+
+ test "gets all the participations for a user, ordered by updated at descending" do
+ user = insert(:user)
+ {:ok, activity_one} = CommonAPI.post(user, %{"status" => "x", "visibility" => "direct"})
+ :timer.sleep(1000)
+ {:ok, activity_two} = CommonAPI.post(user, %{"status" => "x", "visibility" => "direct"})
+ :timer.sleep(1000)
+
+ {:ok, activity_three} =
+ CommonAPI.post(user, %{
+ "status" => "x",
+ "visibility" => "direct",
+ "in_reply_to_status_id" => activity_one.id
+ })
+
+ assert [participation_one, participation_two] =
+ Participation.for_user(user)
+ |> Repo.preload(:conversation)
+
+ assert participation_one.conversation.ap_id == activity_three.data["object"]["context"]
+ assert participation_two.conversation.ap_id == activity_two.data["object"]["context"]
+
+ # Pagination
+ assert [participation_one] =
+ Participation.for_user(user, %{limit: 1})
+ |> Repo.preload(:conversation)
+
+ assert participation_one.conversation.ap_id == activity_three.data["object"]["context"]
+ end
end

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 31, 4:47 PM (16 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1801601
Default Alt Text
(7 KB)

Event Timeline