about summary refs log tree commit diff
path: root/LibMatrix/RoomTypes
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix/RoomTypes')
-rw-r--r--LibMatrix/RoomTypes/GenericRoom.cs76
1 files changed, 54 insertions, 22 deletions
diff --git a/LibMatrix/RoomTypes/GenericRoom.cs b/LibMatrix/RoomTypes/GenericRoom.cs
index 96bcefd..700e530 100644
--- a/LibMatrix/RoomTypes/GenericRoom.cs
+++ b/LibMatrix/RoomTypes/GenericRoom.cs
@@ -1,7 +1,9 @@
+using System.Diagnostics;
 using System.Net.Http.Json;
 using System.Text.Json;
 using System.Text.Json.Serialization;
 using System.Web;
+using ArcaneLibs.Extensions;
 using LibMatrix.EventTypes.Spec;
 using LibMatrix.EventTypes.Spec.State;
 using LibMatrix.Extensions;
@@ -96,22 +98,23 @@ public class GenericRoom {
         return await res.Content.ReadFromJsonAsync<RoomIdResponse>() ?? throw new Exception("Failed to join room?");
     }
 
-    
     public async IAsyncEnumerable<StateEventResponse> GetMembersAsync(bool joinedOnly = true) {
-        // var res = GetFullStateAsync();
-        // await foreach (var member in res) {
-        //     if (member?.Type != "m.room.member") continue;
-        //     if (joinedOnly && (member.TypedContent as RoomMemberEventContent)?.Membership is not "join") continue;
-        //     yield return member;
-        // }
+        var sw = Stopwatch.StartNew();
         var res = await _httpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/members");
+        Console.WriteLine($"Members call responded in {sw.GetElapsedAndRestart()}");
         var resText = await res.Content.ReadAsStringAsync();
-        var result = await JsonSerializer.DeserializeAsync<ChunkedStateEventResponse>(await res.Content.ReadAsStreamAsync());
+        Console.WriteLine($"Members call response read in {sw.GetElapsedAndRestart()}");
+        var result = await JsonSerializer.DeserializeAsync<ChunkedStateEventResponse>(await res.Content.ReadAsStreamAsync(), new JsonSerializerOptions() {
+            TypeInfoResolver = ChunkedStateEventResponseSerializerContext.Default
+        });
+        Console.WriteLine($"Members call deserialised in {sw.GetElapsedAndRestart()}");
         foreach (var resp in result.Chunk) {
             if (resp?.Type != "m.room.member") continue;
             if (joinedOnly && (resp.TypedContent as RoomMemberEventContent)?.Membership is not "join") continue;
             yield return resp;
         }
+
+        Console.WriteLine($"Members call iterated in {sw.GetElapsedAndRestart()}");
     }
 
 #region Utility shortcuts
@@ -153,7 +156,7 @@ public class GenericRoom {
     public async Task<RoomPowerLevelEventContent?> GetPowerLevelsAsync() =>
         await GetStateAsync<RoomPowerLevelEventContent>("m.room.power_levels");
 
-    public async Task<string> GetNameOrFallbackAsync() {
+    public async Task<string> GetNameOrFallbackAsync(int maxMemberNames = 2) {
         try {
             return await GetNameAsync();
         }
@@ -166,8 +169,9 @@ public class GenericRoom {
                     memberList.Add((member.TypedContent is RoomMemberEventContent memberEvent ? memberEvent.DisplayName : "") ?? "");
                 memberCount = memberList.Count;
                 memberList.RemoveAll(string.IsNullOrWhiteSpace);
-                if (memberList.Count >= 3)
-                    return string.Join(", ", memberList.Take(2)) + " and " + (memberCount - 2) + " others.";
+                memberList = memberList.OrderBy(x => x).ToList();
+                if (memberList.Count > maxMemberNames)
+                    return string.Join(", ", memberList.Take(maxMemberNames)) + " and " + (memberCount - maxMemberNames) + " others.";
                 return string.Join(", ", memberList);
             }
             catch {
@@ -176,8 +180,15 @@ public class GenericRoom {
         }
     }
 
+    public async Task InviteUsersAsync(IEnumerable<string> users, string? reason = null, bool skipExisting = true) {
+        var tasks = users.Select(x => InviteUserAsync(x, reason, skipExisting)).ToList();
+        await Task.WhenAll(tasks);
+    }
+
 #endregion
 
+#region Simple calls
+
     public async Task ForgetAsync() =>
         await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null);
 
@@ -198,6 +209,16 @@ public class GenericRoom {
         await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban",
             new UserIdAndReason { UserId = userId });
 
+    public async Task InviteUserAsync(string userId, string? reason = null, bool skipExisting = true) {
+        if (skipExisting && await GetStateAsync<RoomMemberEventContent>("m.room.member", userId) is not null)
+            return;
+        await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason));
+    }
+
+#endregion
+
+#region Events
+
     public async Task<EventIdResponse?> SendStateEventAsync(string eventType, object content) =>
         await (await _httpClient.PutAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content))
             .Content.ReadFromJsonAsync<EventIdResponse>();
@@ -243,8 +264,6 @@ public class GenericRoom {
         }
     }
 
-    public readonly SpaceRoom AsSpace;
-
     public async Task<T> GetEventAsync<T>(string eventId) {
         return await _httpClient.GetFromJsonAsync<T>($"/_matrix/client/v3/rooms/{RoomId}/event/{eventId}");
     }
@@ -255,12 +274,30 @@ public class GenericRoom {
             $"/_matrix/client/v3/rooms/{RoomId}/redact/{eventToRedact}/{Guid.NewGuid()}", data)).Content.ReadFromJsonAsync<EventIdResponse>())!;
     }
 
-    public async Task InviteUserAsync(string userId, string? reason = null, bool skipExisting = true) {
-        if (skipExisting && await GetStateAsync<RoomMemberEventContent>("m.room.member", userId) is not null)
-            return;
-        await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/invite", new UserIdAndReason(userId, reason));
+#endregion
+
+#region Utilities
+
+    public async Task<Dictionary<string, List<string>>> GetMembersByHomeserverAsync(bool joinedOnly = true) {
+        if (Homeserver is AuthenticatedHomeserverMxApiExtended mxaeHomeserver)
+            return await Homeserver.ClientHttpClient.GetFromJsonAsync<Dictionary<string, List<string>>>(
+                $"/_matrix/client/v3/rooms/{RoomId}/members_by_homeserver?joined_only={joinedOnly}");
+        Dictionary<string, List<string>> roomHomeservers = new();
+        var members = GetMembersAsync();
+        await foreach (var member in members) {
+            string memberHs = member.StateKey.Split(':', 2)[1];
+            roomHomeservers.TryAdd(memberHs, new());
+            roomHomeservers[memberHs].Add(member.StateKey);
+        }
+
+        Console.WriteLine($"Finished processing {RoomId}");
+        return roomHomeservers;
     }
 
+#endregion
+
+    public readonly SpaceRoom AsSpace;
+
 #region Disband room
 
     public async Task DisbandRoomAsync() {
@@ -289,11 +326,6 @@ public class GenericRoom {
     }
 
 #endregion
-
-    public async Task InviteUsersAsync(IEnumerable<string> users, string? reason = null, bool skipExisting = true) {
-        var tasks = users.Select(x => InviteUserAsync(x, reason, skipExisting)).ToList();
-        await Task.WhenAll(tasks);
-    }
 }
 
 public class RoomIdResponse {