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}/send/{eventType}/{txnId}
|
||||
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
||||
- GET /_matrix/client/r0/rooms/{roomId}/state
|
||||
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- 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})
|
||||
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
|
||||
|
||||
@impl true
|
||||
|
@ -424,6 +435,24 @@ defmodule Architex.RoomServer do
|
|||
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()) ::
|
||||
(() -> {t(), Room.t(), String.t()} | {:error, atom()})
|
||||
defp process_event_with_txn(
|
||||
|
|
|
@ -4,33 +4,10 @@ defmodule Architex.Event.Formatters do
|
|||
"""
|
||||
alias Architex.Event
|
||||
|
||||
@spec messages_response(Event.t()) :: map()
|
||||
def messages_response(%Event{
|
||||
content: content,
|
||||
type: type,
|
||||
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{
|
||||
@doc """
|
||||
Event format with keys that all formats have in common.
|
||||
"""
|
||||
def base_client_response(%Event{
|
||||
content: content,
|
||||
type: type,
|
||||
id: event_id,
|
||||
|
@ -46,11 +23,37 @@ defmodule Architex.Event.Formatters do
|
|||
origin_server_ts: origin_server_ts
|
||||
}
|
||||
|
||||
data = if unsigned, do: Map.put(data, :unsigned, unsigned), else: data
|
||||
|
||||
data
|
||||
if unsigned, do: Map.put(data, :unsigned, unsigned), else: data
|
||||
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()
|
||||
def as_pdu(%Event{
|
||||
auth_events: auth_events,
|
||||
|
|
|
@ -311,4 +311,33 @@ defmodule ArchitexWeb.Client.RoomController do
|
|||
{:error, _} -> put_error(conn, :bad_json)
|
||||
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
|
||||
|
|
|
@ -87,7 +87,11 @@ defmodule ArchitexWeb.Router do
|
|||
post "/unban", RoomController, :unban
|
||||
put "/send/:event_type/:txn_id", RoomController, :send_message_event
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue