@page "/Rooms"
@using LibMatrix.StateEventTypes
@using LibMatrix.StateEventTypes.Spec
@using LibMatrix.Filters
@using LibMatrix.Helpers
@using LibMatrix.Responses
Room list
@Status
@if (RenderContents) {
}
@code {
public List KnownRooms { get; set; } = new();
private List Rooms { get; set; } = new();
private ProfileResponseEventData GlobalProfile { get; set; }
private SyncFilter filter = new() {
AccountData = new() {
NotTypes = new() { "*" },
Limit = 1
},
Presence = new() {
NotTypes = new() { "*" },
Limit = 1
},
Room = new() {
AccountData = new() {
NotTypes = new() { "*" },
Limit = 1
},
Ephemeral = new() {
NotTypes = new() { "*" },
Limit = 1
},
State = new() {
Types = new List() {
"m.room.name",
"m.room.avatar",
"m.room.create",
"org.matrix.mjolnir.shortcode",
"m.room.power_levels"
}
},
Timeline = new() {
NotTypes = new() { "*" },
Limit = 1
}
}
};
protected override async Task OnInitializedAsync() {
var hs = await MRUStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
GlobalProfile = await hs.GetProfile(hs.WhoAmI.UserId);
Status = "Syncing...";
SyncResult? sync = null;
string? nextBatch = null;
while (sync is null or { Rooms.Join.Count: >= 1}) {
sync = await hs.SyncHelper.Sync(since: nextBatch, filter: filter, timeout: 0);
nextBatch = sync?.NextBatch ?? nextBatch;
if (sync is null) continue;
Console.WriteLine($"Got sync, next batch: {nextBatch}!");
if (sync.Rooms is null) continue;
if (sync.Rooms.Join is null) continue;
foreach (var (roomId, roomData) in sync.Rooms.Join) {
RoomInfo room;
if (Rooms.Any(x => x.Room.RoomId == roomId)) {
room = Rooms.First(x => x.Room.RoomId == roomId);
}
else {
room = new RoomInfo() {
Room = await hs.GetRoom(roomId),
StateEvents = new()
};
Rooms.Add(room);
KnownRooms.Add(room);
}
room.StateEvents.AddRange(roomData.State.Events);
}
Status = $"Got {Rooms.Count} rooms so far! Next batch: {nextBatch}";
StateHasChanged();
await Task.Delay(100);
}
Console.WriteLine("Sync done!");
Status = "Sync complete!";
foreach (var roomInfo in Rooms) {
if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.name")) {
roomInfo.StateEvents.Add(new StateEventResponse() {
Type = "m.room.name",
TypedContent = new RoomNameEventData() {
Name = roomInfo.Room.RoomId
}
});
}
if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.avatar")) {
roomInfo.StateEvents.Add(new StateEventResponse() {
Type = "m.room.avatar",
TypedContent = new RoomAvatarEventData() {
}
});
}
if (!roomInfo.StateEvents.Any(x => x.Type == "org.matrix.mjolnir.shortcode")) {
roomInfo.StateEvents.Add(new StateEventResponse() {
Type = "org.matrix.mjolnir.shortcode"
});
}
}
Console.WriteLine("Set stub data!");
Status = "Set stub data!";
SemaphoreSlim semaphore = new(8, 8);
var memberTasks = Rooms.Select(async roomInfo => {
if (!roomInfo.StateEvents.Any(x => x.Type == "m.room.member" && x.StateKey == hs.WhoAmI.UserId)) {
await semaphore.WaitAsync();
roomInfo.StateEvents.Add(new StateEventResponse() {
Type = "m.room.member",
StateKey = hs.WhoAmI.UserId,
TypedContent = await roomInfo.Room.GetStateAsync("m.room.member", hs.WhoAmI.UserId) ?? new RoomMemberEventData() {
Membership = "unknown"
}
});
semaphore.Release();
}
}).ToList();
await Task.WhenAll(memberTasks);
Console.WriteLine("Set all room member data!");
Status = "Set all room member data!";
// var res = await hs.SyncHelper.Sync(filter: filter);
// if (res is not null) {
// foreach (var (roomId, roomData) in res.Rooms.Join) {
// var room = new RoomInfo() {
// Room = await hs.GetRoom(roomId),
// StateEvents = roomData.State.Events.Where(x => x.Type == "m.room.member" && x.StateKey == hs.WhoAmI.UserId).ToList()
// };
// Rooms.Add(room);
// }
// }
// Rooms = (await hs.GetJoinedRooms()).Select(x => new RoomInfo() { Room = x }).ToList();
RenderContents = true;
Status = "";
await base.OnInitializedAsync();
}
private bool RenderContents { get; set; } = false;
private string _status;
public string Status {
get => _status;
set {
_status = value;
StateHasChanged();
}
}
}