ChatMessageReferences: Move tests
[akkoma] / lib / pleroma / chat.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Chat do
6 use Ecto.Schema
7
8 import Ecto.Changeset
9
10 alias Pleroma.Repo
11 alias Pleroma.User
12
13 @moduledoc """
14 Chat keeps a reference to ChatMessage conversations between a user and an recipient. The recipient can be a user (for now) or a group (not implemented yet).
15
16 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.
17 """
18
19 schema "chats" do
20 belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
21 field(:recipient, :string)
22 field(:unread, :integer, default: 0, read_after_writes: true)
23
24 timestamps()
25 end
26
27 def creation_cng(struct, params) do
28 struct
29 |> cast(params, [:user_id, :recipient, :unread])
30 |> validate_change(:recipient, fn
31 :recipient, recipient ->
32 case User.get_cached_by_ap_id(recipient) do
33 nil -> [recipient: "must be an existing user"]
34 _ -> []
35 end
36 end)
37 |> validate_required([:user_id, :recipient])
38 |> unique_constraint(:user_id, name: :chats_user_id_recipient_index)
39 end
40
41 def get_by_id(id) do
42 __MODULE__
43 |> Repo.get(id)
44 end
45
46 def get(user_id, recipient) do
47 __MODULE__
48 |> Repo.get_by(user_id: user_id, recipient: recipient)
49 end
50
51 def get_or_create(user_id, recipient) do
52 %__MODULE__{}
53 |> creation_cng(%{user_id: user_id, recipient: recipient})
54 |> Repo.insert(
55 # Need to set something, otherwise we get nothing back at all
56 on_conflict: [set: [recipient: recipient]],
57 returning: true,
58 conflict_target: [:user_id, :recipient]
59 )
60 end
61
62 def bump_or_create(user_id, recipient) do
63 %__MODULE__{}
64 |> creation_cng(%{user_id: user_id, recipient: recipient, unread: 1})
65 |> Repo.insert(
66 on_conflict: [set: [updated_at: NaiveDateTime.utc_now()], inc: [unread: 1]],
67 conflict_target: [:user_id, :recipient]
68 )
69 end
70
71 def mark_as_read(chat) do
72 chat
73 |> change(%{unread: 0})
74 |> Repo.update()
75 end
76 end