@page "/PolicyLists" @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 name Policies
@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 sessionStore.GetCurrentHomeserver(navigateOnFailure: true); 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)) } } }; } } }