@page "/Tools/UserTrace" @using ArcaneLibs.Extensions @using LibMatrix.RoomTypes @using System.Collections.ObjectModel @using LibMatrix @using System.Collections.Frozen @using LibMatrix.EventTypes.Spec.State @using MatrixUtils.Abstractions

User Trace


Users:


Import from room (ID)
Rooms to be searched (@rooms.Count) @foreach (var room in rooms) { @room.Room.RoomId
}

Execute
Results @foreach (var (userId, events) in matches) {

@userId

}

@foreach (var line in log.Reverse()) {
@line
} @code { private ObservableCollection log { get; set; } = new(); List rooms { get; set; } = new(); Dictionary> matches = new(); private string UserIdString { get => string.Join("\n", UserIDs); set => UserIDs = value.Split("\n").Select(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); } private List UserIDs { get; set; } = new(); protected override async Task OnInitializedAsync() { log.CollectionChanged += (sender, args) => StateHasChanged(); var hs = await RMUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; var sessions = await RMUStorage.GetAllTokens(); var baseRooms = new List(); foreach (var userAuth in sessions) { var session = await RMUStorage.GetSession(userAuth); if (session is not null) { baseRooms.AddRange(await session.GetJoinedRooms()); var sessionRooms = (await session.GetJoinedRooms()).Where(x => !rooms.Any(y => y.Room.RoomId == x.RoomId)).ToList(); StateHasChanged(); log.Add($"Got {sessionRooms.Count} rooms for {userAuth.UserId}"); } } log.Add("Done fetching rooms!"); baseRooms = baseRooms.DistinctBy(x => x.RoomId).ToList(); // rooms.CollectionChanged += (sender, args) => StateHasChanged(); var tasks = baseRooms.Select(async newRoom => { bool success = false; while (!success) try { var state = await newRoom.GetFullStateAsListAsync(); var newRoomInfo = new RoomInfo(newRoom, state); rooms.Add(newRoomInfo); log.Add($"Got {newRoomInfo.StateEvents.Count} events for {newRoomInfo.RoomName}"); success = true; } catch (MatrixException e) { log.Add($"Failed to fetch room {newRoom.RoomId}! {e}"); throw; } catch (HttpRequestException e) { log.Add($"Failed to fetch room {newRoom.RoomId}! {e}"); } }); await Task.WhenAll(tasks); log.Add($"Done fetching members!"); UserIDs.RemoveAll(x => sessions.Any(y => y.UserId == x)); StateHasChanged(); Console.WriteLine("Rerendered!"); await base.OnInitializedAsync(); } private async Task Execute() { foreach (var userId in UserIDs) { matches.Add(userId, new List()); foreach (var room in rooms) { var state = room.StateEvents.Where(x => x!.Type == RoomMemberEventContent.EventId).ToList(); if (state!.Any(x => x.StateKey == userId)) { matches[userId].Add(new() { Event = state.First(x => x.StateKey == userId), Room = room.Room, RoomName = room.RoomName ?? "No name" }); } } } StateHasChanged(); return ""; } public string? ImportFromRoomId { get; set; } private async Task DoImportFromRoomId() { try { if (ImportFromRoomId is null) return; var room = rooms.FirstOrDefault(x => x.Room.RoomId == ImportFromRoomId); UserIdString = string.Join("\n", (await room.Room.GetMembersListAsync()).Select(x => x.StateKey)); } catch (Exception e) { Console.WriteLine(e); log.Add("Could not fetch members list!\n" + e.ToString()); } StateHasChanged(); } private class Match { public GenericRoom Room; public StateEventResponse Event; public string RoomName { get; set; } } }