Implement client get room stat endpoint
This commit is contained in:
parent
739c496ac6
commit
222b6a309a
5 changed files with 97 additions and 31 deletions
|
@ -61,6 +61,7 @@ Here, implemented and some unimplemented features are listed.
|
||||||
- PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}
|
- PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}
|
||||||
- PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}
|
- PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}
|
||||||
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
||||||
|
- GET /_matrix/client/r0/rooms/{roomId}/state
|
||||||
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
||||||
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
||||||
- GET /_matrix/client/r0/capabilities
|
- GET /_matrix/client/r0/capabilities
|
||||||
|
|
|
@ -189,6 +189,17 @@ defmodule Architex.RoomServer do
|
||||||
GenServer.call(pid, {:send_state_event, account, event_type, content, state_key})
|
GenServer.call(pid, {:send_state_event, account, event_type, content, state_key})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the current state of a room.
|
||||||
|
If the requesting user is not a member of the room,
|
||||||
|
get the state when the user left the room.
|
||||||
|
If the user has never been in the room, return an error.
|
||||||
|
"""
|
||||||
|
@spec get_current_state(pid(), Account.t()) :: {:ok, [Event.t()]} | :error
|
||||||
|
def get_current_state(pid, account) do
|
||||||
|
GenServer.call(pid, {:get_current_state, account})
|
||||||
|
end
|
||||||
|
|
||||||
### Implementation
|
### Implementation
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -424,6 +435,24 @@ defmodule Architex.RoomServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_call({:get_current_state, account}, _from, %{state_set: state_set} = state) do
|
||||||
|
mxid = Account.get_mxid(account)
|
||||||
|
|
||||||
|
case state_set[{"m.room.member", mxid}] do
|
||||||
|
%Event{content: %{"membership" => "join"}} ->
|
||||||
|
# Get the current state of the room.
|
||||||
|
{:reply, {:ok, Map.values(state_set)}, state}
|
||||||
|
|
||||||
|
%Event{content: %{"membership" => "leave"}} = event ->
|
||||||
|
# Get the state of the room, after leaving.
|
||||||
|
state_set = StateResolution.resolve(event)
|
||||||
|
{:reply, {:ok, Map.values(state_set)}, state}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{:reply, :error, state}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@spec process_event_with_txn(t(), Room.t(), Device.t(), %Event{}, String.t()) ::
|
@spec process_event_with_txn(t(), Room.t(), Device.t(), %Event{}, String.t()) ::
|
||||||
(() -> {t(), Room.t(), String.t()} | {:error, atom()})
|
(() -> {t(), Room.t(), String.t()} | {:error, atom()})
|
||||||
defp process_event_with_txn(
|
defp process_event_with_txn(
|
||||||
|
|
|
@ -4,33 +4,10 @@ defmodule Architex.Event.Formatters do
|
||||||
"""
|
"""
|
||||||
alias Architex.Event
|
alias Architex.Event
|
||||||
|
|
||||||
@spec messages_response(Event.t()) :: map()
|
@doc """
|
||||||
def messages_response(%Event{
|
Event format with keys that all formats have in common.
|
||||||
content: content,
|
"""
|
||||||
type: type,
|
def base_client_response(%Event{
|
||||||
id: event_id,
|
|
||||||
sender: sender,
|
|
||||||
origin_server_ts: origin_server_ts,
|
|
||||||
unsigned: unsigned,
|
|
||||||
room_id: room_id,
|
|
||||||
state_key: state_key
|
|
||||||
}) do
|
|
||||||
data = %{
|
|
||||||
content: content,
|
|
||||||
type: type,
|
|
||||||
event_id: event_id,
|
|
||||||
sender: to_string(sender),
|
|
||||||
origin_server_ts: origin_server_ts,
|
|
||||||
room_id: room_id
|
|
||||||
}
|
|
||||||
|
|
||||||
data = if unsigned, do: Map.put(data, :unsigned, unsigned), else: data
|
|
||||||
data = if state_key, do: Map.put(data, :state_key, state_key), else: data
|
|
||||||
|
|
||||||
data
|
|
||||||
end
|
|
||||||
|
|
||||||
def sync_response(%Event{
|
|
||||||
content: content,
|
content: content,
|
||||||
type: type,
|
type: type,
|
||||||
id: event_id,
|
id: event_id,
|
||||||
|
@ -46,11 +23,37 @@ defmodule Architex.Event.Formatters do
|
||||||
origin_server_ts: origin_server_ts
|
origin_server_ts: origin_server_ts
|
||||||
}
|
}
|
||||||
|
|
||||||
data = if unsigned, do: Map.put(data, :unsigned, unsigned), else: data
|
if unsigned, do: Map.put(data, :unsigned, unsigned), else: data
|
||||||
|
|
||||||
data
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The base event format, with room_id and state_key added.
|
||||||
|
Used in the client /messages response.
|
||||||
|
"""
|
||||||
|
@spec messages_response(Event.t()) :: map()
|
||||||
|
def messages_response(%Event{room_id: room_id, state_key: state_key} = event) do
|
||||||
|
data =
|
||||||
|
base_client_response(event)
|
||||||
|
|> Map.put(:room_id, room_id)
|
||||||
|
|
||||||
|
if state_key, do: Map.put(data, :state_key, state_key), else: data
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The event format used in the client /state response.
|
||||||
|
TODO: prev_content
|
||||||
|
"""
|
||||||
|
def state_response(event), do: messages_response(event)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The base event format, used in the client /sync response.
|
||||||
|
"""
|
||||||
|
@spec sync_response(Event.t()) :: map()
|
||||||
|
def sync_response(event), do: base_client_response(event)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The PDU format used for federation.
|
||||||
|
"""
|
||||||
@spec as_pdu(Event.t()) :: map()
|
@spec as_pdu(Event.t()) :: map()
|
||||||
def as_pdu(%Event{
|
def as_pdu(%Event{
|
||||||
auth_events: auth_events,
|
auth_events: auth_events,
|
||||||
|
|
|
@ -311,4 +311,33 @@ defmodule ArchitexWeb.Client.RoomController do
|
||||||
{:error, _} -> put_error(conn, :bad_json)
|
{:error, _} -> put_error(conn, :bad_json)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the state events for the current state of a room.
|
||||||
|
|
||||||
|
Action for GET /_matrix/client/r0/rooms/{roomId}/state.
|
||||||
|
"""
|
||||||
|
def state(%Conn{assigns: %{account: account}} = conn, %{"room_id" => room_id}) do
|
||||||
|
case RoomServer.get_room_server(room_id) do
|
||||||
|
{:ok, pid} ->
|
||||||
|
case RoomServer.get_current_state(pid, account) do
|
||||||
|
{:ok, events} ->
|
||||||
|
events = Enum.map(events, &Event.Formatters.state_response/1)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_status(200)
|
||||||
|
|> json(events)
|
||||||
|
|
||||||
|
:error ->
|
||||||
|
put_error(
|
||||||
|
conn,
|
||||||
|
:forbidden,
|
||||||
|
"You aren't a member of the room and weren't previously a member of the room."
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, :not_found} ->
|
||||||
|
put_error(conn, :not_found, "The given room was not found.")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,7 +87,11 @@ defmodule ArchitexWeb.Router do
|
||||||
post "/unban", RoomController, :unban
|
post "/unban", RoomController, :unban
|
||||||
put "/send/:event_type/:txn_id", RoomController, :send_message_event
|
put "/send/:event_type/:txn_id", RoomController, :send_message_event
|
||||||
get "/messages", RoomController, :messages
|
get "/messages", RoomController, :messages
|
||||||
put "/state/:event_type/*state_key", RoomController, :send_state_event
|
|
||||||
|
scope "/state" do
|
||||||
|
get "/", RoomController, :state
|
||||||
|
put "/:event_type/*state_key", RoomController, :send_state_event
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue