defmodule Pleroma.Chat do
use Ecto.Schema
+
import Ecto.Changeset
+ import Ecto.Query
+ alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
timestamps()
end
+ def last_message_for_chat(chat) do
+ messages_for_chat_query(chat)
+ |> order_by(desc: :id)
+ |> Repo.one()
+ end
+
+ def messages_for_chat_query(chat) do
+ chat =
+ chat
+ |> Repo.preload(:user)
+
+ from(o in Object,
+ where: fragment("?->>'type' = ?", o.data, "ChatMessage"),
+ where:
+ fragment(
+ """
+ (?->>'actor' = ? and ?->'to' = ?)
+ OR (?->>'actor' = ? and ?->'to' = ?)
+ """,
+ o.data,
+ ^chat.user.ap_id,
+ o.data,
+ ^[chat.recipient],
+ o.data,
+ ^chat.recipient,
+ o.data,
+ ^[chat.user.ap_id]
+ )
+ )
+ end
+
def creation_cng(struct, params) do
struct
|> cast(params, [:user_id, :recipient, :unread])
alias Pleroma.Web.PleromaAPI.ChatMessageView
alias Pleroma.Web.PleromaAPI.ChatView
- import Pleroma.Web.ActivityPub.ObjectValidator, only: [stringify_keys: 1]
-
import Ecto.Query
+ import Pleroma.Web.ActivityPub.ObjectValidator, only: [stringify_keys: 1]
# TODO
# - Error handling
def messages(%{assigns: %{user: %{id: user_id} = user}} = conn, %{id: id} = params) do
with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id) do
messages =
- from(o in Object,
- where: fragment("?->>'type' = ?", o.data, "ChatMessage"),
- where:
- fragment(
- """
- (?->>'actor' = ? and ?->'to' = ?)
- OR (?->>'actor' = ? and ?->'to' = ?)
- """,
- o.data,
- ^user.ap_id,
- o.data,
- ^[chat.recipient],
- o.data,
- ^chat.recipient,
- o.data,
- ^[user.ap_id]
- )
- )
+ chat
+ |> Chat.messages_for_chat_query()
|> Pagination.fetch_paginated(params |> stringify_keys())
conn
alias Pleroma.Chat
alias Pleroma.User
alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.PleromaAPI.ChatMessageView
def render("show.json", %{chat: %Chat{} = chat} = opts) do
recipient = User.get_cached_by_ap_id(chat.recipient)
+ last_message = Chat.last_message_for_chat(chat)
+
%{
id: chat.id |> to_string(),
account: AccountView.render("show.json", Map.put(opts, :user, recipient)),
- unread: chat.unread
+ unread: chat.unread,
+ last_message:
+ last_message && ChatMessageView.render("show.json", chat: chat, object: last_message)
}
end
use Pleroma.DataCase
alias Pleroma.Chat
+ alias Pleroma.Object
+ alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.PleromaAPI.ChatView
+ alias Pleroma.Web.PleromaAPI.ChatMessageView
import Pleroma.Factory
assert represented_chat == %{
id: "#{chat.id}",
account: AccountView.render("show.json", user: recipient),
- unread: 0
+ unread: 0,
+ last_message: nil
}
+
+ {:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
+
+ chat_message = Object.normalize(chat_message_creation, false)
+
+ {:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
+
+ represented_chat = ChatView.render("show.json", chat: chat)
+
+ assert represented_chat[:last_message] ==
+ ChatMessageView.render("show.json", chat: chat, object: chat_message)
end
end