diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-11-09 07:38:33 +0100 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-11-09 07:38:33 +0100 |
commit | c37bcb0e4a878d4f4c0e47988adb8624131c82cd (patch) | |
tree | 706f5300ce83b511d807decddd5b3521168b5fc7 /MatrixRoomUtils.Web/Pages | |
parent | Fix updates (diff) | |
download | MatrixUtils-c37bcb0e4a878d4f4c0e47988adb8624131c82cd.tar.xz |
event types
Diffstat (limited to 'MatrixRoomUtils.Web/Pages')
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor | 7 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor | 22 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Index.razor | 22 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/LoginPage.razor | 46 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/ModerationUtilities/UserRoomHistory.razor | 113 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Rooms/Create.razor | 2 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Rooms/Index.razor | 1 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor | 8 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/ServerInfo.razor | 235 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor | 124 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor | 2 | ||||
-rw-r--r-- | MatrixRoomUtils.Web/Pages/User/DMManager.razor | 11 |
12 files changed, 459 insertions, 134 deletions
diff --git a/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor b/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor index 4b2dc4f..94c51b2 100644 --- a/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor +++ b/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor @@ -16,7 +16,7 @@ else { <summary>Room List</summary> @foreach (var room in Rooms) { <a style="color: unset; text-decoration: unset;" href="/RoomStateViewer/@room.Replace('.', '~')"> - <RoomListItem RoomId="@room"></RoomListItem> + <RoomListItem RoomInfo="@(new RoomInfo() { Room = hs.GetRoom(room) })" LoadData="true"></RoomListItem> </a> } </details> @@ -37,10 +37,11 @@ else { @code { public List<string> Rooms { get; set; } = new(); + public AuthenticatedHomeserverGeneric? hs { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + hs = await MRUStorage.GetCurrentSessionOrNavigate(); if (hs == null) return; Rooms = (await hs.GetJoinedRooms()).Select(x => x.RoomId).ToList(); Console.WriteLine("Fetched joined rooms!"); @@ -76,4 +77,4 @@ else { StateHasChanged(); } -} +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor b/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor index 59ce70f..c605e7a 100644 --- a/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor +++ b/MatrixRoomUtils.Web/Pages/HSAdmin/HSAdmin.razor @@ -1,20 +1,34 @@ @page "/HSAdmin" @using LibMatrix.Homeservers +@using ArcaneLibs.Extensions <h3>Homeserver Admininistration</h3> <hr/> -<h4>Synapse tools</h4> -<hr/> -<a href="/HSAdmin/RoomQuery">Query rooms</a> +@if (Homeserver is null) { + <p>Homeserver is null...</p> +} +else { + @if (Homeserver is AuthenticatedHomeserverSynapse) { + <h4>Synapse tools</h4> + <hr/> + <a href="/HSAdmin/RoomQuery">Query rooms</a> + } + else { + <p>Homeserver type @Homeserver.GetType().Name does not have any administration tools in MRU.</p> + <p>Server info:</p> + <pre>@ServerVersionResponse?.ToJson(ignoreNull: true)</pre> + } +} @code { public AuthenticatedHomeserverGeneric? Homeserver { get; set; } + public ServerVersionResponse? ServerVersionResponse { get; set; } protected override async Task OnInitializedAsync() { Homeserver = await MRUStorage.GetCurrentSessionOrNavigate(); if (Homeserver is null) return; + ServerVersionResponse = await Homeserver.GetServerVersionAsync(); await base.OnInitializedAsync(); } - } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor index 74dd651..804fde3 100644 --- a/MatrixRoomUtils.Web/Pages/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Index.razor @@ -3,6 +3,7 @@ @using LibMatrix @using LibMatrix.Homeservers @using ArcaneLibs.Extensions +@using MatrixRoomUtils.Web.Pages.Dev <PageTitle>Index</PageTitle> @@ -28,13 +29,18 @@ Small collection of tools to do not-so-everyday things. </p> <span style="display: inline-block; width: 128px;">@__auth.UserInfo.RoomCount rooms</span> - <span style="color: #888888">@__auth.ServerVersion.Server.Name @__auth.ServerVersion.Server.Version</span> + <a style="color: #888888" href="@("/ServerInfo/"+__auth.Homeserver.ServerName+"/")">@__auth.ServerVersion.Server.Name @__auth.ServerVersion.Server.Version</a> @if (_auth.Proxy != null) { <span class="badge badge-info"> (proxied via @_auth.Proxy)</span> } else { <p>Not proxied</p> } + @if (DEBUG) { + <p>T=@__auth.Homeserver.GetType().FullName</p> + <p>D=@__auth.Homeserver.WhoAmI.DeviceId</p> + <p>U=@__auth.Homeserver.WhoAmI.UserId</p> + } </td> <td> <p> @@ -51,10 +57,17 @@ Small collection of tools to do not-so-everyday things. @code { +#if DEBUG + bool DEBUG = true; +#else + bool DEBUG = false; +#endif + private class AuthInfo { public UserAuth UserAuth { get; set; } public UserInfo UserInfo { get; set; } public ServerVersionResponse ServerVersion { get; set; } + public AuthenticatedHomeserverGeneric Homeserver { get; set; } } // private Dictionary<UserAuth, UserInfo> _users = new(); @@ -69,7 +82,7 @@ Small collection of tools to do not-so-everyday things. UserInfo userInfo = new(); AuthenticatedHomeserverGeneric hs; try { - hs = await hsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken); + hs = await hsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy); } catch (MatrixException e) { if (e.ErrorCode == "M_UNKNOWN_TOKEN") { @@ -88,7 +101,8 @@ Small collection of tools to do not-so-everyday things. _auth.Add(new() { UserInfo = userInfo, UserAuth = token, - ServerVersion = await hs.GetServerVersionAsync() + ServerVersion = await hs.GetServerVersionAsync(), + Homeserver = hs }); // StateHasChanged(); }); @@ -105,7 +119,7 @@ Small collection of tools to do not-so-everyday things. private async Task RemoveUser(UserAuth auth, bool logout = false) { try { if (logout) { - await (await hsProvider.GetAuthenticatedWithToken(auth.Homeserver, auth.AccessToken)).Logout(); + await (await hsProvider.GetAuthenticatedWithToken(auth.Homeserver, auth.AccessToken, auth.Proxy)).Logout(); } } catch (Exception e) { diff --git a/MatrixRoomUtils.Web/Pages/LoginPage.razor b/MatrixRoomUtils.Web/Pages/LoginPage.razor index 1b466c9..c926a93 100644 --- a/MatrixRoomUtils.Web/Pages/LoginPage.razor +++ b/MatrixRoomUtils.Web/Pages/LoginPage.razor @@ -7,15 +7,15 @@ <span> <span>@@</span><!-- - --><FancyTextBox @bind-Value="@newRecordInput.username"></FancyTextBox><!-- + --><FancyTextBox @bind-Value="@newRecordInput.Username"></FancyTextBox><!-- --><span>:</span><!-- - --><FancyTextBox @bind-Value="@newRecordInput.homeserver"></FancyTextBox> + --><FancyTextBox @bind-Value="@newRecordInput.Homeserver"></FancyTextBox> via - <FancyTextBox @bind-Value="@newRecordInput.password" IsPassword="true"></FancyTextBox> + <FancyTextBox @bind-Value="@newRecordInput.Proxy"></FancyTextBox> </span> <span style="display: block;"> <label>Password:</label> - <FancyTextBox @bind-Value="@newRecordInput.password" IsPassword="true"></FancyTextBox> + <FancyTextBox @bind-Value="@newRecordInput.Password" IsPassword="true"></FancyTextBox> </span> <button @onclick="AddRecord">Add account to queue</button> <br/> @@ -34,18 +34,18 @@ </thead> @foreach (var record in records) { var r = record; - <tr style="background-color: @(LoggedInSessions.Any(x => x.UserId == $"@{r.username}:{r.homeserver}" && x.Proxy == r.proxy) ? "green" : "unset")"> + <tr style="background-color: @(LoggedInSessions.Any(x => x.UserId == $"@{r.Username}:{r.Homeserver}" && x.Proxy == r.Proxy) ? "green" : "unset")"> <td style="border-width: 1px;"> - <FancyTextBox @bind-Value="@r.homeserver"></FancyTextBox> + <FancyTextBox @bind-Value="@r.Username"></FancyTextBox> </td> <td style="border-width: 1px;"> - <FancyTextBox @bind-Value="@r.username"></FancyTextBox> + <FancyTextBox @bind-Value="@r.Homeserver"></FancyTextBox> </td> <td style="border-width: 1px;"> - <FancyTextBox @bind-Value="@r.password" IsPassword="true"></FancyTextBox> + <FancyTextBox @bind-Value="@r.Password" IsPassword="true"></FancyTextBox> </td> <td style="border-width: 1px;"> - <FancyTextBox @bind-Value="@r.proxy"></FancyTextBox> + <FancyTextBox @bind-Value="@r.Proxy"></FancyTextBox> </td> <td> <a role="button" @onclick="() => records.Remove(r)">Remove</a> @@ -59,21 +59,20 @@ <LogView></LogView> @code { - readonly List<(string homeserver, string username, string password, string? proxy)> records = new(); - (string homeserver, string username, string password, string? proxy) newRecordInput = ("", "", "", null); + readonly List<LoginStruct> records = new(); + private LoginStruct newRecordInput = new(); List<UserAuth>? LoggedInSessions { get; set; } = new(); async Task Login() { var loginTasks = records.Select(async record => { - var (homeserver, username, password, proxy) = record; - if (LoggedInSessions.Any(x => x.UserId == $"@{username}:{homeserver}" && x.Proxy == proxy)) return; + if (LoggedInSessions.Any(x => x.UserId == $"@{record.Username}:{record.Homeserver}" && x.Proxy == record.Proxy)) return; try { - var result = new UserAuth(await hsProvider.Login(homeserver, username, password, proxy)) { - Proxy = proxy + var result = new UserAuth(await hsProvider.Login(record.Homeserver, record.Username, record.Password, record.Proxy)) { + Proxy = record.Proxy }; if (result == null) { - Console.WriteLine($"Failed to login to {homeserver} as {username}!"); + Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!"); return; } Console.WriteLine($"Obtained access token for {result.UserId}!"); @@ -82,7 +81,7 @@ LoggedInSessions = await MRUStorage.GetAllTokens(); } catch (Exception e) { - Console.WriteLine($"Failed to login to {homeserver} as {username}!"); + Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!"); Console.WriteLine(e); } StateHasChanged(); @@ -104,14 +103,21 @@ if (parts.Length < 3) continue; string? via = parts.Length > 3 ? parts[3] : null; - records.Add((parts[0], parts[1], parts[2], via)); + records.Add(new() { Homeserver = parts[0], Username = parts[1], Password = parts[2], Proxy = via }); } } private async Task AddRecord() { LoggedInSessions = await MRUStorage.GetAllTokens(); records.Add(newRecordInput); - newRecordInput = ("", "", "", null); + newRecordInput = new(); } -} + private class LoginStruct { + public string? Homeserver { get; set; } = ""; + public string? Username { get; set; } = ""; + public string? Password { get; set; } = ""; + public string? Proxy { get; set; } + } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/ModerationUtilities/UserRoomHistory.razor b/MatrixRoomUtils.Web/Pages/ModerationUtilities/UserRoomHistory.razor new file mode 100644 index 0000000..02dfe44 --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/ModerationUtilities/UserRoomHistory.razor @@ -0,0 +1,113 @@ +@page "/UserRoomHistory/{UserId}" +@using LibMatrix.Homeservers +@using LibMatrix +@using LibMatrix.EventTypes.Spec.State +@using LibMatrix.RoomTypes +@using ArcaneLibs.Extensions +<h3>UserRoomHistory</h3> + +<span>Enter mxid: </span> +<FancyTextBox @bind-Value="@UserId"></FancyTextBox> + +@if (string.IsNullOrWhiteSpace(UserId)) { + <p>UserId is null!</p> +} +else { + <p>Checked @checkedRooms.Count so far...</p> + @if (currentHs is not null) { + <p>Checking rooms from @currentHs.UserId's perspective</p> + } + else if (checkedRooms.Count > 1) { + <p>Done!</p> + } + @foreach (var (state, rooms) in matchingStates) { + <u>@state</u> + <br/> + @foreach (var roomInfo in rooms) { + <RoomListItem RoomInfo="roomInfo" LoadData="true"></RoomListItem> + } + } +} + +@code { + private string? _userId; + + [Parameter] + public string? UserId { + get => _userId; + set { + _userId = value; + FindMember(value); + } + } + + private List<AuthenticatedHomeserverGeneric> hss = new(); + private AuthenticatedHomeserverGeneric? currentHs { get; set; } + + protected override async Task OnInitializedAsync() { + var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + if (hs is null) return; + var sessions = await MRUStorage.GetAllTokens(); + foreach (var userAuth in sessions) { + var session = await MRUStorage.GetSession(userAuth); + if (session is not null) { + hss.Add(session); + StateHasChanged(); + } + } + + StateHasChanged(); + Console.WriteLine("Rerendered!"); + await base.OnInitializedAsync(); + if (!string.IsNullOrWhiteSpace(UserId)) FindMember(UserId); + } + + public Dictionary<string, List<RoomInfo>> matchingStates = new(); + public List<string> checkedRooms = new(); + private SemaphoreSlim _semaphoreSlim = new(1, 1); + + public async Task FindMember(string mxid) { + await _semaphoreSlim.WaitAsync(); + if (mxid != UserId) { + _semaphoreSlim.Release(); + return; //abort if changed + } + matchingStates.Clear(); + foreach (var homeserver in hss) { + currentHs = homeserver; + var rooms = await homeserver.GetJoinedRooms(); + rooms.RemoveAll(x => checkedRooms.Contains(x.RoomId)); + checkedRooms.AddRange(rooms.Select(x => x.RoomId)); + var tasks = rooms.Select(x => GetMembershipAsync(x, mxid)).ToAsyncEnumerable(); + await foreach (var (room, state) in tasks) { + if (state is null) continue; + if (!matchingStates.ContainsKey(state.Membership)) + matchingStates.Add(state.Membership, new()); + var roomInfo = new RoomInfo() { + Room = room + }; + matchingStates[state.Membership].Add(roomInfo); + roomInfo.StateEvents.Add(new() { + Type = RoomNameEventContent.EventId, + TypedContent = new RoomNameEventContent() { + Name = await room.GetNameOrFallbackAsync(4) + } + }); + StateHasChanged(); + if (mxid != UserId) { + _semaphoreSlim.Release(); + return; //abort if changed + } + } + StateHasChanged(); + } + currentHs = null; + StateHasChanged(); + _semaphoreSlim.Release(); + } + + public async Task<(GenericRoom roomId, RoomMemberEventContent? content)> GetMembershipAsync(GenericRoom room, string mxid) { + return (room, await room.GetStateOrNullAsync<RoomMemberEventContent>(RoomMemberEventContent.EventId, mxid)); + } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor index 5823757..08b21dd 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor @@ -88,7 +88,7 @@ <tr> <td>Room icon:</td> <td> - <img src="@hsResolver.ResolveMediaUri(Homeserver.ServerName, roomAvatarEvent.Url)" style="width: 128px; height: 128px; border-radius: 50%;"/> + <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> diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor index fd32cb3..60f4f62 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor @@ -156,6 +156,7 @@ Status = $"Got {Rooms.Count} rooms so far! {queue.Count} entries in processing queue..."; } RenderContents |= queue.Count == 0; + if (queue.Count > 10) RenderContents = false; await Task.Delay(RenderContents ? 25 : 25); } else { diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor index 1f4a923..01bf555 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor @@ -47,10 +47,14 @@ private StateEventResponse GetProfileEventBefore(StateEventResponse Event) => Events.TakeWhile(x => x != Event).Last(e => e.Type == "m.room.member" && e.StateKey == Event.Sender); private Type ComponentType(StateEvent Event) => Event.TypedContent switch { - RoomMessageEventContent => typeof(TimelineMessageItem), + RoomCanonicalAliasEventContent => typeof(TimelineCanonicalAliasItem), + RoomHistoryVisibilityEventContent => typeof(TimelineHistoryVisibilityItem), + RoomTopicEventContent => typeof(TimelineRoomTopicItem), RoomMemberEventContent => typeof(TimelineMemberItem), + RoomMessageEventContent => typeof(TimelineMessageItem), RoomCreateEventContent => typeof(TimelineRoomCreateItem), + RoomNameEventContent => typeof(TimelineRoomNameItem), _ => typeof(TimelineUnknownItem) - }; + }; } diff --git a/MatrixRoomUtils.Web/Pages/ServerInfo.razor b/MatrixRoomUtils.Web/Pages/ServerInfo.razor new file mode 100644 index 0000000..5b3f1c1 --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/ServerInfo.razor @@ -0,0 +1,235 @@ +@page "/ServerInfo/{Homeserver}" +@using LibMatrix.Homeservers +@using LibMatrix.Responses +@using ArcaneLibs.Extensions +<h3>ServerInfo</h3> +<hr/> +@if (ServerVersionResponse is not null) { + <p>Server version: @ServerVersionResponse.Server.Name @ServerVersionResponse.Server.Version</p> + <pre>@ServerVersionResponse?.ToJson(ignoreNull: true)</pre> + <br/> +} +@if (ClientVersionsResponse is not null) { + <p>Client versions:</p> + <details> + <summary>JSON data</summary> + <pre>@ClientVersionsResponse?.ToJson(ignoreNull: true)</pre> + </details> + <u>Spec versions</u> + <table> + <thead> + <td></td> + <td>Version</td> + <td>Release date</td> + </thead> + @foreach (var (version, info) in ClientVersions) { + <tr> + <td>@(ClientVersionsResponse.Versions.Contains(version) ? "\u2714" : "\u274c")</td> + <td><a href="@info.SpecUrl">@info.Name</a></td> + <td>@info.Released</td> + </tr> + } + + @foreach (var version in ClientVersionsResponse.Versions) { + if (!ClientVersions.ContainsKey(version)) { + <tr> + <td>@("\u2714")</td> + <td><a href="https://spec.matrix.org/@version">Unknown version: @version</a></td> + <td></td> + </tr> + } + } + </table> + <u>Unstable features</u> + <table> + <thead> + <td style="padding-right: 8px;">Supported</td> + <td style="padding-right: 8px;">Enabled</td> + <td style="padding-right: 8px;">Name</td> + </thead> + @* @foreach (var (version, info) in ClientVersions) { *@ + @* <tr> *@ + @* *@ + @* <td>@("\u2714")</td> *@ + @* <td>@(ClientVersionsResponse.Versions.Contains(version) ? "\u2714" : "\u274c")</td> *@ + @* <td>@info.Released</td> *@ + @* </tr> *@ + @* } *@ + + @foreach (var version in ClientVersionsResponse.UnstableFeatures) { + if (!ClientVersions.ContainsKey(version.Key)) { + <tr> + <td>@("\u2714")</td> + <td>@(version.Value ? "\u2714" : "\u274c")</td> + <td>@version.Key</td> + </tr> + } + } + </table> +} + + +@code { + + [Parameter] + public string? Homeserver { get; set; } + + public ServerVersionResponse? ServerVersionResponse { get; set; } + public ClientVersionsResponse? ClientVersionsResponse { get; set; } + + protected override async Task OnParametersSetAsync() { + if (Homeserver is not null) { + var rhs = await hsProvider.GetRemoteHomeserver(Homeserver); + ServerVersionResponse = await rhs.GetServerVersionAsync(); + ClientVersionsResponse = await rhs.GetClientVersionsAsync(); + } + base.OnParametersSetAsync(); + } + + private class ClientVersionInfo { + public string Name { get; set; } + public string SpecUrl { get; set; } + public DateTime Released { get; set; } + } + + private Dictionary<string, ClientVersionInfo> ClientVersions = new() { + { + "legacy", + new() { + Name = "Legacy: Last draft before formal release of r0.0.0", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/legacy/" + } + }, + { + "r0.0.0", + new() { + Name = "r0.0.0: Initial release: media repo, sync v2", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.0.0/" + } + }, + { + "r0.0.1", + new() { + Name = "r0.0.1: User-interactive authentication, groups, read receipts, presence", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.0.1/" + } + }, + { + "r0.1.0", + new() { + Name = "r0.1.0: Device management, account data, push rules, VoIP", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.1.0/" + } + }, + { + "r0.2.0", + new() { + Name = "r0.2.0: Clarifications", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/client_server/r0.2.0.html" + } + }, + { + "r0.3.0", + new() { + Name = "r0.3.0: Device management", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/client_server/r0.3.0.html" + } + }, + { + "r0.4.0", + new() { + Name = "r0.4.0: Room directory", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.4.0/" + } + }, + { + "r0.5.0", + new() { + Name = "r0.5.0: Push rules, VoIP, groups, read receipts, presence", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.5.0/" + } + }, + { + "r0.6.0", + new() { + Name = "r0.6.0: Unbinding 3PIDs, clean up bindings from register", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.6.0/" + } + }, + { + "r0.6.1", + new(){ + Name = "r0.6.1: Moderation policies, better alias handling", + Released = DateTime.Parse("2014-07-01 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/legacy/r0.6.1/" + } + }, + { + "v1.1", + new() { + Name = "v1.1: Key backup, knocking", + Released = DateTime.Parse("2021-11-09 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/v1.1/" + } + }, { + "v1.2", + new() { + Name = "v1.2: ", + Released = DateTime.Parse("2022-02-02 00:00:00 +0000"), + SpecUrl = "https://spec.matrix.org/v1.2/" + } + }, { + "v1.3", + new() { + Name = "v1.3: ", + Released = DateTime.Parse("2022-06-15 00:00:00 +0100"), + SpecUrl = "https://spec.matrix.org/v1.3/" + } + }, { + "v1.4", + new() { + Name = "v1.4: ", + Released = DateTime.Parse("2022-09-29 00:00:00 +0100"), + SpecUrl = "https://spec.matrix.org/v1.4/" + } + }, { + "v1.5", + new() { + Name = "v1.5: ", + Released = DateTime.Parse("2022-11-17 08:22:11 -0700"), + SpecUrl = "https://spec.matrix.org/v1.5/" + } + }, { + "v1.6", + new () { + Name = "v1.6: ", + Released = DateTime.Parse("2023-02-14 08:25:40 -0700"), + SpecUrl = "https://spec.matrix.org/v1.6" + } + }, { + "v1.7", + new () { + Name = "v1.7: ", + Released = DateTime.Parse("2023-05-25 09:47:21 -0600"), + SpecUrl = "https://spec.matrix.org/v1.7" + } + }, { + "v1.8", + new () { + Name = "v1.8: Room version 11", + Released = DateTime.Parse("2023-08-23 09:23:53 -0600"), + SpecUrl = "https://spec.matrix.org/v1.8" + } + } + }; + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor b/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor index 0ab0bd2..dbf2f5f 100644 --- a/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor +++ b/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor @@ -7,51 +7,43 @@ <hr/> @if (!IsFinished) { - <p>Loading... Please wait...</p> - <progress value="@QueryProgress.ProcessedRooms" max="@QueryProgress.TotalRooms"></progress> - <p>@QueryProgress.ProcessedRooms / @QueryProgress.TotalRooms</p> - @foreach (var (room, state) in QueryProgress.ProcessedUsers.Where(x => !x.Value.IsFinished).OrderByDescending(x => x.Value.Total).ToList()) { - @if (state.Blocked) { - <p>🔒 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...</p> - } - else if (state.Slowmode) { - <p>🐢 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...</p> - } - else { - <p>@room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...</p> - } - <progress value="@state.Processed" max="@state.Total"></progress> - } + <p> + <b>Loading...</b> + </p> } -else { - @foreach (var server in Homeservers.OrderByDescending(x => x.KnownUserCount).ThenBy(x => x.Server).ToList()) { - <p>@server.Server - @server.KnownUserCount</p> - } + +@foreach (var (homeserver, members) in counts.OrderByDescending(x => x.Value)) { + <p>@homeserver - @members</p> } <hr/> @code { - List<HomeserverInfo> Homeservers = new(); + Dictionary<string, List<string>> homeservers { get; set; } = new(); + Dictionary<string, int> counts { get; set; } = new(); + // List<HomeserverInfo> Homeservers = new(); bool IsFinished { get; set; } - HomeserverInfoQueryProgress QueryProgress { get; set; } = new(); - AuthenticatedHomeserverGeneric hs { get; set; } + // HomeserverInfoQueryProgress QueryProgress { get; set; } = new(); + AuthenticatedHomeserverGeneric? hs { get; set; } + protected override async Task OnInitializedAsync() { hs = await MRUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; - var sw = Stopwatch.StartNew(); - Homeservers = await GetHomeservers(progressCallback: async progress => { - if (sw.ElapsedMilliseconds > 1000) { - Console.WriteLine("Progress updated..."); - QueryProgress = progress; - StateHasChanged(); - Console.WriteLine("Progress rendered!"); - sw.Restart(); - await Task.Delay(100); - return true; + var fetchTasks = (await hs.GetJoinedRooms()).Select(x=>x.GetMembersByHomeserverAsync()).ToAsyncEnumerable(); + await foreach (var result in fetchTasks) { + foreach (var (resHomeserver, resMembers) in result) { + if (!homeservers.TryAdd(resHomeserver, resMembers)) { + homeservers[resHomeserver].AddRange(resMembers); + } + counts[resHomeserver] = homeservers[resHomeserver].Count; } - Console.WriteLine($"Progress updated, but not rendering because only {sw.ElapsedMilliseconds}ms elapsed since last call..."); - return false; - }); + // StateHasChanged(); + // await Task.Delay(250); + } + + foreach (var resHomeserver in homeservers.Keys) { + homeservers[resHomeserver] = homeservers[resHomeserver].Distinct().ToList(); + counts[resHomeserver] = homeservers[resHomeserver].Count; + } IsFinished = true; StateHasChanged(); @@ -59,64 +51,4 @@ else { await base.OnInitializedAsync(); } - private async Task<List<HomeserverInfo>> GetHomeservers(int memberLimit = 1000, Func<HomeserverInfoQueryProgress, Task<bool>>? progressCallback = null) { - HomeserverInfoQueryProgress progress = new(); - List<HomeserverInfo> homeServers = new(); - - var rooms = await hs.GetJoinedRooms(); - progress.TotalRooms = rooms.Count; - - var semaphore = new SemaphoreSlim(4); - var tasks = rooms.Select(async room => { - await semaphore.WaitAsync(); - progress.ProcessedUsers.Add(room, new HomeserverInfoQueryProgress.State()); - Console.WriteLine($"Fetching states for room ({rooms.IndexOf(room)}/{rooms.Count}) ({room.RoomId})"); - var states = room.GetMembersAsync(); - await foreach (var state in states) { - if (state.Type is not "m.room.member") continue; - progress.ProcessedUsers[room].Total++; - - if (homeServers.Any(x => x.Server == state.StateKey.Split(':')[1])) continue; - homeServers.Add(new HomeserverInfo { Server = state.StateKey.Split(':')[1] }); - Console.WriteLine($"Added new homeserver {state.StateKey.Split(':')[1]}"); - } - semaphore.Release(); - progress.ProcessedUsers[room].IsFinished = true; - progress.ProcessedRooms++; - if (progressCallback is not null) - await progressCallback.Invoke(progress); - }); - // var results = tasks.ToAsyncEnumerable(); - await Task.WhenAll(tasks); - - Console.WriteLine("Calculating member counts..."); - homeServers.ForEach(x => x.KnownUserCount = x.KnownUsers.Count); - Console.WriteLine(homeServers.First(x => x.Server == "rory.gay").ToJson()); - Console.WriteLine("Recalculated!"); - return homeServers; - } - - class HomeserverInfo { - public string Server { get; set; } - public int? KnownUserCount { get; set; } - public List<string> KnownUsers { get; } = new(); - } - - class HomeserverInfoQueryProgress { - public int ProcessedRooms { get; set; } - public int TotalRooms { get; set; } - public Dictionary<GenericRoom, State> ProcessedUsers { get; } = new(); - public List<HomeserverInfo> CurrentState { get; set; } = new(); - - public class State { - public int Processed { get; set; } - public int Total { get; set; } - public bool Blocked { get; set; } - public bool Slowmode { get; set; } - public float Progress => (float)Processed / Total; - public bool IsFinished { get; set; } - public Stopwatch Timing { get; } = Stopwatch.StartNew(); - } - } - -} +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor b/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor index 59ec79e..20aa639 100644 --- a/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor +++ b/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor @@ -94,7 +94,7 @@ lines.ToList().ForEach(async line => { await sem.WaitAsync(); try { - homeservers.Add((await hsResolver.ResolveHomeserverFromWellKnown(line)).client); + homeservers.Add((await hsResolver.ResolveHomeserverFromWellKnown(line)).Client); StateHasChanged(); } catch (Exception e) { diff --git a/MatrixRoomUtils.Web/Pages/User/DMManager.razor b/MatrixRoomUtils.Web/Pages/User/DMManager.razor index 92e1bc2..f753f18 100644 --- a/MatrixRoomUtils.Web/Pages/User/DMManager.razor +++ b/MatrixRoomUtils.Web/Pages/User/DMManager.razor @@ -40,7 +40,14 @@ var roomList = new List<RoomInfo>(); DMRooms.Add(await Homeserver.GetProfileAsync(userId), roomList); foreach (var room in rooms) { - roomList.Add(new RoomInfo() { Room = Homeserver.GetRoom(room) }); + var roomInfo = new RoomInfo() { Room = Homeserver.GetRoom(room) }; + roomList.Add(roomInfo); + roomInfo.StateEvents.Add(new() { + Type = RoomNameEventContent.EventId, + TypedContent = new RoomNameEventContent() { + Name = await Homeserver.GetRoom(room).GetNameOrFallbackAsync(4) + } + }); } StateHasChanged(); } @@ -51,6 +58,4 @@ await base.OnInitializedAsync(); } - - } \ No newline at end of file |