about summary refs log tree commit diff
path: root/MatrixRoomUtils.LibDMSpace
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixRoomUtils.LibDMSpace')
-rw-r--r--MatrixRoomUtils.LibDMSpace/DMSpaceConfiguration.cs12
-rw-r--r--MatrixRoomUtils.LibDMSpace/DMSpaceRoom.cs83
-rw-r--r--MatrixRoomUtils.LibDMSpace/MatrixRoomUtils.LibDMSpace.csproj16
-rw-r--r--MatrixRoomUtils.LibDMSpace/StateEvents/DMRoomInfo.cs14
-rw-r--r--MatrixRoomUtils.LibDMSpace/StateEvents/DMSpaceInfo.cs14
5 files changed, 139 insertions, 0 deletions
diff --git a/MatrixRoomUtils.LibDMSpace/DMSpaceConfiguration.cs b/MatrixRoomUtils.LibDMSpace/DMSpaceConfiguration.cs
new file mode 100644
index 0000000..4085367
--- /dev/null
+++ b/MatrixRoomUtils.LibDMSpace/DMSpaceConfiguration.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace MatrixRoomUtils.LibDMSpace;
+
+//gay.rory.dm_space
+public class DMSpaceConfiguration {
+    public const string EventId = "gay.rory.dm_space";
+
+    [JsonPropertyName("dm_space_id")]
+    public string? DMSpaceId { get; set; }
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.LibDMSpace/DMSpaceRoom.cs b/MatrixRoomUtils.LibDMSpace/DMSpaceRoom.cs
new file mode 100644
index 0000000..247ace8
--- /dev/null
+++ b/MatrixRoomUtils.LibDMSpace/DMSpaceRoom.cs
@@ -0,0 +1,83 @@
+using ArcaneLibs.Extensions;
+using LibMatrix;
+using LibMatrix.Homeservers;
+using LibMatrix.RoomTypes;
+using MatrixRoomUtils.LibDMSpace.StateEvents;
+
+namespace MatrixRoomUtils.LibDMSpace;
+
+public class DMSpaceRoom(AuthenticatedHomeserverGeneric homeserver, string roomId) : SpaceRoom(homeserver, roomId) {
+    private readonly GenericRoom _room;
+
+    public async Task<DMSpaceInfo?> GetDmSpaceInfo() {
+        return await GetStateOrNullAsync<DMSpaceInfo>(DMSpaceInfo.EventId);
+    }
+
+    public async IAsyncEnumerable<GenericRoom> GetChildrenAsync(bool includeRemoved = false) {
+        var rooms = new List<GenericRoom>();
+        var state = GetFullStateAsync();
+        await foreach (var stateEvent in state) {
+            if (stateEvent!.Type != "m.space.child") continue;
+            if (stateEvent.RawContent!.ToJson() != "{}" || includeRemoved)
+                yield return homeserver.GetRoom(stateEvent.StateKey);
+        }
+    }
+
+    public async Task<EventIdResponse> AddChildAsync(GenericRoom room) {
+        var members = room.GetMembersAsync(true);
+        Dictionary<string, int> memberCountByHs = new();
+        await foreach (var member in members) {
+            var server = member.StateKey.Split(':')[1];
+            if (memberCountByHs.ContainsKey(server)) memberCountByHs[server]++;
+            else memberCountByHs[server] = 1;
+        }
+
+        var resp = await SendStateEventAsync("m.space.child", room.RoomId, new {
+            via = memberCountByHs
+                .OrderByDescending(x => x.Value)
+                .Select(x => x.Key)
+                .Take(10)
+        });
+        return resp;
+    }
+
+    public async Task ImportNativeDMs() {
+        var dmSpaceInfo = await GetDmSpaceInfo();
+        if (dmSpaceInfo is null) throw new NullReferenceException("DM Space is not configured!");
+        if (dmSpaceInfo.LayerByUser)
+            await ImportNativeDMsIntoLayers();
+        else await ImportNativeDMsWithoutLayers();
+    }
+
+#region Import Native DMs
+
+    private async Task ImportNativeDMsWithoutLayers() {
+        var mdirect = await homeserver.GetAccountDataAsync<Dictionary<string, List<string>>>("m.direct");
+        foreach (var (userId, dmRooms) in mdirect) {
+            foreach (var roomid in dmRooms) {
+                var dri = new DMRoomInfo() {
+                    RemoteUsers = new() {
+                        userId
+                    }
+                };
+                // Add all DM room members
+                var members = homeserver.GetRoom(roomid).GetMembersAsync();
+                await foreach (var member in members)
+                    if (member.StateKey != userId)
+                        dri.RemoteUsers.Add(member.StateKey);
+                // Remove members of DM space
+                members = GetMembersAsync();
+                await foreach (var member in members)
+                    if (dri.RemoteUsers.Contains(member.StateKey))
+                        dri.RemoteUsers.Remove(member.StateKey);
+                await SendStateEventAsync(DMRoomInfo.EventId, roomid, dri);
+            }
+        }
+    }
+
+    private async Task ImportNativeDMsIntoLayers() {
+        var mdirect = await homeserver.GetAccountDataAsync<Dictionary<string, List<string>>>("m.direct");
+    }
+
+#endregion
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.LibDMSpace/MatrixRoomUtils.LibDMSpace.csproj b/MatrixRoomUtils.LibDMSpace/MatrixRoomUtils.LibDMSpace.csproj
new file mode 100644
index 0000000..70b4ffc
--- /dev/null
+++ b/MatrixRoomUtils.LibDMSpace/MatrixRoomUtils.LibDMSpace.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>net7.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <LangVersion>preview</LangVersion>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <ProjectReference Condition="Exists('..\ArcaneLibs\ArcaneLibs.Blazor.Components\ArcaneLibs.Blazor.Components.csproj')" Include="..\ArcaneLibs\ArcaneLibs.Blazor.Components\ArcaneLibs.Blazor.Components.csproj"/>
+        <PackageReference Condition="!Exists('..\ArcaneLibs\ArcaneLibs.Blazor.Components\ArcaneLibs.Blazor.Components.csproj')" Include="ArcaneLibs" Version="*-preview*"/>
+        <ProjectReference Include="..\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj" />
+        <ProjectReference Include="..\LibMatrix\LibMatrix\LibMatrix.csproj"/>
+    </ItemGroup>
+</Project>
diff --git a/MatrixRoomUtils.LibDMSpace/StateEvents/DMRoomInfo.cs b/MatrixRoomUtils.LibDMSpace/StateEvents/DMRoomInfo.cs
new file mode 100644
index 0000000..b88f06a
--- /dev/null
+++ b/MatrixRoomUtils.LibDMSpace/StateEvents/DMRoomInfo.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+using LibMatrix.EventTypes;
+using LibMatrix.Interfaces;
+
+namespace MatrixRoomUtils.LibDMSpace.StateEvents; 
+
+[MatrixEvent(EventName = EventId)]
+public class DMRoomInfo : EventContent {
+    public const string EventId = "gay.rory.dm_room_info";
+    [JsonPropertyName("remote_users")]
+    public List<string> RemoteUsers { get; set; }
+    
+    
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.LibDMSpace/StateEvents/DMSpaceInfo.cs b/MatrixRoomUtils.LibDMSpace/StateEvents/DMSpaceInfo.cs
new file mode 100644
index 0000000..7824324
--- /dev/null
+++ b/MatrixRoomUtils.LibDMSpace/StateEvents/DMSpaceInfo.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+using LibMatrix.EventTypes;
+using LibMatrix.Interfaces;
+
+namespace MatrixRoomUtils.LibDMSpace.StateEvents; 
+
+[MatrixEvent(EventName = EventId)]
+public class DMSpaceInfo : EventContent {
+    public const string EventId = "gay.rory.dm_space_info";
+
+    [JsonPropertyName("is_layered")]
+    public bool LayerByUser { get; set; }
+    
+}
\ No newline at end of file