diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor
deleted file mode 100644
index e477f4c..0000000
--- a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor
+++ /dev/null
@@ -1,338 +0,0 @@
-@page "/Rooms/Create"
-@using System.Text.Json
-@using System.Reflection
-@using ArcaneLibs.Extensions
-@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
-@using LibMatrix.EventTypes.Spec.State.RoomInfo
-@using LibMatrix.Homeservers
-@using LibMatrix.Responses
-@using MatrixRoomUtils.Web.Classes.RoomCreationTemplates
-@* @* ReSharper disable once RedundantUsingDirective - Must not remove this, Rider marks this as "unused" when it's not */ *@
-
-<h3>Room Manager - Create Room</h3>
-
-@* <pre Contenteditable="true" @onkeypress="@JsonChanged" content="JsonString">@JsonString</pre> *@
-<style>
- table.table-top-first-tr tr td:first-child {
- vertical-align: top;
- }
- </style>
-<table class="table-top-first-tr">
- <tr style="padding-bottom: 16px;">
- <td>Preset:</td>
- <td>
- @if (Presets is null) {
- <p style="color: red;">Presets is null!</p>
- }
- else {
- <InputSelect @bind-Value="@RoomPreset">
- @foreach (var createRoomRequest in Presets) {
- <option value="@createRoomRequest.Key">@createRoomRequest.Key</option>
- }
- </InputSelect>
- }
- </td>
- </tr>
- @if (creationEvent is not null) {
- <tr>
- <td>Room name:</td>
- <td>
- @if (creationEvent.Name is null) {
- <p style="color: red;">creationEvent.Name is null!</p>
- }
- else {
- <FancyTextBox @bind-Value="@creationEvent.Name"></FancyTextBox>
- <p>(#<FancyTextBox @bind-Value="@creationEvent.RoomAliasName"></FancyTextBox>:@Homeserver.WhoAmI.UserId.Split(':').Last())</p>
- }
- </td>
- </tr>
- <tr>
- <td>Room type:</td>
- <td>
- @if (creationEvent.CreationContentBaseType is null) {
- <p style="color: red;">creationEvent._creationContentBaseType is null!</p>
- }
- else {
- <InputSelect @bind-Value="@creationEvent.CreationContentBaseType.Type">
- <option value="">Room</option>
- <option value="m.space">Space</option>
- </InputSelect>
- <FancyTextBox @bind-Value="@creationEvent.CreationContentBaseType.Type"></FancyTextBox>
- }
- </td>
- </tr>
- <tr>
- <td style="padding-top: 16px;">History visibility:</td>
- <td style="padding-top: 16px;">
- <InputSelect @bind-Value="@historyVisibility.HistoryVisibility">
- <option value="invited">Invited</option>
- <option value="joined">Joined</option>
- <option value="shared">Shared</option>
- <option value="world_readable">World readable</option>
- </InputSelect>
- </td>
- </tr>
- <tr>
- <td>Guest access:</td>
- <td>
- <ToggleSlider @bind-Value="guestAccessEvent.IsGuestAccessEnabled">
- @(guestAccessEvent.IsGuestAccessEnabled ? "Guests can join" : "Guests cannot join") (@guestAccessEvent.GuestAccess)
- </ToggleSlider>
- <InputSelect @bind-Value="@guestAccessEvent.GuestAccess">
- <option value="can_join">Can join</option>
- <option value="forbidden">Forbidden</option>
- </InputSelect>
- </td>
- </tr>
-
- <tr>
- <td>Room icon:</td>
- <td>
- <img src="@Homeserver.ResolveMediaUri(roomAvatarEvent.Url)" style="width: 128px; height: 128px; border-radius: 50%;"/>
- <div style="display: inline-block; vertical-align: middle;">
- <FancyTextBox @bind-Value="@roomAvatarEvent.Url"></FancyTextBox><br/>
- <InputFile OnChange="RoomIconFilePicked"></InputFile>
- </div>
- </td>
- </tr>
- <tr>
- <td>Permissions:</td>
- <details>
- <summary>@creationEvent.PowerLevelContentOverride.Users.Count members</summary>
- @foreach (var user in creationEvent.PowerLevelContentOverride.Events.Keys) {
- var _event = user;
- <tr>
- <td>
- <FancyTextBox Formatter="@GetPermissionFriendlyName"
- Value="@_event"
- ValueChanged="val => { creationEvent.PowerLevelContentOverride.Events.ChangeKey(_event, val); }">
- </FancyTextBox>:
- </td>
- <td>
- <input type="number" value="@creationEvent.PowerLevelContentOverride.Events[_event]" @oninput="val => { creationEvent.PowerLevelContentOverride.Events[_event] = int.Parse(val.Value.ToString()); }" @onfocusout="() => { creationEvent.PowerLevelContentOverride.Events = creationEvent.PowerLevelContentOverride.Events.OrderByDescending(x => x.Value).ThenBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); }"/>
- </td>
- </tr>
- }
- @foreach (var user in creationEvent.PowerLevelContentOverride.Users.Keys) {
- var _user = user;
- <tr>
- <td><FancyTextBox Value="@_user" ValueChanged="val => { creationEvent.PowerLevelContentOverride.Users.ChangeKey(_user, val); creationEvent.PowerLevelContentOverride.Users = creationEvent.PowerLevelContentOverride.Users.OrderByDescending(x => x.Value).ThenBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); }"></FancyTextBox>:</td>
- <td>
- <input type="number" value="@creationEvent.PowerLevelContentOverride.Users[_user]" @oninput="val => { creationEvent.PowerLevelContentOverride.Users[_user] = int.Parse(val.Value.ToString()); }"/>
- </td>
- </tr>
- }
- </details>
- </tr>
- <tr>
- <td>Server ACLs:</td>
- <td>
- @if (serverAcl?.Allow is null) {
- <p>No allow rules exist!</p>
- <button @onclick="@(() => { serverAcl.Allow = new List<string> { "*" }; })">Create sane defaults</button>
- }
- else {
- <details>
- <summary>@((creationEvent["m.room.server_acls"].TypedContent as RoomServerACLEventContent).Allow.Count) allow rules</summary>
- @* <StringListEditor @bind-Items="@serverAcl.Allow"></StringListEditor> *@
- </details>
- }
- @if (serverAcl?.Deny is null) {
- <p>No deny rules exist!</p>
- <button @onclick="@(() => { serverAcl.Allow = new List<string>(); })">Create sane defaults</button>
- }
- else {
- <details>
- <summary>@((creationEvent["m.room.server_acls"].TypedContent as RoomServerACLEventContent).Deny.Count) deny rules</summary>
- @* <StringListEditor @bind-Items="@serverAcl.Allow"></StringListEditor> *@
- </details>
- }
- </td>
- </tr>
-
- <tr>
- <td>Invited members:</td>
- <td>
- <details>
- <summary>@creationEvent.InitialState.Count(x => x.Type == "m.room.member") members</summary>
- @* <button @onclick="() => { RuntimeCache.LoginSessions.Select(x => x.Value.LoginResponse.UserId).ToList().ForEach(InviteMember); }">Invite all logged in accounts</button> *@
- @foreach (var member in creationEvent.InitialState.Where(x => x.Type == "m.room.member" && x.StateKey != Homeserver.UserId)) {
- <UserListItem UserId="@member.StateKey"></UserListItem>
- }
- </details>
- </td>
- </tr>
- @* Initial states, should remain at bottom *@
- <tr>
- <td style="vertical-align: top;">Initial states:</td>
- <td>
- <details>
-
- @code
- {
- private static readonly string[] ImplementedStates = { "m.room.avatar", "m.room.history_visibility", "m.room.guest_access", "m.room.server_acl" };
- }
-
- <summary> @creationEvent.InitialState.Count(x => !ImplementedStates.Contains(x.Type)) custom states</summary>
- <table>
- @foreach (var initialState in creationEvent.InitialState.Where(x => !ImplementedStates.Contains(x.Type))) {
- <tr>
- <td style="vertical-align: top;">
- @(initialState.Type):
- @if (!string.IsNullOrEmpty(initialState.StateKey)) {
- <br/>
- <span>(@initialState.StateKey)</span>
- }
-
- </td>
- <td>
- <pre>@JsonSerializer.Serialize(initialState.RawContent, new JsonSerializerOptions { WriteIndented = true })</pre>
- </td>
- </tr>
- }
- </table>
- </details>
- <details>
- <summary> @creationEvent.InitialState.Count initial states</summary>
- <table>
- @foreach (var initialState in creationEvent.InitialState) {
- var _state = initialState;
- <tr>
- <td style="vertical-align: top;">
- <span>@(_state.Type):</span><br/>
- <button @onclick="() => { creationEvent.InitialState.Remove(_state); StateHasChanged(); }">Remove</button>
- </td>
-
- <td>
- <pre>@JsonSerializer.Serialize(_state.RawContent, new JsonSerializerOptions { WriteIndented = true })</pre>
- </td>
- </tr>
- }
- </table>
- </details>
- </td>
- </tr>
- }
-</table>
-<button @onclick="CreateRoom">Create room</button>
-<br/>
-<ModalWindow Title="Creation JSON">
- <pre>
- @creationEvent.ToJson(ignoreNull: true)
- </pre>
-</ModalWindow>
-<ModalWindow Title="Creation JSON (with null values)">
- <pre>
- @creationEvent.ToJson()
- </pre>
-</ModalWindow>
-
-@if (_matrixException is not null) {
- <ModalWindow Title="@("Matrix exception: " + _matrixException.ErrorCode)">
- <pre>
- @_matrixException.Message
- </pre>
- </ModalWindow>
-}
-
-@code {
-
- private string RoomPreset {
- get => Presets.ContainsValue(creationEvent) ? Presets.First(x => x.Value == creationEvent).Key : "Not a preset";
- set {
- creationEvent = Presets[value];
- JsonChanged();
- StateHasChanged();
- }
- }
-
- private CreateRoomRequest? creationEvent { get; set; }
-
- private Dictionary<string, CreateRoomRequest>? Presets { get; set; } = new();
- private AuthenticatedHomeserverGeneric? Homeserver { get; set; }
-
- private MatrixException? _matrixException { get; set; }
-
- private RoomHistoryVisibilityEventContent? historyVisibility => creationEvent?["m.room.history_visibility"].TypedContent as RoomHistoryVisibilityEventContent;
- private RoomGuestAccessEventContent? guestAccessEvent => creationEvent?["m.room.guest_access"].TypedContent as RoomGuestAccessEventContent;
- private RoomServerACLEventContent? serverAcl => creationEvent?["m.room.server_acls"].TypedContent as RoomServerACLEventContent;
- private RoomAvatarEventContent? roomAvatarEvent => creationEvent?["m.room.avatar"].TypedContent as RoomAvatarEventContent;
-
- protected override async Task OnInitializedAsync() {
- Homeserver = await MRUStorage.GetCurrentSessionOrNavigate();
- if (Homeserver is null) return;
-
- foreach (var x in Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass && !x.IsAbstract && x.GetInterfaces().Contains(typeof(IRoomCreationTemplate))).ToList()) {
- Console.WriteLine($"Found room creation template in class: {x.FullName}");
- var instance = (IRoomCreationTemplate)Activator.CreateInstance(x);
- Presets[instance.Name] = instance.CreateRoomRequest;
- }
- Presets = Presets.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);
-
- if (!Presets.ContainsKey("Default")) {
- Console.WriteLine($"No default room found in {Presets.Count} presets: {string.Join(", ", Presets.Keys)}");
- }
- else RoomPreset = "Default";
-
- await base.OnInitializedAsync();
- }
-
- private void JsonChanged() => Console.WriteLine(creationEvent.ToJson());
-
- private async Task RoomIconFilePicked(InputFileChangeEventArgs obj) {
- var res = await Homeserver.UploadFile(obj.File.Name, obj.File.OpenReadStream(), obj.File.ContentType);
- Console.WriteLine(res);
- (creationEvent["m.room.avatar"].TypedContent as RoomAvatarEventContent).Url = res;
- StateHasChanged();
- }
-
- private async Task CreateRoom() {
- Console.WriteLine("Create room");
- Console.WriteLine(creationEvent.ToJson());
- creationEvent.CreationContent.Add("rory.gay.created_using", "Rory&::MatrixRoomUtils (https://mru.rory.gay)");
- try {
- var id = await Homeserver.CreateRoom(creationEvent);
- }
- catch (MatrixException e) {
- _matrixException = e;
- }
- }
-
- private void InviteMember(string mxid) {
- if (!creationEvent.InitialState.Any(x => x.Type == "m.room.member" && x.StateKey == mxid) && Homeserver.UserId != mxid)
- creationEvent.InitialState.Add(new StateEvent {
- Type = "m.room.member",
- StateKey = mxid,
- TypedContent = new RoomMemberEventContent {
- Membership = "invite",
- Reason = "Automatically invited at room creation time."
- }
- });
- }
-
- private string GetStateFriendlyName(string key) => key switch {
- "m.room.history_visibility" => "History visibility",
- "m.room.guest_access" => "Guest access",
- "m.room.join_rules" => "Join rules",
- "m.room.server_acl" => "Server ACL",
- "m.room.avatar" => "Avatar",
- _ => key
- };
-
- private string GetPermissionFriendlyName(string key) => key switch {
- "m.reaction" => "Send reaction",
- "m.room.avatar" => "Change room icon",
- "m.room.canonical_alias" => "Change room alias",
- "m.room.encryption" => "Enable encryption",
- "m.room.history_visibility" => "Change history visibility",
- "m.room.name" => "Change room name",
- "m.room.power_levels" => "Change power levels",
- "m.room.tombstone" => "Upgrade room",
- "m.room.topic" => "Change room topic",
- "m.room.pinned_events" => "Pin events",
- "m.room.server_acl" => "Change server ACLs",
- _ => key
- };
-
-}
|