From 7aba1a4570cc4d7275fa290e6eba487845fc8e43 Mon Sep 17 00:00:00 2001 From: Rory& Date: Wed, 23 Oct 2024 16:14:45 +0200 Subject: Add policy list list page --- LibMatrix | 2 +- MatrixUtils.Web/Pages/About.razor | 2 +- MatrixUtils.Web/Pages/Rooms/PolicyLists.razor | 177 +++++++++++++++++++++ MatrixUtils.Web/Pages/Rooms/PolicyLists.razor.css | 6 + MatrixUtils.Web/Pages/Rooms/Space.razor | 11 +- .../Pages/Tools/Info/PolicyListActivity.razor | 2 +- MatrixUtils.Web/Shared/NavMenu.razor | 6 + 7 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 MatrixUtils.Web/Pages/Rooms/PolicyLists.razor create mode 100644 MatrixUtils.Web/Pages/Rooms/PolicyLists.razor.css diff --git a/LibMatrix b/LibMatrix index 77650d1..bf1664b 160000 --- a/LibMatrix +++ b/LibMatrix @@ -1 +1 @@ -Subproject commit 77650d16a9cc66fdfe393320164cd8248cdff389 +Subproject commit bf1664b254bfc224f0087eb82fdba5235fbd162e diff --git a/MatrixUtils.Web/Pages/About.razor b/MatrixUtils.Web/Pages/About.razor index 330d1c2..9f83991 100644 --- a/MatrixUtils.Web/Pages/About.razor +++ b/MatrixUtils.Web/Pages/About.razor @@ -8,5 +8,5 @@

These range from joining rooms on dead homeservers, to managing your accounts and rooms, and creating rooms based on templates.


-

You can find the source code on cgit.rory.gay.

+

You can find the source code on cgit.rory.gay.

You can also join the Matrix room for this project.

diff --git a/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor b/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor new file mode 100644 index 0000000..63dc206 --- /dev/null +++ b/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor @@ -0,0 +1,177 @@ +@page "/PolicyLists" +@using System.Collections.ObjectModel +@using ArcaneLibs.Extensions +@using LibMatrix +@using LibMatrix.EventTypes +@using LibMatrix.EventTypes.Common +@using LibMatrix.EventTypes.Spec.State.Policy +@using LibMatrix.RoomTypes +@inject ILogger logger +

Policy lists

