Chats: Basic implementation.
This commit is contained in:
		
							parent
							
								
									037b49c415
								
							
						
					
					
						commit
						fd97b0e634
					
				
					 3 changed files with 101 additions and 0 deletions
				
			
		
							
								
								
									
										41
									
								
								lib/pleroma/chat.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								lib/pleroma/chat.ex
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Chat do
 | 
			
		||||
  use Ecto.Schema
 | 
			
		||||
  import Ecto.Changeset
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Repo
 | 
			
		||||
 | 
			
		||||
  @moduledoc """
 | 
			
		||||
  Chat keeps a reference to DirectMessage conversations between a user and an recipient. The recipient can be a user (for now) or a group (not implemented yet).
 | 
			
		||||
 | 
			
		||||
  It is a helper only, to make it easy to display a list of chats with other people, ordered by last bump. The actual messages are retrieved by querying the recipients of the ChatMessages.
 | 
			
		||||
  """
 | 
			
		||||
 | 
			
		||||
  schema "chats" do
 | 
			
		||||
    belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
 | 
			
		||||
    field(:recipient, :string)
 | 
			
		||||
    field(:unread, :integer, default: 0)
 | 
			
		||||
 | 
			
		||||
    timestamps()
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def creation_cng(struct, params) do
 | 
			
		||||
    struct
 | 
			
		||||
    |> cast(params, [:user_id, :recipient])
 | 
			
		||||
    |> validate_required([:user_id, :recipient])
 | 
			
		||||
    |> unique_constraint(:user_id, name: :chats_user_id_recipient_index)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_or_create(user_id, recipient) do
 | 
			
		||||
    %__MODULE__{}
 | 
			
		||||
    |> creation_cng(%{user_id: user_id, recipient: recipient})
 | 
			
		||||
    |> Repo.insert(
 | 
			
		||||
      on_conflict: [set: [updated_at: NaiveDateTime.utc_now()]],
 | 
			
		||||
      conflict_target: [:user_id, :recipient]
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										16
									
								
								priv/repo/migrations/20200309123730_create_chats.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								priv/repo/migrations/20200309123730_create_chats.exs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
defmodule Pleroma.Repo.Migrations.CreateChats do
 | 
			
		||||
  use Ecto.Migration
 | 
			
		||||
 | 
			
		||||
  def change do
 | 
			
		||||
    create table(:chats) do
 | 
			
		||||
      add(:user_id, references(:users, type: :uuid))
 | 
			
		||||
      # Recipient is an ActivityPub id, to future-proof for group support.
 | 
			
		||||
      add(:recipient, :string)
 | 
			
		||||
      add(:unread, :integer, default: 0)
 | 
			
		||||
      timestamps()
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # There's only one chat between a user and a recipient.
 | 
			
		||||
    create(index(:chats, [:user_id, :recipient], unique: true))
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										44
									
								
								test/chat_test.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								test/chat_test.exs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.ChatTest do
 | 
			
		||||
  use Pleroma.DataCase, async: true
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Chat
 | 
			
		||||
 | 
			
		||||
  import Pleroma.Factory
 | 
			
		||||
 | 
			
		||||
  describe "creation and getting" do
 | 
			
		||||
    test "it creates a chat for a user and recipient" do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      other_user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
 | 
			
		||||
 | 
			
		||||
      assert chat.id
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "it returns a chat for a user and recipient if it already exists" do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      other_user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
 | 
			
		||||
      {:ok, chat_two} = Chat.get_or_create(user.id, other_user.ap_id)
 | 
			
		||||
 | 
			
		||||
      assert chat.id == chat_two.id
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "a returning chat will have an updated `update_at` field" do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      other_user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
 | 
			
		||||
      :timer.sleep(1500)
 | 
			
		||||
      {:ok, chat_two} = Chat.get_or_create(user.id, other_user.ap_id)
 | 
			
		||||
 | 
			
		||||
      assert chat.id == chat_two.id
 | 
			
		||||
      assert chat.updated_at != chat_two.updated_at
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
		Reference in a new issue