summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2019-08-02 11:55:41 +0200
committerlain <lain@soykaf.club>2019-08-02 11:55:41 +0200
commitf88560accd801ac88c60344cef93ef00cf136069 (patch)
treed74e2ef97428b9f64a66fb253b3c7baffab480f1
parentfd4b7239cd6f44a25c9aa4195750e94e0612a3b1 (diff)
downloadpleroma-f88560accd801ac88c60344cef93ef00cf136069.tar.gz
pleroma-f88560accd801ac88c60344cef93ef00cf136069.zip
Conversations: Add recipient list to conversation participation.
This enables to address the same group of people every time.
-rw-r--r--lib/pleroma/conversation.ex11
-rw-r--r--lib/pleroma/conversation/participation.ex4
-rw-r--r--lib/pleroma/conversation/participation_recipient_ship.ex34
-rw-r--r--lib/pleroma/user.ex7
-rw-r--r--priv/repo/migrations/20190205114625_create_thread_mutes.exs2
-rw-r--r--priv/repo/migrations/20190801154554_create_conversation_participation_recipient_ships.exs13
-rw-r--r--test/conversation/participation_test.exs30
7 files changed, 100 insertions, 1 deletions
diff --git a/lib/pleroma/conversation.ex b/lib/pleroma/conversation.ex
index bc97b39ca..fb0dfedca 100644
--- a/lib/pleroma/conversation.ex
+++ b/lib/pleroma/conversation.ex
@@ -4,6 +4,7 @@
defmodule Pleroma.Conversation do
alias Pleroma.Conversation.Participation
+ alias Pleroma.Conversation.Participation.RecipientShip
alias Pleroma.Repo
alias Pleroma.User
use Ecto.Schema
@@ -39,6 +40,15 @@ defmodule Pleroma.Conversation do
Repo.get_by(__MODULE__, ap_id: ap_id)
end
+ def maybe_set_recipients(participation, activity) do
+ participation = Repo.preload(participation, :recipients)
+
+ if participation.recipients |> Enum.empty?() do
+ recipients = User.get_all_by_ap_id(activity.recipients)
+ RecipientShip.create(recipients, participation)
+ end
+ end
+
@doc """
This will
1. Create a conversation if there isn't one already
@@ -60,6 +70,7 @@ defmodule Pleroma.Conversation do
{:ok, participation} =
Participation.create_for_user_and_conversation(user, conversation, opts)
+ maybe_set_recipients(participation, activity)
participation
end)
diff --git a/lib/pleroma/conversation/participation.ex b/lib/pleroma/conversation/participation.ex
index 77b3f61e9..121efb671 100644
--- a/lib/pleroma/conversation/participation.ex
+++ b/lib/pleroma/conversation/participation.ex
@@ -5,6 +5,7 @@
defmodule Pleroma.Conversation.Participation do
use Ecto.Schema
alias Pleroma.Conversation
+ alias Pleroma.Conversation.Participation.RecipientShip
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -17,6 +18,9 @@ defmodule Pleroma.Conversation.Participation do
field(:read, :boolean, default: false)
field(:last_activity_id, Pleroma.FlakeId, virtual: true)
+ has_many(:recipient_ships, RecipientShip)
+ has_many(:recipients, through: [:recipient_ships, :user])
+
timestamps()
end
diff --git a/lib/pleroma/conversation/participation_recipient_ship.ex b/lib/pleroma/conversation/participation_recipient_ship.ex
new file mode 100644
index 000000000..27c0c89cd
--- /dev/null
+++ b/lib/pleroma/conversation/participation_recipient_ship.ex
@@ -0,0 +1,34 @@
+# 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.RecipientShip do
+ use Ecto.Schema
+
+ alias Pleroma.Conversation.Participation
+ alias Pleroma.User
+ alias Pleroma.Repo
+
+ import Ecto.Changeset
+
+ schema "conversation_participation_recipient_ships" do
+ belongs_to(:user, User, type: Pleroma.FlakeId)
+ belongs_to(:participation, Participation)
+ end
+
+ def creation_cng(struct, params) do
+ struct
+ |> cast(params, [:user_id, :participation_id])
+ |> validate_required([:user_id, :participation_id])
+ end
+
+ def create(%User{} = user, participation), do: create([user], participation)
+
+ def create(users, participation) do
+ Enum.each(users, fn user ->
+ %__MODULE__{}
+ |> creation_cng(%{user_id: user.id, participation_id: participation.id})
+ |> Repo.insert!()
+ end)
+ end
+end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 6e2fd3af8..a021e77f0 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -450,6 +450,13 @@ defmodule Pleroma.User do
Repo.get_by(User, ap_id: ap_id)
end
+ def get_all_by_ap_id(ap_ids) do
+ from(u in __MODULE__,
+ where: u.ap_id in ^ap_ids
+ )
+ |> Repo.all()
+ end
+
# This is mostly an SPC migration fix. This guesses the user nickname by taking the last part
# of the ap_id and the domain and tries to get that user
def get_by_guessed_nickname(ap_id) do
diff --git a/priv/repo/migrations/20190205114625_create_thread_mutes.exs b/priv/repo/migrations/20190205114625_create_thread_mutes.exs
index 7e44db121..baaf07253 100644
--- a/priv/repo/migrations/20190205114625_create_thread_mutes.exs
+++ b/priv/repo/migrations/20190205114625_create_thread_mutes.exs
@@ -6,7 +6,7 @@ defmodule Pleroma.Repo.Migrations.CreateThreadMutes do
add :user_id, references(:users, type: :uuid, on_delete: :delete_all)
add :context, :string
end
-
+
create_if_not_exists unique_index(:thread_mutes, [:user_id, :context], name: :unique_index)
end
end
diff --git a/priv/repo/migrations/20190801154554_create_conversation_participation_recipient_ships.exs b/priv/repo/migrations/20190801154554_create_conversation_participation_recipient_ships.exs
new file mode 100644
index 000000000..c6e3469d5
--- /dev/null
+++ b/priv/repo/migrations/20190801154554_create_conversation_participation_recipient_ships.exs
@@ -0,0 +1,13 @@
+defmodule Pleroma.Repo.Migrations.CreateConversationParticipationRecipientShips do
+ use Ecto.Migration
+
+ def change do
+ create_if_not_exists table(:conversation_participation_recipient_ships) do
+ add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
+ add(:participation_id, references(:conversation_participations, on_delete: :delete_all))
+ end
+
+ create_if_not_exists index(:conversation_participation_recipient_ships, [:user_id])
+ create_if_not_exists index(:conversation_participation_recipient_ships, [:participation_id])
+ end
+end
diff --git a/test/conversation/participation_test.exs b/test/conversation/participation_test.exs
index 2a03e5d67..4a3c397bd 100644
--- a/test/conversation/participation_test.exs
+++ b/test/conversation/participation_test.exs
@@ -8,6 +8,36 @@ defmodule Pleroma.Conversation.ParticipationTest do
alias Pleroma.Conversation.Participation
alias Pleroma.Web.CommonAPI
+ test "for a new conversation, it sets the recipents of the participation" do
+ user = insert(:user)
+ other_user = insert(:user)
+ third_user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{"status" => "Hey @#{other_user.nickname}.", "visibility" => "direct"})
+
+ [participation] = Participation.for_user(user)
+ participation = Pleroma.Repo.preload(participation, :recipients)
+
+ assert length(participation.recipients) == 2
+ assert user in participation.recipients
+ assert other_user in participation.recipients
+
+ # Mentioning another user in the same conversation will not add a new recipients.
+
+ {:ok, _activity} =
+ CommonAPI.post(user, %{
+ "in_reply_to_status_id" => activity.id,
+ "status" => "Hey @#{third_user.nickname}.",
+ "visibility" => "direct"
+ })
+
+ [participation] = Participation.for_user(user)
+ participation = Pleroma.Repo.preload(participation, :recipients)
+
+ assert length(participation.recipients) == 2
+ end
+
test "it creates a participation for a conversation and a user" do
user = insert(:user)
conversation = insert(:conversation)