diff --git a/src/AliasEditModel.cpp b/src/AliasEditModel.cpp
index c6dc35c6..cc6ea137 100644
--- a/src/AliasEditModel.cpp
+++ b/src/AliasEditModel.cpp
@@ -10,7 +10,6 @@
#include <mtx/responses/common.hpp>
-#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
#include "Logging.h"
diff --git a/src/AliasEditModel.h b/src/AliasEditModel.h
index 04de5016..62771c8e 100644
--- a/src/AliasEditModel.h
+++ b/src/AliasEditModel.h
@@ -10,8 +10,6 @@
#include <mtx/events/canonical_alias.hpp>
-#include "CacheStructs.h"
-
class FetchPublishedAliasesJob final : public QObject
{
Q_OBJECT
diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp
index b7dc3306..0e4195db 100644
--- a/src/AvatarProvider.cpp
+++ b/src/AvatarProvider.cpp
@@ -6,14 +6,10 @@
#include <QPixmapCache>
#include <QPointer>
#include <memory>
-#include <unordered_map>
#include "AvatarProvider.h"
#include "Cache.h"
-#include "Logging.h"
-#include "MatrixClient.h"
#include "MxcImageProvider.h"
-#include "Utils.h"
static QPixmapCache avatar_cache;
diff --git a/src/AvatarProvider.h b/src/AvatarProvider.h
index 454ce957..b73b1ad6 100644
--- a/src/AvatarProvider.h
+++ b/src/AvatarProvider.h
@@ -4,7 +4,9 @@
#pragma once
+#include <QObject>
#include <QPixmap>
+
#include <functional>
using AvatarCallback = std::function<void(QPixmap)>;
diff --git a/src/BlurhashProvider.cpp b/src/BlurhashProvider.cpp
index 7ca491de..d4482419 100644
--- a/src/BlurhashProvider.cpp
+++ b/src/BlurhashProvider.cpp
@@ -4,8 +4,6 @@
#include "BlurhashProvider.h"
-#include <algorithm>
-
#include <QUrl>
#include "blurhash.hpp"
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 25904e53..d7cd113b 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -24,6 +24,8 @@
#include <qt6keychain/keychain.h>
#endif
+#include <nlohmann/json.hpp>
+
#include <mtx/responses/common.hpp>
#include <mtx/responses/messages.hpp>
@@ -532,8 +534,8 @@ Cache::loadSecretsFromStore(
name,
toLoad,
job,
- name_ = name_,
- internal = internal,
+ name__ = name_,
+ internal_ = internal,
callback,
databaseReadyOnFinished](QKeychain::Job *) mutable {
nhlog::db()->debug("Finished reading '{}'", toLoad.begin()->first);
@@ -549,7 +551,7 @@ Cache::loadSecretsFromStore(
if (secret.isEmpty()) {
nhlog::db()->debug("Restored empty secret '{}'.", name.toStdString());
} else {
- callback(name_, internal, secret.toStdString());
+ callback(name__, internal_, secret.toStdString());
}
// load next secret
@@ -2042,6 +2044,213 @@ isMessage(const mtx::events::RoomEvent<mtx::events::voip::CallHangUp> &)
// }
}
+template<typename T>
+std::optional<mtx::events::StateEvent<T>>
+Cache::getStateEvent(lmdb::txn &txn, const std::string &room_id, std::string_view state_key)
+{
+ try {
+ constexpr auto type = mtx::events::state_content_to_type<T>;
+ static_assert(type != mtx::events::EventType::Unsupported,
+ "Not a supported type in state events.");
+
+ if (room_id.empty())
+ return std::nullopt;
+ const auto typeStr = to_string(type);
+
+ std::string_view value;
+ if (state_key.empty()) {
+ auto db = getStatesDb(txn, room_id);
+ if (!db.get(txn, typeStr, value)) {
+ return std::nullopt;
+ }
+ } else {
+ auto db = getStatesKeyDb(txn, room_id);
+ // we can search using state key, since the compare functions defaults to the whole
+ // string, when there is no nullbyte
+ std::string_view data = state_key;
+ std::string_view typeStrV = typeStr;
+
+ auto cursor = lmdb::cursor::open(txn, db);
+ if (!cursor.get(typeStrV, data, MDB_GET_BOTH))
+ return std::nullopt;
+
+ try {
+ auto eventsDb = getEventsDb(txn, room_id);
+ auto eventid = data;
+ if (auto sep = data.rfind('\0'); sep != std::string_view::npos) {
+ if (!eventsDb.get(txn, eventid.substr(sep + 1), value))
+ return std::nullopt;
+ } else {
+ return std::nullopt;
+ }
+
+ } catch (std::exception &) {
+ return std::nullopt;
+ }
+ }
+
+ return nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>();
+ } catch (std::exception &) {
+ return std::nullopt;
+ }
+}
+
+template<typename T>
+std::vector<mtx::events::StateEvent<T>>
+Cache::getStateEventsWithType(lmdb::txn &txn,
+ const std::string &room_id,
+ mtx::events::EventType type)
+
+{
+ if (room_id.empty())
+ return {};
+
+ std::vector<mtx::events::StateEvent<T>> events;
+
+ {
+ auto db = getStatesKeyDb(txn, room_id);
+ auto eventsDb = getEventsDb(txn, room_id);
+ const auto typeStr = to_string(type);
+ std::string_view typeStrV = typeStr;
+ std::string_view data;
+ std::string_view value;
+
+ auto cursor = lmdb::cursor::open(txn, db);
+ bool first = true;
+ if (cursor.get(typeStrV, data, MDB_SET)) {
+ while (cursor.get(typeStrV, data, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) {
+ first = false;
+
+ try {
+ auto eventid = data;
+ if (auto sep = data.rfind('\0'); sep != std::string_view::npos) {
+ if (eventsDb.get(txn, eventid.substr(sep + 1), value))
+ events.push_back(
+ nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>());
+ }
+ } catch (std::exception &e) {
+ nhlog::db()->warn("Failed to parse state event: {}", e.what());
+ }
+ }
+ }
+ }
+
+ return events;
+}
+
+template<class T>
+void
+Cache::saveStateEvents(lmdb::txn &txn,
+ lmdb::dbi &statesdb,
+ lmdb::dbi &stateskeydb,
+ lmdb::dbi &membersdb,
+ lmdb::dbi &eventsDb,
+ const std::string &room_id,
+ const std::vector<T> &events)
+{
+ for (const auto &e : events)
+ saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e);
+}
+
+template<class T>
+void
+Cache::saveStateEvent(lmdb::txn &txn,
+ lmdb::dbi &statesdb,
+ lmdb::dbi &stateskeydb,
+ lmdb::dbi &membersdb,
+ lmdb::dbi &eventsDb,
+ const std::string &room_id,
+ const T &event)
+{
+ using namespace mtx::events;
+ using namespace mtx::events::state;
+
+ if (auto e = std::get_if<StateEvent<Member>>(&event); e != nullptr) {
+ switch (e->content.membership) {
+ //
+ // We only keep users with invite or join membership.
+ //
+ case Membership::Invite:
+ case Membership::Join: {
+ auto display_name =
+ e->content.display_name.empty() ? e->state_key : e->content.display_name;
+
+ std::string inviter = "";
+ if (e->content.membership == mtx::events::state::Membership::Invite) {
+ inviter = e->sender;
+ }
+
+ // Lightweight representation of a member.
+ MemberInfo tmp{
+ display_name,
+ e->content.avatar_url,
+ inviter,
+ e->content.reason,
+ e->content.is_direct,
+ };
+
+ membersdb.put(txn, e->state_key, nlohmann::json(tmp).dump());
+ break;
+ }
+ default: {
+ membersdb.del(txn, e->state_key, "");
+ break;
+ }
+ }
+ } else if (auto encr = std::get_if<StateEvent<Encryption>>(&event)) {
+ if (!encr->state_key.empty())
+ return;
+
+ setEncryptedRoom(txn, room_id);
+
+ std::string_view temp;
+ // ensure we don't replace the event in the db
+ if (statesdb.get(txn, to_string(encr->type), temp)) {
+ return;
+ }
+ }
+
+ std::visit(
+ [&txn, &statesdb, &stateskeydb, &eventsDb, &membersdb](const auto &e) {
+ if constexpr (isStateEvent_<decltype(e)>) {
+ eventsDb.put(txn, e.event_id, nlohmann::json(e).dump());
+
+ if (e.type != EventType::Unsupported) {
+ if (std::is_same_v<std::remove_cv_t<std::remove_reference_t<decltype(e)>>,
+ StateEvent<mtx::events::msg::Redacted>>) {
+ // apply the redaction event
+ if (e.type == EventType::RoomMember) {
+ // membership is not revoked, but names are yeeted (so we set the name
+ // to the mxid)
+ MemberInfo tmp{e.state_key, ""};
+ membersdb.put(txn, e.state_key, nlohmann::json(tmp).dump());
+ } else if (e.state_key.empty()) {
+ // strictly speaking some stuff in those events can be redacted, but
+ // this is close enough. Ref:
+ // https://spec.matrix.org/v1.6/rooms/v10/#redactions
+ if (e.type != EventType::RoomCreate &&
+ e.type != EventType::RoomJoinRules &&
+ e.type != EventType::RoomPowerLevels &&
+ e.type != EventType::RoomHistoryVisibility)
+ statesdb.del(txn, to_string(e.type));
+ } else
+ stateskeydb.del(txn, to_string(e.type), e.state_key + '\0' + e.event_id);
+ } else if (e.state_key.empty()) {
+ statesdb.put(txn, to_string(e.type), nlohmann::json(e).dump());
+ } else {
+ auto data = e.state_key + '\0' + e.event_id;
+ auto key = to_string(e.type);
+
+ // Work around https://bugs.openldap.org/show_bug.cgi?id=8447
+ stateskeydb.del(txn, key, data);
+ stateskeydb.put(txn, key, data);
+ }
+ }
+ }
+ },
+ event);
+}
+
void
Cache::saveState(const mtx::responses::Sync &res)
{
@@ -6004,3 +6213,33 @@ secret(const std::string &name)
return instance_->secret(name);
}
} // namespace cache
+
+#define NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(Content) \
+ template std::optional<mtx::events::StateEvent<Content>> Cache::getStateEvent( \
+ lmdb::txn &txn, const std::string &room_id, std::string_view state_key); \
+ \
+ template std::vector<mtx::events::StateEvent<Content>> Cache::getStateEventsWithType( \
+ lmdb::txn &txn, const std::string &room_id, mtx::events::EventType type);
+
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Aliases)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Avatar)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::CanonicalAlias)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Create)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Encryption)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::GuestAccess)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::HistoryVisibility)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::JoinRules)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Member)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Name)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::PinnedEvents)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::PowerLevels)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Tombstone)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::ServerAcl)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Topic)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::Widget)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::policy_rule::UserRule)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::policy_rule::RoomRule)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::policy_rule::ServerRule)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::space::Child)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::state::space::Parent)
+NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(mtx::events::msc2545::ImagePack)
diff --git a/src/Cache_p.h b/src/Cache_p.h
index e59796ed..d1316ae5 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -4,7 +4,6 @@
#pragma once
-#include <limits>
#include <optional>
#include <QDateTime>
@@ -15,8 +14,8 @@
#else
#include <lmdb++.h>
#endif
-#include <nlohmann/json.hpp>
+#include <mtx/events/collections.hpp>
#include <mtx/responses/notifications.hpp>
#include <mtx/responses/sync.hpp>
#include <mtxclient/crypto/types.hpp>
@@ -24,7 +23,6 @@
#include "CacheCryptoStructs.h"
#include "CacheStructs.h"
-#include "Logging.h"
namespace mtx::responses {
struct Messages;
@@ -364,8 +362,6 @@ private:
mtx::events::collections::TimelineEvents e,
const std::string &room_id);
- //! Remove a room from the cache.
- // void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
template<class T>
void saveStateEvents(lmdb::txn &txn,
lmdb::dbi &statesdb,
@@ -373,11 +369,7 @@ private:
lmdb::dbi &membersdb,
lmdb::dbi &eventsDb,
const std::string &room_id,
- const std::vector<T> &events)
- {
- for (const auto &e : events)
- saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e);
- }
+ const std::vector<T> &events);
template<class T>
void saveStateEvent(lmdb::txn &txn,
@@ -386,191 +378,18 @@ private:
lmdb::dbi &membersdb,
lmdb::dbi &eventsDb,
const std::string &room_id,
- const T &event)
- {
- using namespace mtx::events;
- using namespace mtx::events::state;
-
- if (auto e = std::get_if<StateEvent<Member>>(&event); e != nullptr) {
- switch (e->content.membership) {
- //
- // We only keep users with invite or join membership.
- //
- case Membership::Invite:
- case Membership::Join: {
- auto display_name =
- e->content.display_name.empty() ? e->state_key : e->content.display_name;
-
- std::string inviter = "";
- if (e->content.membership == mtx::events::state::Membership::Invite) {
- inviter = e->sender;
- }
-
- // Lightweight representation of a member.
- MemberInfo tmp{
- display_name,
- e->content.avatar_url,
- inviter,
- e->content.reason,
- e->content.is_direct,
- };
-
- membersdb.put(txn, e->state_key, nlohmann::json(tmp).dump());
- break;
- }
- default: {
- membersdb.del(txn, e->state_key, "");
- break;
- }
- }
- } else if (auto encr = std::get_if<StateEvent<Encryption>>(&event)) {
- if (!encr->state_key.empty())
- return;
-
- setEncryptedRoom(txn, room_id);
-
- std::string_view temp;
- // ensure we don't replace the event in the db
- if (statesdb.get(txn, to_string(encr->type), temp)) {
- return;
- }
- }
-
- std::visit(
- [&txn, &statesdb, &stateskeydb, &eventsDb, &membersdb](const auto &e) {
- if constexpr (isStateEvent_<decltype(e)>) {
- eventsDb.put(txn, e.event_id, nlohmann::json(e).dump());
-
- if (e.type != EventType::Unsupported) {
- if (std::is_same_v<std::remove_cv_t<std::remove_reference_t<decltype(e)>>,
- StateEvent<mtx::events::msg::Redacted>>) {
- // apply the redaction event
- if (e.type == EventType::RoomMember) {
- // membership is not revoked, but names are yeeted (so we set the name
- // to the mxid)
- MemberInfo tmp{e.state_key, ""};
- membersdb.put(txn, e.state_key, nlohmann::json(tmp).dump());
- } else if (e.state_key.empty()) {
- // strictly speaking some stuff in those events can be redacted, but
- // this is close enough. Ref:
- // https://spec.matrix.org/v1.6/rooms/v10/#redactions
- if (e.type != EventType::RoomCreate &&
- e.type != EventType::RoomJoinRules &&
- e.type != EventType::RoomPowerLevels &&
- e.type != EventType::RoomHistoryVisibility)
- statesdb.del(txn, to_string(e.type));
- } else
- stateskeydb.del(
- txn, to_string(e.type), e.state_key + '\0' + e.event_id);
- } else if (e.state_key.empty()) {
- statesdb.put(txn, to_string(e.type), nlohmann::json(e).dump());
- } else {
- auto data = e.state_key + '\0' + e.event_id;
- auto key = to_string(e.type);
-
- // Work around https://bugs.openldap.org/show_bug.cgi?id=8447
- stateskeydb.del(txn, key, data);
- stateskeydb.put(txn, key, data);
- }
- }
- }
- },
- event);
- }
+ const T &event);
template<typename T>
std::optional<mtx::events::StateEvent<T>>
- getStateEvent(lmdb::txn &txn, const std::string &room_id, std::string_view state_key = "")
- {
- try {
- constexpr auto type = mtx::events::state_content_to_type<T>;
- static_assert(type != mtx::events::EventType::Unsupported,
- "Not a supported type in state events.");
-
- if (room_id.empty())
- return std::nullopt;
- const auto typeStr = to_string(type);
-
- std::string_view value;
- if (state_key.empty()) {
- auto db = getStatesDb(txn, room_id);
- if (!db.get(txn, typeStr, value)) {
- return std::nullopt;
- }
- } else {
- auto db = getStatesKeyDb(txn, room_id);
- // we can search using state key, since the compare functions defaults to the whole
- // string, when there is no nullbyte
- std::string_view data = state_key;
- std::string_view typeStrV = typeStr;
-
- auto cursor = lmdb::cursor::open(txn, db);
- if (!cursor.get(typeStrV, data, MDB_GET_BOTH))
- return std::nullopt;
-
- try {
- auto eventsDb = getEventsDb(txn, room_id);
- auto eventid = data;
- if (auto sep = data.rfind('\0'); sep != std::string_view::npos) {
- if (!eventsDb.get(txn, eventid.substr(sep + 1), value))
- return std::nullopt;
- } else {
- return std::nullopt;
- }
-
- } catch (std::exception &) {
- return std::nullopt;
- }
- }
-
- return nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>();
- } catch (std::exception &) {
- return std::nullopt;
- }
- }
+ getStateEvent(lmdb::txn &txn, const std::string &room_id, std::string_view state_key = "");
template<typename T>
std::vector<mtx::events::StateEvent<T>>
getStateEventsWithType(lmdb::txn &txn,
const std::string &room_id,
- mtx::events::EventType type = mtx::events::state_content_to_type<T>)
-
- {
- if (room_id.empty())
- return {};
+ mtx::events::EventType type = mtx::events::state_content_to_type<T>);
- std::vector<mtx::events::StateEvent<T>> events;
-
- {
- auto db = getStatesKeyDb(txn, room_id);
- auto eventsDb = getEventsDb(txn, room_id);
- const auto typeStr = to_string(type);
- std::string_view typeStrV = typeStr;
- std::string_view data;
- std::string_view value;
-
- auto cursor = lmdb::cursor::open(txn, db);
- bool first = true;
- if (cursor.get(typeStrV, data, MDB_SET)) {
- while (cursor.get(typeStrV, data, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) {
- first = false;
-
- try {
- auto eventid = data;
- if (auto sep = data.rfind('\0'); sep != std::string_view::npos) {
- if (eventsDb.get(txn, eventid.substr(sep + 1), value))
- events.push_back(
- nlohmann::json::parse(value).get<mtx::events::StateEvent<T>>());
- }
- } catch (std::exception &e) {
- nhlog::db()->warn("Failed to parse state event: {}", e.what());
- }
- }
- }
- }
-
- return events;
- }
void
saveInvites(lmdb::txn &txn, const std::map<std::string, mtx::responses::InvitedRoom> &rooms);
@@ -723,3 +542,33 @@ namespace cache {
Cache *
client();
}
+
+#define NHEKO_CACHE_GET_STATE_EVENT_FORWARD(Content) \
+ extern template std::optional<mtx::events::StateEvent<Content>> Cache::getStateEvent( \
+ lmdb::txn &txn, const std::string &room_id, std::string_view state_key); \
+ \
+ extern template std::vector<mtx::events::StateEvent<Content>> Cache::getStateEventsWithType( \
+ lmdb::txn &txn, const std::string &room_id, mtx::events::EventType type);
+
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Aliases)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Avatar)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::CanonicalAlias)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Create)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Encryption)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::GuestAccess)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::HistoryVisibility)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::JoinRules)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Member)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Name)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::PinnedEvents)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::PowerLevels)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Tombstone)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::ServerAcl)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Topic)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::Widget)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::policy_rule::UserRule)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::policy_rule::RoomRule)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::policy_rule::ServerRule)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::space::Child)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::state::space::Parent)
+NHEKO_CACHE_GET_STATE_EVENT_FORWARD(mtx::events::msc2545::ImagePack)
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index db5cbbe8..03144faf 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -9,6 +9,8 @@
#include <algorithm>
#include <unordered_set>
+#include <nlohmann/json.hpp>
+
#include <mtx/responses.hpp>
#include "AvatarProvider.h"
@@ -282,8 +284,8 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
continue;
mtx::events::collections::TimelineEvents te{event};
- std::visit([room_id = room_id](auto &event_) { event_.room_id = room_id; },
- te);
+ std::visit(
+ [room_id_ = room_id](auto &event_) { event_.room_id = room_id_; }, te);
if (auto encryptedEvent =
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
@@ -342,14 +344,14 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
roomModel->roomAvatarUrl(),
96,
this,
- [this, te = te, room_id = room_id, actions = actions](QPixmap image) {
+ [this, te_ = te, room_id_ = room_id, actions_ = actions](QPixmap image) {
notificationsManager->postNotification(
mtx::responses::Notification{
- .actions = actions,
- .event = std::move(te),
+ .actions = actions_,
+ .event = std::move(te_),
.read = false,
.profile_tag = "",
- .room_id = room_id,
+ .room_id = room_id_,
.ts = 0,
},
image.toImage());
diff --git a/src/CompletionProxyModel.cpp b/src/CompletionProxyModel.cpp
index eea1e6aa..bce873e7 100644
--- a/src/CompletionProxyModel.cpp
+++ b/src/CompletionProxyModel.cpp
@@ -9,7 +9,6 @@
#include "CompletionModelRoles.h"
#include "Logging.h"
-#include "Utils.h"
CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
int max_mistakes,
diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp
index 62969ed1..a8ba9e22 100644
--- a/src/EventAccessors.cpp
+++ b/src/EventAccessors.cpp
@@ -8,7 +8,6 @@
#include <algorithm>
#include <cctype>
-#include <concepts>
#include <type_traits>
namespace {
diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp
index 76f37fad..ecb9e66c 100644
--- a/src/InviteesModel.cpp
+++ b/src/InviteesModel.cpp
@@ -4,7 +4,6 @@
#include "InviteesModel.h"
-#include "Cache.h"
#include "Logging.h"
#include "MatrixClient.h"
#include "mtx/responses/profile.hpp"
diff --git a/src/JdenticonProvider.cpp b/src/JdenticonProvider.cpp
index ef083074..f34275c9 100644
--- a/src/JdenticonProvider.cpp
+++ b/src/JdenticonProvider.cpp
@@ -12,10 +12,7 @@
#include <mtxclient/crypto/client.hpp>
-#include "Cache.h"
#include "Logging.h"
-#include "MatrixClient.h"
-#include "Utils.h"
#include "jdenticoninterface.h"
namespace Jdenticon {
diff --git a/src/JdenticonProvider.h b/src/JdenticonProvider.h
index da4d73e1..1c2c0665 100644
--- a/src/JdenticonProvider.h
+++ b/src/JdenticonProvider.h
@@ -11,8 +11,6 @@
#include <mtx/common.hpp>
-#include "jdenticoninterface.h"
-
class JdenticonRunnable final
: public QObject
, public QRunnable
diff --git a/src/Logging.cpp b/src/Logging.cpp
index e7a99458..35fea1d4 100644
--- a/src/Logging.cpp
+++ b/src/Logging.cpp
@@ -9,7 +9,6 @@
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
-#include <iostream>
#include <QString>
#include <QtGlobal>
diff --git a/src/Logging.h b/src/Logging.h
index 9b992660..56f4de8f 100644
--- a/src/Logging.h
+++ b/src/Logging.h
@@ -5,7 +5,6 @@
#pragma once
#include <memory>
-#include <string>
#include <QString>
diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp
index afc660a8..c4e9319c 100644
--- a/src/LoginPage.cpp
+++ b/src/LoginPage.cpp
@@ -11,7 +11,6 @@
#include <mtx/responses/login.hpp>
#include <mtx/responses/version.hpp>
-#include "Config.h"
#include "Logging.h"
#include "LoginPage.h"
#include "MainWindow.h"
diff --git a/src/MainWindow.h b/src/MainWindow.h
index fc06e183..c493b5b2 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -14,8 +14,6 @@
#include "UserSettingsPage.h"
#include "dock/Dock.h"
-#include "jdenticoninterface.h"
-
class ChatPage;
class RegisterPage;
class WelcomePage;
diff --git a/src/MatrixClient.cpp b/src/MatrixClient.cpp
index 2fd2eac9..05ec6a92 100644
--- a/src/MatrixClient.cpp
+++ b/src/MatrixClient.cpp
@@ -5,14 +5,12 @@
#include "MatrixClient.h"
#include <memory>
-#include <set>
#include <QMetaType>
#include <QObject>
#include <QStandardPaths>
#include <QString>
-#include "nlohmann/json.hpp"
#include <mtx/responses.hpp>
namespace http {
diff --git a/src/MemberList.cpp b/src/MemberList.cpp
index 036ef9d4..a5e6565e 100644
--- a/src/MemberList.cpp
+++ b/src/MemberList.cpp
@@ -7,9 +7,7 @@
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
-#include "Config.h"
#include "Logging.h"
-#include "Utils.h"
#include "timeline/TimelineViewManager.h"
MemberListBackend::MemberListBackend(const QString &room_id, QObject *parent)
diff --git a/src/PowerlevelsEditModels.h b/src/PowerlevelsEditModels.h
index c9d262d8..6e17079c 100644
--- a/src/PowerlevelsEditModels.h
+++ b/src/PowerlevelsEditModels.h
@@ -8,10 +8,9 @@
#include <QQmlEngine>
#include <QSortFilterProxyModel>
+#include <mtx/events/event_type.hpp>
#include <mtx/events/power_levels.hpp>
-#include "CacheStructs.h"
-
class PowerlevelsTypeListModel final : public QAbstractListModel
{
Q_OBJECT
diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
index 3b1ba658..2c0a5b07 100644
--- a/src/RegisterPage.cpp
+++ b/src/RegisterPage.cpp
@@ -10,7 +10,6 @@
#include <mtx/responses/well-known.hpp>
#include <mtxclient/http/client.hpp>
-#include "Config.h"
#include "Logging.h"
#include "LoginPage.h"
#include "MainWindow.h"
diff --git a/src/RoomsModel.cpp b/src/RoomsModel.cpp
index 32dce4f6..7481eb51 100644
--- a/src/RoomsModel.cpp
+++ b/src/RoomsModel.cpp
@@ -6,7 +6,6 @@
#include <QUrl>
-#include "Cache.h"
#include "Cache_p.h"
#include "CompletionModelRoles.h"
#include "UserSettingsPage.h"
diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp
index 686184da..1adfdaa2 100644
--- a/src/SingleImagePackModel.cpp
+++ b/src/SingleImagePackModel.cpp
@@ -8,6 +8,8 @@
#include <QFileInfo>
#include <QMimeDatabase>
+#include <nlohmann/json.hpp>
+
#include <unordered_set>
#include <mtx/responses/media.hpp>
diff --git a/src/UserDirectoryModel.cpp b/src/UserDirectoryModel.cpp
index ae8e19b1..72a5a13e 100644
--- a/src/UserDirectoryModel.cpp
+++ b/src/UserDirectoryModel.cpp
@@ -8,7 +8,6 @@
#include <mtx/responses/users.hpp>
-#include "Cache.h"
#include "Logging.h"
#include "MatrixClient.h"
diff --git a/src/UsersModel.cpp b/src/UsersModel.cpp
index 453ef137..a017aa84 100644
--- a/src/UsersModel.cpp
+++ b/src/UsersModel.cpp
@@ -9,6 +9,7 @@
#include "Cache.h"
#include "Cache_p.h"
#include "CompletionModelRoles.h"
+#include "Logging.h"
#include "UserSettingsPage.h"
UsersModel::UsersModel(const std::string &roomId, QObject *parent)
diff --git a/src/Utils.cpp b/src/Utils.cpp
index bb4df7d3..7a487101 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -4,6 +4,11 @@
#include "Utils.h"
+#include <array>
+#include <cmath>
+#include <unordered_set>
+#include <variant>
+
#include <QApplication>
#include <QBuffer>
#include <QComboBox>
@@ -20,14 +25,12 @@
#include <QWindow>
#include <QXmlStreamReader>
-#include <array>
-#include <cmath>
-#include <mtx/responses/messages.hpp>
-#include <unordered_set>
-#include <variant>
+#include <nlohmann/json.hpp>
#include <cmark.h>
+#include <mtx/responses/messages.hpp>
+
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
@@ -36,7 +39,6 @@
#include "Logging.h"
#include "MatrixClient.h"
#include "UserSettingsPage.h"
-#include "timeline/Permissions.h"
template<class T, class Event>
static DescInfo
diff --git a/src/Utils.h b/src/Utils.h
index 83f2cad1..2c75cb5c 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -4,8 +4,6 @@
#pragma once
-#include <variant>
-
#include <CacheStructs.h>
#include <QCoreApplication>
#include <QDateTime>
diff --git a/src/dbus/NhekoDBusBackend.cpp b/src/dbus/NhekoDBusBackend.cpp
index 9690cdfa..5e0f8418 100644
--- a/src/dbus/NhekoDBusBackend.cpp
+++ b/src/dbus/NhekoDBusBackend.cpp
@@ -6,7 +6,6 @@
#include <mutex>
-#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
#include "Logging.h"
diff --git a/src/encryption/DeviceVerificationFlow.cpp b/src/encryption/DeviceVerificationFlow.cpp
index 1e7ed7bc..f0c7ed52 100644
--- a/src/encryption/DeviceVerificationFlow.cpp
+++ b/src/encryption/DeviceVerificationFlow.cpp
@@ -4,6 +4,13 @@
#include "DeviceVerificationFlow.h"
+#include <tuple>
+
+#include <QDateTime>
+#include <QTimer>
+
+#include <nlohmann/json.hpp>
+
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
@@ -11,11 +18,6 @@
#include "Utils.h"
#include "timeline/TimelineModel.h"
-#include <QDateTime>
-#include <QTimer>
-#include <iostream>
-#include <tuple>
-
static constexpr int TIMEOUT = 2 * 60 * 1000; // 2 minutes
static mtx::events::msg::KeyVerificationMac
diff --git a/src/encryption/DeviceVerificationFlow.h b/src/encryption/DeviceVerificationFlow.h
index 50818883..6b1776e0 100644
--- a/src/encryption/DeviceVerificationFlow.h
+++ b/src/encryption/DeviceVerificationFlow.h
@@ -11,7 +11,6 @@
#include "CacheCryptoStructs.h"
#include "Logging.h"
#include "MatrixClient.h"
-#include "Olm.h"
#include "timeline/TimelineModel.h"
class QTimer;
diff --git a/src/encryption/Olm.cpp b/src/encryption/Olm.cpp
index 7fa176b0..aaa7e43f 100644
--- a/src/encryption/Olm.cpp
+++ b/src/encryption/Olm.cpp
@@ -22,7 +22,6 @@
#include "Logging.h"
#include "MatrixClient.h"
#include "UserSettingsPage.h"
-#include "Utils.h"
namespace {
auto client_ = std::make_unique<mtx::crypto::OlmClient>();
diff --git a/src/encryption/Olm.h b/src/encryption/Olm.h
index 726b9590..252d08b4 100644
--- a/src/encryption/Olm.h
+++ b/src/encryption/Olm.h
@@ -4,7 +4,6 @@
#pragma once
-#include <memory>
#include <mtx/events.hpp>
#include <mtx/events/encrypted.hpp>
#include <mtxclient/crypto/client.hpp>
diff --git a/src/encryption/SelfVerificationStatus.cpp b/src/encryption/SelfVerificationStatus.cpp
index e54cbc2d..8981244d 100644
--- a/src/encryption/SelfVerificationStatus.cpp
+++ b/src/encryption/SelfVerificationStatus.cpp
@@ -6,6 +6,10 @@
#include <QApplication>
+#include <nlohmann/json.hpp>
+
+#include <mtx/responses/common.hpp>
+
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
@@ -16,8 +20,6 @@
#include "timeline/TimelineViewManager.h"
#include "ui/UIA.h"
-#include <mtx/responses/common.hpp>
-
SelfVerificationStatus::SelfVerificationStatus(QObject *o)
: QObject(o)
{
diff --git a/src/notifications/Manager.cpp b/src/notifications/Manager.cpp
index ed5c0670..5790d43e 100644
--- a/src/notifications/Manager.cpp
+++ b/src/notifications/Manager.cpp
@@ -6,7 +6,6 @@
#include "Cache.h"
#include "EventAccessors.h"
-#include "Logging.h"
#include "Utils.h"
QString
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index c47a3426..04e548f0 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -7,6 +7,8 @@
#include <QThread>
#include <QTimer>
+#include <nlohmann/json.hpp>
+
#include <mtx/responses/common.hpp>
#include "Cache.h"
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index fcec8e9c..bcb30aa0 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -14,20 +14,20 @@
#include <QMediaPlayer>
#include <QMimeData>
#include <QMimeDatabase>
+#include <QRegularExpression>
#include <QStandardPaths>
#include <QTextBoundaryFinder>
#include <QVideoFrame>
#include <QVideoSink>
-#include <QRegularExpression>
+#include <nlohmann/json.hpp>
+
#include <mtx/responses/common.hpp>
#include <mtx/responses/media.hpp>
#include "Cache.h"
#include "Cache_p.h"
#include "ChatPage.h"
-#include "CombinedImagePackModel.h"
-#include "Config.h"
#include "EventAccessors.h"
#include "Logging.h"
#include "MatrixClient.h"
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index aefdc860..490641a6 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -7,6 +7,7 @@
#include <algorithm>
#include <thread>
#include <type_traits>
+#include <utility>
#include <QClipboard>
#include <QDesktopServices>
@@ -17,7 +18,8 @@
#include <QRegularExpression>
#include <QStandardPaths>
#include <QVariant>
-#include <utility>
+
+#include <nlohmann/json.hpp>
#include "Cache.h"
#include "Cache_p.h"
diff --git a/src/ui/MxcMediaProxy.h b/src/ui/MxcMediaProxy.h
index d245dcae..64c61c4f 100644
--- a/src/ui/MxcMediaProxy.h
+++ b/src/ui/MxcMediaProxy.h
@@ -13,8 +13,6 @@
#include <QUrl>
#include <QVideoSink>
-#include "Logging.h"
-
class TimelineModel;
// I failed to get my own buffer into the MediaPlayer in qml, so just make our own. For that we just
diff --git a/src/ui/NhekoDropArea.cpp b/src/ui/NhekoDropArea.cpp
index 348ef5d8..571ccf69 100644
--- a/src/ui/NhekoDropArea.cpp
+++ b/src/ui/NhekoDropArea.cpp
@@ -11,8 +11,6 @@
#include "timeline/TimelineModel.h"
#include "timeline/TimelineViewManager.h"
-#include "Logging.h"
-
NhekoDropArea::NhekoDropArea(QQuickItem *parent)
: QQuickItem(parent)
{
diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp
index 5f4184b3..073b27d0 100644
--- a/src/ui/RoomSettings.cpp
+++ b/src/ui/RoomSettings.cpp
@@ -15,7 +15,6 @@
#include "Cache.h"
#include "Cache_p.h"
-#include "Config.h"
#include "Logging.h"
#include "MatrixClient.h"
#include "Utils.h"
|