From 063fb6f12aea3a5b71c05beea22e7f6482c2f1cf Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Thu, 19 Oct 2023 07:21:41 +0200 Subject: Refactor, fix stuff --- ArcaneLibs | 2 +- LibMatrix | 2 +- MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs | 4 +- MatrixRoomUtils.Web/Classes/RoomInfo.cs | 54 ++++- MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj | 2 + MatrixRoomUtils.Web/Pages/DebugTools.razor | 80 ------- MatrixRoomUtils.Web/Pages/Dev/DevOptions.razor | 30 +++ MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor | 79 ++++++ MatrixRoomUtils.Web/Pages/Dev/ModalTest.razor | 88 +++++++ MatrixRoomUtils.Web/Pages/DevOptions.razor | 31 --- MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor | 2 - MatrixRoomUtils.Web/Pages/Index.razor | 1 - MatrixRoomUtils.Web/Pages/InvalidSession.razor | 1 - .../Pages/KnownHomeserverList.razor | 173 -------------- MatrixRoomUtils.Web/Pages/LoginPage.razor | 1 - MatrixRoomUtils.Web/Pages/MediaLocator.razor | 112 --------- MatrixRoomUtils.Web/Pages/ModalTest.razor | 88 ------- MatrixRoomUtils.Web/Pages/Rooms/Create.razor | 2 - MatrixRoomUtils.Web/Pages/Rooms/Index.razor | 264 ++++++++++++--------- MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor | 3 - MatrixRoomUtils.Web/Pages/Rooms/Space.razor | 2 - MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor | 2 - MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor | 2 - MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor | 1 - MatrixRoomUtils.Web/Pages/SpaceDebug.razor | 114 --------- .../Pages/Tools/KnownHomeserverList.razor | 171 +++++++++++++ MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor | 111 +++++++++ MatrixRoomUtils.Web/Pages/Tools/SpaceDebug.razor | 113 +++++++++ MatrixRoomUtils.Web/Shared/NavMenu.razor | 49 ++-- MatrixRoomUtils.Web/Shared/PortableDevTools.razor | 26 -- MatrixRoomUtils.Web/Shared/RoomList.razor | 89 ++++--- .../Shared/RoomListComponents/RoomListSpace.razor | 5 +- MatrixRoomUtils.Web/Shared/RoomListItem.razor | 143 ++++++----- MatrixRoomUtils.Web/Shared/RoomListItem.razor.css | 56 ++++- .../TimelineComponents/BaseTimelineItem.razor | 1 - .../TimelineComponents/TimelineMemberItem.razor | 1 - .../TimelineComponents/TimelineMessageItem.razor | 1 - .../TimelineRoomCreateItem.razor | 1 - .../TimelineComponents/TimelineUnknownItem.razor | 1 - MatrixRoomUtils.Web/Shared/UserListItem.razor | 30 +-- MatrixRoomUtils.sln.DotSettings.user | 3 + 41 files changed, 1020 insertions(+), 921 deletions(-) delete mode 100644 MatrixRoomUtils.Web/Pages/DebugTools.razor create mode 100644 MatrixRoomUtils.Web/Pages/Dev/DevOptions.razor create mode 100644 MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor create mode 100644 MatrixRoomUtils.Web/Pages/Dev/ModalTest.razor delete mode 100644 MatrixRoomUtils.Web/Pages/DevOptions.razor delete mode 100644 MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor delete mode 100644 MatrixRoomUtils.Web/Pages/MediaLocator.razor delete mode 100644 MatrixRoomUtils.Web/Pages/ModalTest.razor delete mode 100644 MatrixRoomUtils.Web/Pages/SpaceDebug.razor create mode 100644 MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor create mode 100644 MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor create mode 100644 MatrixRoomUtils.Web/Pages/Tools/SpaceDebug.razor delete mode 100644 MatrixRoomUtils.Web/Shared/PortableDevTools.razor diff --git a/ArcaneLibs b/ArcaneLibs index da722ab..e9cf8d3 160000 --- a/ArcaneLibs +++ b/ArcaneLibs @@ -1 +1 @@ -Subproject commit da722ab1751728d485b415332d0427dd491653c7 +Subproject commit e9cf8d3061cca5319982c1ef15b78f7c7ca36e89 diff --git a/LibMatrix b/LibMatrix index 90d54c1..0330ff6 160000 --- a/LibMatrix +++ b/LibMatrix @@ -1 +1 @@ -Subproject commit 90d54c12a9d1fc06c3e07b4e367021538d08063e +Subproject commit 0330ff6706a968400ca8fe2a3e3ccf6237a15566 diff --git a/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs b/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs index 8ea85e9..0947bbe 100644 --- a/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs +++ b/MatrixRoomUtils.Web/Classes/MRUStorageWrapper.cs @@ -1,6 +1,5 @@ using LibMatrix; using LibMatrix.Homeservers; -using LibMatrix.Responses; using LibMatrix.Services; using Microsoft.AspNetCore.Components; @@ -22,6 +21,9 @@ public class MRUStorageWrapper { } public async Task?> GetAllTokens() { + if (!await _storageService.DataStorageProvider.ObjectExistsAsync("mru.tokens")) { + + } return await _storageService.DataStorageProvider.LoadObjectAsync>("mru.tokens") ?? new List(); } diff --git a/MatrixRoomUtils.Web/Classes/RoomInfo.cs b/MatrixRoomUtils.Web/Classes/RoomInfo.cs index 0e21871..31943dc 100644 --- a/MatrixRoomUtils.Web/Classes/RoomInfo.cs +++ b/MatrixRoomUtils.Web/Classes/RoomInfo.cs @@ -1,13 +1,15 @@ +using System.Collections.ObjectModel; +using ArcaneLibs; using LibMatrix; +using LibMatrix.EventTypes.Spec.State; using LibMatrix.Interfaces; -using LibMatrix.Responses; using LibMatrix.RoomTypes; namespace MatrixRoomUtils.Web.Classes; -public class RoomInfo { +public class RoomInfo : NotifyPropertyChanged { public GenericRoom Room { get; set; } - public List StateEvents { get; init; } = new(); + public ObservableCollection StateEvents { get; } = new(); public async Task GetStateEvent(string type, string stateKey = "") { var @event = StateEvents.FirstOrDefault(x => x.Type == type && x.StateKey == stateKey); @@ -28,4 +30,48 @@ public class RoomInfo { StateEvents.Add(@event); return @event; } -} + + public string? RoomIcon { + get => _roomIcon ?? "https://api.dicebear.com/6.x/identicon/svg?seed=" + Room.RoomId; + set => SetField(ref _roomIcon, value); + } + + public string? RoomName { + get => _roomName ?? Room.RoomId; + set => SetField(ref _roomName, value); + } + + public RoomCreateEventContent? CreationEventContent { + get => _creationEventContent; + set => SetField(ref _creationEventContent, value); + } + + public string? RoomCreator { + get => _roomCreator; + set => SetField(ref _roomCreator, value); + } + + // public string? GetRoomIcon() => (StateEvents.FirstOrDefault(x => x?.Type == RoomAvatarEventContent.EventId)?.TypedContent as RoomAvatarEventContent)?.Url ?? + // "mxc://rory.gay/dgP0YPjJEWaBwzhnbyLLwGGv"; + + private string? _roomIcon; + private string? _roomName; + private RoomCreateEventContent? _creationEventContent; + private string? _roomCreator; + + public RoomInfo() { + StateEvents.CollectionChanged += (_, args) => { + if (args.NewItems is { Count: > 0 }) + foreach (StateEventResponse newState in args.NewItems) { + if (newState.TypedContent is RoomNameEventContent roomNameContent) + RoomName = roomNameContent.Name; + else if (newState.TypedContent is RoomAvatarEventContent roomAvatarContent) + RoomIcon = roomAvatarContent.Url; + else if (newState.TypedContent is RoomCreateEventContent roomCreateContent) { + CreationEventContent = roomCreateContent; + RoomCreator = newState.Sender; + } + } + }; + } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj index 03cc9ae..625a303 100644 --- a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj +++ b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj @@ -21,8 +21,10 @@ + + diff --git a/MatrixRoomUtils.Web/Pages/DebugTools.razor b/MatrixRoomUtils.Web/Pages/DebugTools.razor deleted file mode 100644 index 5d47277..0000000 --- a/MatrixRoomUtils.Web/Pages/DebugTools.razor +++ /dev/null @@ -1,80 +0,0 @@ -@page "/Debug" -@using System.Reflection -@using ArcaneLibs.Extensions -@using LibMatrix -@using LibMatrix.Extensions -@using LibMatrix.Homeservers -@inject ILocalStorageService LocalStorage -@inject NavigationManager NavigationManager -

Debug Tools

-
-@if (Rooms.Count == 0) { -

You are not in any rooms!

- @*

Loading progress: @checkedRoomCount/@totalRoomCount

*@ -} -else { -
- Room List - @foreach (var room in Rooms) { - - - - } -
-} - -
- Send GET request to URL -
- - -
-
-
@get_request_result
-
- -
- - -@code { - public List Rooms { get; set; } = new(); - - protected override async Task OnInitializedAsync() { - await base.OnInitializedAsync(); - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); - if (hs == null) return; - Rooms = (await hs.GetJoinedRooms()).Select(x => x.RoomId).ToList(); - Console.WriteLine("Fetched joined rooms!"); - } - - //send req - string get_request_url { get; set; } = ""; - string get_request_result { get; set; } = ""; - - private async Task SendGetRequest() { - var field = typeof(RemoteHomeServer).GetRuntimeFields().First(x => x.ToString().Contains("<_httpClient>k__BackingField")); - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); - if (hs == null) return; - var httpClient = field.GetValue(hs) as MatrixHttpClient; - try { - var res = await httpClient.GetAsync(get_request_url); - if (res.IsSuccessStatusCode) { - if (res.Content.Headers.ContentType.MediaType == "application/json") - get_request_result = (await res.Content.ReadFromJsonAsync()).ToJson(); - else - get_request_result = await res.Content.ReadAsStringAsync(); - StateHasChanged(); - return; - } - if (res.Content.Headers.ContentType.MediaType == "application/json") - get_request_result = $"Error: {res.StatusCode}\n" + (await res.Content.ReadFromJsonAsync()).ToJson(); - else - get_request_result = $"Error: {res.StatusCode}\n" + await res.Content.ReadAsStringAsync(); - } - catch (Exception e) { - get_request_result = $"Error: {e}"; - } - StateHasChanged(); - } - -} diff --git a/MatrixRoomUtils.Web/Pages/Dev/DevOptions.razor b/MatrixRoomUtils.Web/Pages/Dev/DevOptions.razor new file mode 100644 index 0000000..9b0f61c --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Dev/DevOptions.razor @@ -0,0 +1,30 @@ +@page "/Dev/Options" +@using ArcaneLibs.Extensions +@inject NavigationManager NavigationManager +@inject ILocalStorageService LocalStorage + +Developer options + +

Rory&::MatrixUtils - Developer options

+
+ +
+
+
+
+ +@code { + + MRUStorageWrapper.Settings settings { get; set; } = new(); + protected override async Task OnInitializedAsync() { + settings = await TieredStorage.DataStorageProvider.LoadObjectAsync("mru.settings"); + await base.OnInitializedAsync(); + } + + private async Task LogStuff() { + await Task.Delay(100); + Console.WriteLine($"Settings: {settings.ToJson()}"); + await TieredStorage.DataStorageProvider.SaveObjectAsync("mru.settings", settings); + } + +} diff --git a/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor b/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor new file mode 100644 index 0000000..f7e6aec --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Dev/DevUtilities.razor @@ -0,0 +1,79 @@ +@page "/Dev/Utilities" +@using System.Reflection +@using ArcaneLibs.Extensions +@using LibMatrix.Extensions +@using LibMatrix.Homeservers +@inject ILocalStorageService LocalStorage +@inject NavigationManager NavigationManager +

Debug Tools

+
+@if (Rooms.Count == 0) { +

You are not in any rooms!

+ @*

Loading progress: @checkedRoomCount/@totalRoomCount

*@ +} +else { +
+ Room List + @foreach (var room in Rooms) { + + + + } +
+} + +
+ Send GET request to URL +
+ + +
+
+
@get_request_result
+
+ +
+ + +@code { + public List Rooms { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + if (hs == null) return; + Rooms = (await hs.GetJoinedRooms()).Select(x => x.RoomId).ToList(); + Console.WriteLine("Fetched joined rooms!"); + } + + //send req + string get_request_url { get; set; } = ""; + string get_request_result { get; set; } = ""; + + private async Task SendGetRequest() { + var field = typeof(RemoteHomeServer).GetRuntimeFields().First(x => x.ToString().Contains("<_httpClient>k__BackingField")); + var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + if (hs == null) return; + var httpClient = field.GetValue(hs) as MatrixHttpClient; + try { + var res = await httpClient.GetAsync(get_request_url); + if (res.IsSuccessStatusCode) { + if (res.Content.Headers.ContentType.MediaType == "application/json") + get_request_result = (await res.Content.ReadFromJsonAsync()).ToJson(); + else + get_request_result = await res.Content.ReadAsStringAsync(); + StateHasChanged(); + return; + } + if (res.Content.Headers.ContentType.MediaType == "application/json") + get_request_result = $"Error: {res.StatusCode}\n" + (await res.Content.ReadFromJsonAsync()).ToJson(); + else + get_request_result = $"Error: {res.StatusCode}\n" + await res.Content.ReadAsStringAsync(); + } + catch (Exception e) { + get_request_result = $"Error: {e}"; + } + StateHasChanged(); + } + +} diff --git a/MatrixRoomUtils.Web/Pages/Dev/ModalTest.razor b/MatrixRoomUtils.Web/Pages/Dev/ModalTest.razor new file mode 100644 index 0000000..4a0487f --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Dev/ModalTest.razor @@ -0,0 +1,88 @@ +@page "/Dev/ModalTest" +@inject IJSRuntime JsRuntime +

ModalTest

+ +@foreach (var (key, value) in _windowInfos) { + @* @value.Content *@ +} +@for (var i = 0; i < 5; i++) { + var i1 = i; + + @for (var j = 0; j < i1; j++) { +

@j

+ } +
+} + +@code { + + private Dictionary _windowInfos = new(); + + private class WindowInfo { + public double X; + public double Y; + public string Title; + public RenderFragment Content; + } + + protected override async Task OnInitializedAsync() { + double _x = 2; + double _xv = 20; + double _y = 0; + double multiplier = 1; + + for (var i = 0; i < 200; i++) { + var i1 = i; + _windowInfos.Add(_windowInfos.Count, new WindowInfo { + X = _x, + Y = _y, + Title = "Win" + i1, + Content = builder => { + builder.OpenComponent(0); + builder.AddAttribute(1, "X", _x); + builder.AddAttribute(2, "Y", _y); + builder.AddAttribute(3, "Title", "Win" + i1); + builder.AddAttribute(4, "ChildContent", (RenderFragment)(builder2 => { + builder2.OpenElement(0, "h1"); + builder2.AddContent(1, "Hello " + i1); + builder2.CloseElement(); + })); + builder.CloseComponent(); + } + }); + //_x += _xv /= 1000/System.Math.Sqrt((double)_windowInfos.Count)*_windowInfos.Count.ToString().Length*multiplier; + _y += 20; + _x += 20; + var dimension = await JsRuntime.InvokeAsync("getWindowDimensions"); + if (_x > dimension.Width - 100) _x %= dimension.Width - 100; + if (_y > dimension.Height - 50) { + _y %= dimension.Height - 50; + _xv = 20; + } + if ( + (_windowInfos.Count < 10 && _windowInfos.Count % 2 == 0) || + (_windowInfos.Count < 100 && _windowInfos.Count % 10 == 0) || + (_windowInfos.Count < 1000 && _windowInfos.Count % 50 == 0) || + (_windowInfos.Count < 10000 && _windowInfos.Count % 100 == 0) + ) { + StateHasChanged(); + await Task.Delay(25); + } + if(_windowInfos.Count > 750) multiplier = 2; + if(_windowInfos.Count > 1500) multiplier = 3; + + } + + await base.OnInitializedAsync(); + } + + private void OnCloseClicked(int i1) { + Console.WriteLine("Close clicked on " + i1); + } + + public class WindowDimension { + public int Width { get; set; } + public int Height { get; set; } + } + +} diff --git a/MatrixRoomUtils.Web/Pages/DevOptions.razor b/MatrixRoomUtils.Web/Pages/DevOptions.razor deleted file mode 100644 index 8511a26..0000000 --- a/MatrixRoomUtils.Web/Pages/DevOptions.razor +++ /dev/null @@ -1,31 +0,0 @@ -@page "/DevOptions" -@using LibMatrix.Extensions -@using ArcaneLibs.Extensions -@inject NavigationManager NavigationManager -@inject ILocalStorageService LocalStorage - -Developer options - -

Rory&::MatrixUtils - Developer options

-
- -
-
-
-
- -@code { - - MRUStorageWrapper.Settings settings { get; set; } = new(); - protected override async Task OnInitializedAsync() { - settings = await TieredStorage.DataStorageProvider.LoadObjectAsync("mru.settings"); - await base.OnInitializedAsync(); - } - - private async Task LogStuff() { - await Task.Delay(100); - Console.WriteLine($"Settings: {settings.ToJson()}"); - await TieredStorage.DataStorageProvider.SaveObjectAsync("mru.settings", settings); - } - -} diff --git a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor index a4f9d97..7e4058b 100644 --- a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor +++ b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor @@ -1,8 +1,6 @@ @page "/HSAdmin/RoomQuery" @using LibMatrix.Responses.Admin @using LibMatrix.Filters -@using LibMatrix.Extensions -@using LibMatrix @using LibMatrix.Homeservers @using ArcaneLibs.Extensions diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor index 834c373..00f3253 100644 --- a/MatrixRoomUtils.Web/Pages/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Index.razor @@ -1,7 +1,6 @@ @page "/" @using LibMatrix.Responses @using LibMatrix -@using LibMatrix.Helpers @using LibMatrix.Homeservers @using ArcaneLibs.Extensions diff --git a/MatrixRoomUtils.Web/Pages/InvalidSession.razor b/MatrixRoomUtils.Web/Pages/InvalidSession.razor index b476c68..7d4769c 100644 --- a/MatrixRoomUtils.Web/Pages/InvalidSession.razor +++ b/MatrixRoomUtils.Web/Pages/InvalidSession.razor @@ -1,5 +1,4 @@ @page "/InvalidSession" -@using LibMatrix.Responses @using LibMatrix Invalid session diff --git a/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor b/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor deleted file mode 100644 index 4cd2032..0000000 --- a/MatrixRoomUtils.Web/Pages/KnownHomeserverList.razor +++ /dev/null @@ -1,173 +0,0 @@ -@page "/KnownHomeserverList" -@using System.Diagnostics -@using ArcaneLibs.Extensions -@using LibMatrix -@using LibMatrix.Extensions -@using LibMatrix.Homeservers -@using LibMatrix.RoomTypes -

Known Homeserver List

-
- -@if (!IsFinished) { -

Loading... Please wait...

- -

@QueryProgress.ProcessedRooms / @QueryProgress.TotalRooms

- @foreach (var (room, state) in QueryProgress.ProcessedUsers.Where(x => !x.Value.IsFinished).OrderByDescending(x => x.Value.Total).ToList()) { - @if (state.Blocked) { -

🔒 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

- } - else if (state.Slowmode) { -

🐢 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

- } - else { -

@room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

- } - - } -} -else { - @foreach (var server in HomeServers.OrderByDescending(x => x.KnownUserCount).ThenBy(x => x.Server).ToList()) { -

@server.Server - @server.KnownUserCount

- } -} -
- -@code { - List HomeServers = new(); - bool IsFinished { 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; - } - Console.WriteLine($"Progress updated, but not rendering because only {sw.ElapsedMilliseconds}ms elapsed since last call..."); - return false; - }); - - IsFinished = true; - StateHasChanged(); - Console.WriteLine("Rerendered!"); - await base.OnInitializedAsync(); - } - - private async Task> GetHomeservers(int memberLimit = 1000, Func>? progressCallback = null) { - HomeServerInfoQueryProgress progress = new(); - List homeServers = new(); - - var rooms = await hs.GetJoinedRooms(); - progress.TotalRooms = rooms.Count; - - var semaphore = new SemaphoreSlim(4); - var semLock = new SemaphoreSlim(1); - 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.GetFullStateAsync(); - 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); - - - - // states.RemoveAll(x => x.Type != "m.room.member" || (x.TypedContent as RoomMemberEventContent).Membership != "join"); - // Console.WriteLine($"Room {room.RoomId} has {states.Count} members"); - // if (states.Count > memberLimit) { - // Console.WriteLine("Skipping!"); - // semaphore.Release(); - // progress.ProcessedUsers.Remove(room); - // progress.TotalRooms--; - // return; - // } - // progress.ProcessedUsers[room].Total = states.Count; - // var updateInterval = progress.ProcessedUsers[room].Total >= 1000 ? 1000 : 100; - // while (progress.ProcessedUsers.Any(x => x.Value.Total == 0) && progress.ProcessedUsers[room].Total >= 1000) { - // progress.ProcessedUsers[room].Blocked = true; - // await Task.Delay(1000); - // // if(progressCallback is not null) - // // await progressCallback.Invoke(progress); - // } - // progress.ProcessedUsers[room].Blocked = false; - // var processedStates = 0; - // foreach (var state in states) { - // await semLock.WaitAsync(); - // semLock.Release(); - // if (progress.ProcessedUsers.Count(x => x.Value.Total == 0) > 5 && progress.ProcessedUsers[room].Total >= 200) { - // progress.ProcessedUsers[room].Slowmode = true; - // await Task.Delay(progress.ProcessedUsers[room].Total >= 500 ? 1000 : 100); - // } - // else { - // progress.ProcessedUsers[room].Slowmode = false; - // } - // if (!homeServers.Any(x => x.Server == state.StateKey.Split(':')[1])) { - // homeServers.Add(new HomeServerInfo { Server = state.StateKey.Split(':')[1] }); - // } - // var hs = homeServers.First(x => x.Server == state.StateKey.Split(':')[1]); - // if (!hs.KnownUsers.Contains(state.StateKey.Split(':')[0])) - // hs.KnownUsers.Add(state.StateKey.Split(':')[0]); - // if (++progress.ProcessedUsers[room].Processed % updateInterval == 0 && progressCallback is not null) { - // await semLock.WaitAsync(); - // var _ = await progressCallback.Invoke(progress); - // semLock.Release(); - // } - // } - // Console.WriteLine("Collected states!"); - // progress.ProcessedRooms++; - // progress.ProcessedUsers[room].IsFinished = true; - // progressCallback?.Invoke(progress); - // semaphore.Release(); - }); - 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 KnownUsers { get; } = new(); - } - - class HomeServerInfoQueryProgress { - public int ProcessedRooms { get; set; } - public int TotalRooms { get; set; } - public Dictionary ProcessedUsers { get; } = new(); - public List 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(); - } - } - -} diff --git a/MatrixRoomUtils.Web/Pages/LoginPage.razor b/MatrixRoomUtils.Web/Pages/LoginPage.razor index c7f5922..1b466c9 100644 --- a/MatrixRoomUtils.Web/Pages/LoginPage.razor +++ b/MatrixRoomUtils.Web/Pages/LoginPage.razor @@ -1,6 +1,5 @@ @page "/Login" @using System.Text.Json -@using LibMatrix.Responses @inject ILocalStorageService LocalStorage @inject IJSRuntime JsRuntime

Login

diff --git a/MatrixRoomUtils.Web/Pages/MediaLocator.razor b/MatrixRoomUtils.Web/Pages/MediaLocator.razor deleted file mode 100644 index e1686b9..0000000 --- a/MatrixRoomUtils.Web/Pages/MediaLocator.razor +++ /dev/null @@ -1,112 +0,0 @@ -@page "/MediaLocator" -@using LibMatrix -@using LibMatrix.Homeservers -@inject HttpClient Http -

Media locator

-
- -This is going to expose your IP address to all these homeservers! -
- Checked homeserver list (@homeservers.Count entries) -
    - @foreach (var hs in homeservers) { -
  • @hs
  • - } -
-
- -
-MXC URL: - - - -@if (successResults.Count > 0) { -

Successes

-
    - @foreach (var result in successResults) { -
  • @result
  • - } -
-} - -@if (errorResults.Count > 0) { -

Errors

-
    - @foreach (var result in errorResults) { -
  • @result
  • - } -
-} - - -@code { - string mxcUrl { get; set; } - readonly List successResults = new(); - readonly List errorResults = new(); - readonly List homeservers = new(); - - protected override async Task OnInitializedAsync() { - await base.OnInitializedAsync(); - homeservers.AddRange(new[] { - "matrix.org", - "feline.support", - "rory.gay", - "the-apothecary.club", - "envs.net", - "projectsegfau.lt" - }); - } - - Task executeSearch() { - var sem = new SemaphoreSlim(128, 128); - homeservers.ForEach(async hs => { - await sem.WaitAsync(); - var httpClient = new HttpClient { BaseAddress = new Uri(hs) }; - httpClient.Timeout = TimeSpan.FromSeconds(5); - var rmu = mxcUrl.Replace("mxc://", $"{hs}/_matrix/media/v3/download/"); - try { - var res = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, rmu)); - if (res.IsSuccessStatusCode) { - successResults.Add($"{hs}: found - {res.Content.Headers.ContentLength} bytes"); - StateHasChanged(); - return; - } - errorResults.Add($"Error: {hs} - {res.StatusCode}\n" + await res.Content.ReadAsStringAsync()); - } - catch (Exception e) { - errorResults.Add($"Error: {e}"); - } - finally { - sem.Release(); - } - StateHasChanged(); - }); - return Task.CompletedTask; - } - - async Task addMoreHomeservers() { - var res = await Http.GetAsync("/homeservers.txt"); - var content = await res.Content.ReadAsStringAsync(); - homeservers.Clear(); - var lines = content.Split("\n"); - - var rhs = new RemoteHomeServer("rory.gay"); - var sem = new SemaphoreSlim(128, 128); - lines.ToList().ForEach(async line => { - await sem.WaitAsync(); - try { - homeservers.Add(await hsResolver.ResolveHomeserverFromWellKnown(line)); - StateHasChanged(); - } - catch (Exception e) { - Console.WriteLine(e); - } - finally { - sem.Release(); - } - }); - - StateHasChanged(); - } - -} diff --git a/MatrixRoomUtils.Web/Pages/ModalTest.razor b/MatrixRoomUtils.Web/Pages/ModalTest.razor deleted file mode 100644 index 1d14005..0000000 --- a/MatrixRoomUtils.Web/Pages/ModalTest.razor +++ /dev/null @@ -1,88 +0,0 @@ -@page "/ModalTest" -@inject IJSRuntime JsRuntime -

ModalTest

- -@foreach (var (key, value) in _windowInfos) { - @* @value.Content *@ -} -@for (var i = 0; i < 5; i++) { - var i1 = i; - - @for (var j = 0; j < i1; j++) { -

@j

- } -
-} - -@code { - - private Dictionary _windowInfos = new(); - - private class WindowInfo { - public double X; - public double Y; - public string Title; - public RenderFragment Content; - } - - protected override async Task OnInitializedAsync() { - double _x = 2; - double _xv = 20; - double _y = 0; - double multiplier = 1; - - for (var i = 0; i < 200; i++) { - var i1 = i; - _windowInfos.Add(_windowInfos.Count, new WindowInfo { - X = _x, - Y = _y, - Title = "Win" + i1, - Content = builder => { - builder.OpenComponent(0); - builder.AddAttribute(1, "X", _x); - builder.AddAttribute(2, "Y", _y); - builder.AddAttribute(3, "Title", "Win" + i1); - builder.AddAttribute(4, "ChildContent", (RenderFragment)(builder2 => { - builder2.OpenElement(0, "h1"); - builder2.AddContent(1, "Hello " + i1); - builder2.CloseElement(); - })); - builder.CloseComponent(); - } - }); - //_x += _xv /= 1000/System.Math.Sqrt((double)_windowInfos.Count)*_windowInfos.Count.ToString().Length*multiplier; - _y += 20; - _x += 20; - var dimension = await JsRuntime.InvokeAsync("getWindowDimensions"); - if (_x > dimension.Width - 100) _x %= dimension.Width - 100; - if (_y > dimension.Height - 50) { - _y %= dimension.Height - 50; - _xv = 20; - } - if ( - (_windowInfos.Count < 10 && _windowInfos.Count % 2 == 0) || - (_windowInfos.Count < 100 && _windowInfos.Count % 10 == 0) || - (_windowInfos.Count < 1000 && _windowInfos.Count % 50 == 0) || - (_windowInfos.Count < 10000 && _windowInfos.Count % 100 == 0) - ) { - StateHasChanged(); - await Task.Delay(25); - } - if(_windowInfos.Count > 750) multiplier = 2; - if(_windowInfos.Count > 1500) multiplier = 3; - - } - - await base.OnInitializedAsync(); - } - - private void OnCloseClicked(int i1) { - Console.WriteLine("Close clicked on " + i1); - } - - public class WindowDimension { - public int Width { get; set; } - public int Height { get; set; } - } - -} diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor index 3225862..04dcdcc 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Create.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Create.razor @@ -4,8 +4,6 @@ @using ArcaneLibs.Extensions @using LibMatrix @using LibMatrix.EventTypes.Spec.State -@using LibMatrix.Extensions -@using LibMatrix.Helpers @using LibMatrix.Homeservers @using LibMatrix.Responses @using MatrixRoomUtils.Web.Classes.RoomCreationTemplates diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor index 69a0ede..4d98402 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor @@ -1,25 +1,32 @@ @page "/Rooms" @using LibMatrix.Filters @using LibMatrix.Helpers -@using LibMatrix.Responses @using LibMatrix.EventTypes.Spec.State @using LibMatrix +@using LibMatrix.Homeservers +@using ArcaneLibs.Extensions +@using LibMatrix.Extensions +@using LibMatrix.Responses +@using System.Collections.ObjectModel +@inject ILogger logger

Room list

@Status

-@if (RenderContents) { - -} - +

@Status2

+@* @if (RenderContents) { *@ + +@* } *@ +@* else { *@ +@* *@ +@* } *@ @code { - - public List KnownRooms { get; set; } = new(); - - private List Rooms { get; set; } = new(); + private ObservableCollection Rooms { get; } = new(); private ProfileResponseEventContent GlobalProfile { get; set; } - private SyncFilter filter = new() { + private AuthenticatedHomeserverGeneric? Homeserver { get; set; } + + private static SyncFilter filter = new() { AccountData = new SyncFilter.EventFilter { NotTypes = new List { "*" }, Limit = 1 @@ -43,7 +50,7 @@ "m.room.avatar", "m.room.create", "org.matrix.mjolnir.shortcode", - "m.room.power_levels" + "m.room.power_levels", } }, Timeline = new SyncFilter.RoomFilter.StateFilter { @@ -53,112 +60,115 @@ } }; + private static SyncFilter profileUpdateFilter = new() { + AccountData = new SyncFilter.EventFilter { + NotTypes = new List { "*" }, + Limit = 1 + }, + Presence = new SyncFilter.EventFilter { + NotTypes = new List { "*" }, + Limit = 1 + }, + Room = new SyncFilter.RoomFilter { + AccountData = new SyncFilter.RoomFilter.StateFilter { + NotTypes = new List { "*" }, + Limit = 1 + }, + Ephemeral = new SyncFilter.RoomFilter.StateFilter { + NotTypes = new List { "*" }, + Limit = 1 + }, + State = new SyncFilter.RoomFilter.StateFilter { + Types = new List { + "m.room.member" + }, + Senders = new() + }, + Timeline = new SyncFilter.RoomFilter.StateFilter { + NotTypes = new List { "*" }, + Limit = 1 + } + } + }; + protected override async Task OnInitializedAsync() { - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); - if (hs is null) return; - GlobalProfile = await hs.GetProfileAsync(hs.WhoAmI.UserId); + Homeserver = await MRUStorage.GetCurrentSessionOrNavigate(); + if (Homeserver is null) return; + var rooms = await Homeserver.GetJoinedRooms(); + foreach (var room in rooms) { + Rooms.Add(new(){Room = room}); + } + + GlobalProfile = await Homeserver.GetProfileAsync(Homeserver.WhoAmI.UserId); - Status = "Syncing..."; - var syncHelper = new SyncHelper(hs) { - Timeout = 0, + var syncHelper = new SyncHelper(Homeserver, logger) { + Timeout = 10000, Filter = filter }; - // SyncResponse? sync = null; - string? nextBatch = null; - var syncs = syncHelper.EnumerateSyncAsync(); - await foreach (var sync in syncs) { - nextBatch = sync?.NextBatch ?? nextBatch; - if (sync is null) continue; - Console.WriteLine($"Got sync, next batch: {nextBatch}!"); - - if (sync.Rooms is null) continue; - if (sync.Rooms.Join is null) continue; - foreach (var (roomId, roomData) in sync.Rooms.Join) { - RoomInfo room; - if (Rooms.Any(x => x.Room.RoomId == roomId)) { - room = Rooms.First(x => x.Room.RoomId == roomId); - } - else { - room = new RoomInfo { - Room = hs.GetRoom(roomId), - StateEvents = new List() - }; - Rooms.Add(room); - KnownRooms.Add(room); + profileUpdateFilter.Room.State.Senders.Add(Homeserver.WhoAmI.UserId); + var profileSyncHelper = new SyncHelper(Homeserver, logger) { + Timeout = 10000, + Filter = profileUpdateFilter + }; + RunSyncLoop(syncHelper); + RunSyncLoop(profileSyncHelper); + RunQueueProcessor(); + await base.OnInitializedAsync(); + } + + private async Task RunQueueProcessor() { + while (true) { + try { + if (queue.Count == 0) { + while (queue.Count == 0) { + Console.WriteLine("Queue is empty, waiting..."); + await Task.Delay(2500); + } + Console.WriteLine("Queue no longer empty!"); } - room.StateEvents.AddRange(roomData.State.Events); - } - Status = $"Got {Rooms.Count} rooms so far! Next batch: {nextBatch}"; - StateHasChanged(); - await Task.Delay(100); - if (!syncHelper.IsInitialSync) break; - } - // while (sync is null or { Rooms.Join.Count: >= 1}) { - // sync = await syncHelper.SyncAsync(since: nextBatch, filter: filter, timeout: 0); - - // } - Console.WriteLine("Sync done!"); - Status = "Sync complete!"; - foreach (var roomInfo in Rooms) { - if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.name")) { - roomInfo.StateEvents.Add(new StateEventResponse { - Type = "m.room.name", - TypedContent = new RoomNameEventContent { - Name = roomInfo.Room.RoomId + if (queue.TryDequeue(out var queueEntry)) { + var (roomId, roomData) = queueEntry; + Console.WriteLine($"Dequeued room {roomId}"); + RoomInfo room; + + if (Rooms.Any(x => x.Room.RoomId == roomId)) { + room = Rooms.First(x => x.Room.RoomId == roomId); + Console.WriteLine($"QueueWorker: {roomId} already known with {room.StateEvents?.Count ?? 0} state events"); } - }); - } - if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.avatar")) { - roomInfo.StateEvents.Add(new StateEventResponse { - Type = "m.room.avatar", - TypedContent = new RoomAvatarEventContent { - + else { + Console.WriteLine($"QueueWorker: encountered new room {roomId}!"); + room = new RoomInfo() { + Room = Homeserver.GetRoom(roomId) + }; + Rooms.Add(room); + } + + if (room.StateEvents is null) { + Console.WriteLine($"QueueWorker: {roomId} does not have state events on record?"); + throw new InvalidDataException("Somehow this is null???"); + } + if (roomData.State?.Events is {Count: >0 }) + room.StateEvents.MergeStateEventLists(roomData.State.Events); + else { + Console.WriteLine($"QueueWorker: could not merge state for {room.Room.RoomId} as new data contains no state events!"); } - }); + if (Random.Shared.Next(101) < 20 || true) { + Status = $"Got {Rooms.Count} rooms so far! {queue.Count} entries in processing queue..."; + } + RenderContents |= queue.Count == 0; + await Task.Delay(RenderContents ? 25 : 25); + } + else { + Console.WriteLine("Failed to dequeue item"); + } } - if (!roomInfo.StateEvents.Any(x => x.Type == "org.matrix.mjolnir.shortcode")) { - roomInfo.StateEvents.Add(new StateEventResponse { - Type = "org.matrix.mjolnir.shortcode" - }); + catch (Exception e) { + Console.WriteLine("QueueWorker exception: " + e); } } - Console.WriteLine("Set stub data!"); - Status = "Set stub data!"; - SemaphoreSlim semaphore = new(8, 8); - var memberTasks = Rooms.Select(async roomInfo => { - if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.member" && x.StateKey == hs.WhoAmI.UserId)) { - await semaphore.WaitAsync(); - roomInfo.StateEvents.Add(new StateEventResponse { - Type = "m.room.member", - StateKey = hs.WhoAmI.UserId, - TypedContent = await roomInfo.Room.GetStateAsync("m.room.member", hs.WhoAmI.UserId) ?? new RoomMemberEventContent { - Membership = "unknown" - } - }); - semaphore.Release(); - } - }).ToList(); - await Task.WhenAll(memberTasks); - Console.WriteLine("Set all room member data!"); - Status = "Set all room member data!"; - // var res = await hs.SyncHelper.Sync(filter: filter); - // if (res is not null) { - // foreach (var (roomId, roomData) in res.Rooms.Join) { - // var room = new RoomInfo() { - // Room = hs.GetRoom(roomId), - // StateEvents = roomData.State.Events.Where(x => x.Type == "m.room.member" && x.StateKey == hs.WhoAmI.UserId).ToList() - // }; - // Rooms.Add(room); - // } - // } - // Rooms = (await hs.GetJoinedRooms()).Select(x => new RoomInfo() { Room = x }).ToList(); - - RenderContents = true; - Status = ""; - await base.OnInitializedAsync(); } - private bool RenderContents { get; set; } + private bool RenderContents { get; set; } = false; private string _status; @@ -170,4 +180,46 @@ } } -} + private string _status2; + + public string Status2 { + get => _status2; + set { + _status2 = value; + StateHasChanged(); + } + } + + private Queue> queue = new(); + + private async Task RunSyncLoop(SyncHelper syncHelper) { + Status = "Initial syncing..."; + Console.WriteLine("starting sync"); + + var syncs = syncHelper.EnumerateSyncAsync(); + await foreach (var sync in syncs) { + Console.WriteLine("trying sync"); + if (sync is null) continue; + + Status = $"Got sync with {sync.Rooms?.Join?.Count ?? 0} room updates, next batch: {sync.NextBatch}!"; + if (sync?.Rooms?.Join != null) + foreach (var joinedRoom in sync.Rooms.Join) + if ( /*joinedRoom.Value.AccountData?.Events?.Count > 0 ||*/ joinedRoom.Value.State?.Events?.Count > 0) { + joinedRoom.Value.State.Events.RemoveAll(x => x.Type == "m.room.member" && x.StateKey != Homeserver.WhoAmI?.UserId); + // We can't trust servers to give us what we ask for, and this ruins performance + // Thanks, Conduit. + joinedRoom.Value.State.Events.RemoveAll(x => filter.Room?.State?.Types?.Contains(x.Type) ?? false); + if(filter.Room?.State?.NotSenders?.Any() ?? false) + joinedRoom.Value.State.Events.RemoveAll(x => filter.Room?.State?.NotSenders?.Contains(x.Sender) ?? false); + + queue.Enqueue(joinedRoom); + } + + Status = $"Got {Rooms.Count} rooms so far! {queue.Count} entries in processing queue... " + + $"{sync?.Rooms?.Join?.Count ?? 0} new updates!"; + + Status2 = $"Next batch: {sync.NextBatch}"; + } + } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor index 15220da..3cc6a15 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/PolicyList.razor @@ -1,9 +1,6 @@ @page "/Rooms/{RoomId}/Policies" @using LibMatrix -@using LibMatrix.Extensions -@using LibMatrix.Helpers @using LibMatrix.Homeservers -@using LibMatrix.Responses @using ArcaneLibs.Extensions @using LibMatrix.EventTypes.Spec.State

Policy list editor - Editing @RoomId

diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Space.razor b/MatrixRoomUtils.Web/Pages/Rooms/Space.razor index d0236e2..ce94d01 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Space.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Space.razor @@ -1,6 +1,4 @@ @page "/Rooms/{RoomId}/Space" -@using LibMatrix.Extensions -@using LibMatrix.Responses @using LibMatrix.RoomTypes @using ArcaneLibs.Extensions @using LibMatrix diff --git a/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor b/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor index e47ba11..0e9d4f6 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/StateEditor.razor @@ -1,6 +1,4 @@ @page "/Rooms/{RoomId}/State/Edit" -@using LibMatrix.Extensions -@using LibMatrix.Responses @using ArcaneLibs.Extensions @using LibMatrix @inject ILocalStorageService LocalStorage diff --git a/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor b/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor index e9c5da1..2d0e0b0 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/StateViewer.razor @@ -1,6 +1,4 @@ @page "/Rooms/{RoomId}/State/View" -@using LibMatrix.Extensions -@using LibMatrix.Responses @using ArcaneLibs.Extensions @using LibMatrix @inject ILocalStorageService LocalStorage diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor index 68125cb..e22be4a 100644 --- a/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor +++ b/MatrixRoomUtils.Web/Pages/Rooms/Timeline.razor @@ -4,7 +4,6 @@ @using LibMatrix.EventTypes.Spec @using LibMatrix.EventTypes.Spec.State @using LibMatrix.Homeservers -@using LibMatrix.Responses

RoomManagerTimeline


Loaded @Events.Count events...

diff --git a/MatrixRoomUtils.Web/Pages/SpaceDebug.razor b/MatrixRoomUtils.Web/Pages/SpaceDebug.razor deleted file mode 100644 index b07ba84..0000000 --- a/MatrixRoomUtils.Web/Pages/SpaceDebug.razor +++ /dev/null @@ -1,114 +0,0 @@ -@page "/SpaceDebug" -@using LibMatrix.RoomTypes -@using LibMatrix.Filters -@using LibMatrix.Helpers -

SpaceDebug

-
- -

@Status

- -Has parent: -
- -@foreach (var (roomId, parents) in SpaceParents) { -

@roomId's parents

-
    - @foreach (var parent in parents) { -
  • @parent
  • - } -
-} - -Space children: - -@foreach (var (roomId, children) in SpaceChildren) { -

@roomId's children

-
    - @foreach (var child in children) { -
  • @child
  • - } -
-} - -@code { - private string _status = "Loading..."; - - public string Status { - get => _status; - set { - _status = value; - StateHasChanged(); - } - } - - public Dictionary> SpaceChildren { get; set; } = new(); - public Dictionary> SpaceParents { get; set; } = new(); - - protected override async Task OnInitializedAsync() { - Status = "Getting homeserver..."; - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); - if (hs is null) return; - - var syncHelper = new SyncHelper(hs) { - Filter = new SyncFilter() { - Presence = new(0), - Room = new() { - AccountData = new(limit: 0), - Ephemeral = new(limit: 0), - State = new(limit: 1000, types: new() { "m.space.child", "m.space.parent" }), - Timeline = new(limit: 0) - }, - AccountData = new(limit: 0) - } - }; - - Status = "Syncing..."; - - var syncs = syncHelper.EnumerateSyncAsync(); - await foreach (var sync in syncs) { - if (sync is null) { - Status = "Sync failed"; - continue; - } - - if (sync.Rooms is null) { - Status = "No rooms in sync..."; - break; - } - - if (sync.Rooms.Join is null) { - Status = "No joined rooms in sync..."; - break; - } - - if (sync.Rooms.Join.Count == 0) { - Status = "Joined rooms list was empty..."; - break; - } - - // nextBatch = sync.NextBatch; - foreach (var (roomId, data) in sync.Rooms!.Join!) { - data.State?.Events?.ForEach(e => { - if (e.Type == "m.space.child") { - if (!SpaceChildren.ContainsKey(roomId)) SpaceChildren[roomId] = new(); - if (e.RawContent is null) e.StateKey += " (null)"; - else if (e.RawContent.Count == 0) e.StateKey += " (empty)"; - SpaceChildren[roomId].Add(e.StateKey); - } - if (e.Type == "m.space.parent") { - if (!SpaceParents.ContainsKey(roomId)) SpaceParents[roomId] = new(); - if (e.RawContent is null) e.StateKey += " (null)"; - else if (e.RawContent.Count == 0) e.StateKey += " (empty)"; - SpaceParents[roomId].Add(e.StateKey); - } - }); - } - Status = $"Synced {sync.Rooms.Join.Count} rooms, found {SpaceChildren.Count} spaces, {SpaceParents.Count} parents"; - } - Status = $"Synced: found {SpaceChildren.Count}->{SpaceChildren.Sum(x => x.Value.Count)} spaces, {SpaceParents.Count}->{SpaceParents.Sum(x => x.Value.Count)} parents!"; - - await base.OnInitializedAsync(); - } - - -} diff --git a/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor b/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor new file mode 100644 index 0000000..939838e --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Tools/KnownHomeserverList.razor @@ -0,0 +1,171 @@ +@page "/KnownHomeserverList" +@using System.Diagnostics +@using ArcaneLibs.Extensions +@using LibMatrix.Homeservers +@using LibMatrix.RoomTypes +

Known Homeserver List

+
+ +@if (!IsFinished) { +

Loading... Please wait...

+ +

@QueryProgress.ProcessedRooms / @QueryProgress.TotalRooms

+ @foreach (var (room, state) in QueryProgress.ProcessedUsers.Where(x => !x.Value.IsFinished).OrderByDescending(x => x.Value.Total).ToList()) { + @if (state.Blocked) { +

🔒 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

+ } + else if (state.Slowmode) { +

🐢 @room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

+ } + else { +

@room.RoomId - @state.Processed / @state.Total, @state.Timing.Elapsed elapsed...

+ } + + } +} +else { + @foreach (var server in HomeServers.OrderByDescending(x => x.KnownUserCount).ThenBy(x => x.Server).ToList()) { +

@server.Server - @server.KnownUserCount

+ } +} +
+ +@code { + List HomeServers = new(); + bool IsFinished { 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; + } + Console.WriteLine($"Progress updated, but not rendering because only {sw.ElapsedMilliseconds}ms elapsed since last call..."); + return false; + }); + + IsFinished = true; + StateHasChanged(); + Console.WriteLine("Rerendered!"); + await base.OnInitializedAsync(); + } + + private async Task> GetHomeservers(int memberLimit = 1000, Func>? progressCallback = null) { + HomeServerInfoQueryProgress progress = new(); + List homeServers = new(); + + var rooms = await hs.GetJoinedRooms(); + progress.TotalRooms = rooms.Count; + + var semaphore = new SemaphoreSlim(4); + var semLock = new SemaphoreSlim(1); + 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.GetFullStateAsync(); + 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); + + + + // states.RemoveAll(x => x.Type != "m.room.member" || (x.TypedContent as RoomMemberEventContent).Membership != "join"); + // Console.WriteLine($"Room {room.RoomId} has {states.Count} members"); + // if (states.Count > memberLimit) { + // Console.WriteLine("Skipping!"); + // semaphore.Release(); + // progress.ProcessedUsers.Remove(room); + // progress.TotalRooms--; + // return; + // } + // progress.ProcessedUsers[room].Total = states.Count; + // var updateInterval = progress.ProcessedUsers[room].Total >= 1000 ? 1000 : 100; + // while (progress.ProcessedUsers.Any(x => x.Value.Total == 0) && progress.ProcessedUsers[room].Total >= 1000) { + // progress.ProcessedUsers[room].Blocked = true; + // await Task.Delay(1000); + // // if(progressCallback is not null) + // // await progressCallback.Invoke(progress); + // } + // progress.ProcessedUsers[room].Blocked = false; + // var processedStates = 0; + // foreach (var state in states) { + // await semLock.WaitAsync(); + // semLock.Release(); + // if (progress.ProcessedUsers.Count(x => x.Value.Total == 0) > 5 && progress.ProcessedUsers[room].Total >= 200) { + // progress.ProcessedUsers[room].Slowmode = true; + // await Task.Delay(progress.ProcessedUsers[room].Total >= 500 ? 1000 : 100); + // } + // else { + // progress.ProcessedUsers[room].Slowmode = false; + // } + // if (!homeServers.Any(x => x.Server == state.StateKey.Split(':')[1])) { + // homeServers.Add(new HomeServerInfo { Server = state.StateKey.Split(':')[1] }); + // } + // var hs = homeServers.First(x => x.Server == state.StateKey.Split(':')[1]); + // if (!hs.KnownUsers.Contains(state.StateKey.Split(':')[0])) + // hs.KnownUsers.Add(state.StateKey.Split(':')[0]); + // if (++progress.ProcessedUsers[room].Processed % updateInterval == 0 && progressCallback is not null) { + // await semLock.WaitAsync(); + // var _ = await progressCallback.Invoke(progress); + // semLock.Release(); + // } + // } + // Console.WriteLine("Collected states!"); + // progress.ProcessedRooms++; + // progress.ProcessedUsers[room].IsFinished = true; + // progressCallback?.Invoke(progress); + // semaphore.Release(); + }); + 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 KnownUsers { get; } = new(); + } + + class HomeServerInfoQueryProgress { + public int ProcessedRooms { get; set; } + public int TotalRooms { get; set; } + public Dictionary ProcessedUsers { get; } = new(); + public List 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(); + } + } + +} diff --git a/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor b/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor new file mode 100644 index 0000000..a376efa --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Tools/MediaLocator.razor @@ -0,0 +1,111 @@ +@page "/MediaLocator" +@using LibMatrix.Homeservers +@inject HttpClient Http +

Media locator

+
+ +This is going to expose your IP address to all these homeservers! +
+ Checked homeserver list (@homeservers.Count entries) +
    + @foreach (var hs in homeservers) { +
  • @hs
  • + } +
+
+ +
+MXC URL: + + + +@if (successResults.Count > 0) { +

Successes

+
    + @foreach (var result in successResults) { +
  • @result
  • + } +
+} + +@if (errorResults.Count > 0) { +

Errors

+
    + @foreach (var result in errorResults) { +
  • @result
  • + } +
+} + + +@code { + string mxcUrl { get; set; } + readonly List successResults = new(); + readonly List errorResults = new(); + readonly List homeservers = new(); + + protected override async Task OnInitializedAsync() { + await base.OnInitializedAsync(); + homeservers.AddRange(new[] { + "matrix.org", + "feline.support", + "rory.gay", + "the-apothecary.club", + "envs.net", + "projectsegfau.lt" + }); + } + + Task executeSearch() { + var sem = new SemaphoreSlim(128, 128); + homeservers.ForEach(async hs => { + await sem.WaitAsync(); + var httpClient = new HttpClient { BaseAddress = new Uri(hs) }; + httpClient.Timeout = TimeSpan.FromSeconds(5); + var rmu = mxcUrl.Replace("mxc://", $"{hs}/_matrix/media/v3/download/"); + try { + var res = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, rmu)); + if (res.IsSuccessStatusCode) { + successResults.Add($"{hs}: found - {res.Content.Headers.ContentLength} bytes"); + StateHasChanged(); + return; + } + errorResults.Add($"Error: {hs} - {res.StatusCode}\n" + await res.Content.ReadAsStringAsync()); + } + catch (Exception e) { + errorResults.Add($"Error: {e}"); + } + finally { + sem.Release(); + } + StateHasChanged(); + }); + return Task.CompletedTask; + } + + async Task addMoreHomeservers() { + var res = await Http.GetAsync("/homeservers.txt"); + var content = await res.Content.ReadAsStringAsync(); + homeservers.Clear(); + var lines = content.Split("\n"); + + var rhs = new RemoteHomeServer("rory.gay"); + var sem = new SemaphoreSlim(128, 128); + lines.ToList().ForEach(async line => { + await sem.WaitAsync(); + try { + homeservers.Add(await hsResolver.ResolveHomeserverFromWellKnown(line)); + StateHasChanged(); + } + catch (Exception e) { + Console.WriteLine(e); + } + finally { + sem.Release(); + } + }); + + StateHasChanged(); + } + +} diff --git a/MatrixRoomUtils.Web/Pages/Tools/SpaceDebug.razor b/MatrixRoomUtils.Web/Pages/Tools/SpaceDebug.razor new file mode 100644 index 0000000..5b4815d --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Tools/SpaceDebug.razor @@ -0,0 +1,113 @@ +@page "/SpaceDebug" +@using LibMatrix.Filters +@using LibMatrix.Helpers +

SpaceDebug

+
+ +

@Status

+ +Has parent: +
+ +@foreach (var (roomId, parents) in SpaceParents) { +

@roomId's parents

+
    + @foreach (var parent in parents) { +
  • @parent
  • + } +
+} + +Space children: + +@foreach (var (roomId, children) in SpaceChildren) { +

@roomId's children

+
    + @foreach (var child in children) { +
  • @child
  • + } +
+} + +@code { + private string _status = "Loading..."; + + public string Status { + get => _status; + set { + _status = value; + StateHasChanged(); + } + } + + public Dictionary> SpaceChildren { get; set; } = new(); + public Dictionary> SpaceParents { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + Status = "Getting homeserver..."; + var hs = await MRUStorage.GetCurrentSessionOrNavigate(); + if (hs is null) return; + + var syncHelper = new SyncHelper(hs) { + Filter = new SyncFilter() { + Presence = new(0), + Room = new() { + AccountData = new(limit: 0), + Ephemeral = new(limit: 0), + State = new(limit: 1000, types: new() { "m.space.child", "m.space.parent" }), + Timeline = new(limit: 0) + }, + AccountData = new(limit: 0) + } + }; + + Status = "Syncing..."; + + var syncs = syncHelper.EnumerateSyncAsync(); + await foreach (var sync in syncs) { + if (sync is null) { + Status = "Sync failed"; + continue; + } + + if (sync.Rooms is null) { + Status = "No rooms in sync..."; + break; + } + + if (sync.Rooms.Join is null) { + Status = "No joined rooms in sync..."; + break; + } + + if (sync.Rooms.Join.Count == 0) { + Status = "Joined rooms list was empty..."; + break; + } + + // nextBatch = sync.NextBatch; + foreach (var (roomId, data) in sync.Rooms!.Join!) { + data.State?.Events?.ForEach(e => { + if (e.Type == "m.space.child") { + if (!SpaceChildren.ContainsKey(roomId)) SpaceChildren[roomId] = new(); + if (e.RawContent is null) e.StateKey += " (null)"; + else if (e.RawContent.Count == 0) e.StateKey += " (empty)"; + SpaceChildren[roomId].Add(e.StateKey); + } + if (e.Type == "m.space.parent") { + if (!SpaceParents.ContainsKey(roomId)) SpaceParents[roomId] = new(); + if (e.RawContent is null) e.StateKey += " (null)"; + else if (e.RawContent.Count == 0) e.StateKey += " (empty)"; + SpaceParents[roomId].Add(e.StateKey); + } + }); + } + Status = $"Synced {sync.Rooms.Join.Count} rooms, found {SpaceChildren.Count} spaces, {SpaceParents.Count} parents"; + } + Status = $"Synced: found {SpaceChildren.Count}->{SpaceChildren.Sum(x => x.Value.Count)} spaces, {SpaceParents.Count}->{SpaceParents.Sum(x => x.Value.Count)} parents!"; + + await base.OnInitializedAsync(); + } + + +} diff --git a/MatrixRoomUtils.Web/Shared/NavMenu.razor b/MatrixRoomUtils.Web/Shared/NavMenu.razor index ad671c5..68b491d 100644 --- a/MatrixRoomUtils.Web/Shared/NavMenu.razor +++ b/MatrixRoomUtils.Web/Shared/NavMenu.razor @@ -14,61 +14,74 @@ Home + + + + - + - @* *@ + + + + + - @* *@ - @* *@ - + + + + + + + diff --git a/MatrixRoomUtils.Web/Shared/PortableDevTools.razor b/MatrixRoomUtils.Web/Shared/PortableDevTools.razor deleted file mode 100644 index 8ca10a0..0000000 --- a/MatrixRoomUtils.Web/Shared/PortableDevTools.razor +++ /dev/null @@ -1,26 +0,0 @@ -@* @if (Enabled) { *@ -@* Portable devtools (enabled) *@ -@*
*@ -@* $1$

Cache size: @RuntimeCache.GenericResponseCache.Sum(x => x.Value.Cache.Count)

#1# *@ -@*
*@ -@* } *@ -@* else { *@ -@* Portable devtools (disabled) *@ -@* } *@ -@* *@ -@* @code { *@ -@* private bool Enabled { get; set; } = LocalStorageWrapper.Settings.DeveloperSettings.EnablePortableDevtools; *@ -@* *@ -@* protected override async Task OnInitializedAsync() => *@ -@* // if(!RuntimeCache.WasLoaded) *@ -@* // await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); *@ -@* // StateHasChanged(); *@ -@* Task.Run(async () => { *@ -@* while (true) { *@ -@* await Task.Delay(100); *@ -@* Enabled = LocalStorageWrapper.Settings.DeveloperSettings.EnablePortableDevtools; *@ -@* StateHasChanged(); *@ -@* } *@ -@* }); *@ -@* *@ -@* } *@ \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomList.razor b/MatrixRoomUtils.Web/Shared/RoomList.razor index 91ebb0b..705f68c 100644 --- a/MatrixRoomUtils.Web/Shared/RoomList.razor +++ b/MatrixRoomUtils.Web/Shared/RoomList.razor @@ -3,8 +3,10 @@ @using LibMatrix.Extensions @using ArcaneLibs.Extensions @using LibMatrix.EventTypes.Spec.State -@if(Rooms.Count != RoomsWithTypes.Sum(x=>x.Value.Count)) { -

Fetching room details... @RoomsWithTypes.Sum(x=>x.Value.Count) out of @Rooms.Count done!

+@using System.Collections.ObjectModel +@using _Imports = MatrixRoomUtils.Web._Imports +@if (!StillFetching) { +

Fetching room details... @RoomsWithTypes.Sum(x => x.Value.Count) out of @Rooms.Count done!

@foreach (var category in RoomsWithTypes.OrderBy(x => x.Value.Count)) {

@category.Key (@category.Value.Count)

} @@ -18,23 +20,35 @@ else { @code { [Parameter] - public List Rooms { get; set; } + public ObservableCollection Rooms { get; set; } + [Parameter] public ProfileResponseEventContent? GlobalProfile { get; set; } - Dictionary> RoomsWithTypes = new(); + [Parameter] + public bool StillFetching { get; set; } = true; + + [Parameter] + public EventCallback StillFetchingChanged { get; set; } - protected override async Task OnInitializedAsync() { + private Dictionary> RoomsWithTypes => Rooms is null ? new() : Rooms.GroupBy(x => GetRoomTypeName(x.CreationEventContent?.Type)).ToDictionary(x => x.Key, x => x.ToList()); + + protected override async Task OnParametersSetAsync() { var hs = await MRUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; + Rooms.CollectionChanged += (_, args) => { + foreach (RoomInfo item in args.NewItems) { + item.PropertyChanged += (_, args2) => { + Console.WriteLine(args2); + if(args2.PropertyName == nameof(item.CreationEventContent)) + StateHasChanged(); + }; + } + }; - GlobalProfile ??= await hs.GetProfileAsync(hs.WhoAmI.UserId); - if (RoomsWithTypes.Any()) return; - - var tasks = Rooms.Select(ProcessRoom); - await Task.WhenAll(tasks); + // GlobalProfile ??= await hs.GetProfileAsync(hs.WhoAmI.UserId); - await base.OnInitializedAsync(); + await base.OnParametersSetAsync(); } private string GetRoomTypeName(string? roomType) => roomType switch { @@ -45,32 +59,33 @@ else { _ => roomType }; + // private static SemaphoreSlim _semaphoreSlim = new(8, 8); - private static SemaphoreSlim _semaphoreSlim = new(8, 8); - private async Task ProcessRoom(RoomInfo room) { - await _semaphoreSlim.WaitAsync(); - string roomType; - try { - var createEvent = (await room.GetStateEvent("m.room.create")).TypedContent as RoomCreateEventContent; - roomType = GetRoomTypeName(createEvent.Type); - - if (roomType == "Room") { - var mjolnirData = await room.GetStateEvent("org.matrix.mjolnir.shortcode"); - if(mjolnirData?.RawContent?.ToJson(ignoreNull: true) is not null and not "{}") - roomType = "Legacy policy room"; - } - } - catch (MatrixException e) { - roomType = $"Error: {e.ErrorCode}"; - } - - if (!RoomsWithTypes.ContainsKey(roomType)) { - RoomsWithTypes.Add(roomType, new List()); - } - RoomsWithTypes[roomType].Add(room); - - StateHasChanged(); - _semaphoreSlim.Release(); - } + // private async Task ProcessRoom(RoomInfo room) { + // await _semaphoreSlim.WaitAsync(); + // string roomType; + // try { + // var createEvent = (await room.GetStateEvent("m.room.create")).TypedContent as RoomCreateEventContent; + // roomType = GetRoomTypeName(createEvent.Type); + // + // if (roomType == "Room") { + // var mjolnirData = await room.GetStateEvent("org.matrix.mjolnir.shortcode"); + // if (mjolnirData?.RawContent?.ToJson(ignoreNull: true) is not null and not "{}") + // roomType = "Legacy policy room"; + // } + // } + // catch (MatrixException e) { + // roomType = $"Error: {e.ErrorCode}"; + // } + // + // // if (!RoomsWithTypes.ContainsKey(roomType)) { + // // RoomsWithTypes.Add(roomType, new List()); + // // } + // // RoomsWithTypes[roomType].Add(room); + // + // StateHasChanged(); + // _semaphoreSlim.Release(); + // } } + diff --git a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor index 1b54577..e08f98d 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor @@ -1,3 +1,4 @@ +@using System.Collections.ObjectModel Manage space
@@ -25,7 +26,7 @@ set => _breadcrumbs = value; } - private List Children { get; set; } = new(); + private ObservableCollection Children { get; set; } = new(); protected override async Task OnInitializedAsync() { if (Breadcrumbs == null) throw new ArgumentNullException(nameof(Breadcrumbs)); @@ -35,7 +36,7 @@ if (Breadcrumbs.Contains(room.RoomId)) continue; var roomInfo = KnownRooms.FirstOrDefault(x => x.Room.RoomId == room.RoomId); if (roomInfo is null) { - roomInfo = new RoomInfo { + roomInfo = new RoomInfo() { Room = room }; KnownRooms.Add(roomInfo); diff --git a/MatrixRoomUtils.Web/Shared/RoomListItem.razor b/MatrixRoomUtils.Web/Shared/RoomListItem.razor index 0e1d70d..79c7f4e 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListItem.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListItem.razor @@ -5,41 +5,38 @@ @using LibMatrix.Homeservers @using LibMatrix.RoomTypes @using MatrixRoomUtils.Web.Classes.Constants -
- @if (OwnMemberState != null) { - - - @(OwnMemberState?.DisplayName ?? GlobalProfile?.DisplayName ?? "Loading...") - - -> - } - -
- @roomName - @if (ChildContent is not null) { - @ChildContent +@if (RoomInfo is not null) { +
+ @if (OwnMemberState != null) { + + + @(OwnMemberState?.DisplayName ?? GlobalProfile?.DisplayName ?? "Loading...") + + -> } -
+ @* style="@(ChildContent is not null ? "vertical-align: baseline;" : "")"*@ +
+ @RoomInfo.RoomName + @* @if (ChildContent is not null) { *@ + @* @ChildContent *@ + @* } *@ +
-
+
+} +else { +

Warning: RoomInfo is null!

+} @code { - [Parameter] - public RenderFragment? ChildContent { get; set; } - - [Parameter] - public GenericRoom? Room { get; set; } + // [Parameter] + // public RenderFragment? ChildContent { get; set; } [Parameter] public RoomInfo? RoomInfo { get; set; } - [Parameter] - public string? RoomId { get; set; } - [Parameter] public bool ShowOwnProfile { get; set; } = false; @@ -49,16 +46,20 @@ [CascadingParameter] public ProfileResponseEventContent? GlobalProfile { get; set; } - private string? roomName { get; set; } - - private string? roomIcon { get; set; } = "/icon-192.png"; - - private bool hasOldRoomVersion { get; set; } = false; - private bool hasDangerousRoomVersion { get; set; } = false; + private bool HasOldRoomVersion { get; set; } = false; + private bool HasDangerousRoomVersion { get; set; } = false; private static SemaphoreSlim _semaphoreSlim = new(8); private static AuthenticatedHomeserverGeneric? hs { get; set; } + protected override async Task OnParametersSetAsync() { + RoomInfo.PropertyChanged += (_, a) => { + Console.WriteLine(a.PropertyName); + StateHasChanged(); + }; + await base.OnParametersSetAsync(); + } + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -67,34 +68,20 @@ hs ??= await MRUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; - if (Room is null && RoomId is null && RoomInfo is null) { - throw new ArgumentNullException(nameof(RoomId)); - } - - // sweep from roominfo to id - if (RoomInfo is not null) Room = RoomInfo.Room; - if(Room is not null) RoomId = Room.RoomId; - - //sweep from id to roominfo - if(RoomId is not null) Room ??= hs.GetRoom(RoomId); - if(Room is not null) RoomInfo ??= new RoomInfo { - Room = Room - }; - try { - await CheckRoomVersion(); - await GetRoomInfo(); - await LoadOwnProfile(); + await CheckRoomVersion(); + // await GetRoomInfo(); + // await LoadOwnProfile(); } catch (MatrixException e) { if (e is not { ErrorCode: "M_FORBIDDEN" }) { throw; } - roomName = "Error: " + e.Message; - roomIcon = "/blobfox_outage.gif"; + // RoomName = "Error: " + e.Message; + // RoomIcon = "/blobfox_outage.gif"; } catch (Exception e) { - Console.WriteLine($"Failed to load room info for {RoomId}: {e.Message}"); + Console.WriteLine($"Failed to load room info for {RoomInfo.Room.RoomId}: {e.Message}"); } _semaphoreSlim.Release(); } @@ -102,7 +89,7 @@ private async Task LoadOwnProfile() { if (!ShowOwnProfile) return; try { - OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.UserId)).TypedContent as RoomMemberEventContent; + // OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.UserId)).TypedContent as RoomMemberEventContent; GlobalProfile ??= await hs.GetProfileAsync(hs.UserId); } catch (MatrixException e) { @@ -117,35 +104,39 @@ } private async Task CheckRoomVersion() { - var ce = (await RoomInfo.GetStateEvent("m.room.create")).TypedContent as RoomCreateEventContent; + while (RoomInfo?.CreationEventContent is null) { + Console.WriteLine($"Room creation event content for {RoomInfo.Room.RoomId} is null..."); + await Task.Delay(Random.Shared.Next(1000, 2500)); + } + var ce = RoomInfo.CreationEventContent; if (int.TryParse(ce.RoomVersion, out var rv)) { if (rv < 10) - hasOldRoomVersion = true; + HasOldRoomVersion = true; } else // treat unstable room versions as dangerous - hasDangerousRoomVersion = true; + HasDangerousRoomVersion = true; if (RoomConstants.DangerousRoomVersions.Contains(ce.RoomVersion)) { - hasDangerousRoomVersion = true; - roomName = "Dangerous room: " + roomName; - } - } - - private async Task GetRoomInfo() { - try { - roomName ??= ((await RoomInfo.GetStateEvent("m.room.name"))?.TypedContent as RoomNameEventContent)?.Name ?? RoomId; - - var state = (await RoomInfo.GetStateEvent("m.room.avatar")).TypedContent as RoomAvatarEventContent; - if (state?.Url is { } url) { - roomIcon = await hsResolver.ResolveMediaUri(hs.ServerName, url); - // Console.WriteLine($"Got avatar for room {RoomId}: {roomIcon} ({url})"); - } - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_FORBIDDEN" }) { - throw; - } + HasDangerousRoomVersion = true; + // RoomName = "Dangerous room: " + RoomName; } } -} + // private async Task GetRoomInfo() { + // try { + // RoomName ??= ((await RoomInfo.GetStateEvent("m.room.name"))?.TypedContent as RoomNameEventContent)?.Name ?? RoomId; + // + // var state = (await RoomInfo.GetStateEvent("m.room.avatar")).TypedContent as RoomAvatarEventContent; + // if (state?.Url is { } url) { + // RoomIcon = await hsResolver.ResolveMediaUri(hs.ServerName, url); + // // Console.WriteLine($"Got avatar for room {RoomId}: {roomIcon} ({url})"); + // } + // } + // catch (MatrixException e) { + // if (e is not { ErrorCode: "M_FORBIDDEN" }) { + // throw; + // } + // } + // } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomListItem.razor.css b/MatrixRoomUtils.Web/Shared/RoomListItem.razor.css index da22d38..13de656 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListItem.razor.css +++ b/MatrixRoomUtils.Web/Shared/RoomListItem.razor.css @@ -1,10 +1,48 @@ -/*.imageUnloaded {*/ -/* scale: 3;*/ -/* opacity: 0.5;*/ -/* transition: scale 0.5s ease-in-out;*/ -/*}*/ - -.imageLoaded { - opacity: 1; - scale: 1; +.roomListItem { + background-color: #ffffff11; + border-radius: 25px; + margin: 8px; + width: fit-Content; +} + +.roomListItem.dangerousRoomVersion { + border: red 4px solid; +} + +.roomListItem.oldRoomVersion { + border: #FF0 1px solid; +} + +.avatar32 { + width: 32px; + height: 32px; + border-radius: 50%; +} + +.avatar32.vcenter { + vertical-align: baseline; +} + +.highlightChange { + background-color: red; + border-color: red; + border-width: 3px; + border-style: dashed; +} + +.inlineBlock { + display: inline-block; +} + +.centerVertical { + vertical-align: middle; + padding-right: 8px; +} + +.noLeftPadding { + padding-left: 0px; +} + +.border75 { + border-radius: 75px; } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor index e4ee873..9efeaab 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor @@ -1,4 +1,3 @@ -@using LibMatrix.Responses @using LibMatrix @using LibMatrix.Homeservers

BaseTimelineItem

diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor index b58afba..a454103 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor @@ -1,4 +1,3 @@ -@using LibMatrix.Extensions @using ArcaneLibs.Extensions @using LibMatrix.EventTypes.Spec.State @inherits BaseTimelineItem diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor index 5dd87e0..8073406 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor @@ -1,4 +1,3 @@ -@using LibMatrix.Extensions @using ArcaneLibs.Extensions @inherits BaseTimelineItem diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor index ff77726..2d05151 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor @@ -1,4 +1,3 @@ -@using LibMatrix.Extensions @using ArcaneLibs.Extensions @using LibMatrix.EventTypes.Spec.State @inherits BaseTimelineItem diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor index 69845d9..1ab530d 100644 --- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor +++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor @@ -1,4 +1,3 @@ -@using LibMatrix.Extensions @using ArcaneLibs.Extensions @inherits BaseTimelineItem diff --git a/MatrixRoomUtils.Web/Shared/UserListItem.razor b/MatrixRoomUtils.Web/Shared/UserListItem.razor index 9010820..96e8e64 100644 --- a/MatrixRoomUtils.Web/Shared/UserListItem.razor +++ b/MatrixRoomUtils.Web/Shared/UserListItem.razor @@ -1,8 +1,9 @@ @using LibMatrix.Helpers @using LibMatrix.EventTypes.Spec.State +@using LibMatrix.Homeservers
- - @profileName + + @User?.DisplayName
@if (ChildContent is not null) { @@ -18,36 +19,25 @@ public RenderFragment? ChildContent { get; set; } [Parameter] - public ProfileResponseEventContent User { get; set; } + public ProfileResponseEventContent? User { get; set; } [Parameter] public string UserId { get; set; } - private string? profileAvatar { get; set; } = "/icon-192.png"; - private string? profileName { get; set; } = "Loading..."; - - private static SemaphoreSlim _semaphoreSlim = new(8); + private AuthenticatedHomeserverGeneric _homeserver = null!; protected override async Task OnInitializedAsync() { - await base.OnInitializedAsync(); - - var hs = await MRUStorage.GetCurrentSessionOrNavigate(); - if (hs is null) return; - - await _semaphoreSlim.WaitAsync(); + _homeserver = await MRUStorage.GetCurrentSessionOrNavigate(); + if (_homeserver is null) return; if (User == null) { if (UserId == null) { throw new ArgumentNullException(nameof(UserId)); } - User = await hs.GetProfileAsync(UserId); + User = await _homeserver.GetProfileAsync(UserId); } - // UserId = User.; - profileAvatar = await hsResolver.ResolveMediaUri(hs.ServerName, User.AvatarUrl); - profileName = User.DisplayName; - - _semaphoreSlim.Release(); + await base.OnInitializedAsync(); } -} +} \ No newline at end of file diff --git a/MatrixRoomUtils.sln.DotSettings.user b/MatrixRoomUtils.sln.DotSettings.user index b2b542c..1df0f07 100644 --- a/MatrixRoomUtils.sln.DotSettings.user +++ b/MatrixRoomUtils.sln.DotSettings.user @@ -44,6 +44,9 @@ <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;LibMatrix&gt; #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="/home/root@Rory/git/Matrix/MatrixRoomUtils" Presentation="&lt;LibMatrix&gt;" /> </SessionState> + True + True + True -- cgit 1.4.1