diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-14 22:26:39 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-14 22:26:39 +0200 |
commit | b48f78a381058c188ed61e6f372fbf86d95ad2f9 (patch) | |
tree | 178e5d85a92da68b42ffcc68cbbba9b8ea3c40fd | |
parent | Change syntax style (diff) | |
download | MatrixUtils-b48f78a381058c188ed61e6f372fbf86d95ad2f9.tar.xz |
Add changes
17 files changed, 240 insertions, 21 deletions
diff --git a/MatrixRoomUtils.Core/Room.cs b/MatrixRoomUtils.Core/Room.cs index a867c0c..2d6dc46 100644 --- a/MatrixRoomUtils.Core/Room.cs +++ b/MatrixRoomUtils.Core/Room.cs @@ -3,6 +3,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Web; using MatrixRoomUtils.Core.Extensions; +using MatrixRoomUtils.Core.RoomTypes; namespace MatrixRoomUtils.Core; @@ -12,6 +13,8 @@ public class Room { public Room(HttpClient httpClient, string roomId) { _httpClient = httpClient; RoomId = roomId; + if(GetType() != typeof(SpaceRoom)) + AsSpace = new SpaceRoom(_httpClient, RoomId); } public string RoomId { get; set; } @@ -137,6 +140,16 @@ public class Room { return res.Value.Deserialize<CreateEvent>() ?? new CreateEvent(); } + + public async Task<string?> GetRoomType() { + var res = await GetStateAsync("m.room.create"); + if (!res.HasValue) return null; + if (res.Value.TryGetProperty("type", out var type)) return type.GetString(); + return null; + } + + + public SpaceRoom AsSpace; } public class MessagesResponse { diff --git a/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs b/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs new file mode 100644 index 0000000..e8d4823 --- /dev/null +++ b/MatrixRoomUtils.Core/RoomTypes/SpaceRoom.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using MatrixRoomUtils.Core.Extensions; + +namespace MatrixRoomUtils.Core.RoomTypes; + +public class SpaceRoom : Room { + public SpaceRoom(HttpClient httpClient, string roomId) : base(httpClient, roomId) { } + + public async Task<List<Room>> GetRoomsAsync(bool includeRemoved = false) { + var rooms = new List<Room>(); + var state = await GetStateAsync(""); + if (state != null) { + var states = state.Value.Deserialize<StateEventResponse<object>[]>()!; + foreach (var stateEvent in states.Where(x => x.Type == "m.space.child")) { + var roomId = stateEvent.StateKey; + if(stateEvent.Content.ToJson() != "{}" || includeRemoved) + rooms.Add(await RuntimeCache.CurrentHomeServer.GetRoom(roomId)); + } + } + + return rooms; + } +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/FileUploadTest.razor b/MatrixRoomUtils.Web/FileUploadTest.razor index 478a3e4..cbdb5ce 100644 --- a/MatrixRoomUtils.Web/FileUploadTest.razor +++ b/MatrixRoomUtils.Web/FileUploadTest.razor @@ -6,7 +6,7 @@ @code { - private async void FilePicked(InputFileChangeEventArgs obj) { + private async Task FilePicked(InputFileChangeEventArgs obj) { Console.WriteLine("FilePicked"); Console.WriteLine(obj.File.Name); Console.WriteLine(obj.File.Size); diff --git a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj index c76452f..e1511c4 100644 --- a/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj +++ b/MatrixRoomUtils.Web/MatrixRoomUtils.Web.csproj @@ -7,17 +7,17 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Blazored.LocalStorage" Version="4.3.0"/> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.3"/> - <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.3" PrivateAssets="all"/> + <PackageReference Include="Blazored.LocalStorage" Version="4.3.0" /> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.3" /> + <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.3" PrivateAssets="all" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj"/> + <ProjectReference Include="..\MatrixRoomUtils.Core\MatrixRoomUtils.Core.csproj" /> </ItemGroup> <ItemGroup> - <Folder Include="Shared\TimelineComponents\TimelineMessageComponents"/> + <Folder Include="Shared\TimelineComponents\TimelineMessageComponents" /> </ItemGroup> </Project> diff --git a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor index e6f95c7..a62362b 100644 --- a/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor +++ b/MatrixRoomUtils.Web/Pages/HSAdmin/RoomQuery.razor @@ -18,19 +18,26 @@ <button class="btn btn-primary" @onclick="Search">Search</button> <br/> +@if (Results.Count > 0) { + <p>Found @Results.Count rooms</p> +} + @foreach (var res in Results) { <div style="background-color: #ffffff11; border-radius: 0.5em; display: block; margin-top: 4px; padding: 4px;"> <RoomListItem RoomName="@res.Name" RoomId="@res.RoomId"></RoomListItem> <p> - @res.CanonicalAlias + @if (!string.IsNullOrWhiteSpace(res.CanonicalAlias)) { + <span>@res.CanonicalAlias (@res.RoomId)</span><br/> + } + else { + <span>@res.RoomId</span><br/> + } @if (!string.IsNullOrWhiteSpace(res.Creator)) { - <span> - , created by <InlineUserItem UserId="@res.Creator"></InlineUserItem> - </span> + <span>Created by <InlineUserItem UserId="@res.Creator"></InlineUserItem></span><br/> } </p> - <p>@res.StateEvents state events</p> - <p>@res.JoinedMembers members, of which @res.JoinedLocalMembers are on this server</p> + <span>@res.StateEvents state events</span><br/> + <span>@res.JoinedMembers members, of which @res.JoinedLocalMembers are on this server</span> </div> } @@ -41,11 +48,11 @@ public string? OrderBy { get; set; } [Parameter] - [SupplyParameterFromQuery(Name = "search_term")] + [SupplyParameterFromQuery(Name = "name_search")] public string SearchTerm { get; set; } [Parameter] - [SupplyParameterFromQuery(Name = "content_search_term")] + [SupplyParameterFromQuery(Name = "content_search")] public string ContentSearchTerm { get; set; } [Parameter] @@ -69,6 +76,8 @@ var room = searchRooms.Current; Console.WriteLine("Hit: " + room.ToJson(false)); Results.Add(room); + if (Results.Count % 10 == 0) + StateHasChanged(); } } diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerTimeline.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerTimeline.razor index 2db7cab..b90cc09 100644 --- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerTimeline.razor +++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerTimeline.razor @@ -1,4 +1,4 @@ -@page "/RoomManager/Timeline/{RoomId}" +@page "/Rooms/{RoomId}/Timeline" @using MatrixRoomUtils.Web.Shared.TimelineComponents <h3>RoomManagerTimeline</h3> <hr/> diff --git a/MatrixRoomUtils.Web/Pages/Rooms/Index.razor b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor new file mode 100644 index 0000000..17551c9 --- /dev/null +++ b/MatrixRoomUtils.Web/Pages/Rooms/Index.razor @@ -0,0 +1,22 @@ +@page "/Rooms" +<h3>Room list</h3> + +@if (Rooms != null) { + <RoomList Rooms="Rooms"></RoomList> +} + + +@code { + + private List<Room> Rooms { get; set; } + + protected override async Task OnInitializedAsync() + { + await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); + + Rooms = await RuntimeCache.CurrentHomeServer.GetJoinedRooms(); + + await base.OnInitializedAsync(); + } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomList.razor b/MatrixRoomUtils.Web/Shared/RoomList.razor new file mode 100644 index 0000000..ca93fa6 --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/RoomList.razor @@ -0,0 +1,56 @@ +@using MatrixRoomUtils.Web.Shared.RoomListComponents; +<p>@Rooms.Count rooms total, @RoomsWithTypes.Sum(x=>x.Value.Count) fetched so far...</p> +@foreach (var category in RoomsWithTypes.OrderBy(x => x.Value.Count)) { + <RoomListCategory Category="@category"></RoomListCategory> +} + +@code { + + [Parameter] + public List<Room> Rooms { get; set; } + + Dictionary<string, List<Room>> RoomsWithTypes = new(); + + protected override async Task OnInitializedAsync() { + if (RoomsWithTypes.Any()) return; + + await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); + + var tasks = Rooms.Select(AddRoom); + await Task.WhenAll(tasks); + + await base.OnInitializedAsync(); + } + + private string GetRoomTypeName(string? roomType) => roomType switch { + "m.space" => "Space", + "msc3588.stories.stories-room" => "Story room", + null => "Room", + _ => roomType + }; + + + private static SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(8, 8); + private async Task AddRoom(Room room) { + await _semaphoreSlim.WaitAsync(); + var roomType = GetRoomTypeName(await room.GetRoomType()); + + if (roomType == "Room") { + var shortcodeState = await room.GetStateAsync("org.matrix.mjolnir.shortcode"); + if (shortcodeState.HasValue) roomType = "Legacy policy room"; + } + + if (!RoomsWithTypes.ContainsKey(roomType)) { + RoomsWithTypes.Add(roomType, new List<Room>()); + } + RoomsWithTypes[roomType].Add(room); + + // if (RoomsWithTypes.Count % 10 == 0) + StateHasChanged(); + await Task.Delay(100); + _semaphoreSlim.Release(); + } + + private bool _isSpaceChildrenOpen = false; + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomList.razor.css b/MatrixRoomUtils.Web/Shared/RoomList.razor.css new file mode 100644 index 0000000..a159305 --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/RoomList.razor.css @@ -0,0 +1,8 @@ +.room-list-item { + background-color: #ffffff11; + border-radius: 0.5em; + display: block; + margin-top: 4px; + padding: 4px; + width: fit-content; +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor new file mode 100644 index 0000000..ecdcc68 --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListCategory.razor @@ -0,0 +1,24 @@ +<details> + <summary>@roomType (@rooms.Count)</summary> + @foreach (var room in rooms) { + <div class="room-list-item"> + <RoomListItem Room="@room" ShowOwnProfile="@(roomType == "Room")"></RoomListItem> + <MatrixRoomUtils.Web.Shared.SimpleComponents.LinkButton href="@($"/Rooms/{room.RoomId}/Timeline")">View timeline</MatrixRoomUtils.Web.Shared.SimpleComponents.LinkButton> + + @if (roomType == "Space") { + <RoomListSpace Space="@room"></RoomListSpace> + } + </div> + } +</details> +<br/> + +@code { + + [Parameter] + public KeyValuePair<string, List<Room>> Category { get; set; } + + private string roomType => Category.Key; + private List<Room> rooms => Category.Value; + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor new file mode 100644 index 0000000..c90ae8f --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/RoomListComponents/RoomListSpace.razor @@ -0,0 +1,42 @@ +<LinkButton href="@($"/Rooms/{Space.RoomId}/Space")">Manage space</LinkButton> + +<br/> +<details @ontoggle="SpaceChildrenOpened"> + <summary>@Children.Count children</summary> + @if (_shouldRenderChildren) { + <p>Breadcrumb: @Breadcrumbs</p> + <div style="margin-left: 8px;"> + <RoomList Rooms="Children"></RoomList> + </div> + } +</details> + +@code { + + [Parameter] + public Room Space { get; set; } + + [Parameter, CascadingParameter] + public string? Breadcrumbs { + get => _breadcrumbs + Space.RoomId; + set => _breadcrumbs = value; + } + + private List<Room> Children { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + if (Breadcrumbs == null) throw new ArgumentNullException(nameof(Breadcrumbs)); + Children = (await Space.AsSpace.GetRoomsAsync()).Where(x => !Breadcrumbs.Contains(x.RoomId)).ToList(); + await base.OnInitializedAsync(); + } + + private bool _shouldRenderChildren = false; + private string? _breadcrumbs; + + private async Task SpaceChildrenOpened() { + if (_shouldRenderChildren) return; + _shouldRenderChildren = true; + Console.WriteLine($"[RoomList] Rendering children of {Space.RoomId}"); + } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/RoomListItem.razor b/MatrixRoomUtils.Web/Shared/RoomListItem.razor index f58ab3a..6dc0683 100644 --- a/MatrixRoomUtils.Web/Shared/RoomListItem.razor +++ b/MatrixRoomUtils.Web/Shared/RoomListItem.razor @@ -2,7 +2,7 @@ @using System.Text.Json <div class="roomListItem" style="background-color: #ffffff11; border-radius: 25px; margin: 8px; width: fit-Content; @(hasDangerousRoomVersion ? "border: red 4px solid;" : hasOldRoomVersion ? "border: #FF0 1px solid;" : "")"> @if (ShowOwnProfile) { - <img class="imageUnloaded @(string.IsNullOrWhiteSpace(profileAvatar) ? "" : "imageLoaded")" style="@(ChildContent != null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%; @(hasCustomProfileAvatar ? "border-color: red; border-width: 3px; border-style: dashed;" : "")" src="@(profileAvatar ?? "/icon-192.png")" @onload="Callback"/> + <img class="imageUnloaded @(string.IsNullOrWhiteSpace(profileAvatar) ? "" : "imageLoaded")" style="@(ChildContent != null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%; @(hasCustomProfileAvatar ? "border-color: red; border-width: 3px; border-style: dashed;" : "")" src="@(profileAvatar ?? "/icon-192.png")" /> <span style="vertical-align: middle; margin-right: 8px; border-radius: 75px; @(hasCustomProfileName ? "background-color: red;" : "")">@(profileName ?? "Loading...")</span> <span style="vertical-align: middle; padding-right: 8px; padding-left: 0px;">-></span> } @@ -51,7 +51,7 @@ await _semaphoreSlim.WaitAsync(); - var hs = RuntimeCache.CurrentHomeServer; //await new AuthenticatedHomeServer(RuntimeCache.CurrentHomeServer.UserId, RuntimeCache.CurrentHomeServer.AccessToken, RuntimeCache.CurrentHomeServer.HomeServerDomain).Configure(); + var hs = RuntimeCache.CurrentHomeServer; if (Room == null) { if (RoomId == null) { @@ -119,6 +119,4 @@ await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage); } - private void Callback(ProgressEventArgs obj) => Console.WriteLine("prog: " + obj.ToJson(false)); - } \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor b/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor index d17d0de..966c44d 100644 --- a/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor +++ b/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor @@ -3,7 +3,7 @@ <input autofocus type="@(IsPassword ? "password" : "text")" @bind="Value" @onfocusout="() => { isVisible = false; ValueChanged.InvokeAsync(Value); }" @ref="elementToFocus"/> } else { - <span tabindex="0" style="border-bottom: #ccc solid 1px; height: 1.4em; display: inline-block; @(string.IsNullOrEmpty(Value) ? "min-width: 50px;" : "")" @onfocusin="() => isVisible = true">@(Formatter?.Invoke(Value) ?? (IsPassword ? string.Join("", Value.Select(x => '*')) : Value))</span> + <span class="fancy-textbox-inline" tabindex="0" style="@(string.IsNullOrEmpty(Value) ? "min-width: 50px;" : "")" @onfocusin="() => isVisible = true">@(Formatter?.Invoke(Value) ?? (IsPassword ? string.Join("", Value.Select(x => '*')) : Value))</span> } @code { diff --git a/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor.css b/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor.css new file mode 100644 index 0000000..01b2c6f --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/SimpleComponents/FancyTextBox.razor.css @@ -0,0 +1,5 @@ +.fancy-textbox-inline { + border-bottom: #ccc solid 1px; + height: 1.4em; + display: inline-block; +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/Shared/SimpleComponents/LinkButton.razor b/MatrixRoomUtils.Web/Shared/SimpleComponents/LinkButton.razor new file mode 100644 index 0000000..8c9e73b --- /dev/null +++ b/MatrixRoomUtils.Web/Shared/SimpleComponents/LinkButton.razor @@ -0,0 +1,13 @@ +<a href="@href" class="btn btn-primary"> + @ChildContent +</a> + +@code { + + [Parameter] + public string href { get; set; } + + [Parameter] + public RenderFragment ChildContent { get; set; } + +} \ No newline at end of file diff --git a/MatrixRoomUtils.Web/_Imports.razor b/MatrixRoomUtils.Web/_Imports.razor index 837780e..155837b 100644 --- a/MatrixRoomUtils.Web/_Imports.razor +++ b/MatrixRoomUtils.Web/_Imports.razor @@ -11,13 +11,18 @@ @using MatrixRoomUtils.Web @using MatrixRoomUtils.Web.Classes @using MatrixRoomUtils.Web.Shared +@using MatrixRoomUtils.Core.RoomTypes +@using MatrixRoomUtils.Core.Extensions + +@using LinkButton = MatrixRoomUtils.Web.Shared.SimpleComponents.LinkButton + + @inject ILocalStorageService LocalStorage @inject NavigationManager NavigationManager @code { - protected override async Task OnInitializedAsync() { if (!RuntimeCache.WasLoaded) { await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage); diff --git a/MatrixRoomUtils.sln.DotSettings b/MatrixRoomUtils.sln.DotSettings index 4ac5b79..3da5982 100644 --- a/MatrixRoomUtils.sln.DotSettings +++ b/MatrixRoomUtils.sln.DotSettings @@ -1,2 +1,3 @@ <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> + <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AsyncVoidMethod/@EntryIndexedValue">ERROR</s:String> <s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String></wpf:ResourceDictionary> \ No newline at end of file |