about summary refs log tree commit diff
path: root/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor')
-rw-r--r--MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor240
1 files changed, 240 insertions, 0 deletions
diff --git a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
new file mode 100644
index 0000000..a70e9c5
--- /dev/null
+++ b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
@@ -0,0 +1,240 @@
+@using LibMatrix.Homeservers
+@using LibMatrix.RoomTypes
+@using LibMatrix
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.Responses
+@using MatrixUtils.LibDMSpace
+@using MatrixUtils.LibDMSpace.StateEvents
+@using ArcaneLibs.Extensions
+@using System.Text.Json.Serialization
+@using MatrixUtils.Abstractions
+<b>
+    <u>DM Space setup tool - stage 2: Fix DM room attribution</u>
+</b>
+<p>This is just to make sure that your DMs are attributed to the right person!</p>
+
+@if (!string.IsNullOrWhiteSpace(Status)) {
+    <p>@Status</p>
+}
+
+@if (SetupData is not null) {
+    if (SetupData.DMRooms is { Count: > 0 }) {
+        @foreach (var (userId, room) in SetupData.DMRooms.OrderBy(x => x.Key.Id)) {
+            <InlineUserItem User="@userId"></InlineUserItem>
+            @foreach (var roomInfo in room) {
+                <RoomListItem RoomInfo="@roomInfo">
+                    <LinkButton Round="true" OnClick="@(async () => DmToReassign = roomInfo)">Reassign</LinkButton>
+                </RoomListItem>
+            }
+        }
+    }
+    else {
+        <p>DM room list is loading, please wait...</p>
+    }
+}
+else {
+    <b>Error: DMSpaceRootPage is null!</b>
+}
+
+<br/>
+<LinkButton OnClick="@Execute">Next</LinkButton>
+
+@{
+    var _offset = 0;
+}
+@foreach (var (room, usersList) in duplicateDmRooms) {
+    <ModalWindow Title="Duplicate room found" X="_offset += 30" Y="_offset">
+        <p>Found room assigned to multiple users: <RoomListItem RoomInfo="@room"></RoomListItem></p>
+        <p>Users:</p>
+        @foreach (var userProfileResponse in usersList) {
+            <LinkButton OnClick="@(() => SetRoomAssignment(room.Room.RoomId, userProfileResponse.Id))">
+                <span>Assign to </span>
+                <InlineUserItem User="userProfileResponse"></InlineUserItem>
+            </LinkButton>
+            <br/>
+        }
+    </ModalWindow>
+}
+
+@if (DmToReassign is not null) {
+    <ModalWindow Title="Re-assign DM" OnCloseClicked="@(() => DmToReassign = null)">
+        <RoomListItem RoomInfo="@DmToReassign"></RoomListItem>
+        @foreach (var userProfileResponse in roomMembers[DmToReassign]) {
+            <LinkButton OnClick="@(() => SetRoomAssignment(DmToReassign.Room.RoomId, userProfileResponse.Id))">
+                <span>Assign to </span>
+                <InlineUserItem User="userProfileResponse"></InlineUserItem>
+            </LinkButton>
+            <br/>
+        }
+    </ModalWindow>
+}
+
+@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<RoomInfo, List<DMSpace.DMSpaceSetupData.UserProfileWithId>> duplicateDmRooms { get; set; } = new();
+    private Dictionary<RoomInfo, List<DMSpace.DMSpaceSetupData.UserProfileWithId>> 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<Dictionary<string, List<string>>>("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<DMSpace.DMSpaceSetupData.UserProfileWithId, List<RoomInfo>>();
+
+        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<RoomInfo>();
+            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<string, List<DMSpace.DMSpaceSetupData.UserProfileWithId>>();
+        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<RoomInfo> 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<List<RoomInfo>> GetRoomInfoForRooms(List<GenericRoom> 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<Dictionary<string, List<string>>>("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();
+    }
+
+}