 c4439c630f
			
		
	
	
		c4439c630f
		
			
		
	
	
	
	
		
			
			grep -rl '# Copyright © .* Pleroma' * | xargs sed -i 's;Copyright © .* Pleroma .*;Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>;'
		
			
				
	
	
		
			117 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
| # Pleroma: A lightweight social networking server
 | |
| # Copyright © 2017-2021 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
 |