ChatView: Add the last message to the view.

This commit is contained in:
lain 2020-05-10 13:00:01 +02:00
parent e297d8c649
commit f335e1404a
4 changed files with 60 additions and 23 deletions

View File

@ -4,8 +4,11 @@
defmodule Pleroma.Chat do defmodule Pleroma.Chat do
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset
import Ecto.Changeset
import Ecto.Query
alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
@ -23,6 +26,37 @@ defmodule Pleroma.Chat do
timestamps() timestamps()
end 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 def creation_cng(struct, params) do
struct struct
|> cast(params, [:user_id, :recipient, :unread]) |> cast(params, [:user_id, :recipient, :unread])

View File

@ -14,9 +14,8 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
alias Pleroma.Web.PleromaAPI.ChatMessageView alias Pleroma.Web.PleromaAPI.ChatMessageView
alias Pleroma.Web.PleromaAPI.ChatView alias Pleroma.Web.PleromaAPI.ChatView
import Pleroma.Web.ActivityPub.ObjectValidator, only: [stringify_keys: 1]
import Ecto.Query import Ecto.Query
import Pleroma.Web.ActivityPub.ObjectValidator, only: [stringify_keys: 1]
# TODO # TODO
# - Error handling # - Error handling
@ -65,24 +64,8 @@ def mark_as_read(%{assigns: %{user: %{id: user_id}}} = conn, %{id: id}) do
def messages(%{assigns: %{user: %{id: user_id} = user}} = conn, %{id: id} = params) do 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 with %Chat{} = chat <- Repo.get_by(Chat, id: id, user_id: user_id) do
messages = messages =
from(o in Object, chat
where: fragment("?->>'type' = ?", o.data, "ChatMessage"), |> Chat.messages_for_chat_query()
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]
)
)
|> Pagination.fetch_paginated(params |> stringify_keys()) |> Pagination.fetch_paginated(params |> stringify_keys())
conn conn

View File

@ -8,14 +8,19 @@ defmodule Pleroma.Web.PleromaAPI.ChatView do
alias Pleroma.Chat alias Pleroma.Chat
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.PleromaAPI.ChatMessageView
def render("show.json", %{chat: %Chat{} = chat} = opts) do def render("show.json", %{chat: %Chat{} = chat} = opts) do
recipient = User.get_cached_by_ap_id(chat.recipient) recipient = User.get_cached_by_ap_id(chat.recipient)
last_message = Chat.last_message_for_chat(chat)
%{ %{
id: chat.id |> to_string(), id: chat.id |> to_string(),
account: AccountView.render("show.json", Map.put(opts, :user, recipient)), 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 end

View File

@ -6,8 +6,11 @@ defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
use Pleroma.DataCase use Pleroma.DataCase
alias Pleroma.Chat alias Pleroma.Chat
alias Pleroma.Object
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.PleromaAPI.ChatView alias Pleroma.Web.PleromaAPI.ChatView
alias Pleroma.Web.PleromaAPI.ChatMessageView
import Pleroma.Factory import Pleroma.Factory
@ -22,7 +25,19 @@ test "it represents a chat" do
assert represented_chat == %{ assert represented_chat == %{
id: "#{chat.id}", id: "#{chat.id}",
account: AccountView.render("show.json", user: recipient), 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
end end