chat_message_reference.ex (2393B)
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.ChatMessageReference do 6 @moduledoc """ 7 A reference that builds a relation between an AP chat message that a user can see and whether it has been seen 8 by them, or should be displayed to them. Used to build the chat view that is presented to the user. 9 """ 10 11 use Ecto.Schema 12 13 alias Pleroma.Chat 14 alias Pleroma.Object 15 alias Pleroma.Repo 16 17 import Ecto.Changeset 18 import Ecto.Query 19 20 @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} 21 22 schema "chat_message_references" do 23 belongs_to(:object, Object) 24 belongs_to(:chat, Chat) 25 26 field(:unread, :boolean, default: true) 27 28 timestamps() 29 end 30 31 def changeset(struct, params) do 32 struct 33 |> cast(params, [:object_id, :chat_id, :unread]) 34 |> validate_required([:object_id, :chat_id, :unread]) 35 end 36 37 def get_by_id(id) do 38 __MODULE__ 39 |> Repo.get(id) 40 |> Repo.preload(:object) 41 end 42 43 def delete(cm_ref) do 44 cm_ref 45 |> Repo.delete() 46 end 47 48 def delete_for_object(%{id: object_id}) do 49 from(cr in __MODULE__, 50 where: cr.object_id == ^object_id 51 ) 52 |> Repo.delete_all() 53 end 54 55 def for_chat_and_object(%{id: chat_id}, %{id: object_id}) do 56 __MODULE__ 57 |> Repo.get_by(chat_id: chat_id, object_id: object_id) 58 |> Repo.preload(:object) 59 end 60 61 def for_chat_query(chat) do 62 from(cr in __MODULE__, 63 where: cr.chat_id == ^chat.id, 64 order_by: [desc: :id], 65 preload: [:object] 66 ) 67 end 68 69 def last_message_for_chat(chat) do 70 chat 71 |> for_chat_query() 72 |> limit(1) 73 |> Repo.one() 74 end 75 76 def create(chat, object, unread) do 77 params = %{ 78 chat_id: chat.id, 79 object_id: object.id, 80 unread: unread 81 } 82 83 %__MODULE__{} 84 |> changeset(params) 85 |> Repo.insert() 86 end 87 88 def unread_count_for_chat(chat) do 89 chat 90 |> for_chat_query() 91 |> where([cmr], cmr.unread == true) 92 |> Repo.aggregate(:count) 93 end 94 95 def mark_as_read(cm_ref) do 96 cm_ref 97 |> changeset(%{unread: false}) 98 |> Repo.update() 99 end 100 101 def set_all_seen_for_chat(chat) do 102 chat 103 |> for_chat_query() 104 |> exclude(:order_by) 105 |> exclude(:preload) 106 |> where([cmr], cmr.unread == true) 107 |> Repo.update_all(set: [unread: false]) 108 end 109 end