Implement initial_state option for client room creation
This commit is contained in:
parent
56be8ba301
commit
b34fd58cf7
3 changed files with 148 additions and 78 deletions
|
@ -450,10 +450,35 @@ defmodule Architex.RoomServer do
|
||||||
invite: invite,
|
invite: invite,
|
||||||
power_level_content_override: power_level_content_override,
|
power_level_content_override: power_level_content_override,
|
||||||
is_direct: is_direct,
|
is_direct: is_direct,
|
||||||
creation_content: creation_content
|
creation_content: creation_content,
|
||||||
|
initial_state: initial_state
|
||||||
}) do
|
}) do
|
||||||
events =
|
invite_events = room_creation_invite_events(account, invite, room, is_direct)
|
||||||
([
|
|
||||||
|
name_and_topic_events =
|
||||||
|
Enum.reject(
|
||||||
|
[
|
||||||
|
if(name, do: Event.Name.new(room, account, name)),
|
||||||
|
if(topic, do: Event.Topic.new(room, account, topic))
|
||||||
|
],
|
||||||
|
&Kernel.is_nil/1
|
||||||
|
)
|
||||||
|
|
||||||
|
initial_state_pairs =
|
||||||
|
if initial_state, do: Enum.map(initial_state, &{&1.type, &1.state_key}), else: []
|
||||||
|
|
||||||
|
initial_state_events =
|
||||||
|
room_creation_initial_state_events(account, initial_state, room)
|
||||||
|
|> Enum.reject(fn %Event{type: type, state_key: state_key} ->
|
||||||
|
({type, state_key} == {"m.room.name", ""} and name) ||
|
||||||
|
({type, state_key} == {"m.room.topic", ""} and topic)
|
||||||
|
end)
|
||||||
|
|
||||||
|
preset_events =
|
||||||
|
room_creation_preset(account, preset, room)
|
||||||
|
|> Enum.reject(&({&1.type, &1.state_key} in initial_state_pairs))
|
||||||
|
|
||||||
|
basic_events = [
|
||||||
Event.CreateRoom.new(room, account, room_version, creation_content),
|
Event.CreateRoom.new(room, account, room_version, creation_content),
|
||||||
Event.Join.new(room, account),
|
Event.Join.new(room, account),
|
||||||
Event.PowerLevels.create_room_new(
|
Event.PowerLevels.create_room_new(
|
||||||
|
@ -463,13 +488,11 @@ defmodule Architex.RoomServer do
|
||||||
invite,
|
invite,
|
||||||
preset
|
preset
|
||||||
)
|
)
|
||||||
] ++
|
]
|
||||||
room_creation_preset(account, preset, room) ++
|
|
||||||
[
|
events =
|
||||||
if(name, do: Event.Name.new(room, account, name)),
|
basic_events ++
|
||||||
if(topic, do: Event.Topic.new(room, account, topic))
|
preset_events ++ initial_state_events ++ name_and_topic_events ++ invite_events
|
||||||
] ++ room_creation_invite_events(account, invite, room, is_direct))
|
|
||||||
|> Enum.reject(&Kernel.is_nil/1)
|
|
||||||
|
|
||||||
fn ->
|
fn ->
|
||||||
result =
|
result =
|
||||||
|
@ -541,6 +564,14 @@ defmodule Architex.RoomServer do
|
||||||
Enum.map(invite_user_ids, &Event.Invite.new(room, account, &1, is_direct))
|
Enum.map(invite_user_ids, &Event.Invite.new(room, account, &1, is_direct))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp room_creation_initial_state_events(_, nil, _), do: []
|
||||||
|
|
||||||
|
defp room_creation_initial_state_events(account, initial_state, room) do
|
||||||
|
Enum.map(initial_state, fn %{type: type, content: content, state_key: state_key} ->
|
||||||
|
Event.custom_state_event(room, account, type, content, state_key)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
# Finalize the event struct and insert it into the room's state using state resolution.
|
# Finalize the event struct and insert it into the room's state using state resolution.
|
||||||
# The values that are automatically added are:
|
# The values that are automatically added are:
|
||||||
# - Auth events
|
# - Auth events
|
||||||
|
|
|
@ -66,7 +66,7 @@ defmodule Architex.Event.PowerLevels do
|
||||||
@spec create_room_new(
|
@spec create_room_new(
|
||||||
Room.t(),
|
Room.t(),
|
||||||
Account.t(),
|
Account.t(),
|
||||||
CreateRoom.plco_t(),
|
CreateRoom.PowerLevelContentOverride.t(),
|
||||||
[String.t()] | nil,
|
[String.t()] | nil,
|
||||||
String.t() | nil
|
String.t() | nil
|
||||||
) :: %Event{}
|
) :: %Event{}
|
||||||
|
|
|
@ -1,6 +1,97 @@
|
||||||
defmodule ArchitexWeb.Client.Request.CreateRoom do
|
defmodule ArchitexWeb.Client.Request.CreateRoom do
|
||||||
use ArchitexWeb.APIRequest
|
use ArchitexWeb.APIRequest
|
||||||
|
|
||||||
|
defmodule PowerLevelContentOverride do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
defmodule Notifications do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
room: integer() | nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@primary_key false
|
||||||
|
embedded_schema do
|
||||||
|
field :room, :integer
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(data, params) do
|
||||||
|
cast(data, params, [:room])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
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: Notifications.t() | nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@primary_key false
|
||||||
|
embedded_schema 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
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(data, params) do
|
||||||
|
data
|
||||||
|
|> cast(params, [
|
||||||
|
:ban,
|
||||||
|
:events,
|
||||||
|
:events_default,
|
||||||
|
:invite,
|
||||||
|
:kick,
|
||||||
|
:redact,
|
||||||
|
:state_default,
|
||||||
|
:users,
|
||||||
|
:users_default
|
||||||
|
])
|
||||||
|
|> cast_embed(:notifications,
|
||||||
|
with: &Notifications.changeset/2,
|
||||||
|
required: false
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule StateEvent do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{
|
||||||
|
type: String.t(),
|
||||||
|
state_key: String.t(),
|
||||||
|
content: %{optional(String.t()) => any()}
|
||||||
|
}
|
||||||
|
|
||||||
|
@primary_key false
|
||||||
|
embedded_schema do
|
||||||
|
field :type, :string
|
||||||
|
field :state_key, :string, default: ""
|
||||||
|
field :content, :map
|
||||||
|
end
|
||||||
|
|
||||||
|
def changeset(data, params) do
|
||||||
|
data
|
||||||
|
|> cast(params, [:type, :state_key, :content])
|
||||||
|
|> validate_required([:type, :content])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@type t :: %__MODULE__{
|
@type t :: %__MODULE__{
|
||||||
visibility: String.t() | nil,
|
visibility: String.t() | nil,
|
||||||
room_alias_name: String.t() | nil,
|
room_alias_name: String.t() | nil,
|
||||||
|
@ -11,28 +102,13 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do
|
||||||
preset: String.t() | nil,
|
preset: String.t() | nil,
|
||||||
is_direct: boolean() | nil,
|
is_direct: boolean() | nil,
|
||||||
creation_content: %{optional(String.t()) => any()} | nil,
|
creation_content: %{optional(String.t()) => any()} | nil,
|
||||||
power_level_content_override: plco_t() | nil
|
power_level_content_override: PowerLevelContentOverride.t() | nil,
|
||||||
}
|
initial_state: [StateEvent.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
|
@primary_key false
|
||||||
embedded_schema do
|
embedded_schema do
|
||||||
|
# TODO: unimplemented: invite_3pid and room_alias_name
|
||||||
field :visibility, :string
|
field :visibility, :string
|
||||||
field :room_alias_name, :string
|
field :room_alias_name, :string
|
||||||
field :name, :string
|
field :name, :string
|
||||||
|
@ -43,23 +119,8 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do
|
||||||
field :is_direct, :boolean
|
field :is_direct, :boolean
|
||||||
field :creation_content, :map
|
field :creation_content, :map
|
||||||
|
|
||||||
embeds_one :power_level_content_override, PowerLevelContentOverride, primary_key: false do
|
embeds_many :initial_state, StateEvent
|
||||||
field :ban, :integer
|
embeds_one :power_level_content_override, PowerLevelContentOverride
|
||||||
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: invite_3pid, initial_state, room_alias_name
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(data, params) do
|
def changeset(data, params) do
|
||||||
|
@ -76,32 +137,10 @@ defmodule ArchitexWeb.Client.Request.CreateRoom do
|
||||||
:creation_content
|
:creation_content
|
||||||
])
|
])
|
||||||
|> cast_embed(:power_level_content_override,
|
|> cast_embed(:power_level_content_override,
|
||||||
with: &power_level_content_override_changeset/2,
|
with: &PowerLevelContentOverride.changeset/2,
|
||||||
required: false
|
required: false
|
||||||
)
|
)
|
||||||
|
|> cast_embed(:initial_state, with: &StateEvent.changeset/2, required: false)
|
||||||
|> validate_inclusion(:preset, ["private_chat", "public_chat", "trusted_private_chat"])
|
|> validate_inclusion(:preset, ["private_chat", "public_chat", "trusted_private_chat"])
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue