message_reference.ex (2574B)
- # Pleroma: A lightweight social networking server
- # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
- # SPDX-License-Identifier: AGPL-3.0-only
- defmodule Pleroma.Chat.MessageReference do
- @moduledoc """
- A reference that builds a relation between an AP chat message that a user can see and whether it has been seen
- by them, or should be displayed to them. Used to build the chat view that is presented to the user.
- """
- use Ecto.Schema
- alias Pleroma.Chat
- alias Pleroma.Object
- alias Pleroma.Repo
- import Ecto.Changeset
- import Ecto.Query
- @primary_key {:id, FlakeId.Ecto.Type, autogenerate: true}
- schema "chat_message_references" do
- belongs_to(:object, Object)
- belongs_to(:chat, Chat, type: FlakeId.Ecto.CompatType)
- field(:unread, :boolean, default: true)
- timestamps()
- end
- def changeset(struct, params) do
- struct
- |> cast(params, [:object_id, :chat_id, :unread])
- |> validate_required([:object_id, :chat_id, :unread])
- end
- def get_by_id(id) do
- __MODULE__
- |> Repo.get(id)
- |> Repo.preload(:object)
- end
- def delete(cm_ref) do
- cm_ref
- |> Repo.delete()
- end
- def delete_for_object(%{id: object_id}) do
- from(cr in __MODULE__,
- where: cr.object_id == ^object_id
- )
- |> Repo.delete_all()
- end
- def for_chat_and_object(%{id: chat_id}, %{id: object_id}) do
- __MODULE__
- |> Repo.get_by(chat_id: chat_id, object_id: object_id)
- |> Repo.preload(:object)
- end
- def for_chat_query(chat) do
- from(cr in __MODULE__,
- where: cr.chat_id == ^chat.id,
- order_by: [desc: :id],
- preload: [:object]
- )
- end
- def last_message_for_chat(chat) do
- chat
- |> for_chat_query()
- |> limit(1)
- |> Repo.one()
- end
- def create(chat, object, unread) do
- params = %{
- chat_id: chat.id,
- object_id: object.id,
- unread: unread
- }
- %__MODULE__{}
- |> changeset(params)
- |> Repo.insert()
- end
- def unread_count_for_chat(chat) do
- chat
- |> for_chat_query()
- |> where([cmr], cmr.unread == true)
- |> Repo.aggregate(:count)
- end
- def mark_as_read(cm_ref) do
- cm_ref
- |> changeset(%{unread: false})
- |> Repo.update()
- end
- def set_all_seen_for_chat(chat, last_read_id \\ nil) do
- query =
- chat
- |> for_chat_query()
- |> exclude(:order_by)
- |> exclude(:preload)
- |> where([cmr], cmr.unread == true)
- if last_read_id do
- query
- |> where([cmr], cmr.id <= ^last_read_id)
- else
- query
- end
- |> Repo.update_all(set: [unread: false])
- end
- end