Skip to content

Releases: quotient-im/libQuotient

Version 0.4.0

12 Oct 10:11
Compare
Choose a tag to compare
Version 0.4.0 Pre-release
Pre-release

It's been more than 3 months since the last release - it's really a good time to make a new one, especially since we have a new official snapshot of CS API! Coincidentally, both CS API and libQMatrixClient are now at version 0.4.0, with plenty of new functionality available from the server thanks to a massive effort of the Matrix spec core team in August. Several major (and long awaited) features and, of course, bugfixes, have landed in the library, with the memory footprint and performance still being the primary points for which the library is valued.

Thanks

This release is also notable because the developers of all the three active clients based on libQMatrixClient have contributed to it: aside from yours truly (@KitsuneRal), @encombhat of Spectral, and @delijati of uMatriks. Many thanks to you, as well as all users and testers of these clients!

Compatibility

Version 0.4 breaks API compatibility with previous versions; unless your client used very basic functionality, you may need to adapt it to the new interface. As usual, see diffs in header files to track the changes and update the client code accordingly; these release notes highlight most prominent API changes.

Micro-versions in 0.4.x will maintain the API and ABI. Version 0.5 will break either API or ABI or both.

Toolchain (see also README.md)

No changes since version 0.2 - Qt 5.6 is the oldest supported; Qt 5.10 is recommended. GCC 5+, Clang 5+, MSVC 2015+ are officially supported; GCC 4.9.2 and Clang 3.8 still work. The library uses C++14 for the language standard. Beware that the next library version may switch to newer Qt (5.7 or even 5.9).

Integration

Version 0.4 can be compiled either in static or (Linux-only so far) dynamic linking configuration. QML code can use most library facilities, assuming respective types are registered - you need a shim in C/C++ for that (see the code of uMatriks and Spectral for inspiration).

Starting from this version, libQMatrixClient integrates with pkg-config on Linux - in other words, you can use its .pc file to find out all necessary paths (thanks to @encombhat).

Note that the compiled library name is capitalised as libQMatrixClient.*, following Qt's naming conventions, instead of libqmatrixclient.* used before version 0.2.

The library requires the newest (master) GTAD to generate job classes; pre-generated files are also supplied with the source code and in the Git tree.

Features

The full list of changes can be found in the commit log; you can also find the list of GitHub issues closed in the release.

New features, along with key library API for them:

  • Plenty of new network jobs thanks to the new release of CS API - this commit is the best place to find most of them. Notably, jobs for discovery API (aka .well-known, MSC433) have been added to the library, as well as enhancements for registration jobs and third-parties lookup.
  • Room now knows about VoIP signalling (m.call.*) events, emitting callEvent() so that clients could wire it to whatever WebRTC implementation they have at hand and providing Room::call* methods to generate these events. This is based on the earlier work by UBPorts' @mariogrip; special thanks to @delijati for landing it to the master branch!
  • Events system has been refactored to allow adding custom event types. Previously custom event types (not defined in the library) were second-class citizens; e.g., they could not be added to parsing the response in SyncJob. Now library-defined and custom-defined events are completely equal. This required to get away from identifying event types using one common enumeration and switch to identification by strings used for the event type in JSON payloads. If you switched to using the (also relatively recent) TimelineItem::viewAs<>, you should not need to change your code; otherwise, if you're in C++, you're strongly advised to use it as well as the newly introduced is<> and eventCast<> that provide you with a typesafe interface instead of unreliable "check the type id and static_cast<>" antipattern. If you absolutely need the old enumeration-based ids, pass -DENABLE_EVENTTYPE_ALIAS but be aware that this option will only be there for another release or two.
  • User::ignore(), User::unmarkIgnore() and isIgnored()/ignoredUsers()/addTo/removeFromIgnoredUsers().
  • Local echo support; most of the interface can be found by looking at Room::pendingEvent* symbols; on top of that there are retryMessage() and discardMessage(). Warning: the functionality is still slightly buggy, pending events may get stuck even after receiving the actual event from the sync.
  • Room and user avatars are now cached to disk rather than to memory - meaning that they are saved between restarts! Thanks to @encombhat for making it happen.

API changes:

  • Instead of Room::postMessage() there's a multitude of Room::post* methods, to better support direct invocation of that functionality from QML.
  • Similarly, Room::add/removeTag() are now QML-friendly; and tag order is now float rather than QString - because The Spec says so.

