Skip to content

0.1

Pre-release
Pre-release
Compare
Choose a tag to compare
@KitsuneRal KitsuneRal released this 04 Nov 21:25

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