diff --git a/lib/architex/room_server.ex b/lib/architex/room_server.ex index 2ff81ab..fe25ee4 100644 --- a/lib/architex/room_server.ex +++ b/lib/architex/room_server.ex @@ -207,7 +207,6 @@ defmodule Architex.RoomServer do _from, %{room: %Room{id: room_id} = room} = state ) do - # TODO: power_level_content_override, initial_state, invite_3pid case Repo.transaction(create_room_insert_events(room, account, request)) do {:ok, {state_set, room}} -> {:reply, {:ok, room_id}, %{state | state_set: state_set, room: room}} @@ -448,13 +447,15 @@ defmodule Architex.RoomServer do preset: preset, name: name, topic: topic, - invite: invite + invite: invite, + power_level_content_override: power_level_content_override }) do + events = ([ Event.CreateRoom.new(room, account, room_version), Event.Join.new(room, account), - Event.PowerLevels.new(room, account) + Event.PowerLevels.create_room_new(room, account, power_level_content_override) ] ++ room_creation_preset(account, preset, room) ++ [ diff --git a/lib/architex/schema/event/generators.ex b/lib/architex/schema/event/generators.ex index abb52ad..24e40aa 100644 --- a/lib/architex/schema/event/generators.ex +++ b/lib/architex/schema/event/generators.ex @@ -37,30 +37,61 @@ end defmodule Architex.Event.PowerLevels do alias Architex.{Event, Account, Room} + alias ArchitexWeb.Client.Request.CreateRoom + alias ArchitexWeb.Client.Request.CreateRoom.PowerLevelContentOverride - @spec new(Room.t(), Account.t()) :: %Event{} - def new(room, %Account{localpart: localpart} = sender) do + @ban 50 + @events_default 0 + @invite 50 + @kick 50 + @redact 50 + @state_default 50 + @creator 50 + @users_default 0 + @notifications_room 50 + + @spec create_room_new(Room.t(), Account.t(), CreateRoom.plco_t()) :: %Event{} + def create_room_new(room, sender, nil) do + create_room_new(room, sender, %PowerLevelContentOverride{}) + end + + def create_room_new(room, %Account{localpart: localpart} = sender, %PowerLevelContentOverride{ + ban: ban_override, + events: events_override, + events_default: events_default_override, + invite: invite_override, + kick: kick_override, + redact: redact_override, + state_default: state_default_override, + users: users_override, + users_default: users_default_override, + notifications: notifications_override + }) do mxid = Architex.get_mxid(localpart) + users = %{mxid => @creator} + users = if users_override, do: Map.merge(users, users_override), else: users + + notifications = + case notifications_override do + %{room: room} -> %{"room" => room} + _ -> %{"room" => @notifications_room} + end %Event{ Event.new(room, sender) | type: "m.room.power_levels", state_key: "", content: %{ - "ban" => 50, - "events" => %{}, - "events_default" => 0, - "invite" => 50, - "kick" => 50, - "redact" => 50, - "state_default" => 50, - "users" => %{ - mxid => 50 - }, - "users_default" => 0, - "notifications" => %{ - "room" => 50 - } + "ban" => ban_override || @ban, + "events" => events_override || %{}, + "events_default" => events_default_override || @events_default, + "invite" => invite_override || @invite, + "kick" => kick_override || @kick, + "redact" => redact_override || @redact, + "state_default" => state_default_override || @state_default, + "users" => users, + "users_default" => users_default_override || @users_default, + "notifications" => notifications } } end diff --git a/lib/architex_web/api_schemas/client/request/create_room.ex b/lib/architex_web/api_schemas/client/request/create_room.ex index 77d72c7..4a57ec3 100644 --- a/lib/architex_web/api_schemas/client/request/create_room.ex +++ b/lib/architex_web/api_schemas/client/request/create_room.ex @@ -8,7 +8,25 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do topic: String.t() | nil, invite: list(String.t()) | nil, room_version: String.t() | nil, - preset: String.t() | nil + preset: String.t() | nil, + power_level_content_override: plco_t() | nil + } + + @type plco_t :: %__MODULE__.PowerLevelContentOverride{ + ban: integer() | nil, + events: %{optional(String.t()) => integer()} | nil, + events_default: integer() | nil, + invite: integer() | nil, + kick: integer() | nil, + redact: integer() | nil, + state_default: integer() | nil, + users: %{optional(String.t()) => integer()} | nil, + users_default: integer() | nil, + notifications: plco_n_t() | nil + } + + @type plco_n_t :: %__MODULE__.PowerLevelContentOverride.Notifications{ + room: integer() | nil } @primary_key false @@ -20,9 +38,25 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do field :invite, {:array, :string} field :room_version, :string field :preset, :string + + embeds_one :power_level_content_override, PowerLevelContentOverride, primary_key: false do + field :ban, :integer + field :events, {:map, :integer} + field :events_default, :integer + field :invite, :integer + field :kick, :integer + field :redact, :integer + field :state_default, :integer + field :users, {:map, :integer} + field :users_default, :integer + + embeds_one :notifications, Notifications, primary_key: false do + field :room, :integer + end + end + # TODO: unimplemented: - # creation_content, initial_state, invite_3pid, initial_state, - # is_direct, power_level_content_override + # creation_content, initial_state, invite_3pid, initial_state, is_direct end def changeset(data, params) do @@ -36,6 +70,33 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do :room_version, :preset ]) + |> cast_embed(:power_level_content_override, + with: &power_level_content_override_changeset/2, + required: false + ) |> validate_inclusion(:preset, ["private_chat", "public_chat", "trusted_private_chat"]) end + + def power_level_content_override_changeset(data, params) do + data + |> cast(params, [ + :ban, + :events, + :events_default, + :invite, + :kick, + :redact, + :state_default, + :users, + :users_default + ]) + |> cast_embed(:notifications, + with: &power_level_content_override_notifications_changeset/2, + required: false + ) + end + + def power_level_content_override_notifications_changeset(data, params) do + cast(data, params, [:room]) + end end