@page "/UserRoomHistory/{UserId}"
@using LibMatrix.Homeservers
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.RoomTypes
@using ArcaneLibs.Extensions
@using MatrixRoomUtils.Abstractions
UserRoomHistory
Enter mxid:
@if (string.IsNullOrWhiteSpace(UserId)) {
UserId is null!
}
else {
Checked @checkedRooms.Count so far...
@if (currentHs is not null) {
Checking rooms from @currentHs.UserId's perspective
}
else if (checkedRooms.Count > 1) {
Done!
}
@foreach (var (state, rooms) in matchingStates) {
@state
@foreach (var roomInfo in rooms) {
}
}
}
@code {
private string? _userId;
[Parameter]
public string? UserId {
get => _userId;
set {
_userId = value;
FindMember(value);
}
}
private List hss = new();
private AuthenticatedHomeserverGeneric? currentHs { get; set; }
protected override async Task OnInitializedAsync() {
var hs = await MRUStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
var sessions = await MRUStorage.GetAllTokens();
foreach (var userAuth in sessions) {
var session = await MRUStorage.GetSession(userAuth);
if (session is not null) {
hss.Add(session);
StateHasChanged();
}
}
StateHasChanged();
Console.WriteLine("Rerendered!");
await base.OnInitializedAsync();
if (!string.IsNullOrWhiteSpace(UserId)) FindMember(UserId);
}
public Dictionary> matchingStates = new();
public List checkedRooms = new();
private SemaphoreSlim _semaphoreSlim = new(1, 1);
public async Task FindMember(string mxid) {
await _semaphoreSlim.WaitAsync();
if (mxid != UserId) {
_semaphoreSlim.Release();
return; //abort if changed
}
matchingStates.Clear();
foreach (var homeserver in hss) {
currentHs = homeserver;
var rooms = await homeserver.GetJoinedRooms();
rooms.RemoveAll(x => checkedRooms.Contains(x.RoomId));
checkedRooms.AddRange(rooms.Select(x => x.RoomId));
var tasks = rooms.Select(x => GetMembershipAsync(x, mxid)).ToAsyncEnumerable();
await foreach (var (room, state) in tasks) {
if (state is null) continue;
if (!matchingStates.ContainsKey(state.Membership))
matchingStates.Add(state.Membership, new());
var roomInfo = new RoomInfo() {
Room = room
};
matchingStates[state.Membership].Add(roomInfo);
roomInfo.StateEvents.Add(new() {
Type = RoomNameEventContent.EventId,
TypedContent = new RoomNameEventContent() {
Name = await room.GetNameOrFallbackAsync(4)
},
RoomId = null, Sender = null, EventId = null //TODO implement
});
StateHasChanged();
if (mxid != UserId) {
_semaphoreSlim.Release();
return; //abort if changed
}
}
StateHasChanged();
}
currentHs = null;
StateHasChanged();
_semaphoreSlim.Release();
}
public async Task<(GenericRoom roomId, RoomMemberEventContent? content)> GetMembershipAsync(GenericRoom room, string mxid) {
return (room, await room.GetStateOrNullAsync(RoomMemberEventContent.EventId, mxid));
}
}