Version 0.5
A long time has passed since version 0.4 has been released - more than 200 new commits landed since then so there's quite a lot to share! As usual, the new version includes a few bigger features and plenty of bug fixes, while staying focused on memory footprint and performance.
Thanks to all contributors and testers, as well as users of the library - authors of Matrix clients!
Compatibility
As usual for 0.x versions, 0.5 breaks API compatibility with previous versions; 0.4-compatible clients may or may not need changes in order to compile with version 0.5. 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.5.y will maintain the API and ABI. Version 0.6 will break either API or ABI or both.
Version tags
Packagers, please update your scripts: from this version onwards, Git tags change naming convention: instead of rc0.x
and v0.x.y
the project will use 0.x-betaN
and 0.x-rcN
for pre-releases and 0.x.y
for releases. The minor version number in the release tag is mandatory now.
Toolchain (see also README.md)
The supported compilers didn't change: GCC 5+, Clang 5+, MSVC 2015+. GCC 4.9.2 and Clang 3.8 still work but no significant effort is put into that. The library uses C++14 for the language standard.
QMatrixClient 0.5 is the last one supported on Qt 5.6, as The Qt Company ends support of this version in March 2019. If you still use Qt 5.6, make utmost effort to upgrade to the later version of Qt in the nearest months (Qt 5.12, the most recent LTS version for now, is recommended). From the next libQMatrixClient version, the officially supported minimum will be Qt 5.9 (the oldest supported LTS version from April), with possible workarounds for as low as Qt 5.7.
Integration
There are no big changes in integration Version 0.5 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).
Same as before, the library includes pre-generated files for CS API; regenerating them requires GTAD from master branch (see also .travis,yml for the library for the general idea and CONTRIBUTING.md for details).
Features and changes
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:
- Fresh snapshot of CS API
- Massive changes to the way state is loaded, cached and saved:
- #253: Members are lazy-loaded and room summaries are parsed if the server supports these; the full list of members is only loaded upon calling
Room::getAllMembers()
, or along withRoom::setDisplayed()
(which the clients are supposed to use to let the library know that the room is actually shown on the screen). This method has been there before 0.5 but now there's a really serious reason to use it! Given the massively successful use of lazy-loading, there's no option to switch it off. - #194: previously only the "known" types of state events were cached both to memory and to disk. This has changed - all state events are included into the room's state, not only into the timeline, and are saved to disk accordingly. Thanks to smart sharing of events between the state and the timeline, the memory footprint almost didn't suffer from that; at the same time clients can now process even state events the library doesn't know about (e.g., custom state events). Quaternion 0.0.9.4, for one, uses that to pretty-print TWIM bot state changes.
- #194, #257: since the disk cache size became considerably bigger due to this change, and in order to generally better handle accounts with many (500+) rooms, each room's state is now cached to its separate file. That means that if you have 800 rooms you're going to have a directory with 800 files (which is peanuts for any contemporary file system but avoids the need to create and dump a huge JSON payload).
- #253: Members are lazy-loaded and room summaries are parsed if the server supports these; the full list of members is only loaded upon calling
- #233, #235, #236: the library fully supports room versions and room upgrades - both invocation of those locally (
Room::switchVersion()
) and receiving of tombstone events and indicating that an upgrade happened (Room::upgraded()
). If you callRoom::switchVersion()
, you may also want to connect toRoom::upgradeFailed()
to handle a possible case when the user is not allowed to upgrade a room. Also, checkRoom::isUnstable()
in order to suggest your users to upgrade the room. - #234:
RoomCreateEvent
is now a first-class citizen in the library, with proper accessors to the event data. - #267:
Room::postFile()
, a much better API for sending files. Previously you had to separately callRoom::uploadFile()
and then, once the transfer is done, send a file event.Room::postFile()
does the entire process for you, emitting appropriate signals along the way. - #264:
Connection::roomByAlias()
- a room can now be retrieved by any of its known aliases;Connection::room()
that gets a room by its id, didn't go anywhere either. Searching rooms by a string inside an alias or name is on the way! - Changes in the room state are grouped from every sync and emitted via
Room::changed()
signal. This allows to reduce the number of connections clients need to track the room changes. Room::messageSent()
to make it really easy to connect to the result ofRoom::post<anything>()
Room::fileSource()
to figure out where the up/downloaded file is from.- Fake state events (those without
state_key
) no more trick the library into changing any state.
API breakage and deprecations:
- In simple state events (such as
RoomNameEvent
)content_type
typedef now means the actually enclosed content type, which isSimpleContent<ValueType>
;value_type
is introduced to refer to the actual value type inside the content object. Room::timelineEdge()
is now soft-deprecated (the compiler won't warn you, only the doc-string will); useRoom::historyEdge()
instead. At the same time we now haveRoom::syncEdge()
that returns an iterator after the newest event.Connection::*error()
signals now passQString
instead ofQByteArray
for details (their second parameter)Connection::load/saveState()
no more receives the parameter defining the cache location (because the cache is no more a single file). UsecacheLocation()
if you need to find out where the cache is.GetRoomStateByTypeJob
is broken for now; will be fixed in patch versions of 0.5.Omittable<>
no more implicitly casts tobool
; if there ever was some code using it that code has to be fixed anyway.toJson()/fromJson()
stuff massively refactored - should be much more scalable towards new data types now.SimpleContent
no more derives fromEventContent::Base
(unlikely anybody ever relied on that)
Fixes and smaller things:
- #127:
Connection::joinRoom()
now allows to join rooms on other servers Room::eventsHistoryJob()
is exposed as aQ_PROPERTY
for the sake of checking from QML code- #248: Local echo is no more stuck in the list of pending events
- #258: Banning now correctly removes the user from room members locally, not only on the server
- #273: A workaround has been added for a bug in Synapse that doesn't process retracted invites in some cases. The library will ensure the invite is deleted if the invite is additionally rejected from the local client.
- #274:
Connection::syncLoop()
, to save small glue code in clients connecting the next loop to the completion of the previous one. If you want to do it with time gaps etc., you still have to useConnection::sync()
and your own custom glue code. - #279: event ids with pipes (
|
) and slashes (/
) won't break downloading to a temporary file from these events anymore. - #278: URI schemes except spec-approved
http(s)
,ftp
,mailto
andmagnet
are no more linkified byprettyPrint()
. SyncJob
can now accept a standard CS APIFilter
instead of a genericQString
. TheQString
overload is still there to allow passing filter ids.Connection::nextBatchToken()
, in case you need a token to the (sync-side) end of the timeline.- a new
qt_connection_util.h
header file with two facilities to ease working with QObject connections:connectSingleShot()
andconnectUntil()
.