@page "/RoomManagerCreateRoom" @using MatrixRoomUtils.Core.Extensions @using MatrixRoomUtils.Core.Responses @using System.Text.Json @using System.Text.Json.Serialization @using System.Reflection @using MatrixRoomUtils.Web.Classes.RoomCreationTemplates @* ReSharper disable once RedundantUsingDirective - Must not remove this, Rider marks this as "unused" when it's not *@ @using MatrixRoomUtils.Web.Shared.SimpleComponents

Room Manager - Create Room

@*
@JsonString
*@ @if (creationEvent != null) {
@creationEvent.PowerLevelContentOverride.Users.Count members @foreach (var user in creationEvent.PowerLevelContentOverride.Events.Keys) { var _event = user;
} @foreach (var user in creationEvent.PowerLevelContentOverride.Users.Keys) { var _user = user; } @* Initial states, should remain at bottom? *@ }
Preset: @foreach (var createRoomRequest in Presets) { }
Room name:
Room alias (localpart):
Room type:
History visibility:
Guest access: @(guestAccessEvent.IsGuestAccessEnabled ? "Guests can join" : "Guests cannot join") (@guestAccessEvent.GuestAccess) @* *@ @* *@ @* *@ @* *@
Room icon:

Permissions:
:
:
Server ACLs:
@(creationEvent.ServerACLs.Allow.Count) allow rules
@creationEvent.ServerACLs.Deny.Count deny rules
Invited members:
@creationEvent.InitialState.Count(x => x.Type == "m.room.member") members @foreach (var member in creationEvent.InitialState.Where(x => x.Type == "m.room.member" && x.StateKey != RuntimeCache.CurrentHomeServer.UserId)) { }
Initial states:
@code{ private static readonly string[] ImplementedStates = { "m.room.avatar", "m.room.history_visibility", "m.room.guest_access", "m.room.server_acl" }; } @creationEvent.InitialState.Count(x => !ImplementedStates.Contains(x.Type)) custom states @foreach (var initialState in creationEvent.InitialState.Where(x => !ImplementedStates.Contains(x.Type))) { }
@(initialState.Type): @if (!string.IsNullOrEmpty(initialState.StateKey)) {
(@initialState.StateKey) }
@JsonSerializer.Serialize(initialState.Content, new JsonSerializerOptions { WriteIndented = true })
@creationEvent.InitialState.Count initial states @foreach (var initialState in creationEvent.InitialState) { var _state = initialState; }
@(_state.Type):
@JsonSerializer.Serialize(_state.Content, new JsonSerializerOptions { WriteIndented = true })

Creation JSON
        @creationEvent.ToJson(ignoreNull: true)
    
Creation JSON (with null values)
    @creationEvent.ToJson()
    
@code { private string RoomPreset { get { if (Presets.ContainsValue(creationEvent)) { return Presets.First(x => x.Value == creationEvent).Key; } return "Not a preset"; } set { creationEvent = Presets[value]; JsonChanged(); OverwriteWrappedPropertiesFromEvent(); creationEvent.PowerLevelContentOverride.Events = creationEvent.PowerLevelContentOverride.Events.OrderByDescending(x => x.Value).ThenBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); creationEvent.PowerLevelContentOverride.Users = creationEvent.PowerLevelContentOverride.Users.OrderByDescending(x => x.Value).ThenBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value); guestAccessEvent = creationEvent["m.room.guest_access"].As().Content; Console.WriteLine($"Creation event uncasted: {creationEvent["m.room.guest_access"].ToJson()}"); Console.WriteLine($"Creation event casted: {creationEvent["m.room.guest_access"].As().ToJson()}"); creationEvent["m.room.guest_access"].As().Content.IsGuestAccessEnabled = true; Console.WriteLine("-- Created new guest access content --"); Console.WriteLine($"Creation event uncasted: {creationEvent["m.room.guest_access"].ToJson()}"); Console.WriteLine($"Creation event casted: {creationEvent["m.room.guest_access"].As().ToJson()}"); Console.WriteLine($"Creation event casted back: {creationEvent["m.room.guest_access"].As().ToJson()}"); StateHasChanged(); } } private Dictionary creationEventValidationErrors { get; set; } = new(); private CreateRoomRequest creationEvent { get; set; } GuestAccessContent guestAccessEvent { get; set; } private Dictionary Presets { get; set; } = new(); protected override async Task OnInitializedAsync() { await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); //creationEvent = Presets["Default room"] = 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()); //wrappers private List ServerACLAllowRules { get; set; } = new(); private List ServerACLDenyRules { get; set; } = new(); private void OverwriteWrappedPropertiesFromEvent() { Console.WriteLine("Overwriting wrapped properties from event"); ServerACLAllowRules = creationEvent.ServerACLs.Allow; ServerACLDenyRules = creationEvent.ServerACLs.Deny; } private async Task OverwriteWrappedProperties() { Console.WriteLine("Overwriting wrapped properties"); Console.WriteLine($"Allow: {ServerACLAllowRules.Count}: {string.Join(", ", ServerACLAllowRules)}"); Console.WriteLine($"Deny: {ServerACLDenyRules.Count}: {string.Join(", ", ServerACLDenyRules)}"); creationEvent.ServerACLs = new ServerACL { Allow = ServerACLAllowRules, Deny = ServerACLDenyRules, AllowIpLiterals = creationEvent.ServerACLs.AllowIpLiterals }; StateHasChanged(); } private async Task RoomIconFilePicked(InputFileChangeEventArgs obj) { var res = await RuntimeCache.CurrentHomeServer.UploadFile(obj.File.Name, obj.File.OpenReadStream(), obj.File.ContentType); Console.WriteLine(res); creationEvent.RoomIcon = 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)"); //creationEvent.CreationContent.Add(); var id = await RuntimeCache.CurrentHomeServer.CreateRoom(creationEvent); // NavigationManager.NavigateTo($"/RoomManager/{id.RoomId.Replace('.','~')}"); } private void InviteMember(string mxid) { if (!creationEvent.InitialState.Any(x => x.Type == "m.room.member" && x.StateKey == mxid) && RuntimeCache.CurrentHomeServer.UserId != mxid) creationEvent.InitialState.Add(new StateEvent { Type = "m.room.member", StateKey = mxid, Content = new { 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 }; public class GuestAccessContent { [JsonPropertyName("guest_access")] public string GuestAccess { get; set; } public bool IsGuestAccessEnabled { get => GuestAccess == "can_join"; set => GuestAccess = value ? "can_join" : "forbidden"; } } }