diff --git a/src/Cache.cpp b/src/Cache.cpp index be3380c1..18b991af 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -99,7 +99,6 @@ using Receipts = std::map>; Q_DECLARE_METATYPE(RoomMember) Q_DECLARE_METATYPE(mtx::responses::Timeline) -Q_DECLARE_METATYPE(RoomSearchResult) Q_DECLARE_METATYPE(RoomInfo) Q_DECLARE_METATYPE(mtx::responses::QueryKeys) @@ -2451,6 +2450,39 @@ Cache::roomInfo(bool withInvites) return result; } +std::vector +Cache::roomNamesAndAliases() +{ + auto txn = ro_txn(env_); + + std::vector result; + result.reserve(roomsDb_.size(txn)); + + std::string_view room_id; + std::string_view room_data; + auto roomsCursor = lmdb::cursor::open(txn, roomsDb_); + while (roomsCursor.get(room_id, room_data, MDB_NEXT)) { + try { + std::string room_id_str = std::string(room_id); + RoomInfo info = nlohmann::json::parse(std::move(room_data)).get(); + + auto aliases = getStateEvent(txn, room_id_str); + std::string alias; + if (aliases) { + alias = aliases->content.alias; + } + + result.push_back(RoomNameAlias{.id = std::move(room_id_str), + .name = std::move(info.name), + .alias = std::move(alias)}); + } catch (std::exception &e) { + nhlog::db()->warn("Failed to add room {} to result: {}", room_id, e.what()); + } + } + + return result; +} + std::string Cache::getLastEventId(lmdb::txn &txn, const std::string &room_id) { @@ -5136,7 +5168,6 @@ void init(const QString &user_id) { qRegisterMetaType(); - qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); qRegisterMetaType>(); diff --git a/src/CacheStructs.h b/src/CacheStructs.h index bf8741ea..aba35f96 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -103,6 +103,12 @@ to_json(nlohmann::json &j, const RoomInfo &info); void from_json(const nlohmann::json &j, RoomInfo &info); +//! A plain struct with roomid, name and alias used for filling the room completer. +struct RoomNameAlias +{ + std::string id, name, alias; +}; + //! Basic information per member. struct MemberInfo { diff --git a/src/Cache_p.h b/src/Cache_p.h index 306194de..c85f5edc 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -167,6 +167,9 @@ public: RoomInfo singleRoomInfo(const std::string &room_id); std::vector roomsWithStateUpdates(const mtx::responses::Sync &res); std::map getRoomInfo(const std::vector &rooms); + + std::vector roomNamesAndAliases(); + void updateLastMessageTimestamp(const std::string &room_id, uint64_t ts); //! Calculates which the read status of a room. diff --git a/src/RoomsModel.cpp b/src/RoomsModel.cpp index 476a2d8b..d148c480 100644 --- a/src/RoomsModel.cpp +++ b/src/RoomsModel.cpp @@ -12,34 +12,16 @@ #include "Cache_p.h" #include "CompletionModelRoles.h" #include "UserSettingsPage.h" +#include "Utils.h" RoomsModel::RoomsModel(bool showOnlyRoomWithAliases, QObject *parent) : QAbstractListModel(parent) , showOnlyRoomWithAliases_(showOnlyRoomWithAliases) { - std::vector rooms_ = cache::joinedRooms(); - roomInfos = cache::getRoomInfo(rooms_); - if (!showOnlyRoomWithAliases_) { - roomids.reserve(rooms_.size()); - roomAliases.reserve(rooms_.size()); - } - - for (const auto &r : rooms_) { - auto roomAliasesList = - cache::client()->getStateEvent(r); + rooms = cache::client()->roomNamesAndAliases(); - if (showOnlyRoomWithAliases_) { - if (roomAliasesList && !roomAliasesList->content.alias.empty()) { - roomids.push_back(QString::fromStdString(r)); - roomAliases.push_back(QString::fromStdString(roomAliasesList->content.alias)); - } - } else { - roomids.push_back(QString::fromStdString(r)); - roomAliases.push_back(roomAliasesList - ? QString::fromStdString(roomAliasesList->content.alias) - : QLatin1String("")); - } - } + if (showOnlyRoomWithAliases_) + utils::erase_if(rooms, [](auto &r) { return r.alias.empty(); }); } QHash @@ -60,29 +42,28 @@ RoomsModel::data(const QModelIndex &index, int role) const if (hasIndex(index.row(), index.column(), index.parent())) { switch (role) { case CompletionModel::CompletionRole: { + auto alias = QString::fromStdString(rooms[index.row()].alias); if (UserSettings::instance()->markdown()) { - QString percentEncoding = QUrl::toPercentEncoding(roomAliases[index.row()]); + QString percentEncoding = QUrl::toPercentEncoding(alias); return QStringLiteral("[%1](https://matrix.to/#/%2)") - .arg(QString(roomAliases[index.row()]) - .replace("[", "\\[") - .replace("]", "\\]") - .toHtmlEscaped(), + .arg(alias.replace("[", "\\[").replace("]", "\\]").toHtmlEscaped(), percentEncoding); } else { - return roomAliases[index.row()]; + return alias; } } case CompletionModel::SearchRole: case Qt::DisplayRole: case Roles::RoomAlias: - return roomAliases[index.row()].toHtmlEscaped(); + return QString::fromStdString(rooms[index.row()].alias).toHtmlEscaped(); case CompletionModel::SearchRole2: case Roles::RoomName: - return QString::fromStdString(roomInfos.at(roomids[index.row()]).name).toHtmlEscaped(); + return QString::fromStdString(rooms[index.row()].name); case Roles::AvatarUrl: - return QString::fromStdString(roomInfos.at(roomids[index.row()]).avatar_url); + return QString::fromStdString( + cache::client()->singleRoomInfo(rooms[index.row()].id).avatar_url); case Roles::RoomID: - return roomids[index.row()].toHtmlEscaped(); + return QString::fromStdString(rooms[index.row()].id).toHtmlEscaped(); } } return {}; diff --git a/src/RoomsModel.h b/src/RoomsModel.h index b2f4e44e..82ce7d7f 100644 --- a/src/RoomsModel.h +++ b/src/RoomsModel.h @@ -27,13 +27,11 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override { (void)parent; - return (int)roomids.size(); + return (int)rooms.size(); } QVariant data(const QModelIndex &index, int role) const override; private: - std::vector roomids; - std::vector roomAliases; - std::map roomInfos; + std::vector rooms; bool showOnlyRoomWithAliases_; };