Fix updating joined rooms when event is inserted in history
This commit is contained in:
parent
658efa228f
commit
a1475c1a46
1 changed files with 35 additions and 22 deletions
|
@ -14,7 +14,6 @@ defmodule MatrixServer.RoomServer do
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
alias MatrixServer.{Repo, Room, Event, StateResolution, Account, JoinedRoom}
|
alias MatrixServer.{Repo, Room, Event, StateResolution, Account, JoinedRoom}
|
||||||
alias MatrixServer.Types.UserId
|
|
||||||
alias MatrixServer.StateResolution.Authorization
|
alias MatrixServer.StateResolution.Authorization
|
||||||
alias MatrixServerWeb.Client.Request.CreateRoom
|
alias MatrixServerWeb.Client.Request.CreateRoom
|
||||||
|
|
||||||
|
@ -208,7 +207,11 @@ defmodule MatrixServer.RoomServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call({:join, account}, _from, %{room: %Room{id: room_id} = room, state_set: state_set} = state) do
|
def handle_call(
|
||||||
|
{:join, account},
|
||||||
|
_from,
|
||||||
|
%{room: %Room{id: room_id} = room, state_set: state_set} = state
|
||||||
|
) do
|
||||||
case Repo.transaction(join_insert_event(room, state_set, account)) do
|
case Repo.transaction(join_insert_event(room, state_set, account)) do
|
||||||
{:ok, state_set} -> {:reply, {:ok, room_id}, %{state | state_set: state_set}}
|
{:ok, state_set} -> {:reply, {:ok, room_id}, %{state | state_set: state_set}}
|
||||||
{:error, reason} -> {:reply, {:error, reason}, state}
|
{:error, reason} -> {:reply, {:error, reason}, state}
|
||||||
|
@ -216,7 +219,7 @@ defmodule MatrixServer.RoomServer do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a function that inserts a join event into the room for the given account.
|
# Get a function that inserts a join event into the room for the given account.
|
||||||
@spec join_insert_event(Room.t(), t(), Account.t()) :: (-> {:ok, t()} | {:error, atom()})
|
@spec join_insert_event(Room.t(), t(), Account.t()) :: (() -> {:ok, t()} | {:error, atom()})
|
||||||
defp join_insert_event(room, state_set, account) do
|
defp join_insert_event(room, state_set, account) do
|
||||||
join_event = Event.join(room, account)
|
join_event = Event.join(room, account)
|
||||||
|
|
||||||
|
@ -429,7 +432,7 @@ defmodule MatrixServer.RoomServer do
|
||||||
room = Room.update_forward_extremities(event, room)
|
room = Room.update_forward_extremities(event, room)
|
||||||
event = Repo.insert!(event)
|
event = Repo.insert!(event)
|
||||||
state_set = StateResolution.resolve_forward_extremities(event)
|
state_set = StateResolution.resolve_forward_extremities(event)
|
||||||
_ = update_joined_rooms(event, room)
|
_ = update_joined_rooms(room, state_set)
|
||||||
|
|
||||||
{:ok, state_set, room}
|
{:ok, state_set, room}
|
||||||
else
|
else
|
||||||
|
@ -438,23 +441,33 @@ defmodule MatrixServer.RoomServer do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Update local accounts' room membership if applicable.
|
# Update local accounts' room membership if applicable.
|
||||||
@spec update_joined_rooms(Event.t(), Room.t()) :: JoinedRoom.t() | nil
|
# TODO: Could be a background job.
|
||||||
defp update_joined_rooms(
|
@spec update_joined_rooms(Room.t(), t()) :: JoinedRoom.t() | nil
|
||||||
%Event{
|
defp update_joined_rooms(%Room{id: room_id}, state_set) do
|
||||||
type: "m.room.member",
|
server_name = MatrixServer.server_name()
|
||||||
sender: %UserId{localpart: localpart, domain: domain},
|
|
||||||
content: %{"membership" => membership}
|
|
||||||
},
|
|
||||||
%Room{id: room_id}
|
|
||||||
) do
|
|
||||||
if domain == MatrixServer.server_name() do
|
|
||||||
if membership == "join" do
|
|
||||||
Repo.insert(%JoinedRoom{localpart: localpart, room_id: room_id}, on_conflict: :nothing)
|
|
||||||
else
|
|
||||||
Repo.delete_all(from jr in JoinedRoom, where: jr.room_id == ^room_id and jr.localpart == ^localpart)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp update_joined_rooms(_, _), do: nil
|
{joined, not_joined} =
|
||||||
|
state_set
|
||||||
|
|> Enum.filter(fn {{type, state_key}, _} ->
|
||||||
|
type == "m.room.member" and MatrixServer.get_domain(state_key) == server_name
|
||||||
|
end)
|
||||||
|
|> Enum.split_with(fn {_, %Event{content: %{"membership" => membership}}} ->
|
||||||
|
membership == "join"
|
||||||
|
end)
|
||||||
|
|
||||||
|
joined_assocs =
|
||||||
|
Enum.map(joined, fn {{_, state_key}, _} ->
|
||||||
|
%{localpart: MatrixServer.get_localpart(state_key), room_id: room_id}
|
||||||
|
end)
|
||||||
|
|
||||||
|
not_joined_localparts =
|
||||||
|
Enum.map(not_joined, fn {{_, state_key}, _} -> MatrixServer.get_localpart(state_key) end)
|
||||||
|
|
||||||
|
_ = Repo.insert_all(JoinedRoom, joined_assocs, on_conflict: :nothing)
|
||||||
|
|
||||||
|
Repo.delete_all(
|
||||||
|
from jr in JoinedRoom,
|
||||||
|
where: jr.room_id == ^room_id and jr.localpart in ^not_joined_localparts
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue