chat_channel.ex 1.24 KB
Newer Older
lain's avatar
lain committed
1
2
defmodule Pleroma.Web.ChatChannel do
  use Phoenix.Channel
lain's avatar
lain committed
3
  alias Pleroma.Web.ChatChannel.ChatChannelState
lain's avatar
lain committed
4
5

  def join("chat:public", _message, socket) do
lain's avatar
lain committed
6
    send(self(), :after_join)
lain's avatar
lain committed
7
8
9
    {:ok, socket}
  end

lain's avatar
lain committed
10
11
12
13
14
  def handle_info(:after_join, socket) do
    push socket, "messages", %{messages: ChatChannelState.messages()}
    {:noreply, socket}
  end

lain's avatar
lain committed
15
16
17
  def handle_in("new_msg", %{"text" => text}, socket) do
    author = socket.assigns[:user]
    author = Pleroma.Web.MastodonAPI.AccountView.render("account.json", user: author)
lain's avatar
lain committed
18
19
20
    message= ChatChannelState.add_message(%{text: text, author: author})

    broadcast! socket, "new_msg", message
lain's avatar
lain committed
21
22
23
    {:noreply, socket}
  end
end
lain's avatar
lain committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

defmodule Pleroma.Web.ChatChannel.ChatChannelState do
  use Agent
  @max_messages 20

  def start_link do
    Agent.start_link(fn -> %{max_id: 1, messages: []} end, name: __MODULE__)
  end

  def add_message(message) do
    Agent.get_and_update(__MODULE__, fn state ->
      id = state[:max_id] + 1
      message = Map.put(message, "id", id)
      messages = [message | state[:messages]] |> Enum.take(@max_messages)
      {message, %{max_id: id, messages: messages}}
    end)
  end

  def messages() do
    Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse end)
  end
end