diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
index 6d27679..35bf501 100644
--- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
@@ -11,21 +11,28 @@
else
{
<p>You are in @Rooms.Count rooms and @Spaces.Count spaces</p>
+ <p>
+ <a href="/RoomManagerCreateRoom">Create room</a>
+ </p>
+
<details open>
<summary>Space List</summary>
@foreach (var room in Spaces)
{
- <a style="color: unset; text-decoration: unset;" href="/RoomManager/Space/@room.RoomId.Replace('.', '~')"><RoomListItem Room="@room" ShowOwnProfile="true"></RoomListItem></a>
+ <a style="color: unset; text-decoration: unset;" href="/RoomManager/Space/@room.RoomId.Replace('.', '~')">
+ <RoomListItem Room="@room" ShowOwnProfile="true"></RoomListItem>
+ </a>
}
</details>
<details open>
<summary>Room List</summary>
@foreach (var room in Rooms)
{
- <a style="color: unset; text-decoration: unset;" href="/RoomManager/Room/@room.RoomId.Replace('.', '~')"><RoomListItem Room="@room" ShowOwnProfile="true"></RoomListItem></a>
+ <a style="color: unset; text-decoration: unset;" href="/RoomManager/Room/@room.RoomId.Replace('.', '~')">
+ <RoomListItem Room="@room" ShowOwnProfile="true"></RoomListItem>
+ </a>
}
</details>
-
}
<div style="margin-bottom: 4em;"></div>
@@ -34,9 +41,10 @@ else
@code {
public List<Room> Rooms { get; set; } = new();
public List<Room> Spaces { get; set; } = new();
+
protected override async Task OnInitializedAsync()
{
- if (!RuntimeCache.WasLoaded) await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
+ await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
await base.OnInitializedAsync();
if (RuntimeCache.CurrentHomeServer == null)
{
@@ -45,40 +53,47 @@ else
}
Rooms = await RuntimeCache.CurrentHomeServer.GetJoinedRooms();
StateHasChanged();
- var semaphore = new SemaphoreSlim(1000);
+ Console.WriteLine($"Got {Rooms.Count} rooms");
+ var semaphore = new SemaphoreSlim(10);
var tasks = new List<Task<Room?>>();
foreach (var room in Rooms)
{
tasks.Add(CheckIfSpace(room, semaphore));
}
await Task.WhenAll(tasks);
-
+
Console.WriteLine("Fetched joined rooms!");
}
-
+
private async Task<Room?> CheckIfSpace(Room room, SemaphoreSlim semaphore)
{
await semaphore.WaitAsync();
+ // Console.WriteLine($"Checking if {room.RoomId} is a space");
try
{
- var state = await room.GetStateAsync("m.room.create");
+ var state = await room.GetStateAsync<CreateEvent>("m.room.create");
if (state != null)
{
- //Console.WriteLine(state.Value.ToJson());
- if(state.Value.TryGetProperty("type", out var type))
+ //Console.WriteLine(state.Value.ToJson());
+ if (state.Type != null)
{
- if(type.ToString() == "m.space")
+ if (state.Type == "m.space")
{
+ Console.WriteLine($"Room {room.RoomId} is a space!");
Spaces.Add(room);
Rooms.Remove(room);
StateHasChanged();
return room;
}
+ else
+ {
+ Console.WriteLine($"Encountered unknown room type {state.Type}");
+ }
}
else
{
- //this is fine, apprently...
- //Console.WriteLine($"Room {room.RoomId} has no content.type in m.room.create!");
+ //this is fine, apprently...
+ // Console.WriteLine($"Room {room.RoomId} has no Content.type in m.room.create!");
}
}
}
@@ -93,4 +108,5 @@ else
}
return null;
}
-}
\ No newline at end of file
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor
new file mode 100644
index 0000000..7b4db37
--- /dev/null
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor
@@ -0,0 +1,298 @@
+@page "/RoomManagerCreateRoom"
+@using System.Text.Json
+@using MatrixRoomUtils.Core.Extensions
+@using MatrixRoomUtils.Core.Responses
+@using System.Runtime.Intrinsics.X86
+<h3>Room Manager - Create Room</h3>
+
+@* <pre Contenteditable="true" @onkeypress="@JsonChanged" ="JsonString">@JsonString</pre> *@
+<table>
+ <tr >
+ <td style="padding-bottom: 16px;">Preset:</td>
+ <td style="padding-bottom: 16px;">
+ <InputSelect @bind-Value="@RoomPreset">
+ @foreach (var createRoomRequest in Presets)
+ {
+ <option value="@createRoomRequest.Key">@createRoomRequest.Key</option>
+ }
+ @* <option value="private_chat">Private chat</option> *@
+ @* <option value="trusted_private_chat">Trusted private chat</option> *@
+ @* <option value="public_chat">Public chat</option> *@
+ </InputSelect>
+ </td>
+ </tr>
+ <tr>
+ <td>Room name:</td>
+ <td>
+ <InputText @bind-Value="@creationEvent.Name"></InputText>
+ </td>
+ </tr>
+ <tr>
+ <td>Room alias (localpart):</td>
+ <td>
+ <InputText @bind-Value="@creationEvent.RoomAliasName"></InputText>
+ </td>
+ </tr>
+ <tr>
+ <td>Room type:</td>
+ <td>
+ <InputSelect @bind-Value="@creationEvent._creationContentBaseType.Type">
+ <option value="">Room</option>
+ <option value="m.space">Space</option>
+ </InputSelect>
+ <InputText @bind-Value="@creationEvent._creationContentBaseType.Type"></InputText>
+ </td>
+ </tr>
+ <tr>
+ <td style="padding-top: 16px;">History visibility:</td>
+ <td style="padding-top: 16px;">
+ <InputSelect @bind-Value="@creationEvent.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>
+ <InputSelect @bind-Value="@creationEvent.GuestAccess">
+ <option value="can_join">Can join</option>
+ <option value="forbidden">Forbidden</option>
+ </InputSelect>
+ </td>
+ </tr>
+
+ <tr>
+ <td>Room icon:</td>
+ <td>
+ <img src="@RuntimeCache.CurrentHomeServer?.ResolveMediaUri(creationEvent.RoomIcon ?? "")" style="max-width: 100px; max-height: 100px; border-radius: 50%;"/>
+ @* <InputText @bind-Value="@creationEvent.RoomIcon"></InputText> *@
+ </td>
+
+ </tr>
+
+ <tr>
+ <td style="vertical-align: top;">Initial states:</td>
+ <td>
+ <details>
+ @code{
+
+ private static string[] ImplementedStates = new[] { "m.room.avatar", "m.room.history_visibility", "m.room.guest_access", };
+
+ }
+ <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):</td>
+
+ <td>
+ <pre>@JsonSerializer.Serialize(initialState.Content, new JsonSerializerOptions { WriteIndented = true })</pre>
+ </td>
+ </tr>
+ }
+ </table>
+ </details>
+ <details>
+ <summary>@creationEvent.InitialState.Count initial states</summary>
+ <table>
+ @foreach (var initialState in creationEvent.InitialState.Where(x => !new[] { "m.room.avatar", "m.room.history_visibility" }.Contains(x.Type)))
+ {
+ <tr>
+ <td style="vertical-align: top;">@(initialState.Type):</td>
+
+ <td>
+ <pre>@JsonSerializer.Serialize(initialState.Content, new JsonSerializerOptions { WriteIndented = true })</pre>
+ </td>
+ </tr>
+ }
+ </table>
+ </details>
+ </td>
+ </tr>
+</table>
+<br/>
+<details>
+ <summary>Creation JSON</summary>
+ <pre>
+ @creationEvent.ToJson(ignoreNull: true)
+ </pre>
+</details>
+<details open>
+ <summary>Creation JSON (with null values)</summary>
+ <EditablePre @bind-Value="@JsonString" oninput="@JsonChanged"></EditablePre>
+</details>
+
+
+@code {
+
+ private string JsonString
+ {
+ get => creationEvent.ToJson();
+ set
+ {
+ creationEvent = JsonSerializer.Deserialize<CreateRoomRequest>(value);
+ JsonChanged();
+ }
+ }
+
+ 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();
+ }
+ }
+
+ private Dictionary<string, string> creationEventValidationErrors { get; set; } = new();
+
+ private CreateRoomRequest creationEvent { get; set; }
+
+ private Dictionary<string, CreateRoomRequest> Presets { get; set; } = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+ await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
+
+ creationEvent = Presets["Default room"] = new CreateRoomRequest
+ {
+ Name = "My new room",
+ RoomAliasName = "myroom",
+ InitialState = new()
+ {
+ new()
+ {
+ Type = "m.room.history_visibility",
+ Content = new
+ {
+ history_visibility = "world_readable"
+ }
+ },
+ new()
+ {
+ Type = "m.room.guest_access",
+ Content = new
+ {
+ guest_access = "can_join"
+ }
+ },
+ new()
+ {
+ Type = "m.room.join_rules",
+ Content = new
+ {
+ join_rule = "public"
+ }
+ },
+ new()
+ {
+ Type = "m.room.server_acl",
+ Content = new
+ {
+ allow = new[] { "*" },
+ deny = new[]
+ {
+ "midov.pl",
+ "qoto.org",
+ "matrix.kiwifarms.net",
+ "plan9.rocks",
+ "thisisjoes.site",
+ "konqi.work",
+ "austinhuang.lol",
+ "arcticfox.ems.host",
+ "*.thisisjoes.site",
+ "*.abuser.eu",
+ "*.austinhuang.lol"
+ },
+ allow_ip_literals = false
+ }
+ },
+ new()
+ {
+ Type = "m.room.avatar",
+ Content = new
+ {
+ url = "mxc://feline.support/UKNhEyrVsrAbYteVvZloZcFj"
+ }
+ }
+ },
+ Visibility = "public",
+ PowerLevelContentOverride = new()
+ {
+ UsersDefault = 0,
+ EventsDefault = 100,
+ StateDefault = 50,
+ Invite = 0,
+ Redact = 50,
+ Kick = 50,
+ Ban = 50,
+ NotificationsPl = new()
+ {
+ Room = 50
+ },
+ Events = new()
+ {
+ { "im.vector.modular.widgets", 50 },
+ { "io.element.voice_broadcast_info", 50 },
+ { "m.reaction", 100 },
+ { "m.room.avatar", 50 },
+ { "m.room.canonical_alias", 50 },
+ { "m.room.encryption", 100 },
+ { "m.room.history_visibility", 100 },
+ { "m.room.name", 50 },
+ { "m.room.pinned_events", 50 },
+ { "m.room.power_levels", 100 },
+ { "m.room.redaction", 100 },
+ { "m.room.server_acl", 100 },
+ { "m.room.tombstone", 100 },
+ { "m.room.topic", 50 },
+ { "m.space.child", 50 },
+ { "org.matrix.msc3401.call", 50 },
+ { "org.matrix.msc3401.call.member", 50 }
+ },
+ Users = new()
+ {
+ { "@alicia:rory.gay", 100 },
+ { "@emma:rory.gay", 100 },
+ { "@root:rory.gay", 100 },
+ { "@rory:rory.gay", 100 }
+ },
+ },
+ CreationContent = new()
+ {
+ { "type", null }
+ }
+ };
+
+
+ await base.OnInitializedAsync();
+ }
+
+ private void JsonChanged()
+ {
+ Console.WriteLine(JsonString);
+ }
+
+
+ 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
+ };
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
index 4a5bddf..a44b2b4 100644
--- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
@@ -13,9 +13,9 @@
<br/>
<details style="background: #0002;">
<summary style="background: #fff1;">State list</summary>
- @foreach (var stateEvent in States.OrderBy(x => x.state_key).ThenBy(x => x.type))
+ @foreach (var stateEvent in States.OrderBy(x => x.StateKey).ThenBy(x => x.Type))
{
- <p>@stateEvent.state_key/@stateEvent.type:</p>
+ <p>@stateEvent.StateKey/@stateEvent.Type:</p>
<pre>@stateEvent.content.ToJson()</pre>
}
</details>
@@ -27,7 +27,7 @@
private Room? Room { get; set; }
- private StateEvent<object>[] States { get; set; } = Array.Empty<StateEvent<object>>();
+ private StateEventResponse<object>[] States { get; set; } = Array.Empty<StateEventResponse<object>>();
private List<Room> Rooms { get; set; } = new();
protected override async Task OnInitializedAsync()
@@ -38,14 +38,14 @@
if (state != null)
{
Console.WriteLine(state.Value.ToJson());
- States = state.Value.Deserialize<StateEvent<object>[]>()!;
+ States = state.Value.Deserialize<StateEventResponse<object>[]>()!;
foreach (var stateEvent in States)
{
- if (stateEvent.type == "m.space.child")
+ if (stateEvent.Type == "m.space.child")
{
- // if (stateEvent.content.ToJson().Length < 5) return;
- var roomId = stateEvent.state_key;
+ // if (stateEvent.Content.ToJson().Length < 5) return;
+ var roomId = stateEvent.StateKey;
var room = await RuntimeCache.CurrentHomeServer.GetRoom(roomId);
if (room != null)
{
@@ -54,13 +54,13 @@
}
}
- // if(state.Value.TryGetProperty("type", out var type))
+ // if(state.Value.TryGetProperty("Type", out var Type))
// {
// }
// else
// {
// //this is fine, apprently...
- // //Console.WriteLine($"Room {room.RoomId} has no content.type in m.room.create!");
+ // //Console.WriteLine($"Room {room.RoomId} has no Content.Type in m.room.create!");
// }
}
await base.OnInitializedAsync();
|