Smaller improvements:

  • Autogenerated jobs now come with doc-comments carefully taken directly from API description files (thanks to the new GTAD).
  • Connection::stateChanged() to more conveniently track changes in the connection state
  • Settings::get<> - a convenience template method that returns you a value of the type you want, rather than QVariant.
  • Room::beforeDestruction(), emitted before deleting the room. Note that even if you inherit from room, beforeDestruction() will be called before your destructor is even entered, so you can still operate the room's state.
  • Room::usersAtEventId() - a much better way to find out who's read this event than going through all users and checking their last read events. Thanks to @encombhat for the PR!
  • Room::displayNameAboutToChange()
  • Network jobs now try to use HTTP2 if it's available. Thanks to @krombel!
  • Left rooms still get account data. Unlikely that you'd notice.
  • And the usual bug squashing, leaks plugging and memory saving

Version 0.3.0.1

11 Jun 04:33
Compare
Choose a tag to compare
Version 0.3.0.1 Pre-release
Pre-release

Minor fix in yet-to-be-used code breaking the MSVC build.

Version 0.3

11 Jun 02:00
Compare
Choose a tag to compare
Version 0.3 Pre-release
Pre-release

It didn't take too long since 0.2.1, did it? Despite that, version 0.3 includes 200+ new commits, featuring a lot of new network job classes. In fact, the entire (non-deprecated) CS API, as defined by the newest version of The Spec, is now covered with network jobs! This means that you get full (even if low-level) access to the documented Matrix CS API - be that device and key management, or user registration, or pushrules configuration. This, of course, comes along the usual work on bugfixing and other less prominent features, while keeping memory footprint and performance under control.

GTAD

All those new jobs (and most of older ones added before 0.2.1) are actually generated code. This has been made possible thanks to GTAD - Generate Things from API Descriptions, another project of @KitsuneRal. GTAD 0.6 allows you to get code in C/C++ (and possibly other languages) for the whole CS API using OpenAPI files provided by the Matrix project and Mustache template files you define. Feel free to try it; get help at #gtad:matrix.org.

Compatibility

Version 0.3 breaks API compatibility with previous versions; unless your client used very basic functionality, you may need to adapt it to the new interface. As usual, see diffs in header files to track the changes and update the client code accordingly; these release notes highlight most prominent API changes.

Micro-versions in 0.3.x will maintain the API and ABI. Version 0.4 will break either API or ABI or both.

Toolchain (see also README.md)

No changes since version 0.2 - Qt 5.6 is the oldest supported; Qt 5.10 is recommended. GCC 5+, Clang 5+, MSVC 2015+ are officially supported; GCC 4.9.2 and Clang 3.8 still work. The library uses C++14 for the language standard.

Integration

Version 0.3 can be compiled either in static or (Linux-only so far) dynamic build configuration. QML code can use most library facilities, assuming respective types are registered - you need a shim in C/C++ for that (see the code of uMatriks for an example how to do that).

Note that the compiled library name is capitalised as libQMatrixClient.*, following Qt's naming conventions, instead of libqmatrixclient.* used before version 0.2.

Features

The full list of changes can be found in the commit log; you can also find the list of GitHub issues closed in the release.

