diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
index 916780e..b453d87 100644
--- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
+++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
@@ -669,5 +669,10 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver {
public required List<string> Aliases { get; set; }
}
+ public async Task<HttpResponseMessage> SetRoomDirectoryVisibilityAsync(string roomId, RoomDirectoryVisibilityResponse.VisibilityValue visibility)
+ => await ClientHttpClient.PostAsJsonAsync($"/_matrix/client/v3/directory/list/room/{HttpUtility.UrlEncode(roomId)}", new RoomDirectoryVisibilityResponse {
+ Visibility = visibility
+ });
+
#endregion
}
\ No newline at end of file
diff --git a/LibMatrix/Homeservers/FederationClient.cs b/LibMatrix/Homeservers/FederationClient.cs
index 9760e20..310fa93 100644
--- a/LibMatrix/Homeservers/FederationClient.cs
+++ b/LibMatrix/Homeservers/FederationClient.cs
@@ -10,7 +10,6 @@ public class FederationClient {
BaseAddress = new Uri(proxy?.TrimEnd('/') ?? federationEndpoint.TrimEnd('/')),
// Timeout = TimeSpan.FromSeconds(120) // TODO: Re-implement this
};
- if (proxy is not null) HttpClient.DefaultRequestHeaders.Add("MXAE_UPSTREAM", federationEndpoint);
}
public MatrixHttpClient HttpClient { get; set; }
@@ -18,6 +17,4 @@ public class FederationClient {
public async Task<ServerVersionResponse> GetServerVersionAsync() => await HttpClient.GetFromJsonAsync<ServerVersionResponse>("/_matrix/federation/v1/version");
public async Task<SignedObject<ServerKeysResponse>> GetServerKeysAsync() => await HttpClient.GetFromJsonAsync<SignedObject<ServerKeysResponse>>("/_matrix/key/v2/server");
-}
-
-
+}
\ No newline at end of file
diff --git a/LibMatrix/Homeservers/RemoteHomeServer.cs b/LibMatrix/Homeservers/RemoteHomeServer.cs
index af84be2..54f5937 100644
--- a/LibMatrix/Homeservers/RemoteHomeServer.cs
+++ b/LibMatrix/Homeservers/RemoteHomeServer.cs
@@ -23,7 +23,6 @@ public class RemoteHomeserver {
// Timeout = TimeSpan.FromSeconds(300) // TODO: Re-implement this
};
- if (proxy is not null) ClientHttpClient.DefaultRequestHeaders.Add("MXAE_UPSTREAM", serverName);
if (!string.IsNullOrWhiteSpace(wellKnownUris.Server))
FederationClient = new FederationClient(WellKnownUris.Server!, proxy);
Auth = new(this);
@@ -61,29 +60,54 @@ public class RemoteHomeserver {
return data ?? throw new InvalidOperationException($"Could not resolve alias {alias}");
}
- public Task<PublicRoomDirectoryResult> GetPublicRoomsAsync(int limit = 100, string? server = null, string? since = null) {
- var url = $"/_matrix/client/v3/publicRooms?limit={limit}";
- if (!string.IsNullOrWhiteSpace(server)) {
- url += $"&server={server}";
+ public async Task<PublicRoomDirectoryResult> GetPublicRoomsAsync(int limit = 100, string? server = null, string? since = null, string? thirdPartyInstanceId = null,
+ bool? includeAllNetworks = null, RoomDirectoryFilter? filter = null) {
+ if (thirdPartyInstanceId is null && includeAllNetworks is null && filter is null) {
+ var url = $"/_matrix/client/v3/publicRooms?limit={limit}";
+ if (!string.IsNullOrWhiteSpace(server)) {
+ url += $"&server={server}";
+ }
+
+ if (!string.IsNullOrWhiteSpace(since)) {
+ url += $"&since={since}";
+ }
+
+ return await ClientHttpClient.GetFromJsonAsync<PublicRoomDirectoryResult>(url);
}
- if (!string.IsNullOrWhiteSpace(since)) {
- url += $"&since={since}";
+ // this technically requires authentication... TODO: move to AuthenticatedHomeserver?
+ var postUrl = "/_matrix/client/v3/publicRooms";
+ if (!string.IsNullOrWhiteSpace(server)) {
+ postUrl += $"?server={HttpUtility.UrlEncode(server)}";
}
- return ClientHttpClient.GetFromJsonAsync<PublicRoomDirectoryResult>(url);
+ var postData = new RoomDirectoryFilteredRequest {
+ Limit = limit,
+ Since = since,
+ ThirdPartyInstanceId = thirdPartyInstanceId,
+ IncludeAllNetworks = includeAllNetworks,
+ Filter = filter
+ };
+
+ return await (await ClientHttpClient.PostAsJsonAsync(postUrl, postData)).EnsureSuccessStatusCode()
+ .Content.ReadFromJsonAsync<PublicRoomDirectoryResult>() ?? throw new InvalidOperationException();
}
- public async IAsyncEnumerable<PublicRoomDirectoryResult> EnumeratePublicRoomsAsync(int limit = int.MaxValue, string? server = null, string? since = null, int chunkSize = 100) {
+ public async IAsyncEnumerable<PublicRoomDirectoryResult> EnumeratePublicRoomsAsync(int limit = int.MaxValue, string? server = null, string? since = null,
+ string? thirdPartyInstanceId = null, bool? includeAllNetworks = null, RoomDirectoryFilter? filter = null, int chunkSize = 100) {
PublicRoomDirectoryResult res;
do {
- res = await GetPublicRoomsAsync(chunkSize, server, since);
+ res = await GetPublicRoomsAsync(chunkSize, server, since, thirdPartyInstanceId, includeAllNetworks, filter);
yield return res;
if (res.NextBatch is null || res.NextBatch == since || res.Chunk.Count == 0) break;
since = res.NextBatch;
} while (limit > 0 && limit-- > 0);
}
+ public async Task<RoomDirectoryVisibilityResponse> GetRoomDirectoryVisibilityAsync(string roomId)
+ => await (await ClientHttpClient.GetAsync($"/_matrix/client/v3/directory/list/room/{HttpUtility.UrlEncode(roomId)}")).Content
+ .ReadFromJsonAsync<RoomDirectoryVisibilityResponse>() ?? throw new InvalidOperationException();
+
#region Authentication
public async Task<LoginResponse> LoginAsync(string username, string password, string? deviceName = null) {
@@ -121,6 +145,42 @@ public class RemoteHomeserver {
public UserInteractiveAuthClient Auth;
}
+public class RoomDirectoryFilteredRequest {
+ [JsonPropertyName("filter")]
+ public RoomDirectoryFilter? Filter { get; set; }
+
+ [JsonPropertyName("include_all_networks")]
+ public bool? IncludeAllNetworks { get; set; }
+
+ [JsonPropertyName("limit")]
+ public int Limit { get; set; }
+
+ [JsonPropertyName("since")]
+ public string? Since { get; set; }
+
+ [JsonPropertyName("third_party_instance_id")]
+ public string? ThirdPartyInstanceId { get; set; }
+}
+
+public class RoomDirectoryFilter {
+ [JsonPropertyName("generic_search_term")]
+ public string? GenericSearchTerm { get; set; }
+
+ [JsonPropertyName("room_types")]
+ public List<string?>? RoomTypes { get; set; }
+}
+
+public class RoomDirectoryVisibilityResponse {
+ [JsonPropertyName("visibility")]
+ public VisibilityValue Visibility { get; set; }
+
+ [JsonConverter(typeof(JsonStringEnumConverter))]
+ public enum VisibilityValue {
+ [JsonStringEnumMemberName("public")] Public,
+ [JsonStringEnumMemberName("private")] Private
+ }
+}
+
public class PublicRoomDirectoryResult {
[JsonPropertyName("chunk")]
public List<PublicRoomListItem> Chunk { get; set; }
|