@* Create new policy list *@ + +@if (!string.IsNullOrWhiteSpace(Status)) { +

@Status

+} +@if (!string.IsNullOrWhiteSpace(Status2)) { +

@Status2

+} +
+ + + + + + + + + + @foreach (var room in Rooms.OrderByDescending(x => x.PolicyCounts.Sum(y => y.Value))) { + + + + + + } + +
+ Room namePolicies
+ + + + + @room.RoomName + @if (room.IsLegacy) { + (legacy) + } +
+ @if (!string.IsNullOrWhiteSpace(room.Shortcode)) { + @room.Shortcode + } + else { + (no shortcode) + } +
+ @(room.PolicyCounts.GetValueOrDefault(RoomInfo.PolicyType.User) ?? 0) user policies
+ @(room.PolicyCounts.GetValueOrDefault(RoomInfo.PolicyType.Server) ?? 0) server policies
+ @(room.PolicyCounts.GetValueOrDefault(RoomInfo.PolicyType.Room) ?? 0) room policies
+
+ +@code { + + private List Rooms { get; } = []; + + private AuthenticatedHomeserverGeneric? Homeserver { get; set; } + + protected override async Task OnInitializedAsync() { + Homeserver = await RMUStorage.GetCurrentSessionOrNavigate(); + if (Homeserver is null) return; + + Status = "Fetching rooms..."; + + var userEventTypes = EventContent.GetMatchingEventTypes(); + var serverEventTypes = EventContent.GetMatchingEventTypes(); + var roomEventTypes = EventContent.GetMatchingEventTypes(); + var knownPolicyTypes = (List) [..userEventTypes, ..serverEventTypes, ..roomEventTypes]; + + List roomsByType = []; + await foreach (var room in Homeserver.GetJoinedRoomsByType("support.feline.policy.lists.msc.v1")) { + roomsByType.Add(room); + Status2 = $"Found {room.RoomId} (MSC3784)..."; + } + + List> tasks = roomsByType.Select(async room => { + Status2 = $"Fetching room {room.RoomId}..."; + return await RoomInfo.FromRoom(room); + }).ToList(); + + var results = tasks.ToAsyncEnumerable(); + await foreach (var result in results) { + Rooms.Add(result); + StateHasChanged(); + } + + Status = "Searching for legacy lists..."; + + var rooms = (await Homeserver.GetJoinedRooms()) + .Where(x => !Rooms.Any(y => y.Room.RoomId == x.RoomId)) + .Select(async room => { + var state = await room.GetFullStateAsListAsync(); + var policies = state + .Where(x => knownPolicyTypes.Contains(x.Type)) + .ToList(); + if (policies.Count == 0) return null; + Status2 = $"Found legacy list {room.RoomId}..."; + return await RoomInfo.FromRoom(room, state, true); + }) + .ToAsyncEnumerable(); + + await foreach (var room in rooms) { + if (room is not null) { + Rooms.Add(room); + StateHasChanged(); + } + } + + Status = ""; + Status2 = ""; + await base.OnInitializedAsync(); + } + + private string _status; + + public string Status { + get => _status; + set { + _status = value; + StateHasChanged(); + } + } + + private string _status2; + + public string Status2 { + get => _status2; + set { + _status2 = value; + StateHasChanged(); + } + } + + private class RoomInfo { + public GenericRoom Room { get; set; } + public string RoomName { get; set; } + public string? Shortcode { get; set; } + public Dictionary PolicyCounts { get; set; } + public bool IsLegacy { get; set; } + + public enum PolicyType { + User, + Room, + Server + } + + private static readonly List userEventTypes = EventContent.GetMatchingEventTypes(); + private static readonly List serverEventTypes = EventContent.GetMatchingEventTypes(); + private static readonly List roomEventTypes = EventContent.GetMatchingEventTypes(); + private static readonly List allKnownPolicyTypes = [..userEventTypes, ..serverEventTypes, ..roomEventTypes]; + + public static async Task FromRoom(GenericRoom room, List? state = null, bool legacy = false) { + state ??= await room.GetFullStateAsListAsync(); + return new RoomInfo() { + Room = room, + IsLegacy = legacy, + RoomName = await room.GetNameAsync() + ?? (await room.GetCanonicalAliasAsync())?.Alias + ?? (await room.GetStateOrNullAsync(MjolnirShortcodeEventContent.EventId))?.Shortcode + ?? room.RoomId, + Shortcode = (await room.GetStateOrNullAsync(MjolnirShortcodeEventContent.EventId))?.Shortcode, + PolicyCounts = new() { + { PolicyType.User, state.Count(x => userEventTypes.Contains(x.Type)) }, + { PolicyType.Server, state.Count(x => serverEventTypes.Contains(x.Type)) }, + { PolicyType.Room, state.Count(x => roomEventTypes.Contains(x.Type)) } + } + }; + } + } + +} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor.css b/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor.css new file mode 100644 index 0000000..f9b5b3f --- /dev/null +++ b/MatrixUtils.Web/Pages/Rooms/PolicyLists.razor.css @@ -0,0 +1,6 @@ +table, th, td { + border-width: 1px; +} +td { + padding: 8px; +} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/Rooms/Space.razor b/MatrixUtils.Web/Pages/Rooms/Space.razor index 8153224..088fdcd 100644 --- a/MatrixUtils.Web/Pages/Rooms/Space.razor +++ b/MatrixUtils.Web/Pages/Rooms/Space.razor @@ -6,6 +6,9 @@ @using MatrixUtils.Abstractions

Room manager - Viewing Space

+Add new room to space: + + @foreach (var room in Rooms) { @@ -31,6 +34,7 @@ private StateEventResponse[] States { get; set; } = Array.Empty(); private List Rooms { get; } = new(); private List ServersInSpace { get; } = new(); + private string? NewRoomId { get; set; } protected override async Task OnInitializedAsync() { var hs = await RMUStorage.GetCurrentSessionOrNavigate(); @@ -123,7 +127,7 @@ var ce = await room.GetCreateEventAsync(); if(ce is null) continue; if (ce.Type == "m.space") { - var children = room.AsSpace.GetChildrenAsync(true); + var children = room.AsSpace.GetChildrenAsync(false); await foreach (var child in children) { JoinRecursive(child.RoomId); } @@ -137,4 +141,9 @@ } + private async Task AddNewRoom() { + if (string.IsNullOrWhiteSpace(NewRoomId)) return; + await Room.AsSpace.AddChildByIdAsync(NewRoomId); + } + } diff --git a/MatrixUtils.Web/Pages/Tools/Info/PolicyListActivity.razor b/MatrixUtils.Web/Pages/Tools/Info/PolicyListActivity.razor index f2af9b5..e093db2 100644 --- a/MatrixUtils.Web/Pages/Tools/Info/PolicyListActivity.razor +++ b/MatrixUtils.Web/Pages/Tools/Info/PolicyListActivity.razor @@ -140,7 +140,7 @@ else var rgb = RoomData[roomName][date.Year][date]; if (message.RawContent?.Count == 0) rgb.R++; - else if (string.IsNullOrWhiteSpace(message.Unsigned?.ReplacesState)) rgb.G++; + else if (message.Unsigned?.ContainsKey("replaces_state") ?? false) rgb.G++; else rgb.B++; RoomData[roomName][date.Year][date] = rgb; } diff --git a/MatrixUtils.Web/Shared/NavMenu.razor b/MatrixUtils.Web/Shared/NavMenu.razor index 770a246..7371e66 100644 --- a/MatrixUtils.Web/Shared/NavMenu.razor +++ b/MatrixUtils.Web/Shared/NavMenu.razor @@ -36,6 +36,12 @@ + +