New features enabled, along with key library API for them:

  • New network jobs (#212): GetNotificationsJob (/notifications), GetWhoIsJob (/admin/whois), GetEventContextJob (/context), SearchJob (/search), GetTurnServerJob (/voip/turn), PeekEventsJob (/peek), ReportContentJob (/report), GetOneEventJob (/events), GetMembersByRoomJob (/members) and GetJoinedMembersByRoomJob (/joined_members), jobs for /presence, /pushrules, /filter, /state, /register, /devices, /keys.
  • GTAD configuration and templates have been added to the master branch; job classes are now (re-)generated on a regular basis, getting updates from the most recent (or whichever you choose for your branch) OpenAPI files. Note that the current set of job classes in the master branch is generated from QMatrixClient/matrix-doc fork rather than from vanilla files at matrix-org/matrix-doc. Details on how to use GTAD in libQMatrixClient are covered in CONTRIBUTING.md

API changes:

  • Most of network job classes (specifically - all classes generated by GTAD) now reside in csapi/ instead of jobs/. A small number of manually written jobs (with better interface than the one provided by generated ones - notably, SyncJob and MediaThumbnailJob) stay in jobs/.
  • If you happened to use RoomMessagesJob directly, rather than Room::getPreviousContent() - this job is no more, use GetRoomEventsJob instead.
  • JoinRoomJob, while keeping the name, now resides in csapi/joining.h and accepts a slightly different set of arguments. You better use Connection::joinRoom() anyway which has been there for some time already.
  • Similarly, SetRoomStateJob is now two jobs residing in csapi/room_state.h. Room::set* methods provide a more stable API for you (including the newly introduced Room::setMemberState()).
  • EventsBatch<> template is dismissed, and EventsArray<> (a typedef for std::vector of event pointers) is used instead.
  • Connection::createRoom now accepts QStringList instead of QVector<QString> for the list of invitees. Jobs that used to get or return QVector<QString> also use QStringList now (GetVersionsJob, e.g.).
  • Connection::networkError now carries the error message and details, in case a client wants to log intermittent errors.
  • Jobs in content-repo.* now return their result in data() instead of content() - a side-effect from using a unified name for single return parameters in GTAD. If you used MediaThumbnailJob and DownloadFileJob (or method wrappers in Connection and Room), you're not affected.

Smaller changes:

  • Feature (#206): the library now exposes a single signal, Connection::requestFailed(), for any failure of a network job that cannot or wasn't fixed by retrying (e.g. malformed requests, trying to send a message over continuously unavailable network, not found resources etc.). Clients can use it to provide error messages to the user in a unified way; just make sure to be not too obtrusive with those.
  • Feature (#211): a new Connection::loadedRoomState() signal is emitted as soon as a new room is not only created but its initial state from the nearest sync is entirely processed. This is useful, e.g., to only show the just-created room after it's been filled with some state. The library uses this signal in its own testsuite, qmc-example.
  • Feature: BaseJob::statusChanged signal to track job state transitions.
  • Feature: you can access isFavourite/isLowPriority as properties and isDirectChat as a function from QML.
  • Enhancement: TimelineItem (the wrapper class for events stored in the Room timeline) has got a facility method viewAs<> that unwraps the event and casts it to the desired pointer type with const qualifier. Instead of writing static_cast<const WhateverEvent*>(ti->event()) you can just do ti->viewAs<WhateverEvent>() now.
  • Enhancement (#207): "Consent not given" error has a special status code (BaseJob::UserConsentRequiredError); BaseJob::errorUrl() returns the consent page URL.
  • Enhancement: network jobs now can be started as either as "foreground" or "background" - generally, the idea is that "foreground" network requests are directly concerned with user interaction, while background requests serve supplementary role. Connection::sync and (by default) Connection::getThumbnail start background requests; others are foreground. Quaternion uses this distinction to decide whether or not an error message from a request should be shown to the user,
  • More work on improving stability and memory footprint
  • More work in .md files, in particular on using GTAD.

Version 0.2.1

27 Apr 07:15
Compare
Choose a tag to compare
Version 0.2.1 Pre-release
Pre-release

This is mostly a bugfix release, fully backwards-compatible with v0.2:

  • Fixed an occasional crash due to dangling callbacks in avatar fetching code
  • Fixed unreliable network error handling leading to sync loop getting "unlooped" when server is temporarily unavailable
  • Fixed a regression leading to bridge postfixes not being removed from user display names
  • Fixed a regression manifesting in dysfunctional user name disambiguation
  • Added User::rawName() to get a user name together with its bridge postfix
  • Bridge names are now used as the first line of disambiguation, with user ids being the next (and ultimate) fallback.

Version 0.2

03 Apr 10:55
Compare
Choose a tag to compare
Version 0.2 Pre-release
Pre-release

A big update over 0.1, 0.2 comes almost 5 months after the previous release. More than 300 commits have landed in the master branch since then, with 50+ feature requests and bugs closed. The primary goal was to get more Matrix features available (notably, CS API coverage is now much wider), with stability and memory footprint being the close second priority.

As the library matures, so the development process around it does. The libqmatrixclient project has been registered at a Core Infrastructure Initiative Best Practices website (under a cool number 1023=210-1) and is now proudly wearing the badge with the Passing status.

Thanks

This release is a collective effort of: Kitsune Ral (@KitsuneRal), Roman Plášil (@Quiark), Lewis Rockliffe (@r0kk3rz) and others. Many thanks to all of you, as well as authors and users of client applications based on libQMatrixClient - your feedback is invaluable!

Compatibility

0.2 breaks API compatibility with 0.1; there's no guarantee that clients compiled with version 0.1 will compile with 0.2. See diffs in header files to track the changes and update the client code accordingly; these release notes highlight most prominent API changes.

Micro-versions in 0.2.x will maintain the API; ABI compatibility is still not enforced (the primary linkage of the library is still static).

Toolchain (see also README.md)

Qt 5.6 is the oldest supported; Qt 5.10 is recommended. GCC 5+, Clang 5+, MSVC 2015+ are officially supported; GCC 4.9.2 and Clang 3.8 still work. The library uses C++14 for the language standard now.

Integration

Same as 0.1, version 0.2 is mainly used in static build configuration but is usable as a dynamic library as well. QML code can use most library facilities, assuming respective types are registered (see the code of uMatriks for an example how to do that).

Note that the compiled library name is now capitalised as libQMatrixClient.*, following Qt's naming conventions, instead of libqmatrixclient.*.

Features

The full list of changes can be found in the commit log; you can also find the list of GitHub issues closed in the release.

New features enabled, along with key library API for them:

  • Redactions
    • Processing (#117): Room::RedactionEvent, Room::replacedEvent()
    • Sending (#118): Room::redactEvent()
  • Files transfer (only mxc://, no freeform URLs - see #153):
    • Downloading (#121): GetContent*Job, DownloadFileJob, Connection::getContent(), Connection::downloadFile(), Room::downloadFile(), Room::*ToDownload() (#168)
    • Uploading (#122): UploadContentJob, Connection::uploadContent(), Connection::uploadFile(), Room::uploadFile()
    • Progress tracking: Connection::upload/downloadProgress(), Room::fileTransfer*() signals family, Room::fileTransferInfo(), Room::cancelFileTransfer()
  • Setting an avatar from the local file (implicitly uploads the file to content repo (#150): User::setAvatar()
  • Saving the range of shown events in the room object (#151): Room::*DisplayedEvent*() accessors and signals
  • Rooms creation (#34): CreateRoomJob, Connection::createRoom() and Connection::createdRoom()
  • Changing the room state: SetRoomStateJob, Room::setName(), Room::setCanonicalAlias()
  • Per-room user properties (display names and avatars) support (#141): almost all methods of User now get a room object as a parameter; clients are advised to add this parameter to the existing calls of User but the previous signatures work too (handling the most used display name/avatar; before it was the one last encountered in /sync response).
  • Account data (#123 and #152):
    • Room tags support (#134): TagEvent, various accessors and signals (Connection::tag*() and Room::tag*()), Connection::roomsWithTag(), Room::add/removeTag(), Room::setTags(), Room::isFavourite() and Room::isLowPriority() (just because The Spec explicitly mentions these two tags)
    • Server-side read marker support (aka "m.fully_read", #183): no changes to the library read marker API, it's now automatically synchronised with the server; ReadMarkerEvent and PostReadMarkersJob for those who need to deal with the synchronisation logic
    • Direct chats support (#163): DirectChatEvent; in Connection, directChats(), directChatUsers(), addTo/removeFromDirectChats(), isDirectChat() (with the counterpart in Room), directChatsListChanged(); requestDirectChat() to get a hold of the direct chat room object (directChatAvailable() is the corresponding signal and User::requestDirectChat() is a shortcut if you have a user object at hand); alternatively, doInDirectChat() can be used for continuation-styled operations on a direct chat
    • Generic account data: Room::accountData() and Room::accountdataChanged(), SetAccountDataJob, SetAccountDataPerRoomJob
  • New CS API coverage (#128, see the issue for specific class names): 3PID administration, room directory, sending typing notifications, getting protocol versions from the server, "whoami" request for access tokens - all this is in addition to operations mentioned above
  • Unread messages are counted now: Room::unreadCount() (saved in cache so that clients could provide reasonably accurate estimates - "as in Slack or better" - on the next run without saving the messages themselves)
  • API change: Client callbacks for SSL errors and proxy authentication (#143): NetworkAccessManager::instance() and NetworkAccessManager::sslErrors()
    • The library no more suppresses self-signed certificate errors etc. (#144), clients should explicitly process those (quotient-im/Quaternion#250 gives an example)
    • Speaking of proxy servers, clients can now use the NetworkSettings class to store network proxy settings.
  • API change: all network request (job) classes now follow the camelCase naming convention (no snake_case parameters sneaking in).
  • API change: initial job state is now Pending rather than NoError (this allows to distinguish between "no result yet" and "good result" but breaks clients that checked for NoError before job completion).

Other changes:

  • Feature: plain text with URLs can be pretty-printed into HTML using Room::prettyPrint()
  • Feature: many more Q_PROPERTYs exposed for use in QML
  • Feature: Connection::room() and Connection::invitation() to get an (existing) Room object for the specified room id and join state mask; no more need to run Connection::roomMap() (that has linear complexity, btw) only to access a single room object
  • Enhancement: bridged Telegram users are recognised as such, with (Telegram) suffix removed from their names
  • Enhancement (#109): workaround losing connectivity due to poor Qt bearer management
  • Enhancement: network requests (jobs) can now use arbitrary data streams derived from QIODevice (including local files) for the request body (enables file uploading mentioned above and other useful cases)
  • Enhancement: Room and User objects now have QObject names, making them more readable in debugging views of Qt Creator and other Qt-aware IDEs
  • Enhancement (#179): caching through Connection::saveState() now uses Qt's binary representation of JSON (making it unreadable but considerably faster); set "libqmatrixclient/cache_type" (also programmatically accessible through QMatrixClient::Settings or QSettings) to "json" to use the plain-text JSON format for the cache
  • Enhancement (#186): network requests respect rate limiting imposed by the server and will retry according to the provided timeout (some requests fall victim to matrix-org/synapse#3054 though)
  • Fix (#119): homeserver names are resolved properly
  • Fix (#115): fake state events (having no state_key) do not cause state changes
  • Fix (#148): prev_content is properly searched in incoming events
  • Fix (#138): trying to send a (non-encrypted) message to an encrypted room will cause a complaint in the logs but no observable action; use Room::usesEncryption() and Room::encryption() to check whether the room is encrypted
  • Massive work on improving stability and plugging memory leaks; the CI script on Linux and OSX now includes running qmc-example under Valgrind; CI for Windows is introduced for the library
  • More documentation work, both in doc-comments and .md files

0.1

04 Nov 21:25
Compare
Choose a tag to compare
0.1 Pre-release
Pre-release

This is the first official release of the library code that strives to mark a more-or-less stabilised API for clients. The primary goal of the release is to enable functionality; there's no test suite as of yet, and documentation is very initial (see README.md and comments across the lib code). A minimal example is supplied (see examples/) to give an idea of where to start with. Quaternion and Tensor source code may be useful as a reference to how an actual client can be organised.

Thanks

This release is a collective effort of: Felix Rohrbach (@Fxrh), Kitsune Ral (@KitsuneRal), David A Roberts (@davidar), Roman Plášil (@Quiark), Elvis Angelaccio (@elvisangelaccio), Malte Brandy (@maralorn), and others. Many thanks to all of you, as well as authors and users of client applications based on libqmatrixclient - your feedback is invaluable!

Compatibility

It's the first release; there are no previous versions to provide compatibility with. Further development will be done in two branches, master and (to be made) '0.1.x'. Micro-versions in 0.1.x will maintain the API; ABI compatibility is not enforced.

Toolchain (see also README.md)

Qt 5.2.1 is the oldest supported; Qt 5.9 is recommended. GCC 4.8.2 is known to build the code; GCC 5.3 is the main version used for development. Clang and MSVC can be used as well.

Integration

The library is mainly used in static build configuration but should potentially be usable as a dynamic library as well. QML code can use most library facilities, assuming respective types are registered (see Tensor code for an example how to do that).

Features

On a high level, the following use cases are enabled:

  • Multiple server connections (completely separate from each other, no events/rooms/users aggregation)
  • Login to servers by username and password, with device names/ids (externally provided access token is also supported)
  • Logout
  • Long-polling via /sync; creating users, rooms, updating their state and filling up the timeline from sync results
  • Retrieval of historical room events using prev_batch
  • Sending messages and room state updates (see the itemized list of event types in the next paragraph)
  • Network requests retry mechanism (3 retries by default except /sync that retries infinitely)
  • Getting and setting room avatars
  • Getting user avatars
  • Getting and sending read receipts
  • Local read marker management driven by read receipts (no RM integration with the server yet)
  • Getting typing notifications (sending may probably work as well but hasn't been tested)
  • Caching the state of rooms and their members to a file
  • Room operations: inviting, joining, leaving, kicking, banning (invocation and syncing from the server)
  • Room unbanning and forgetting (invocation only, syncing not supported by CS API)
  • Room and user display name disambiguation (according to The Spec)
  • Highlights/notifications number updates

Below is the list of supported Matrix Client-Server API parts. The convention is "feature/endpoint: lib call that invokes operation -> lib signal upon operation completion". Please refer to the CS API specification to understand payloads passed around and potential issues concerned with some calls.

  • DNS Lookup of servers using _matrix._tcp record: Connection::resolveServer() -> Connection::resolved() or Connection::resolveError()
  • /login for user-password credentials: Connection::connectToServer() -> Connection::connected() or Connection::loginError()
    • Existing access token can be supplied with Connection::connectWithToken() (skips calling the network) -> Connection::connected()
  • /logout: Connection::logout() -> Connection::loggedOut()
  • /sync - Connection::sync() -> Connection::syncDone(), or Connection::loginError() if trying to sync from a forbidden endpoint
    • Connection::stopSync() to abandon an ongoing sync
    • signals emitted upon sync result processing by the library:
      • Connection:: context: newRoom()/aboutToDeleteRoom() to register/unregister room objects; invitedRoom(), joinedRoom(), leftRoom() to track room join state changes (see comments in connection.h, \group Signals emitted on room transitions, in particular the Invite state caveat)
      • Room:: context: aboutToAddNewMessages()/addedMessages() when receiving events to the timeline; avatarChanged(), displaynameChanged(), joinStateChanged() (note the Invite state caveat, see above), highlightCountChanged(), lastReadEventChanged(), memberRenamed() (including a rename due to disambiguation in the room-context), namesChanged() (for room name and aliases, including canonical), readMarkerMoved() (for the local user), topicChanged(), typingChanged(), unreadMessagesChanged() (no unread messages count), userAdded(), userRemoved().
      • User:: context: nameChanged() (outside of room context), avatarChanged().
      • Supported event types: m.room.message (all msgtypes listed in The Spec), m.room.name, m.room.aliases, m.room.canonical_alias, m.room.avatar, m.room.member, m.room.topic, m.room.encryption (but not m.room.encrypted - E2EE support is not in this release), m.receipt, m.typing. Other types are considered unknown; if such events appear in the timeline section, they are still added to the room timeline in the library but not analysed.
  • /messages: Room::getPreviousContent() -> aboutToAddHistoricalMessages()/addedMessages()
  • /rooms/{}/invite|leave|kick|ban|unban: Room::inviteToRoom()|leaveRoom()|kickMember()|ban()|unban() -> BaseJob signals or updates from the next sync
  • /rooms/{}/forget: Connection::forgetRoom() -> BaseJob signals or updates from the next sync (note that unlike the original CS API call, forgetRoom() tries to call /leave if it notices the room is still not left)
  • PUT /rooms/{}/state and PUT /rooms/{}/state/{state_key}: Connection::callApi<SetRoomStateJob>() -> BaseJob signals
  • PUT /rooms/{}/send/{txnId}: Room::postMessage() or Connection::callApi<SendEventJob>() -> BaseJob signals
  • PUT /profile/{}/displayname: User::rename() -> User::nameChanged()
  • GET /profile/{}/displayname: User::displayname() (fetched from /sync, no dedicated method in User to update from the server)
  • GET /profile/{}/avatar_url: first User::avatar() invocation triggers a job to fetch the thumbnail with the needed size, returning an empty pixmap immediately -> User::avatarChanged(), a slot connected to it can call User::avatar() again to get the fetched pixmap of the needed size
  • /rooms/{}/receipt: Connection::callApi<PostReceiptJob>() -> BaseJob signals or updates from the next sync
  • /thumbnail: Connection::callApi<MediaThumbnailJob>() -> BaseJob signals
  • An arbitrary call to CS API can be done using the library by subclassing BaseJob and invoking Connection::callApi() template method, passing the job type and parameters as callApi() parameters. BaseJob::finished() is emitted upon job completion; BaseJob::success() or BaseJob::failure() is emitted depending on the job outcome.

Ancillary features:

  • Network requests error handling: Connection::networkError();
  • Network request timeouts and retries: by default every network request (except /sync, which retries infinitely) can do 3 retries with gradually increasing timeouts and retry intervals; in BaseJob, see the maxRetries Q_PROPERTY as well as getCurrentTimeout() and getNextRetryInterval(); the timeout and retry interval tuples are not tunable as of yet
  • Rooms state caching (per Connection): saveState(), loadState(); cacheState is a Q_PROPERTY feature flag for this