@using LibMatrix.RoomTypes
@using LibMatrix.EventTypes.Spec.State
@using ArcaneLibs.Extensions
@using MatrixUtils.Abstractions
DM Space setup tool - stage 2: Fix DM room attribution
This is just to make sure that your DMs are attributed to the right person!
@if (!string.IsNullOrWhiteSpace(Status)) {
@Status
}
@if (SetupData is not null) {
if (SetupData.DMRooms is { Count: > 0 }) {
@foreach (var (userId, room) in SetupData.DMRooms.OrderBy(x => x.Key.Id)) {
@foreach (var roomInfo in room) {
Reassign
}
}
}
else {
DM room list is loading, please wait...
}
}
else {
Error: DMSpaceRootPage is null!
}
Next
@{
var _offset = 0;
}
@foreach (var (room, usersList) in duplicateDmRooms) {
Found room assigned to multiple users:
Users:
@foreach (var userProfileResponse in usersList) {
Assign to
}
}
@if (DmToReassign is not null) {
@foreach (var userProfileResponse in roomMembers[DmToReassign]) {
Assign to
}
}
@code {
private string newMxid { get; set; } = "";
private RoomInfo? DmToReassign {
get => _dmToReassign;
set {
_dmToReassign = value;
StateHasChanged();
}
}
private string? Status {
get => _status;
set {
_status = value;
StateHasChanged();
}
}
private string? _status;
private RoomInfo? _dmToReassign;
[CascadingParameter]
public DMSpace.DMSpaceSetupData SetupData { get; set; }
private Dictionary> duplicateDmRooms { get; set; } = new();
private Dictionary> roomMembers { get; set; } = new();
SemaphoreSlim _semaphore = new(1, 1);
protected override async Task OnInitializedAsync() {
if (SetupData is null)
return;
await _semaphore.WaitAsync();
DmToReassign = null;
var hs = SetupData.Homeserver;
Status = "Loading DM list from account data...";
var dms = await SetupData.Homeserver.GetAccountDataAsync>>("m.direct");
Status = "Optimising DM list from account data...";
var joinedRooms = (await hs.GetJoinedRooms()).Select(x => x.RoomId).ToList();
foreach (var (user, rooms) in dms) {
for (var i = rooms.Count - 1; i >= 0; i--) {
var roomId = rooms[i];
if (!joinedRooms.Contains(roomId))
rooms.RemoveAt(i);
}
dms[user] = rooms.Distinct().ToList();
}
dms.RemoveAll((x, y) => y is { Count: 0 });
await SetupData.Homeserver.SetAccountDataAsync("m.direct", dms);
Status = "DM list optimised, fetching info...";
SetupData.DMRooms = new Dictionary>();
var results = dms.Select(async x => {
var (userId, rooms) = x;
DMSpace.DMSpaceSetupData.UserProfileWithId userProfile;
try {
var profile = await SetupData.Homeserver.GetProfileAsync(userId);
userProfile = new() {
AvatarUrl = profile.AvatarUrl,
Id = userId,
DisplayName = profile.DisplayName
};
}
catch {
userProfile = new() {
AvatarUrl = "mxc://feline.support/uUxBwaboPkMGtbZcAGZaIzpK",
DisplayName = userId,
Id = userId
};
}
var roomList = new List();
var tasks = rooms.Select(x => GetRoomInfo(hs.GetRoom(x))).ToAsyncEnumerable();
await foreach (var result in tasks)
roomList.Add(result);
return (userProfile, roomList);
// StateHasChanged();
}).ToAsyncEnumerable();
await foreach (var res in results) {
SetupData.DMRooms.Add(res.userProfile, res.roomList);
// Status = $"Listed {dmRooms.Count} users";
}
_semaphore.Release();
var duplicateDmRoomIds = new Dictionary>();
foreach (var (user, rooms) in SetupData.DMRooms) {
foreach (var roomInfo in rooms) {
if (!duplicateDmRoomIds.ContainsKey(roomInfo.Room.RoomId))
duplicateDmRoomIds.Add(roomInfo.Room.RoomId, new());
duplicateDmRoomIds[roomInfo.Room.RoomId].Add(user);
}
}
duplicateDmRoomIds.RemoveAll((x, y) => y.Count == 1);
foreach (var (roomId, users) in duplicateDmRoomIds) {
duplicateDmRooms.Add(SetupData.DMRooms.First(x => x.Value.Any(x => x.Room.RoomId == roomId)).Value.First(x => x.Room.RoomId == roomId), users);
}
// StateHasChanged();
Status = null;
await base.OnParametersSetAsync();
}
private async Task Execute() {
NavigationManager.NavigateTo("/User/DMSpace/Setup?stage=3");
}
private async Task GetRoomInfo(GenericRoom room) {
var roomInfo = new RoomInfo(room);
await roomInfo.FetchAllStateAsync();
roomMembers[roomInfo] = new();
// roomInfo.CreationEventContent = await room.GetCreateEventAsync();
if(roomInfo.RoomName == room.RoomId)
try {
roomInfo.RoomName = await room.GetNameOrFallbackAsync();
}
catch { }
var membersEnum = room.GetMembersEnumerableAsync(true);
await foreach (var member in membersEnum)
if (member.TypedContent is RoomMemberEventContent memberEvent)
roomMembers[roomInfo].Add(new() { DisplayName = memberEvent.DisplayName, AvatarUrl = memberEvent.AvatarUrl, Id = member.StateKey });
try {
string? roomIcon = (await room.GetAvatarUrlAsync())?.Url;
if (room is not null)
roomInfo.RoomIcon = roomIcon;
}
catch { }
return roomInfo;
}
private async Task> GetRoomInfoForRooms(List rooms) {
var tasks = rooms.Select(GetRoomInfo).ToList();
await Task.WhenAll(tasks);
return tasks.Select(x => x.Result).ToList();
}
private async Task SetRoomAssignment(string roomId, string userId) {
var hs = SetupData.Homeserver;
Status = "Loading DM list from account data...";
var dms = await SetupData.Homeserver.GetAccountDataAsync>>("m.direct");
Status = "Updating DM list from account data...";
foreach (var (user, rooms) in dms) {
rooms.RemoveAll(x => x == roomId);
dms[user] = rooms.Distinct().ToList();
}
if (!dms.ContainsKey(userId))
dms.Add(userId, new());
dms[userId].Add(roomId);
dms.RemoveAll((x, y) => y is { Count: 0 });
await SetupData.Homeserver.SetAccountDataAsync("m.direct", dms);
duplicateDmRooms.RemoveAll((x, y) => x.Room.RoomId == roomId);
StateHasChanged();
if (duplicateDmRooms.Count == 0) await OnParametersSetAsync();
}
}