feat: Upgrade to spec 1.6

In theory this is a breaking change, since it changes the read receipt
API slightly.
This commit is contained in:
Nicolas Werner 2023-04-17 11:57:56 +02:00
parent ab7fc034f2
commit d99bb05f47
No known key found for this signature in database
3 changed files with 767 additions and 98 deletions

View File

@ -119,6 +119,277 @@ class Api {
return GetSpaceHierarchyResponse.fromJson(json); return GetSpaceHierarchyResponse.fromJson(json);
} }
/// Retrieve all of the child events for a given parent event.
///
/// Note that when paginating the `from` token should be "after" the `to` token in
/// terms of topological ordering, because it is only possible to paginate "backwards"
/// through events, starting at `from`.
///
/// For example, passing a `from` token from page 2 of the results, and a `to` token
/// from page 1, would return the empty set. The caller can use a `from` token from
/// page 1 and a `to` token from page 2 to paginate over the same range, however.
///
/// [roomId] The ID of the room containing the parent event.
///
/// [eventId] The ID of the parent event whose child events are to be returned.
///
/// [from] The pagination token to start returning results from. If not supplied, results
/// start at the most recent topological event known to the server.
///
/// Can be a `next_batch` or `prev_batch` token from a previous call, or a returned
/// `start` token from [`/messages`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3roomsroomidmessages),
/// or a `next_batch` token from [`/sync`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3sync).
///
/// [to] The pagination token to stop returning results at. If not supplied, results
/// continue up to `limit` or until there are no more events.
///
/// Like `from`, this can be a previous token from a prior call to this endpoint
/// or from `/messages` or `/sync`.
///
/// [limit] The maximum number of results to return in a single `chunk`. The server can
/// and should apply a maximum value to this parameter to avoid large responses.
///
/// Similarly, the server should apply a default value when not supplied.
///
/// [dir] Optional (default `b`) direction to return events from. If this is set to `f`, events
/// will be returned in chronological order starting at `from`. If it
/// is set to `b`, events will be returned in *reverse* chronological
/// order, again starting at `from`.
Future<GetRelatingEventsResponse> getRelatingEvents(
String roomId, String eventId,
{String? from, String? to, int? limit, Direction? dir}) async {
final requestUri = Uri(
path:
'_matrix/client/v1/rooms/${Uri.encodeComponent(roomId)}/relations/${Uri.encodeComponent(eventId)}',
queryParameters: {
if (from != null) 'from': from,
if (to != null) 'to': to,
if (limit != null) 'limit': limit.toString(),
if (dir != null) 'dir': dir.name,
});
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return GetRelatingEventsResponse.fromJson(json);
}
/// Retrieve all of the child events for a given parent event which relate to the parent
/// using the given `relType`.
///
/// Note that when paginating the `from` token should be "after" the `to` token in
/// terms of topological ordering, because it is only possible to paginate "backwards"
/// through events, starting at `from`.
///
/// For example, passing a `from` token from page 2 of the results, and a `to` token
/// from page 1, would return the empty set. The caller can use a `from` token from
/// page 1 and a `to` token from page 2 to paginate over the same range, however.
///
/// [roomId] The ID of the room containing the parent event.
///
/// [eventId] The ID of the parent event whose child events are to be returned.
///
/// [relType] The [relationship type](https://spec.matrix.org/unstable/client-server-api/#relationship-types) to search for.
///
/// [from] The pagination token to start returning results from. If not supplied, results
/// start at the most recent topological event known to the server.
///
/// Can be a `next_batch` or `prev_batch` token from a previous call, or a returned
/// `start` token from [`/messages`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3roomsroomidmessages),
/// or a `next_batch` token from [`/sync`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3sync).
///
/// [to] The pagination token to stop returning results at. If not supplied, results
/// continue up to `limit` or until there are no more events.
///
/// Like `from`, this can be a previous token from a prior call to this endpoint
/// or from `/messages` or `/sync`.
///
/// [limit] The maximum number of results to return in a single `chunk`. The server can
/// and should apply a maximum value to this parameter to avoid large responses.
///
/// Similarly, the server should apply a default value when not supplied.
///
/// [dir] Optional (default `b`) direction to return events from. If this is set to `f`, events
/// will be returned in chronological order starting at `from`. If it
/// is set to `b`, events will be returned in *reverse* chronological
/// order, again starting at `from`.
Future<GetRelatingEventsWithRelTypeResponse> getRelatingEventsWithRelType(
String roomId, String eventId, String relType,
{String? from, String? to, int? limit, Direction? dir}) async {
final requestUri = Uri(
path:
'_matrix/client/v1/rooms/${Uri.encodeComponent(roomId)}/relations/${Uri.encodeComponent(eventId)}/${Uri.encodeComponent(relType)}',
queryParameters: {
if (from != null) 'from': from,
if (to != null) 'to': to,
if (limit != null) 'limit': limit.toString(),
if (dir != null) 'dir': dir.name,
});
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return GetRelatingEventsWithRelTypeResponse.fromJson(json);
}
/// Retrieve all of the child events for a given parent event which relate to the parent
/// using the given `relType` and have the given `eventType`.
///
/// Note that when paginating the `from` token should be "after" the `to` token in
/// terms of topological ordering, because it is only possible to paginate "backwards"
/// through events, starting at `from`.
///
/// For example, passing a `from` token from page 2 of the results, and a `to` token
/// from page 1, would return the empty set. The caller can use a `from` token from
/// page 1 and a `to` token from page 2 to paginate over the same range, however.
///
/// [roomId] The ID of the room containing the parent event.
///
/// [eventId] The ID of the parent event whose child events are to be returned.
///
/// [relType] The [relationship type](https://spec.matrix.org/unstable/client-server-api/#relationship-types) to search for.
///
/// [eventType] The event type of child events to search for.
///
/// Note that in encrypted rooms this will typically always be `m.room.encrypted`
/// regardless of the event type contained within the encrypted payload.
///
/// [from] The pagination token to start returning results from. If not supplied, results
/// start at the most recent topological event known to the server.
///
/// Can be a `next_batch` or `prev_batch` token from a previous call, or a returned
/// `start` token from [`/messages`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3roomsroomidmessages),
/// or a `next_batch` token from [`/sync`](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv3sync).
///
/// [to] The pagination token to stop returning results at. If not supplied, results
/// continue up to `limit` or until there are no more events.
///
/// Like `from`, this can be a previous token from a prior call to this endpoint
/// or from `/messages` or `/sync`.
///
/// [limit] The maximum number of results to return in a single `chunk`. The server can
/// and should apply a maximum value to this parameter to avoid large responses.
///
/// Similarly, the server should apply a default value when not supplied.
///
/// [dir] Optional (default `b`) direction to return events from. If this is set to `f`, events
/// will be returned in chronological order starting at `from`. If it
/// is set to `b`, events will be returned in *reverse* chronological
/// order, again starting at `from`.
Future<GetRelatingEventsWithRelTypeAndEventTypeResponse>
getRelatingEventsWithRelTypeAndEventType(
String roomId, String eventId, String relType, String eventType,
{String? from, String? to, int? limit, Direction? dir}) async {
final requestUri = Uri(
path:
'_matrix/client/v1/rooms/${Uri.encodeComponent(roomId)}/relations/${Uri.encodeComponent(eventId)}/${Uri.encodeComponent(relType)}/${Uri.encodeComponent(eventType)}',
queryParameters: {
if (from != null) 'from': from,
if (to != null) 'to': to,
if (limit != null) 'limit': limit.toString(),
if (dir != null) 'dir': dir.name,
});
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return GetRelatingEventsWithRelTypeAndEventTypeResponse.fromJson(json);
}
/// Paginates over the thread roots in a room, ordered by the `latest_event` of each thread root
/// in its bundle.
///
/// [roomId] The room ID where the thread roots are located.
///
/// [include] Optional (default `all`) flag to denote which thread roots are of interest to the caller.
/// When `all`, all thread roots found in the room are returned. When `participated`, only
/// thread roots for threads the user has [participated in](https://spec.matrix.org/unstable/client-server-api/#server-side-aggregation-of-mthread-relationships)
/// will be returned.
///
/// [limit] Optional limit for the maximum number of thread roots to include per response. Must be an integer
/// greater than zero.
///
/// Servers should apply a default value, and impose a maximum value to avoid resource exhaustion.
///
/// [from] A pagination token from a previous result. When not provided, the server starts paginating from
/// the most recent event visible to the user (as per history visibility rules; topologically).
Future<GetThreadRootsResponse> getThreadRoots(String roomId,
{Include? include, int? limit, String? from}) async {
final requestUri = Uri(
path: '_matrix/client/v1/rooms/${Uri.encodeComponent(roomId)}/threads',
queryParameters: {
if (include != null) 'include': include.name,
if (limit != null) 'limit': limit.toString(),
if (from != null) 'from': from,
});
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return GetThreadRootsResponse.fromJson(json);
}
/// Get the ID of the event closest to the given timestamp, in the
/// direction specified by the `dir` parameter.
///
/// If the server does not have all of the room history and does not have
/// an event suitably close to the requested timestamp, it can use the
/// corresponding [federation endpoint](https://spec.matrix.org/unstable/server-server-api/#get_matrixfederationv1timestamp_to_eventroomid)
/// to ask other servers for a suitable event.
///
/// After calling this endpoint, clients can call
/// [`/rooms/{roomId}/context/{eventId}`](#get_matrixclientv3roomsroomidcontexteventid)
/// to obtain a pagination token to retrieve the events around the returned event.
///
/// The event returned by this endpoint could be an event that the client
/// cannot render, and so may need to paginate in order to locate an event
/// that it can display, which may end up being outside of the client's
/// suitable range. Clients can employ different strategies to display
/// something reasonable to the user. For example, the client could try
/// paginating in one direction for a while, while looking at the
/// timestamps of the events that it is paginating through, and if it
/// exceeds a certain difference from the target timestamp, it can try
/// paginating in the opposite direction. The client could also simply
/// paginate in one direction and inform the user that the closest event
/// found in that direction is outside of the expected range.
///
/// [roomId] The ID of the room to search
///
/// [ts] The timestamp to search from, as given in milliseconds
/// since the Unix epoch.
///
/// [dir] The direction in which to search. `f` for forwards, `b` for backwards.
Future<GetEventByTimestampResponse> getEventByTimestamp(
String roomId, int ts, Direction dir) async {
final requestUri = Uri(
path:
'_matrix/client/v1/rooms/${Uri.encodeComponent(roomId)}/timestamp_to_event',
queryParameters: {
'ts': ts.toString(),
'dir': dir.name,
});
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return GetEventByTimestampResponse.fromJson(json);
}
/// Gets a list of the third party identifiers that the homeserver has /// Gets a list of the third party identifiers that the homeserver has
/// associated with the user's account. /// associated with the user's account.
/// ///
@ -1134,7 +1405,9 @@ class Api {
/// checks, delete the alias and return a successful response even if the user does not /// checks, delete the alias and return a successful response even if the user does not
/// have permission to update the `m.room.canonical_alias` event. /// have permission to update the `m.room.canonical_alias` event.
/// ///
/// [roomAlias] The room alias to remove. /// [roomAlias] The room alias to remove. Its format is defined
/// [in the appendices](https://spec.matrix.org/unstable/appendices/#room-aliases).
///
Future<void> deleteRoomAlias(String roomAlias) async { Future<void> deleteRoomAlias(String roomAlias) async {
final requestUri = Uri( final requestUri = Uri(
path: path:
@ -1155,7 +1428,9 @@ class Api {
/// domain part of the alias does not correspond to the server's own /// domain part of the alias does not correspond to the server's own
/// domain. /// domain.
/// ///
/// [roomAlias] The room alias. /// [roomAlias] The room alias. Its format is defined
/// [in the appendices](https://spec.matrix.org/unstable/appendices/#room-aliases).
///
Future<GetRoomIdByAliasResponse> getRoomIdByAlias(String roomAlias) async { Future<GetRoomIdByAliasResponse> getRoomIdByAlias(String roomAlias) async {
final requestUri = Uri( final requestUri = Uri(
path: path:
@ -1171,7 +1446,9 @@ class Api {
/// setRoomAlias /// setRoomAlias
/// ///
/// [roomAlias] The room alias to set. /// [roomAlias] The room alias to set. Its format is defined
/// [in the appendices](https://spec.matrix.org/unstable/appendices/#room-aliases).
///
/// ///
/// [roomId] The room ID to set. /// [roomId] The room ID to set.
Future<void> setRoomAlias(String roomAlias, String roomId) async { Future<void> setRoomAlias(String roomAlias, String roomId) async {
@ -1277,7 +1554,7 @@ class Api {
return MatrixEvent.fromJson(json); return MatrixEvent.fromJson(json);
} }
/// *Note that this API takes either a room ID or alias, unlike* `/room/{roomId}/join`. /// *Note that this API takes either a room ID or alias, unlike* `/rooms/{roomId}/join`.
/// ///
/// This API starts a user participating in a particular room, if that user /// This API starts a user participating in a particular room, if that user
/// is allowed to participate in that room. After this call, the client is /// is allowed to participate in that room. After this call, the client is
@ -1609,6 +1886,8 @@ class Api {
/// [password] Required when `type` is `m.login.password`. The user's /// [password] Required when `type` is `m.login.password`. The user's
/// password. /// password.
/// ///
/// [refreshToken] If true, the client supports refresh tokens.
///
/// [token] Required when `type` is `m.login.token`. Part of Token-based login. /// [token] Required when `type` is `m.login.token`. Part of Token-based login.
/// ///
/// [type] The login type being used. /// [type] The login type being used.
@ -1621,6 +1900,7 @@ class Api {
String? initialDeviceDisplayName, String? initialDeviceDisplayName,
String? medium, String? medium,
String? password, String? password,
bool? refreshToken,
String? token, String? token,
String? user}) async { String? user}) async {
final requestUri = Uri(path: '_matrix/client/v3/login'); final requestUri = Uri(path: '_matrix/client/v3/login');
@ -1634,6 +1914,7 @@ class Api {
'initial_device_display_name': initialDeviceDisplayName, 'initial_device_display_name': initialDeviceDisplayName,
if (medium != null) 'medium': medium, if (medium != null) 'medium': medium,
if (password != null) 'password': password, if (password != null) 'password': password,
if (refreshToken != null) 'refresh_token': refreshToken,
if (token != null) 'token': token, if (token != null) 'token': token,
'type': type.name, 'type': type.name,
if (user != null) 'user': user, if (user != null) 'user': user,
@ -2037,9 +2318,20 @@ class Api {
return PushRule.fromJson(json); return PushRule.fromJson(json);
} }
/// This endpoint allows the creation, modification and deletion of pushers /// This endpoint allows the creation and modification of user defined push
/// for this user ID. The behaviour of this endpoint varies depending on the /// rules.
/// values in the JSON body. ///
/// If a rule with the same `rule_id` already exists among rules of the same
/// kind, it is updated with the new parameters, otherwise a new rule is
/// created.
///
/// If both `after` and `before` are provided, the new or updated rule must
/// be the next most important rule with respect to the rule identified by
/// `before`.
///
/// If neither `after` nor `before` are provided and the rule is created, it
/// should be added as the most important user defined rule among rules of
/// the same kind.
/// ///
/// When creating push rules, they MUST be enabled by default. /// When creating push rules, they MUST be enabled by default.
/// ///
@ -2048,7 +2340,9 @@ class Api {
/// [kind] The kind of rule /// [kind] The kind of rule
/// ///
/// ///
/// [ruleId] The identifier for the rule. /// [ruleId] The identifier for the rule. If the string starts with a dot ("."),
/// the request MUST be rejected as this is reserved for server-default
/// rules. Slashes ("/") and backslashes ("\\") are also not allowed.
/// ///
/// ///
/// [before] Use 'before' with a `rule_id` as its value to make the new rule the /// [before] Use 'before' with a `rule_id` as its value to make the new rule the
@ -2213,6 +2507,40 @@ class Api {
return ignore(json); return ignore(json);
} }
/// Refresh an access token. Clients should use the returned access token
/// when making subsequent API calls, and store the returned refresh token
/// (if given) in order to refresh the new access token when necessary.
///
/// After an access token has been refreshed, a server can choose to
/// invalidate the old access token immediately, or can choose not to, for
/// example if the access token would expire soon anyways. Clients should
/// not make any assumptions about the old access token still being valid,
/// and should use the newly provided access token instead.
///
/// The old refresh token remains valid until the new access token or refresh token
/// is used, at which point the old refresh token is revoked.
///
/// Note that this endpoint does not require authentication via an
/// access token. Authentication is provided via the refresh token.
///
/// Application Service identity assertion is disabled for this endpoint.
///
/// [refreshToken] The refresh token
Future<RefreshResponse> refresh(String refreshToken) async {
final requestUri = Uri(path: '_matrix/client/v3/refresh');
final request = Request('POST', baseUri!.resolveUri(requestUri));
request.headers['content-type'] = 'application/json';
request.bodyBytes = utf8.encode(jsonEncode({
'refresh_token': refreshToken,
}));
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody);
final responseString = utf8.decode(responseBody);
final json = jsonDecode(responseString);
return RefreshResponse.fromJson(json);
}
/// This API endpoint uses the [User-Interactive Authentication API](https://spec.matrix.org/unstable/client-server-api/#user-interactive-authentication-api), except in /// This API endpoint uses the [User-Interactive Authentication API](https://spec.matrix.org/unstable/client-server-api/#user-interactive-authentication-api), except in
/// the cases where a guest account is being registered. /// the cases where a guest account is being registered.
/// ///
@ -2274,6 +2602,8 @@ class Api {
/// ///
/// [password] The desired password for the account. /// [password] The desired password for the account.
/// ///
/// [refreshToken] If true, the client supports refresh tokens.
///
/// [username] The basis for the localpart of the desired Matrix ID. If omitted, /// [username] The basis for the localpart of the desired Matrix ID. If omitted,
/// the homeserver MUST generate a Matrix ID local part. /// the homeserver MUST generate a Matrix ID local part.
Future<RegisterResponse> register( Future<RegisterResponse> register(
@ -2283,6 +2613,7 @@ class Api {
bool? inhibitLogin, bool? inhibitLogin,
String? initialDeviceDisplayName, String? initialDeviceDisplayName,
String? password, String? password,
bool? refreshToken,
String? username}) async { String? username}) async {
final requestUri = final requestUri =
Uri(path: '_matrix/client/v3/register', queryParameters: { Uri(path: '_matrix/client/v3/register', queryParameters: {
@ -2297,6 +2628,7 @@ class Api {
if (initialDeviceDisplayName != null) if (initialDeviceDisplayName != null)
'initial_device_display_name': initialDeviceDisplayName, 'initial_device_display_name': initialDeviceDisplayName,
if (password != null) 'password': password, if (password != null) 'password': password,
if (refreshToken != null) 'refresh_token': refreshToken,
if (username != null) 'username': username, if (username != null) 'username': username,
})); }));
final response = await httpClient.send(request); final response = await httpClient.send(request);
@ -2861,7 +3193,10 @@ class Api {
/// ///
/// [eventId] The event to get context around. /// [eventId] The event to get context around.
/// ///
/// [limit] The maximum number of events to return. Default: 10. /// [limit] The maximum number of context events to return. The limit applies
/// to the sum of the `events_before` and `events_after` arrays. The
/// requested event ID is always returned in `event` even if `limit` is
/// 0. Defaults to 10.
/// ///
/// [filter] A JSON `RoomEventFilter` to filter the returned events with. The /// [filter] A JSON `RoomEventFilter` to filter the returned events with. The
/// filter is only applied to `events_before`, `events_after`, and /// filter is only applied to `events_before`, `events_after`, and
@ -2984,7 +3319,8 @@ class Api {
/// ///
/// [idServer] The hostname+port of the identity server which should be used for third party identifier lookups. /// [idServer] The hostname+port of the identity server which should be used for third party identifier lookups.
/// ///
/// [medium] The kind of address being passed in the address field, for example `email`. /// [medium] The kind of address being passed in the address field, for example
/// `email` (see [the list of recognised values](https://spec.matrix.org/unstable/appendices/#3pid-types)).
Future<void> inviteBy3PID(String roomId, String address, String idAccessToken, Future<void> inviteBy3PID(String roomId, String address, String idAccessToken,
String idServer, String medium) async { String idServer, String medium) async {
final requestUri = Uri( final requestUri = Uri(
@ -3008,8 +3344,8 @@ class Api {
/// *Note that there are two forms of this API, which are documented separately. /// *Note that there are two forms of this API, which are documented separately.
/// This version of the API requires that the inviter knows the Matrix /// This version of the API requires that the inviter knows the Matrix
/// identifier of the invitee. The other is documented in the* /// identifier of the invitee. The other is documented in the
/// [third party invites section](https://spec.matrix.org/unstable/client-server-api/#post_matrixclientv3roomsroomidinvite-1). /// [third party invites](https://spec.matrix.org/unstable/client-server-api/#third-party-invites) section.*
/// ///
/// This API invites a user to participate in a particular room. /// This API invites a user to participate in a particular room.
/// They do not start participating in the room until they actually join the /// They do not start participating in the room until they actually join the
@ -3280,8 +3616,12 @@ class Api {
/// [mRead] The event ID to set the read receipt location at. This is /// [mRead] The event ID to set the read receipt location at. This is
/// equivalent to calling `/receipt/m.read/$elsewhere:example.org` /// equivalent to calling `/receipt/m.read/$elsewhere:example.org`
/// and is provided here to save that extra call. /// and is provided here to save that extra call.
Future<void> setReadMarker(String roomId, String mFullyRead, ///
{String? mRead}) async { /// [mReadPrivate] The event ID to set the *private* read receipt location at. This
/// equivalent to calling `/receipt/m.read.private/$elsewhere:example.org`
/// and is provided here to save that extra call.
Future<void> setReadMarker(String roomId,
{String? mFullyRead, String? mRead, String? mReadPrivate}) async {
final requestUri = Uri( final requestUri = Uri(
path: path:
'_matrix/client/v3/rooms/${Uri.encodeComponent(roomId)}/read_markers'); '_matrix/client/v3/rooms/${Uri.encodeComponent(roomId)}/read_markers');
@ -3289,8 +3629,9 @@ class Api {
request.headers['authorization'] = 'Bearer ${bearerToken!}'; request.headers['authorization'] = 'Bearer ${bearerToken!}';
request.headers['content-type'] = 'application/json'; request.headers['content-type'] = 'application/json';
request.bodyBytes = utf8.encode(jsonEncode({ request.bodyBytes = utf8.encode(jsonEncode({
'm.fully_read': mFullyRead, if (mFullyRead != null) 'm.fully_read': mFullyRead,
if (mRead != null) 'm.read': mRead, if (mRead != null) 'm.read': mRead,
if (mReadPrivate != null) 'm.read.private': mReadPrivate,
})); }));
final response = await httpClient.send(request); final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes(); final responseBody = await response.stream.toBytes();
@ -3305,21 +3646,31 @@ class Api {
/// ///
/// [roomId] The room in which to send the event. /// [roomId] The room in which to send the event.
/// ///
/// [receiptType] The type of receipt to send. /// [receiptType] The type of receipt to send. This can also be `m.fully_read` as an
/// alternative to [`/read_markers`](https://spec.matrix.org/unstable/client-server-api/#post_matrixclientv3roomsroomidread_markers).
///
/// Note that `m.fully_read` does not appear under `m.receipt`: this endpoint
/// effectively calls `/read_markers` internally when presented with a receipt
/// type of `m.fully_read`.
/// ///
/// [eventId] The event ID to acknowledge up to. /// [eventId] The event ID to acknowledge up to.
/// ///
/// [receipt] Extra receipt information to attach to `content` if any. The /// [threadId] The root thread event's ID (or `main`) for which
/// server will automatically set the `ts` field. /// thread this receipt is intended to be under. If
Future<void> postReceipt(String roomId, ReceiptType receiptType, /// not specified, the read receipt is *unthreaded*
String eventId, Map<String, dynamic> receipt) async { /// (default).
Future<void> postReceipt(
String roomId, ReceiptType receiptType, String eventId,
{String? threadId}) async {
final requestUri = Uri( final requestUri = Uri(
path: path:
'_matrix/client/v3/rooms/${Uri.encodeComponent(roomId)}/receipt/${Uri.encodeComponent(receiptType.name)}/${Uri.encodeComponent(eventId)}'); '_matrix/client/v3/rooms/${Uri.encodeComponent(roomId)}/receipt/${Uri.encodeComponent(receiptType.name)}/${Uri.encodeComponent(eventId)}');
final request = Request('POST', baseUri!.resolveUri(requestUri)); final request = Request('POST', baseUri!.resolveUri(requestUri));
request.headers['authorization'] = 'Bearer ${bearerToken!}'; request.headers['authorization'] = 'Bearer ${bearerToken!}';
request.headers['content-type'] = 'application/json'; request.headers['content-type'] = 'application/json';
request.bodyBytes = utf8.encode(jsonEncode(receipt)); request.bodyBytes = utf8.encode(jsonEncode({
if (threadId != null) 'thread_id': threadId,
}));
final response = await httpClient.send(request); final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes(); final responseBody = await response.stream.toBytes();
if (response.statusCode != 200) unexpectedResponse(response, responseBody); if (response.statusCode != 200) unexpectedResponse(response, responseBody);
@ -3344,7 +3695,7 @@ class Api {
/// ///
/// [eventId] The ID of the event to redact /// [eventId] The ID of the event to redact
/// ///
/// [txnId] The transaction ID for this event. Clients should generate a /// [txnId] The [transaction ID](https://spec.matrix.org/unstable/client-server-api/#transaction-identifiers) for this event. Clients should generate a
/// unique ID; it will be used by the server to ensure idempotency of requests. /// unique ID; it will be used by the server to ensure idempotency of requests.
/// ///
/// [reason] The reason for the event being redacted. /// [reason] The reason for the event being redacted.
@ -3413,7 +3764,7 @@ class Api {
/// ///
/// [eventType] The type of event to send. /// [eventType] The type of event to send.
/// ///
/// [txnId] The transaction ID for this event. Clients should generate an /// [txnId] The [transaction ID](https://spec.matrix.org/unstable/client-server-api/#transaction-identifiers) for this event. Clients should generate an
/// ID unique across requests with the same access token; it will be /// ID unique across requests with the same access token; it will be
/// used by the server to ensure idempotency of requests. /// used by the server to ensure idempotency of requests.
/// ///
@ -3640,7 +3991,7 @@ class Api {
/// ///
/// [eventType] The type of event to send. /// [eventType] The type of event to send.
/// ///
/// [txnId] The transaction ID for this event. Clients should generate an /// [txnId] The [transaction ID](https://spec.matrix.org/unstable/client-server-api/#transaction-identifiers) for this event. Clients should generate an
/// ID unique across requests with the same access token; it will be /// ID unique across requests with the same access token; it will be
/// used by the server to ensure idempotency of requests. /// used by the server to ensure idempotency of requests.
/// ///
@ -3877,13 +4228,13 @@ class Api {
return (json as List).map((v) => ThirdPartyUser.fromJson(v)).toList(); return (json as List).map((v) => ThirdPartyUser.fromJson(v)).toList();
} }
/// Get some account_data for the client. This config is only visible to the user /// Get some account data for the client. This config is only visible to the user
/// that set the account_data. /// that set the account data.
/// ///
/// [userId] The ID of the user to get account_data for. The access token must be /// [userId] The ID of the user to get account data for. The access token must be
/// authorized to make requests for this user ID. /// authorized to make requests for this user ID.
/// ///
/// [type] The event type of the account_data to get. Custom types should be /// [type] The event type of the account data to get. Custom types should be
/// namespaced to avoid clashes. /// namespaced to avoid clashes.
Future<Map<String, dynamic>> getAccountData( Future<Map<String, dynamic>> getAccountData(
String userId, String type) async { String userId, String type) async {
@ -3900,17 +4251,18 @@ class Api {
return json as Map<String, dynamic>; return json as Map<String, dynamic>;
} }
/// Set some account_data for the client. This config is only visible to the user /// Set some account data for the client. This config is only visible to the user
/// that set the account_data. The config will be synced to clients in the /// that set the account data. The config will be available to clients through the
/// top-level `account_data`. /// top-level `account_data` field in the homeserver response to
/// [/sync](#get_matrixclientv3sync).
/// ///
/// [userId] The ID of the user to set account_data for. The access token must be /// [userId] The ID of the user to set account data for. The access token must be
/// authorized to make requests for this user ID. /// authorized to make requests for this user ID.
/// ///
/// [type] The event type of the account_data to set. Custom types should be /// [type] The event type of the account data to set. Custom types should be
/// namespaced to avoid clashes. /// namespaced to avoid clashes.
/// ///
/// [content] The content of the account_data /// [content] The content of the account data.
Future<void> setAccountData( Future<void> setAccountData(
String userId, String type, Map<String, dynamic> content) async { String userId, String type, Map<String, dynamic> content) async {
final requestUri = Uri( final requestUri = Uri(
@ -3984,7 +4336,7 @@ class Api {
/// be used to request another OpenID access token or call `/sync`, for /// be used to request another OpenID access token or call `/sync`, for
/// example. /// example.
/// ///
/// [userId] The user to request and OpenID token for. Should be the user who /// [userId] The user to request an OpenID token for. Should be the user who
/// is authenticated for the request. /// is authenticated for the request.
/// ///
/// [body] An empty object. Reserved for future expansion. /// [body] An empty object. Reserved for future expansion.
@ -4005,15 +4357,15 @@ class Api {
return OpenIdCredentials.fromJson(json); return OpenIdCredentials.fromJson(json);
} }
/// Get some account_data for the client on a given room. This config is only /// Get some account data for the client on a given room. This config is only
/// visible to the user that set the account_data. /// visible to the user that set the account data.
/// ///
/// [userId] The ID of the user to set account_data for. The access token must be /// [userId] The ID of the user to get account data for. The access token must be
/// authorized to make requests for this user ID. /// authorized to make requests for this user ID.
/// ///
/// [roomId] The ID of the room to get account_data for. /// [roomId] The ID of the room to get account data for.
/// ///
/// [type] The event type of the account_data to get. Custom types should be /// [type] The event type of the account data to get. Custom types should be
/// namespaced to avoid clashes. /// namespaced to avoid clashes.
Future<Map<String, dynamic>> getAccountDataPerRoom( Future<Map<String, dynamic>> getAccountDataPerRoom(
String userId, String roomId, String type) async { String userId, String roomId, String type) async {
@ -4030,19 +4382,19 @@ class Api {
return json as Map<String, dynamic>; return json as Map<String, dynamic>;
} }
/// Set some account_data for the client on a given room. This config is only /// Set some account data for the client on a given room. This config is only
/// visible to the user that set the account_data. The config will be synced to /// visible to the user that set the account data. The config will be delivered to
/// clients in the per-room `account_data`. /// clients in the per-room entries via [/sync](#get_matrixclientv3sync).
/// ///
/// [userId] The ID of the user to set account_data for. The access token must be /// [userId] The ID of the user to set account data for. The access token must be
/// authorized to make requests for this user ID. /// authorized to make requests for this user ID.
/// ///
/// [roomId] The ID of the room to set account_data on. /// [roomId] The ID of the room to set account data on.
/// ///
/// [type] The event type of the account_data to set. Custom types should be /// [type] The event type of the account data to set. Custom types should be
/// namespaced to avoid clashes. /// namespaced to avoid clashes.
/// ///
/// [content] The content of the account_data /// [content] The content of the account data.
Future<void> setAccountDataPerRoom(String userId, String roomId, String type, Future<void> setAccountDataPerRoom(String userId, String roomId, String type,
Map<String, dynamic> content) async { Map<String, dynamic> content) async {
final requestUri = Uri( final requestUri = Uri(

View File

@ -95,6 +95,7 @@ class PublicRoomsChunk {
this.name, this.name,
required this.numJoinedMembers, required this.numJoinedMembers,
required this.roomId, required this.roomId,
this.roomType,
this.topic, this.topic,
required this.worldReadable, required this.worldReadable,
}); });
@ -109,6 +110,7 @@ class PublicRoomsChunk {
name = ((v) => v != null ? v as String : null)(json['name']), name = ((v) => v != null ? v as String : null)(json['name']),
numJoinedMembers = json['num_joined_members'] as int, numJoinedMembers = json['num_joined_members'] as int,
roomId = json['room_id'] as String, roomId = json['room_id'] as String,
roomType = ((v) => v != null ? v as String : null)(json['room_type']),
topic = ((v) => v != null ? v as String : null)(json['topic']), topic = ((v) => v != null ? v as String : null)(json['topic']),
worldReadable = json['world_readable'] as bool; worldReadable = json['world_readable'] as bool;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -116,6 +118,7 @@ class PublicRoomsChunk {
final canonicalAlias = this.canonicalAlias; final canonicalAlias = this.canonicalAlias;
final joinRule = this.joinRule; final joinRule = this.joinRule;
final name = this.name; final name = this.name;
final roomType = this.roomType;
final topic = this.topic; final topic = this.topic;
return { return {
if (avatarUrl != null) 'avatar_url': avatarUrl.toString(), if (avatarUrl != null) 'avatar_url': avatarUrl.toString(),
@ -125,6 +128,7 @@ class PublicRoomsChunk {
if (name != null) 'name': name, if (name != null) 'name': name,
'num_joined_members': numJoinedMembers, 'num_joined_members': numJoinedMembers,
'room_id': roomId, 'room_id': roomId,
if (roomType != null) 'room_type': roomType,
if (topic != null) 'topic': topic, if (topic != null) 'topic': topic,
'world_readable': worldReadable, 'world_readable': worldReadable,
}; };
@ -154,6 +158,9 @@ class PublicRoomsChunk {
/// The ID of the room. /// The ID of the room.
String roomId; String roomId;
/// The `type` of room (from [`m.room.create`](https://spec.matrix.org/unstable/client-server-api/#mroomcreate)), if any.
String? roomType;
/// The topic of the room, if any. /// The topic of the room, if any.
String? topic; String? topic;
@ -161,14 +168,14 @@ class PublicRoomsChunk {
bool worldReadable; bool worldReadable;
} }
@_NameSource('rule override generated') @_NameSource('spec')
class SpaceRoomsChunkBase { class ChildRoomsChunk {
SpaceRoomsChunkBase({ ChildRoomsChunk({
required this.childrenState, required this.childrenState,
this.roomType, this.roomType,
}); });
SpaceRoomsChunkBase.fromJson(Map<String, dynamic> json) ChildRoomsChunk.fromJson(Map<String, dynamic> json)
: childrenState = (json['children_state'] as List) : childrenState = (json['children_state'] as List)
.map((v) => ChildrenState.fromJson(v)) .map((v) => ChildrenState.fromJson(v))
.toList(), .toList(),
@ -192,7 +199,7 @@ class SpaceRoomsChunkBase {
} }
@_NameSource('rule override generated') @_NameSource('rule override generated')
class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase { class SpaceRoomsChunk implements PublicRoomsChunk, ChildRoomsChunk {
SpaceRoomsChunk({ SpaceRoomsChunk({
this.avatarUrl, this.avatarUrl,
this.canonicalAlias, this.canonicalAlias,
@ -201,10 +208,10 @@ class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase {
this.name, this.name,
required this.numJoinedMembers, required this.numJoinedMembers,
required this.roomId, required this.roomId,
this.roomType,
this.topic, this.topic,
required this.worldReadable, required this.worldReadable,
required this.childrenState, required this.childrenState,
this.roomType,
}); });
SpaceRoomsChunk.fromJson(Map<String, dynamic> json) SpaceRoomsChunk.fromJson(Map<String, dynamic> json)
@ -217,19 +224,19 @@ class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase {
name = ((v) => v != null ? v as String : null)(json['name']), name = ((v) => v != null ? v as String : null)(json['name']),
numJoinedMembers = json['num_joined_members'] as int, numJoinedMembers = json['num_joined_members'] as int,
roomId = json['room_id'] as String, roomId = json['room_id'] as String,
roomType = ((v) => v != null ? v as String : null)(json['room_type']),
topic = ((v) => v != null ? v as String : null)(json['topic']), topic = ((v) => v != null ? v as String : null)(json['topic']),
worldReadable = json['world_readable'] as bool, worldReadable = json['world_readable'] as bool,
childrenState = (json['children_state'] as List) childrenState = (json['children_state'] as List)
.map((v) => ChildrenState.fromJson(v)) .map((v) => ChildrenState.fromJson(v))
.toList(), .toList();
roomType = ((v) => v != null ? v as String : null)(json['room_type']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final avatarUrl = this.avatarUrl; final avatarUrl = this.avatarUrl;
final canonicalAlias = this.canonicalAlias; final canonicalAlias = this.canonicalAlias;
final joinRule = this.joinRule; final joinRule = this.joinRule;
final name = this.name; final name = this.name;
final topic = this.topic;
final roomType = this.roomType; final roomType = this.roomType;
final topic = this.topic;
return { return {
if (avatarUrl != null) 'avatar_url': avatarUrl.toString(), if (avatarUrl != null) 'avatar_url': avatarUrl.toString(),
if (canonicalAlias != null) 'canonical_alias': canonicalAlias, if (canonicalAlias != null) 'canonical_alias': canonicalAlias,
@ -238,10 +245,10 @@ class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase {
if (name != null) 'name': name, if (name != null) 'name': name,
'num_joined_members': numJoinedMembers, 'num_joined_members': numJoinedMembers,
'room_id': roomId, 'room_id': roomId,
if (roomType != null) 'room_type': roomType,
if (topic != null) 'topic': topic, if (topic != null) 'topic': topic,
'world_readable': worldReadable, 'world_readable': worldReadable,
'children_state': childrenState.map((v) => v.toJson()).toList(), 'children_state': childrenState.map((v) => v.toJson()).toList(),
if (roomType != null) 'room_type': roomType,
}; };
} }
@ -269,6 +276,9 @@ class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase {
/// The ID of the room. /// The ID of the room.
String roomId; String roomId;
/// The `type` of room (from [`m.room.create`](https://spec.matrix.org/unstable/client-server-api/#mroomcreate)), if any.
String? roomType;
/// The topic of the room, if any. /// The topic of the room, if any.
String? topic; String? topic;
@ -280,9 +290,6 @@ class SpaceRoomsChunk implements PublicRoomsChunk, SpaceRoomsChunkBase {
/// ///
/// If the room is not a space-room, this should be empty. /// If the room is not a space-room, this should be empty.
List<ChildrenState> childrenState; List<ChildrenState> childrenState;
/// The `type` of room (from [`m.room.create`](https://spec.matrix.org/unstable/client-server-api/#mroomcreate)), if any.
String? roomType;
} }
@_NameSource('generated') @_NameSource('generated')
@ -313,6 +320,195 @@ class GetSpaceHierarchyResponse {
List<SpaceRoomsChunk> rooms; List<SpaceRoomsChunk> rooms;
} }
@_NameSource('rule override generated')
@EnhancedEnum()
enum Direction {
@EnhancedEnumValue(name: 'b')
b,
@EnhancedEnumValue(name: 'f')
f
}
@_NameSource('generated')
class GetRelatingEventsResponse {
GetRelatingEventsResponse({
required this.chunk,
this.nextBatch,
this.prevBatch,
});
GetRelatingEventsResponse.fromJson(Map<String, dynamic> json)
: chunk = (json['chunk'] as List)
.map((v) => MatrixEvent.fromJson(v))
.toList(),
nextBatch = ((v) => v != null ? v as String : null)(json['next_batch']),
prevBatch = ((v) => v != null ? v as String : null)(json['prev_batch']);
Map<String, dynamic> toJson() {
final nextBatch = this.nextBatch;
final prevBatch = this.prevBatch;
return {
'chunk': chunk.map((v) => v.toJson()).toList(),
if (nextBatch != null) 'next_batch': nextBatch,
if (prevBatch != null) 'prev_batch': prevBatch,
};
}
/// The child events of the requested event, ordered topologically most-recent first.
List<MatrixEvent> chunk;
/// An opaque string representing a pagination token. The absence of this token
/// means there are no more results to fetch and the client should stop paginating.
String? nextBatch;
/// An opaque string representing a pagination token. The absence of this token
/// means this is the start of the result set, i.e. this is the first batch/page.
String? prevBatch;
}
@_NameSource('generated')
class GetRelatingEventsWithRelTypeResponse {
GetRelatingEventsWithRelTypeResponse({
required this.chunk,
this.nextBatch,
this.prevBatch,
});
GetRelatingEventsWithRelTypeResponse.fromJson(Map<String, dynamic> json)
: chunk = (json['chunk'] as List)
.map((v) => MatrixEvent.fromJson(v))
.toList(),
nextBatch = ((v) => v != null ? v as String : null)(json['next_batch']),
prevBatch = ((v) => v != null ? v as String : null)(json['prev_batch']);
Map<String, dynamic> toJson() {
final nextBatch = this.nextBatch;
final prevBatch = this.prevBatch;
return {
'chunk': chunk.map((v) => v.toJson()).toList(),
if (nextBatch != null) 'next_batch': nextBatch,
if (prevBatch != null) 'prev_batch': prevBatch,
};
}
/// The child events of the requested event, ordered topologically
/// most-recent first. The events returned will match the `relType`
/// supplied in the URL.
List<MatrixEvent> chunk;
/// An opaque string representing a pagination token. The absence of this token
/// means there are no more results to fetch and the client should stop paginating.
String? nextBatch;
/// An opaque string representing a pagination token. The absence of this token
/// means this is the start of the result set, i.e. this is the first batch/page.
String? prevBatch;
}
@_NameSource('generated')
class GetRelatingEventsWithRelTypeAndEventTypeResponse {
GetRelatingEventsWithRelTypeAndEventTypeResponse({
required this.chunk,
this.nextBatch,
this.prevBatch,
});
GetRelatingEventsWithRelTypeAndEventTypeResponse.fromJson(
Map<String, dynamic> json)
: chunk = (json['chunk'] as List)
.map((v) => MatrixEvent.fromJson(v))
.toList(),
nextBatch = ((v) => v != null ? v as String : null)(json['next_batch']),
prevBatch = ((v) => v != null ? v as String : null)(json['prev_batch']);
Map<String, dynamic> toJson() {
final nextBatch = this.nextBatch;
final prevBatch = this.prevBatch;
return {
'chunk': chunk.map((v) => v.toJson()).toList(),
if (nextBatch != null) 'next_batch': nextBatch,
if (prevBatch != null) 'prev_batch': prevBatch,
};
}
/// The child events of the requested event, ordered topologically most-recent
/// first. The events returned will match the `relType` and `eventType` supplied
/// in the URL.
List<MatrixEvent> chunk;
/// An opaque string representing a pagination token. The absence of this token
/// means there are no more results to fetch and the client should stop paginating.
String? nextBatch;
/// An opaque string representing a pagination token. The absence of this token
/// means this is the start of the result set, i.e. this is the first batch/page.
String? prevBatch;
}
@_NameSource('generated')
@EnhancedEnum()
enum Include {
@EnhancedEnumValue(name: 'all')
all,
@EnhancedEnumValue(name: 'participated')
participated
}
@_NameSource('generated')
class GetThreadRootsResponse {
GetThreadRootsResponse({
required this.chunk,
this.nextBatch,
});
GetThreadRootsResponse.fromJson(Map<String, dynamic> json)
: chunk = (json['chunk'] as List)
.map((v) => MatrixEvent.fromJson(v))
.toList(),
nextBatch = ((v) => v != null ? v as String : null)(json['next_batch']);
Map<String, dynamic> toJson() {
final nextBatch = this.nextBatch;
return {
'chunk': chunk.map((v) => v.toJson()).toList(),
if (nextBatch != null) 'next_batch': nextBatch,
};
}
/// The thread roots, ordered by the `latest_event` in each event's aggregation bundle. All events
/// returned include bundled [aggregations](https://spec.matrix.org/unstable/client-server-api/#aggregations).
///
/// If the thread root event was sent by an [ignored user](https://spec.matrix.org/unstable/client-server-api/#ignoring-users), the
/// event is returned redacted to the caller. This is to simulate the same behaviour of a client doing
/// aggregation locally on the thread.
List<MatrixEvent> chunk;
/// A token to supply to `from` to keep paginating the responses. Not present when there are
/// no further results.
String? nextBatch;
}
@_NameSource('generated')
class GetEventByTimestampResponse {
GetEventByTimestampResponse({
required this.eventId,
required this.originServerTs,
});
GetEventByTimestampResponse.fromJson(Map<String, dynamic> json)
: eventId = json['event_id'] as String,
originServerTs = json['origin_server_ts'] as int;
Map<String, dynamic> toJson() => {
'event_id': eventId,
'origin_server_ts': originServerTs,
};
/// The ID of the event found
String eventId;
/// The event's timestamp, in milliseconds since the Unix epoch.
/// This makes it easy to do a quick comparison to see if the
/// `event_id` fetched is too far out of range to be useful for your
/// use case.
int originServerTs;
}
@_NameSource('rule override generated') @_NameSource('rule override generated')
@EnhancedEnum() @EnhancedEnum()
enum ThirdPartyIdentifierMedium { enum ThirdPartyIdentifierMedium {
@ -734,7 +930,8 @@ class Invite3pid {
/// The hostname+port of the identity server which should be used for third party identifier lookups. /// The hostname+port of the identity server which should be used for third party identifier lookups.
String idServer; String idServer;
/// The kind of address being passed in the address field, for example `email`. /// The kind of address being passed in the address field, for example `email`
/// (see [the list of recognised values](https://spec.matrix.org/unstable/appendices/#3pid-types)).
String medium; String medium;
} }
@ -996,7 +1193,7 @@ class ClaimKeysResponse {
(k, v) => MapEntry( (k, v) => MapEntry(
k, k,
(v as Map<String, dynamic>) (v as Map<String, dynamic>)
.map((k, v) => MapEntry(k, v as dynamic)))); .map((k, v) => MapEntry(k, v as Map<String, dynamic>))));
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final failures = this.failures; final failures = this.failures;
return { return {
@ -1023,7 +1220,7 @@ class ClaimKeysResponse {
/// ///
/// If necessary, the claimed key might be a fallback key. Fallback /// If necessary, the claimed key might be a fallback key. Fallback
/// keys are re-used by the server until replaced by the device. /// keys are re-used by the server until replaced by the device.
Map<String, Map<String, dynamic>> oneTimeKeys; Map<String, Map<String, Map<String, dynamic>>> oneTimeKeys;
} }
@_NameSource('generated') @_NameSource('generated')
@ -1151,45 +1348,59 @@ enum LoginType {
@_NameSource('generated') @_NameSource('generated')
class LoginResponse { class LoginResponse {
LoginResponse({ LoginResponse({
this.accessToken, required this.accessToken,
this.deviceId, required this.deviceId,
this.expiresInMs,
this.homeServer, this.homeServer,
this.userId, this.refreshToken,
required this.userId,
this.wellKnown, this.wellKnown,
}); });
LoginResponse.fromJson(Map<String, dynamic> json) LoginResponse.fromJson(Map<String, dynamic> json)
: accessToken = : accessToken = json['access_token'] as String,
((v) => v != null ? v as String : null)(json['access_token']), deviceId = json['device_id'] as String,
deviceId = ((v) => v != null ? v as String : null)(json['device_id']), expiresInMs =
((v) => v != null ? v as int : null)(json['expires_in_ms']),
homeServer = homeServer =
((v) => v != null ? v as String : null)(json['home_server']), ((v) => v != null ? v as String : null)(json['home_server']),
userId = ((v) => v != null ? v as String : null)(json['user_id']), refreshToken =
((v) => v != null ? v as String : null)(json['refresh_token']),
userId = json['user_id'] as String,
wellKnown = ((v) => v != null wellKnown = ((v) => v != null
? DiscoveryInformation.fromJson(v) ? DiscoveryInformation.fromJson(v)
: null)(json['well_known']); : null)(json['well_known']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final accessToken = this.accessToken; final expiresInMs = this.expiresInMs;
final deviceId = this.deviceId;
final homeServer = this.homeServer; final homeServer = this.homeServer;
final userId = this.userId; final refreshToken = this.refreshToken;
final wellKnown = this.wellKnown; final wellKnown = this.wellKnown;
return { return {
if (accessToken != null) 'access_token': accessToken, 'access_token': accessToken,
if (deviceId != null) 'device_id': deviceId, 'device_id': deviceId,
if (expiresInMs != null) 'expires_in_ms': expiresInMs,
if (homeServer != null) 'home_server': homeServer, if (homeServer != null) 'home_server': homeServer,
if (userId != null) 'user_id': userId, if (refreshToken != null) 'refresh_token': refreshToken,
'user_id': userId,
if (wellKnown != null) 'well_known': wellKnown.toJson(), if (wellKnown != null) 'well_known': wellKnown.toJson(),
}; };
} }
/// An access token for the account. /// An access token for the account.
/// This access token can then be used to authorize other requests. /// This access token can then be used to authorize other requests.
String? accessToken; String accessToken;
/// ID of the logged-in device. Will be the same as the /// ID of the logged-in device. Will be the same as the
/// corresponding parameter in the request, if one was specified. /// corresponding parameter in the request, if one was specified.
String? deviceId; String deviceId;
/// The lifetime of the access token, in milliseconds. Once
/// the access token has expired a new access token can be
/// obtained by using the provided refresh token. If no
/// refresh token is provided, the client will need to re-log in
/// to obtain a new access token. If not given, the client can
/// assume that the access token will not expire.
int? expiresInMs;
/// The server_name of the homeserver on which the account has /// The server_name of the homeserver on which the account has
/// been registered. /// been registered.
@ -1199,8 +1410,13 @@ class LoginResponse {
/// it. Note also that `homeserver` is not spelt this way. /// it. Note also that `homeserver` is not spelt this way.
String? homeServer; String? homeServer;
/// A refresh token for the account. This token can be used to
/// obtain a new access token when it expires by calling the
/// `/refresh` endpoint.
String? refreshToken;
/// The fully-qualified Matrix ID for the account. /// The fully-qualified Matrix ID for the account.
String? userId; String userId;
/// Optional client configuration provided by the server. If present, /// Optional client configuration provided by the server. If present,
/// clients SHOULD use the provided object to reconfigure themselves, /// clients SHOULD use the provided object to reconfigure themselves,
@ -1425,21 +1641,33 @@ class GetPublicRoomsResponse {
class PublicRoomQueryFilter { class PublicRoomQueryFilter {
PublicRoomQueryFilter({ PublicRoomQueryFilter({
this.genericSearchTerm, this.genericSearchTerm,
this.roomTypes,
}); });
PublicRoomQueryFilter.fromJson(Map<String, dynamic> json) PublicRoomQueryFilter.fromJson(Map<String, dynamic> json)
: genericSearchTerm = ((v) => : genericSearchTerm = ((v) =>
v != null ? v as String : null)(json['generic_search_term']); v != null ? v as String : null)(json['generic_search_term']),
roomTypes = ((v) => v != null
? (v as List).map((v) => v as String).toList()
: null)(json['room_types']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final genericSearchTerm = this.genericSearchTerm; final genericSearchTerm = this.genericSearchTerm;
final roomTypes = this.roomTypes;
return { return {
if (genericSearchTerm != null) 'generic_search_term': genericSearchTerm, if (genericSearchTerm != null) 'generic_search_term': genericSearchTerm,
if (roomTypes != null) 'room_types': roomTypes.map((v) => v).toList(),
}; };
} }
/// A string to search for in the room metadata, e.g. name, /// An optional string to search for in the room metadata, e.g. name,
/// topic, canonical alias etc. (Optional). /// topic, canonical alias, etc.
String? genericSearchTerm; String? genericSearchTerm;
/// An optional list of [room types](https://spec.matrix.org/unstable/client-server-api/#types) to search
/// for. To include rooms without a room type, specify `null` within this
/// list. When not specified, all applicable rooms (regardless of type)
/// are returned.
List<String>? roomTypes;
} }
/// A list of the rooms on the server. /// A list of the rooms on the server.
@ -1797,6 +2025,44 @@ enum PushRuleKind {
underride underride
} }
@_NameSource('generated')
class RefreshResponse {
RefreshResponse({
required this.accessToken,
this.expiresInMs,
this.refreshToken,
});
RefreshResponse.fromJson(Map<String, dynamic> json)
: accessToken = json['access_token'] as String,
expiresInMs =
((v) => v != null ? v as int : null)(json['expires_in_ms']),
refreshToken =
((v) => v != null ? v as String : null)(json['refresh_token']);
Map<String, dynamic> toJson() {
final expiresInMs = this.expiresInMs;
final refreshToken = this.refreshToken;
return {
'access_token': accessToken,
if (expiresInMs != null) 'expires_in_ms': expiresInMs,
if (refreshToken != null) 'refresh_token': refreshToken,
};
}
/// The new access token to use.
String accessToken;
/// The lifetime of the access token, in milliseconds. If not
/// given, the client can assume that the access token will not
/// expire.
int? expiresInMs;
/// The new refresh token to use when the access token needs to
/// be refreshed again. If not given, the old refresh token can
/// be re-used.
String? refreshToken;
}
@_NameSource('rule override generated') @_NameSource('rule override generated')
@EnhancedEnum() @EnhancedEnum()
enum AccountKind { enum AccountKind {
@ -1811,7 +2077,9 @@ class RegisterResponse {
RegisterResponse({ RegisterResponse({
this.accessToken, this.accessToken,
this.deviceId, this.deviceId,
this.expiresInMs,
this.homeServer, this.homeServer,
this.refreshToken,
required this.userId, required this.userId,
}); });
@ -1819,17 +2087,25 @@ class RegisterResponse {
: accessToken = : accessToken =
((v) => v != null ? v as String : null)(json['access_token']), ((v) => v != null ? v as String : null)(json['access_token']),
deviceId = ((v) => v != null ? v as String : null)(json['device_id']), deviceId = ((v) => v != null ? v as String : null)(json['device_id']),
expiresInMs =
((v) => v != null ? v as int : null)(json['expires_in_ms']),
homeServer = homeServer =
((v) => v != null ? v as String : null)(json['home_server']), ((v) => v != null ? v as String : null)(json['home_server']),
refreshToken =
((v) => v != null ? v as String : null)(json['refresh_token']),
userId = json['user_id'] as String; userId = json['user_id'] as String;
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final accessToken = this.accessToken; final accessToken = this.accessToken;
final deviceId = this.deviceId; final deviceId = this.deviceId;
final expiresInMs = this.expiresInMs;
final homeServer = this.homeServer; final homeServer = this.homeServer;
final refreshToken = this.refreshToken;
return { return {
if (accessToken != null) 'access_token': accessToken, if (accessToken != null) 'access_token': accessToken,
if (deviceId != null) 'device_id': deviceId, if (deviceId != null) 'device_id': deviceId,
if (expiresInMs != null) 'expires_in_ms': expiresInMs,
if (homeServer != null) 'home_server': homeServer, if (homeServer != null) 'home_server': homeServer,
if (refreshToken != null) 'refresh_token': refreshToken,
'user_id': userId, 'user_id': userId,
}; };
} }
@ -1844,6 +2120,16 @@ class RegisterResponse {
/// Required if the `inhibit_login` option is false. /// Required if the `inhibit_login` option is false.
String? deviceId; String? deviceId;
/// The lifetime of the access token, in milliseconds. Once
/// the access token has expired a new access token can be
/// obtained by using the provided refresh token. If no
/// refresh token is provided, the client will need to re-log in
/// to obtain a new access token. If not given, the client can
/// assume that the access token will not expire.
///
/// Omitted if the `inhibit_login` option is true.
int? expiresInMs;
/// The server_name of the homeserver on which the account has /// The server_name of the homeserver on which the account has
/// been registered. /// been registered.
/// ///
@ -1852,6 +2138,13 @@ class RegisterResponse {
/// it. Note also that `homeserver` is not spelt this way. /// it. Note also that `homeserver` is not spelt this way.
String? homeServer; String? homeServer;
/// A refresh token for the account. This token can be used to
/// obtain a new access token when it expires by calling the
/// `/refresh` endpoint.
///
/// Omitted if the `inhibit_login` option is true.
String? refreshToken;
/// The fully-qualified Matrix user ID (MXID) that has been registered. /// The fully-qualified Matrix user ID (MXID) that has been registered.
/// ///
/// Any user ID returned by this API must conform to the grammar given in the /// Any user ID returned by this API must conform to the grammar given in the
@ -2161,15 +2454,6 @@ enum Membership {
leave leave
} }
@_NameSource('rule override generated')
@EnhancedEnum()
enum Direction {
@EnhancedEnumValue(name: 'b')
b,
@EnhancedEnumValue(name: 'f')
f
}
/// A list of messages with a new token to request more. /// A list of messages with a new token to request more.
@_NameSource('generated') @_NameSource('generated')
class GetRoomEventsResponse { class GetRoomEventsResponse {
@ -2237,8 +2521,12 @@ class GetRoomEventsResponse {
@_NameSource('generated') @_NameSource('generated')
@EnhancedEnum() @EnhancedEnum()
enum ReceiptType { enum ReceiptType {
@EnhancedEnumValue(name: 'm.fully_read')
mFullyRead,
@EnhancedEnumValue(name: 'm.read') @EnhancedEnumValue(name: 'm.read')
mRead mRead,
@EnhancedEnumValue(name: 'm.read.private')
mReadPrivate
} }
@_NameSource('spec') @_NameSource('spec')
@ -2344,6 +2632,7 @@ class RoomEventFilter {
this.lazyLoadMembers, this.lazyLoadMembers,
this.notRooms, this.notRooms,
this.rooms, this.rooms,
this.unreadThreadNotifications,
}); });
RoomEventFilter.fromJson(Map<String, dynamic> json) RoomEventFilter.fromJson(Map<String, dynamic> json)
@ -2358,13 +2647,16 @@ class RoomEventFilter {
: null)(json['not_rooms']), : null)(json['not_rooms']),
rooms = ((v) => v != null rooms = ((v) => v != null
? (v as List).map((v) => v as String).toList() ? (v as List).map((v) => v as String).toList()
: null)(json['rooms']); : null)(json['rooms']),
unreadThreadNotifications = ((v) =>
v != null ? v as bool : null)(json['unread_thread_notifications']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final containsUrl = this.containsUrl; final containsUrl = this.containsUrl;
final includeRedundantMembers = this.includeRedundantMembers; final includeRedundantMembers = this.includeRedundantMembers;
final lazyLoadMembers = this.lazyLoadMembers; final lazyLoadMembers = this.lazyLoadMembers;
final notRooms = this.notRooms; final notRooms = this.notRooms;
final rooms = this.rooms; final rooms = this.rooms;
final unreadThreadNotifications = this.unreadThreadNotifications;
return { return {
if (containsUrl != null) 'contains_url': containsUrl, if (containsUrl != null) 'contains_url': containsUrl,
if (includeRedundantMembers != null) if (includeRedundantMembers != null)
@ -2372,6 +2664,8 @@ class RoomEventFilter {
if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers, if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers,
if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(), if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(),
if (rooms != null) 'rooms': rooms.map((v) => v).toList(), if (rooms != null) 'rooms': rooms.map((v) => v).toList(),
if (unreadThreadNotifications != null)
'unread_thread_notifications': unreadThreadNotifications,
}; };
} }
@ -2395,6 +2689,10 @@ class RoomEventFilter {
/// A list of room IDs to include. If this list is absent then all rooms are included. /// A list of room IDs to include. If this list is absent then all rooms are included.
List<String>? rooms; List<String>? rooms;
/// If `true`, enables per-[thread](https://spec.matrix.org/unstable/client-server-api/#threading) notification
/// counts. Only applies to the `/sync` endpoint. Defaults to `false`.
bool? unreadThreadNotifications;
} }
@_NameSource('rule override generated') @_NameSource('rule override generated')
@ -2410,6 +2708,7 @@ class SearchFilter implements EventFilter, RoomEventFilter {
this.lazyLoadMembers, this.lazyLoadMembers,
this.notRooms, this.notRooms,
this.rooms, this.rooms,
this.unreadThreadNotifications,
}); });
SearchFilter.fromJson(Map<String, dynamic> json) SearchFilter.fromJson(Map<String, dynamic> json)
@ -2437,7 +2736,9 @@ class SearchFilter implements EventFilter, RoomEventFilter {
: null)(json['not_rooms']), : null)(json['not_rooms']),
rooms = ((v) => v != null rooms = ((v) => v != null
? (v as List).map((v) => v as String).toList() ? (v as List).map((v) => v as String).toList()
: null)(json['rooms']); : null)(json['rooms']),
unreadThreadNotifications = ((v) =>
v != null ? v as bool : null)(json['unread_thread_notifications']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final limit = this.limit; final limit = this.limit;
final notSenders = this.notSenders; final notSenders = this.notSenders;
@ -2449,6 +2750,7 @@ class SearchFilter implements EventFilter, RoomEventFilter {
final lazyLoadMembers = this.lazyLoadMembers; final lazyLoadMembers = this.lazyLoadMembers;
final notRooms = this.notRooms; final notRooms = this.notRooms;
final rooms = this.rooms; final rooms = this.rooms;
final unreadThreadNotifications = this.unreadThreadNotifications;
return { return {
if (limit != null) 'limit': limit, if (limit != null) 'limit': limit,
if (notSenders != null) 'not_senders': notSenders.map((v) => v).toList(), if (notSenders != null) 'not_senders': notSenders.map((v) => v).toList(),
@ -2461,6 +2763,8 @@ class SearchFilter implements EventFilter, RoomEventFilter {
if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers, if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers,
if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(), if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(),
if (rooms != null) 'rooms': rooms.map((v) => v).toList(), if (rooms != null) 'rooms': rooms.map((v) => v).toList(),
if (unreadThreadNotifications != null)
'unread_thread_notifications': unreadThreadNotifications,
}; };
} }
@ -2499,6 +2803,10 @@ class SearchFilter implements EventFilter, RoomEventFilter {
/// A list of room IDs to include. If this list is absent then all rooms are included. /// A list of room IDs to include. If this list is absent then all rooms are included.
List<String>? rooms; List<String>? rooms;
/// If `true`, enables per-[thread](https://spec.matrix.org/unstable/client-server-api/#threading) notification
/// counts. Only applies to the `/sync` endpoint. Defaults to `false`.
bool? unreadThreadNotifications;
} }
@_NameSource('rule override generated') @_NameSource('rule override generated')
@ -3145,6 +3453,7 @@ class StateFilter implements EventFilter, RoomEventFilter {
this.lazyLoadMembers, this.lazyLoadMembers,
this.notRooms, this.notRooms,
this.rooms, this.rooms,
this.unreadThreadNotifications,
}); });
StateFilter.fromJson(Map<String, dynamic> json) StateFilter.fromJson(Map<String, dynamic> json)
@ -3172,7 +3481,9 @@ class StateFilter implements EventFilter, RoomEventFilter {
: null)(json['not_rooms']), : null)(json['not_rooms']),
rooms = ((v) => v != null rooms = ((v) => v != null
? (v as List).map((v) => v as String).toList() ? (v as List).map((v) => v as String).toList()
: null)(json['rooms']); : null)(json['rooms']),
unreadThreadNotifications = ((v) =>
v != null ? v as bool : null)(json['unread_thread_notifications']);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final limit = this.limit; final limit = this.limit;
final notSenders = this.notSenders; final notSenders = this.notSenders;
@ -3184,6 +3495,7 @@ class StateFilter implements EventFilter, RoomEventFilter {
final lazyLoadMembers = this.lazyLoadMembers; final lazyLoadMembers = this.lazyLoadMembers;
final notRooms = this.notRooms; final notRooms = this.notRooms;
final rooms = this.rooms; final rooms = this.rooms;
final unreadThreadNotifications = this.unreadThreadNotifications;
return { return {
if (limit != null) 'limit': limit, if (limit != null) 'limit': limit,
if (notSenders != null) 'not_senders': notSenders.map((v) => v).toList(), if (notSenders != null) 'not_senders': notSenders.map((v) => v).toList(),
@ -3196,6 +3508,8 @@ class StateFilter implements EventFilter, RoomEventFilter {
if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers, if (lazyLoadMembers != null) 'lazy_load_members': lazyLoadMembers,
if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(), if (notRooms != null) 'not_rooms': notRooms.map((v) => v).toList(),
if (rooms != null) 'rooms': rooms.map((v) => v).toList(), if (rooms != null) 'rooms': rooms.map((v) => v).toList(),
if (unreadThreadNotifications != null)
'unread_thread_notifications': unreadThreadNotifications,
}; };
} }
@ -3234,6 +3548,10 @@ class StateFilter implements EventFilter, RoomEventFilter {
/// A list of room IDs to include. If this list is absent then all rooms are included. /// A list of room IDs to include. If this list is absent then all rooms are included.
List<String>? rooms; List<String>? rooms;
/// If `true`, enables per-[thread](https://spec.matrix.org/unstable/client-server-api/#threading) notification
/// counts. Only applies to the `/sync` endpoint. Defaults to `false`.
bool? unreadThreadNotifications;
} }
@_NameSource('spec') @_NameSource('spec')
@ -3287,7 +3605,7 @@ class RoomFilter {
/// The per user account data to include for rooms. /// The per user account data to include for rooms.
StateFilter? accountData; StateFilter? accountData;
/// The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms. /// The ephemeral events to include for rooms. These are the events that appear in the `ephemeral` property in the `/sync` response.
StateFilter? ephemeral; StateFilter? ephemeral;
/// Include rooms that the user has left in the sync, default false /// Include rooms that the user has left in the sync, default false

View File

@ -979,7 +979,6 @@ void main() {
'!localpart:example.com', '!localpart:example.com',
ReceiptType.mRead, ReceiptType.mRead,
'\$1234:example.com', '\$1234:example.com',
{},
); );
matrixApi.homeserver = matrixApi.accessToken = null; matrixApi.homeserver = matrixApi.accessToken = null;
@ -990,7 +989,7 @@ void main() {
await matrixApi.setReadMarker( await matrixApi.setReadMarker(
'!localpart:example.com', '!localpart:example.com',
'\$1234:example.com', mFullyRead: '\$1234:example.com',
mRead: '\$1234:example.com', mRead: '\$1234:example.com',
); );