architex/lib/matrix_server/schema/room.ex

66 lines
1.8 KiB
Elixir
Raw Normal View History

2021-07-10 21:16:00 +00:00
defmodule MatrixServer.Room do
use Ecto.Schema
import Ecto.Changeset
2021-07-25 12:57:52 +00:00
import Ecto.Query
2021-07-10 21:16:00 +00:00
2021-07-30 13:56:24 +00:00
alias MatrixServer.{Repo, Room, Event, Alias, RoomServer}
alias MatrixServerWeb.Client.Request.CreateRoom
2021-07-10 21:16:00 +00:00
@type t :: %__MODULE__{
visibility: :public | :private,
state: list(list(String.t())),
forward_extremities: list(String.t())
}
2021-07-10 21:16:00 +00:00
@primary_key {:id, :string, []}
schema "rooms" do
field :visibility, Ecto.Enum, values: [:public, :private]
field :state, {:array, {:array, :string}}
2021-07-25 12:57:52 +00:00
field :forward_extremities, {:array, :string}
has_many :events, Event, foreign_key: :event_id
2021-07-30 13:56:24 +00:00
has_many :aliases, Alias, foreign_key: :room_id
2021-07-10 21:16:00 +00:00
end
2021-07-17 15:38:20 +00:00
def changeset(room, params \\ %{}) do
cast(room, params, [:visibility])
2021-07-10 21:16:00 +00:00
end
2021-07-17 15:38:20 +00:00
def create_changeset(%CreateRoom{} = input) do
visibility = input.visibility || :public
%Room{id: generate_room_id()}
2021-07-17 15:38:20 +00:00
|> changeset(%{visibility: visibility})
2021-07-10 21:16:00 +00:00
end
2021-07-17 15:38:20 +00:00
def generate_room_id do
"!" <> MatrixServer.random_string(18) <> ":" <> MatrixServer.server_name()
2021-07-10 21:16:00 +00:00
end
2021-07-25 12:57:52 +00:00
def update_forward_extremities(
%Event{
event_id: event_id,
prev_events: prev_event_ids
},
%Room{id: room_id, forward_extremities: forward_extremities}
) do
2021-07-25 12:57:52 +00:00
new_forward_extremities = [event_id | forward_extremities -- prev_event_ids]
2021-07-29 20:06:02 +00:00
# TODO: might not need to save to DB here.
{_, [room]} =
2021-07-25 12:57:52 +00:00
from(r in Room, where: r.id == ^room_id, select: r)
|> Repo.update_all(set: [forward_extremities: new_forward_extremities])
room
end
2021-07-29 20:06:02 +00:00
def create(account, input) do
with {:ok, %Room{id: room_id}} <- Repo.insert(create_changeset(input)),
{:ok, pid} <- RoomServer.get_room_server(room_id) do
RoomServer.create_room(pid, account, input)
else
_ -> {:error, :unknown}
end
end
2021-07-10 21:16:00 +00:00
end