aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/csapi/account-data.h61
-rw-r--r--lib/csapi/definitions/public_rooms_response.h6
-rw-r--r--lib/csapi/definitions/room_event_filter.h9
-rw-r--r--lib/csapi/joining.h2
-rw-r--r--lib/csapi/keys.h4
-rw-r--r--lib/csapi/list_public_rooms.h10
-rw-r--r--lib/csapi/login.cpp3
-rw-r--r--lib/csapi/read_markers.cpp7
-rw-r--r--lib/csapi/read_markers.h11
-rw-r--r--lib/csapi/receipts.h8
-rw-r--r--lib/csapi/redaction.h6
-rw-r--r--lib/csapi/relations.cpp45
-rw-r--r--lib/csapi/relations.h55
-rw-r--r--lib/csapi/room_send.h7
-rw-r--r--lib/csapi/threads_list.cpp37
-rw-r--r--lib/csapi/threads_list.h76
-rw-r--r--lib/csapi/to_device.h7
17 files changed, 269 insertions, 85 deletions
diff --git a/lib/csapi/account-data.h b/lib/csapi/account-data.h
index 5140d340..70d4e492 100644
--- a/lib/csapi/account-data.h
+++ b/lib/csapi/account-data.h
@@ -8,46 +8,47 @@
namespace Quotient {
-/*! \brief Set some account_data for the user.
+/*! \brief Set some account data for 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
- * top-level `account_data`.
+ * Set some account data for the client. This config is only visible to the user
+ * that set the account data. The config will be available to clients through
+ * the top-level `account_data` field in the homeserver response to
+ * [/sync](#get_matrixclientv3sync).
*/
class QUOTIENT_API SetAccountDataJob : public BaseJob {
public:
- /*! \brief Set some account_data for the user.
+ /*! \brief Set some account data for the user.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to set account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param type
- * The event type of the account_data to set. Custom types should be
+ * The event type of the account data to set. Custom types should be
* namespaced to avoid clashes.
*
* \param content
- * The content of the account_data
+ * The content of the account data.
*/
explicit SetAccountDataJob(const QString& userId, const QString& type,
const QJsonObject& content = {});
};
-/*! \brief Get some account_data for the user.
+/*! \brief Get some account data for the user.
*
- * Get some account_data for the client. This config is only visible to the user
- * that set the account_data.
+ * Get some account data for the client. This config is only visible to the user
+ * that set the account data.
*/
class QUOTIENT_API GetAccountDataJob : public BaseJob {
public:
- /*! \brief Get some account_data for the user.
+ /*! \brief Get some account data for the user.
*
* \param userId
- * The ID of the user to get account_data for. The access token must be
+ * The ID of the user to get account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param type
- * The event type of the account_data to get. Custom types should be
+ * The event type of the account data to get. Custom types should be
* namespaced to avoid clashes.
*/
explicit GetAccountDataJob(const QString& userId, const QString& type);
@@ -61,53 +62,53 @@ public:
const QString& type);
};
-/*! \brief Set some account_data for the user.
+/*! \brief Set some account data for the user that is specific to a room.
*
- * 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
- * clients in the per-room `account_data`.
+ * 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 delivered
+ * to clients in the per-room entries via [/sync](#get_matrixclientv3sync).
*/
class QUOTIENT_API SetAccountDataPerRoomJob : public BaseJob {
public:
- /*! \brief Set some account_data for the user.
+ /*! \brief Set some account data for the user that is specific to a room.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to set account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
- * The ID of the room to set account_data on.
+ * The ID of the room to set account data on.
*
* \param type
- * The event type of the account_data to set. Custom types should be
+ * The event type of the account data to set. Custom types should be
* namespaced to avoid clashes.
*
* \param content
- * The content of the account_data
+ * The content of the account data.
*/
explicit SetAccountDataPerRoomJob(const QString& userId,
const QString& roomId, const QString& type,
const QJsonObject& content = {});
};
-/*! \brief Get some account_data for the user.
+/*! \brief Get some account data for the user that is specific to a room.
*
- * Get some account_data for the client on a given room. This config is only
- * visible to the user that set the account_data.
+ * Get some account data for the client on a given room. This config is only
+ * visible to the user that set the account data.
*/
class QUOTIENT_API GetAccountDataPerRoomJob : public BaseJob {
public:
- /*! \brief Get some account_data for the user.
+ /*! \brief Get some account data for the user that is specific to a room.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to get account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
- * The ID of the room to get account_data for.
+ * The ID of the room to get account data for.
*
* \param type
- * The event type of the account_data to get. Custom types should be
+ * The event type of the account data to get. Custom types should be
* namespaced to avoid clashes.
*/
explicit GetAccountDataPerRoomJob(const QString& userId,
diff --git a/lib/csapi/definitions/public_rooms_response.h b/lib/csapi/definitions/public_rooms_response.h
index d0a2595c..7c7d9cc6 100644
--- a/lib/csapi/definitions/public_rooms_response.h
+++ b/lib/csapi/definitions/public_rooms_response.h
@@ -35,6 +35,10 @@ struct PublicRoomsChunk {
/// The URL for the room's avatar, if one is set.
QUrl avatarUrl;
+ /// The `type` of room (from
+ /// [`m.room.create`](/client-server-api/#mroomcreate)), if any.
+ QString roomType;
+
/// The room's join rule. When not present, the room is assumed to
/// be `public`. Note that rooms with `invite` join rules are not
/// expected here, but rooms with `knock` rules are given their
@@ -56,6 +60,7 @@ struct JsonObjectConverter<PublicRoomsChunk> {
addParam<>(jo, QStringLiteral("world_readable"), pod.worldReadable);
addParam<>(jo, QStringLiteral("guest_can_join"), pod.guestCanJoin);
addParam<IfNotEmpty>(jo, QStringLiteral("avatar_url"), pod.avatarUrl);
+ addParam<IfNotEmpty>(jo, QStringLiteral("room_type"), pod.roomType);
addParam<IfNotEmpty>(jo, QStringLiteral("join_rule"), pod.joinRule);
}
static void fillFrom(const QJsonObject& jo, PublicRoomsChunk& pod)
@@ -68,6 +73,7 @@ struct JsonObjectConverter<PublicRoomsChunk> {
fromJson(jo.value("world_readable"_ls), pod.worldReadable);
fromJson(jo.value("guest_can_join"_ls), pod.guestCanJoin);
fromJson(jo.value("avatar_url"_ls), pod.avatarUrl);
+ fromJson(jo.value("room_type"_ls), pod.roomType);
fromJson(jo.value("join_rule"_ls), pod.joinRule);
}
};
diff --git a/lib/csapi/definitions/room_event_filter.h b/lib/csapi/definitions/room_event_filter.h
index 91caf667..293e5492 100644
--- a/lib/csapi/definitions/room_event_filter.h
+++ b/lib/csapi/definitions/room_event_filter.h
@@ -11,6 +11,11 @@
namespace Quotient {
struct RoomEventFilter : EventFilter {
+ /// If `true`, enables per-[thread](/client-server-api/#threading)
+ /// notification counts. Only applies to the `/sync` endpoint. Defaults to
+ /// `false`.
+ Omittable<bool> unreadThreadNotifications;
+
/// If `true`, enables lazy-loading of membership events. See
/// [Lazy-loading room
/// members](/client-server-api/#lazy-loading-room-members) for more
@@ -44,6 +49,8 @@ struct JsonObjectConverter<RoomEventFilter> {
static void dumpTo(QJsonObject& jo, const RoomEventFilter& pod)
{
fillJson<EventFilter>(jo, pod);
+ addParam<IfNotEmpty>(jo, QStringLiteral("unread_thread_notifications"),
+ pod.unreadThreadNotifications);
addParam<IfNotEmpty>(jo, QStringLiteral("lazy_load_members"),
pod.lazyLoadMembers);
addParam<IfNotEmpty>(jo, QStringLiteral("include_redundant_members"),
@@ -56,6 +63,8 @@ struct JsonObjectConverter<RoomEventFilter> {
static void fillFrom(const QJsonObject& jo, RoomEventFilter& pod)
{
fillFromJson<EventFilter>(jo, pod);
+ fromJson(jo.value("unread_thread_notifications"_ls),
+ pod.unreadThreadNotifications);
fromJson(jo.value("lazy_load_members"_ls), pod.lazyLoadMembers);
fromJson(jo.value("include_redundant_members"_ls),
pod.includeRedundantMembers);
diff --git a/lib/csapi/joining.h b/lib/csapi/joining.h
index 233537bb..c86baa90 100644
--- a/lib/csapi/joining.h
+++ b/lib/csapi/joining.h
@@ -55,7 +55,7 @@ public:
/*! \brief Start the requesting user participating in a particular room.
*
* *Note that this API takes either a room ID or alias, unlike*
- * `/room/{roomId}/join`.
+ * `/rooms/{roomId}/join`.
*
* 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
diff --git a/lib/csapi/keys.h b/lib/csapi/keys.h
index 2f2ebc6d..b28de305 100644
--- a/lib/csapi/keys.h
+++ b/lib/csapi/keys.h
@@ -4,11 +4,11 @@
#pragma once
-#include "e2ee/e2ee.h"
-
#include "csapi/definitions/cross_signing_key.h"
#include "csapi/definitions/device_keys.h"
+#include "e2ee/e2ee.h"
+
#include "jobs/basejob.h"
namespace Quotient {
diff --git a/lib/csapi/list_public_rooms.h b/lib/csapi/list_public_rooms.h
index e1f03db7..3b6b91b9 100644
--- a/lib/csapi/list_public_rooms.h
+++ b/lib/csapi/list_public_rooms.h
@@ -139,9 +139,14 @@ public:
/// Filter to apply to the results.
struct Filter {
- /// A string to search for in the room metadata, e.g. name,
- /// topic, canonical alias etc. (Optional).
+ /// An optional string to search for in the room metadata, e.g. name,
+ /// topic, canonical alias, etc.
QString genericSearchTerm;
+ /// An optional list of [room types](/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.
+ QStringList roomTypes;
};
// Construction/destruction
@@ -211,6 +216,7 @@ struct JsonObjectConverter<QueryPublicRoomsJob::Filter> {
{
addParam<IfNotEmpty>(jo, QStringLiteral("generic_search_term"),
pod.genericSearchTerm);
+ addParam<IfNotEmpty>(jo, QStringLiteral("room_types"), pod.roomTypes);
}
};
diff --git a/lib/csapi/login.cpp b/lib/csapi/login.cpp
index 81e603b5..7bb74e29 100644
--- a/lib/csapi/login.cpp
+++ b/lib/csapi/login.cpp
@@ -38,4 +38,7 @@ LoginJob::LoginJob(const QString& type,
addParam<IfNotEmpty>(_dataJson, QStringLiteral("refresh_token"),
refreshToken);
setRequestData({ _dataJson });
+ addExpectedKey("user_id");
+ addExpectedKey("access_token");
+ addExpectedKey("device_id");
}
diff --git a/lib/csapi/read_markers.cpp b/lib/csapi/read_markers.cpp
index de5f4a9a..febd6d3a 100644
--- a/lib/csapi/read_markers.cpp
+++ b/lib/csapi/read_markers.cpp
@@ -8,12 +8,15 @@ using namespace Quotient;
SetReadMarkerJob::SetReadMarkerJob(const QString& roomId,
const QString& mFullyRead,
- const QString& mRead)
+ const QString& mRead,
+ const QString& mReadPrivate)
: BaseJob(HttpVerb::Post, QStringLiteral("SetReadMarkerJob"),
makePath("/_matrix/client/v3", "/rooms/", roomId, "/read_markers"))
{
QJsonObject _dataJson;
- addParam<>(_dataJson, QStringLiteral("m.fully_read"), mFullyRead);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.fully_read"), mFullyRead);
addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.read"), mRead);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.read.private"),
+ mReadPrivate);
setRequestData({ _dataJson });
}
diff --git a/lib/csapi/read_markers.h b/lib/csapi/read_markers.h
index d13fa4fc..1024076f 100644
--- a/lib/csapi/read_markers.h
+++ b/lib/csapi/read_markers.h
@@ -28,9 +28,16 @@ public:
* The event ID to set the read receipt location at. This is
* equivalent to calling `/receipt/m.read/$elsewhere:example.org`
* and is provided here to save that extra call.
+ *
+ * \param 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.
*/
- explicit SetReadMarkerJob(const QString& roomId, const QString& mFullyRead,
- const QString& mRead = {});
+ explicit SetReadMarkerJob(const QString& roomId,
+ const QString& mFullyRead = {},
+ const QString& mRead = {},
+ const QString& mReadPrivate = {});
};
} // namespace Quotient
diff --git a/lib/csapi/receipts.h b/lib/csapi/receipts.h
index e29e7b29..98bc5004 100644
--- a/lib/csapi/receipts.h
+++ b/lib/csapi/receipts.h
@@ -21,7 +21,13 @@ public:
* The room in which to send the event.
*
* \param receiptType
- * The type of receipt to send.
+ * The type of receipt to send. This can also be `m.fully_read` as an
+ * alternative to
+ * [`/read_makers`](/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`.
*
* \param eventId
* The event ID to acknowledge up to.
diff --git a/lib/csapi/redaction.h b/lib/csapi/redaction.h
index 29d9c5d5..2f85793e 100644
--- a/lib/csapi/redaction.h
+++ b/lib/csapi/redaction.h
@@ -33,9 +33,9 @@ public:
* The ID of the event to redact
*
* \param txnId
- * The transaction ID for this event. Clients should generate a
- * unique ID; it will be used by the server to ensure idempotency of
- * requests.
+ * The [transaction ID](/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.
*
* \param reason
* The reason for the event being redacted.
diff --git a/lib/csapi/relations.cpp b/lib/csapi/relations.cpp
index 8bcecee4..1d8febcc 100644
--- a/lib/csapi/relations.cpp
+++ b/lib/csapi/relations.cpp
@@ -7,105 +7,112 @@
using namespace Quotient;
auto queryToGetRelatingEvents(const QString& from, const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit, const QString& dir)
{
QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
return _q;
}
QUrl GetRelatingEventsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& eventId,
const QString& from, const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit,
+ const QString& dir)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
makePath("/_matrix/client/v1", "/rooms/",
roomId, "/relations/", eventId),
- queryToGetRelatingEvents(from, to, limit));
+ queryToGetRelatingEvents(from, to, limit,
+ dir));
}
-GetRelatingEventsJob::GetRelatingEventsJob(const QString& roomId,
- const QString& eventId,
- const QString& from,
- const QString& to,
- Omittable<int> limit)
+GetRelatingEventsJob::GetRelatingEventsJob(
+ const QString& roomId, const QString& eventId, const QString& from,
+ const QString& to, Omittable<int> limit, const QString& dir)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRelatingEventsJob"),
makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
eventId),
- queryToGetRelatingEvents(from, to, limit))
+ queryToGetRelatingEvents(from, to, limit, dir))
{
addExpectedKey("chunk");
}
auto queryToGetRelatingEventsWithRelType(const QString& from, const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit,
+ const QString& dir)
{
QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
return _q;
}
QUrl GetRelatingEventsWithRelTypeJob::makeRequestUrl(
QUrl baseUrl, const QString& roomId, const QString& eventId,
const QString& relType, const QString& from, const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit, const QString& dir)
{
return BaseJob::makeRequestUrl(
std::move(baseUrl),
makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
eventId, "/", relType),
- queryToGetRelatingEventsWithRelType(from, to, limit));
+ queryToGetRelatingEventsWithRelType(from, to, limit, dir));
}
GetRelatingEventsWithRelTypeJob::GetRelatingEventsWithRelTypeJob(
const QString& roomId, const QString& eventId, const QString& relType,
- const QString& from, const QString& to, Omittable<int> limit)
+ const QString& from, const QString& to, Omittable<int> limit,
+ const QString& dir)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRelatingEventsWithRelTypeJob"),
makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
eventId, "/", relType),
- queryToGetRelatingEventsWithRelType(from, to, limit))
+ queryToGetRelatingEventsWithRelType(from, to, limit, dir))
{
addExpectedKey("chunk");
}
auto queryToGetRelatingEventsWithRelTypeAndEventType(const QString& from,
const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit,
+ const QString& dir)
{
QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
return _q;
}
QUrl GetRelatingEventsWithRelTypeAndEventTypeJob::makeRequestUrl(
QUrl baseUrl, const QString& roomId, const QString& eventId,
const QString& relType, const QString& eventType, const QString& from,
- const QString& to, Omittable<int> limit)
+ const QString& to, Omittable<int> limit, const QString& dir)
{
return BaseJob::makeRequestUrl(
std::move(baseUrl),
makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
eventId, "/", relType, "/", eventType),
- queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit));
+ queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit, dir));
}
GetRelatingEventsWithRelTypeAndEventTypeJob::
GetRelatingEventsWithRelTypeAndEventTypeJob(
const QString& roomId, const QString& eventId, const QString& relType,
const QString& eventType, const QString& from, const QString& to,
- Omittable<int> limit)
+ Omittable<int> limit, const QString& dir)
: BaseJob(HttpVerb::Get,
QStringLiteral("GetRelatingEventsWithRelTypeAndEventTypeJob"),
makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
eventId, "/", relType, "/", eventType),
- queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit))
+ queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit,
+ dir))
{
addExpectedKey("chunk");
}
diff --git a/lib/csapi/relations.h b/lib/csapi/relations.h
index 794ae445..5d6efd1c 100644
--- a/lib/csapi/relations.h
+++ b/lib/csapi/relations.h
@@ -36,8 +36,8 @@ public:
* 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` token from a previous call, or a returned
- * `start` token from
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
* [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
* or a `next_batch` token from
* [`/sync`](/client-server-api/#get_matrixclientv3sync).
@@ -55,11 +55,18 @@ public:
* responses.
*
* Similarly, the server should apply a default value when not supplied.
+ *
+ * \param 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`.
*/
explicit GetRelatingEventsJob(const QString& roomId, const QString& eventId,
const QString& from = {},
const QString& to = {},
- Omittable<int> limit = none);
+ Omittable<int> limit = none,
+ const QString& dir = {});
/*! \brief Construct a URL without creating a full-fledged job object
*
@@ -69,7 +76,8 @@ public:
static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& eventId, const QString& from = {},
const QString& to = {},
- Omittable<int> limit = none);
+ Omittable<int> limit = none,
+ const QString& dir = {});
// Result properties
@@ -122,8 +130,8 @@ public:
* 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` token from a previous call, or a returned
- * `start` token from
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
* [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
* or a `next_batch` token from
* [`/sync`](/client-server-api/#get_matrixclientv3sync).
@@ -141,13 +149,17 @@ public:
* responses.
*
* Similarly, the server should apply a default value when not supplied.
+ *
+ * \param 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`.
*/
- explicit GetRelatingEventsWithRelTypeJob(const QString& roomId,
- const QString& eventId,
- const QString& relType,
- const QString& from = {},
- const QString& to = {},
- Omittable<int> limit = none);
+ explicit GetRelatingEventsWithRelTypeJob(
+ const QString& roomId, const QString& eventId, const QString& relType,
+ const QString& from = {}, const QString& to = {},
+ Omittable<int> limit = none, const QString& dir = {});
/*! \brief Construct a URL without creating a full-fledged job object
*
@@ -157,7 +169,8 @@ public:
static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& eventId, const QString& relType,
const QString& from = {}, const QString& to = {},
- Omittable<int> limit = none);
+ Omittable<int> limit = none,
+ const QString& dir = {});
// Result properties
@@ -219,8 +232,8 @@ public:
* 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` token from a previous call, or a returned
- * `start` token from
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
* [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
* or a `next_batch` token from
* [`/sync`](/client-server-api/#get_matrixclientv3sync).
@@ -238,11 +251,18 @@ public:
* responses.
*
* Similarly, the server should apply a default value when not supplied.
+ *
+ * \param 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`.
*/
explicit GetRelatingEventsWithRelTypeAndEventTypeJob(
const QString& roomId, const QString& eventId, const QString& relType,
const QString& eventType, const QString& from = {},
- const QString& to = {}, Omittable<int> limit = none);
+ const QString& to = {}, Omittable<int> limit = none,
+ const QString& dir = {});
/*! \brief Construct a URL without creating a full-fledged job object
*
@@ -254,7 +274,8 @@ public:
const QString& eventId, const QString& relType,
const QString& eventType,
const QString& from = {}, const QString& to = {},
- Omittable<int> limit = none);
+ Omittable<int> limit = none,
+ const QString& dir = {});
// Result properties
diff --git a/lib/csapi/room_send.h b/lib/csapi/room_send.h
index fcb6b24f..abe5f207 100644
--- a/lib/csapi/room_send.h
+++ b/lib/csapi/room_send.h
@@ -30,9 +30,10 @@ public:
* The type of event to send.
*
* \param txnId
- * The transaction ID for this event. Clients should generate an
- * ID unique across requests with the same access token; it will be
- * used by the server to ensure idempotency of requests.
+ * The [transaction ID](/client-server-api/#transaction-identifiers) for
+ * this event. Clients should generate an ID unique across requests with the
+ * same access token; it will be used by the server to ensure idempotency of
+ * requests.
*
* \param body
* This endpoint is used to send a message event to a room. Message events
diff --git a/lib/csapi/threads_list.cpp b/lib/csapi/threads_list.cpp
new file mode 100644
index 00000000..26924f24
--- /dev/null
+++ b/lib/csapi/threads_list.cpp
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "threads_list.h"
+
+using namespace Quotient;
+
+auto queryToGetThreadRoots(const QString& include, Omittable<int> limit,
+ const QString& from)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("include"), include);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ return _q;
+}
+
+QUrl GetThreadRootsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& include,
+ Omittable<int> limit, const QString& from)
+{
+ return BaseJob::makeRequestUrl(std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/",
+ roomId, "/threads"),
+ queryToGetThreadRoots(include, limit, from));
+}
+
+GetThreadRootsJob::GetThreadRootsJob(const QString& roomId,
+ const QString& include,
+ Omittable<int> limit, const QString& from)
+ : BaseJob(HttpVerb::Get, QStringLiteral("GetThreadRootsJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/threads"),
+ queryToGetThreadRoots(include, limit, from))
+{
+ addExpectedKey("chunk");
+}
diff --git a/lib/csapi/threads_list.h b/lib/csapi/threads_list.h
new file mode 100644
index 00000000..7041583a
--- /dev/null
+++ b/lib/csapi/threads_list.h
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "events/roomevent.h"
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Retrieve a list of threads in a room, with optional filters.
+ *
+ * Paginates over the thread roots in a room, ordered by the `latest_event` of
+ * each thread root in its bundle.
+ */
+class QUOTIENT_API GetThreadRootsJob : public BaseJob {
+public:
+ /*! \brief Retrieve a list of threads in a room, with optional filters.
+ *
+ * \param roomId
+ * The room ID where the thread roots are located.
+ *
+ * \param 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](/client-server-api/#server-side-aggreagtion-of-mthread-relationships)
+ * will be returned.
+ *
+ * \param 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.
+ *
+ * \param 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).
+ */
+ explicit GetThreadRootsJob(const QString& roomId,
+ const QString& include = {},
+ Omittable<int> limit = none,
+ const QString& from = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for GetThreadRootsJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& include = {},
+ Omittable<int> limit = none,
+ const QString& from = {});
+
+ // Result properties
+
+ /// The thread roots, ordered by the `latest_event` in each event's
+ /// aggregation bundle. All events returned include bundled
+ /// [aggregations](/client-server-api/#aggregations).
+ ///
+ /// If the thread root event was sent by an [ignored
+ /// user](/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.
+ RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
+
+ /// A token to supply to `from` to keep paginating the responses. Not
+ /// present when there are no further results.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/to_device.h b/lib/csapi/to_device.h
index 5b6e0bfb..54828337 100644
--- a/lib/csapi/to_device.h
+++ b/lib/csapi/to_device.h
@@ -21,9 +21,10 @@ public:
* The type of event to send.
*
* \param txnId
- * The transaction ID for this event. Clients should generate an
- * ID unique across requests with the same access token; it will be
- * used by the server to ensure idempotency of requests.
+ * The [transaction ID](/client-server-api/#transaction-identifiers) for
+ * this event. Clients should generate an ID unique across requests with the
+ * same access token; it will be used by the server to ensure idempotency of
+ * requests.
*
* \param messages
* The messages to send. A map from user ID, to a map from