From 2b9e056eafb8a69a74d22e2ee00c66e3d200252a Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Mon, 13 May 2024 17:44:42 -0700 Subject: [PATCH 1/6] Remove workaround for QTBUG-93281 This is fixed in Qt 6.7.0 and signal `imagesLoaded` was removed. Nheko warns about `No such signal QTextDocument::imagesLoaded()` --- src/timeline/TimelineViewManager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 1b2635b0..fd1d6d4e 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -620,6 +620,9 @@ TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEven } //! WORKAROUND(Nico): for https://bugreports.qt.io/browse/QTBUG-93281 +// QTBUG-93281 Fixed in 6.7.0 +// https://github.com/qt/qtdeclarative/commit/7fb39a7accba014063e32ac41a58b77905bbd95b +#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0) void TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t, [[maybe_unused]] QQuickItem *i) @@ -630,6 +633,11 @@ TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t, } #endif } +#else +void +TimelineViewManager::fixImageRendering(QQuickTextDocument *, QQuickItem *) +{} +#endif using IgnoredUsers = mtx::events::EphemeralEvent; From 46a8019913e25d961c7f922a34f20d1683179f96 Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Mon, 13 May 2024 19:09:02 -0700 Subject: [PATCH 2/6] List parent room name next to room names in room switcher --- resources/qml/Completer.qml | 5 +++++ src/Cache.cpp | 31 +++++++++++++++++++++++++++++++ src/CacheStructs.h | 1 + src/RoomsModel.cpp | 3 +++ src/RoomsModel.h | 1 + 5 files changed, 41 insertions(+) diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index c6fea98e..2d635434 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -249,6 +249,11 @@ Control { text: model.roomName textFormat: Text.RichText } + + Label { + text: model.roomParent === "" ? "" : ("[" + model.roomParent + "]") + font.pixelSize: popup.avatarHeight * 0.5 + } } } DelegateChoice { diff --git a/src/Cache.cpp b/src/Cache.cpp index e12e9512..bd8d8f76 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -26,6 +26,7 @@ #include +#include #include #include @@ -2945,6 +2946,26 @@ Cache::roomNamesAndAliases() { auto txn = ro_txn(env_); + auto getParentRoomIdsWithTxn = [&](const std::string &id) -> std::optional { + auto cursor = lmdb::cursor::open(txn, spacesParentsDb_); + std::string_view sp = id, space_parent; + if (cursor.get(sp, space_parent, MDB_SET)) { + while (cursor.get(sp, space_parent, MDB_FIRST_DUP)) { + if (!space_parent.empty()) + return std::make_optional(static_cast(space_parent)); + } + } + cursor.close(); + + return std::nullopt; + }; + + auto getRoomName = [&](const std::string &roomId) { + auto spaceDb = getStatesDb(txn, roomId); + auto membersDb = getMembersDb(txn, roomId); + return Cache::getRoomName(txn, spaceDb, membersDb).toStdString(); + }; + std::vector result; result.reserve(roomsDb_.size(txn)); @@ -2962,6 +2983,15 @@ Cache::roomNamesAndAliases() alias = aliases->content.alias; } + auto parentId = getParentRoomIdsWithTxn(room_id_str); + auto parentName = std::string{}; + + if (parentId) { + parentName = getRoomName(*parentId); + } + + nhlog::db()->info("{} has parent [{}]", room_id_str, parentName); + result.push_back(RoomNameAlias{ .id = std::move(room_id_str), .name = std::move(info.name), @@ -2969,6 +2999,7 @@ Cache::roomNamesAndAliases() .recent_activity = info.approximate_last_modification_ts, .is_tombstoned = info.is_tombstoned, .is_space = info.is_space, + .parent = std::move(parentName), }); } catch (std::exception &e) { nhlog::db()->warn("Failed to add room {} to result: {}", room_id, e.what()); diff --git a/src/CacheStructs.h b/src/CacheStructs.h index f1aafb96..18dadc10 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -111,6 +111,7 @@ struct RoomNameAlias std::uint64_t recent_activity; bool is_tombstoned; bool is_space; + std::string parent; }; //! Basic information per member. diff --git a/src/RoomsModel.cpp b/src/RoomsModel.cpp index fff9cbc6..034a3ce2 100644 --- a/src/RoomsModel.cpp +++ b/src/RoomsModel.cpp @@ -35,6 +35,7 @@ RoomsModel::roleNames() const {Roles::AvatarUrl, "avatarUrl"}, {Roles::RoomID, "roomid"}, {Roles::RoomName, "roomName"}, + {Roles::RoomParent, "roomParent"}, {Roles::IsTombstoned, "isTombstoned"}, {Roles::IsSpace, "isSpace"}, }; @@ -72,6 +73,8 @@ RoomsModel::data(const QModelIndex &index, int role) const return rooms[index.row()].is_tombstoned; case Roles::IsSpace: return rooms[index.row()].is_space; + case Roles::RoomParent: + return QString::fromStdString(rooms[index.row()].parent); } } return {}; diff --git a/src/RoomsModel.h b/src/RoomsModel.h index 83a21ae0..5d3d3813 100644 --- a/src/RoomsModel.h +++ b/src/RoomsModel.h @@ -20,6 +20,7 @@ public: RoomName, IsTombstoned, IsSpace, + RoomParent, }; RoomsModel(bool showOnlyRoomWithAliases = false, QObject *parent = nullptr); From 7582c6d3a87eae552078fa67c535e9a995b82b90 Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Fri, 17 May 2024 17:25:18 -0700 Subject: [PATCH 3/6] Add configuration to display room's parent in room switcher --- resources/qml/Completer.qml | 11 +++++++---- src/UserSettingsPage.cpp | 31 +++++++++++++++++++++++++++++++ src/UserSettingsPage.h | 7 +++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml index 2d635434..c580cbc2 100644 --- a/resources/qml/Completer.qml +++ b/resources/qml/Completer.qml @@ -249,10 +249,13 @@ Control { text: model.roomName textFormat: Text.RichText } - - Label { - text: model.roomParent === "" ? "" : ("[" + model.roomParent + "]") - font.pixelSize: popup.avatarHeight * 0.5 + Loader { + active: Settings.displayParentInSwitcher && model.roomParent !== "" + sourceComponent: Label { + color: model.index == popup.currentIndex ? palette.highlightedText : palette.text + text: "[" + model.roomParent + "]" + font.pixelSize: popup.avatarHeight * 0.5 + } } } } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 49fb6a59..0376606b 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -75,6 +75,7 @@ UserSettings::load(std::optional profile) sortByAlphabet_ = settings.value("user/sort_by_alphabet", false).toBool(); readReceipts_ = settings.value("user/read_receipts", true).toBool(); theme_ = settings.value("user/theme", defaultTheme_).toString(); + displayParentInSwitcher_ = settings.value("user/display_parent_on_room_switch", true).toBool(); font_ = settings.value("user/font_family", "").toString(); @@ -857,6 +858,16 @@ UserSettings::setOpenVideoExternal(bool state) save(); } +void +UserSettings::setDisplayParentInSwitcher(bool state) +{ + if (state == displayParentInSwitcher_) + return; + displayParentInSwitcher_ = state; + emit displayParentInSwitcherChanged(displayParentInSwitcher_); + save(); +} + void UserSettings::applyTheme() { @@ -931,6 +942,7 @@ UserSettings::save() settings.setValue("expose_dbus_api", exposeDBusApi_); settings.setValue("space_background_maintenance", updateSpaceVias_); settings.setValue("expired_events_background_maintenance", expireEvents_); + settings.setValue("display_parent_on_room_switch", displayParentInSwitcher_); settings.endGroup(); // user @@ -1014,6 +1026,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const return tr("Communities sidebar"); case ScrollbarsInRoomlist: return tr("Scrollbars in room list"); + case DisplayParentInSwitcher: + return tr("Display room's parent in room switcher"); case Markdown: return tr("Send messages as Markdown"); case InvertEnterKey: @@ -1172,6 +1186,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const return i->groupView(); case ScrollbarsInRoomlist: return i->scrollbarsInRoomlist(); + case DisplayParentInSwitcher: + return i->displayParentInSwitcher(); case Markdown: return i->markdown(); case InvertEnterKey: @@ -1334,6 +1350,10 @@ UserSettingsModel::data(const QModelIndex &index, int role) const return tr("Show a column containing communities and tags next to the room list."); case ScrollbarsInRoomlist: return tr("Shows scrollbars in the room list and communities list."); + case DisplayParentInSwitcher: + return tr("Display a room's parent in the room switcher. " + "Enabling this option allows distinguishing multiple rooms " + "with the same name"); case Markdown: return tr( "Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain " @@ -1516,6 +1536,7 @@ UserSettingsModel::data(const QModelIndex &index, int role) const case StartInTray: case GroupView: case ScrollbarsInRoomlist: + case DisplayParentInSwitcher: case Markdown: case InvertEnterKey: case Bubbles: @@ -1758,6 +1779,13 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int } else return false; } + case DisplayParentInSwitcher: { + if (value.userType() == QMetaType::Bool) { + i->setDisplayParentInSwitcher(value.toBool()); + return true; + } else + return false; + } case Markdown: { if (value.userType() == QMetaType::Bool) { i->setMarkdown(value.toBool()); @@ -2253,6 +2281,9 @@ UserSettingsModel::UserSettingsModel(QObject *p) connect(s.get(), &UserSettings::scrollbarsInRoomlistChanged, this, [this]() { emit dataChanged(index(ScrollbarsInRoomlist), index(ScrollbarsInRoomlist), {Value}); }); + connect(s.get(), &UserSettings::displayParentInSwitcherChanged, this, [this]() { + emit dataChanged(index(DisplayParentInSwitcher), index(DisplayParentInSwitcher), {Value}); + }); connect(s.get(), &UserSettings::roomSortingChangedImportance, this, [this]() { emit dataChanged(index(SortByImportance), index(SortByImportance), {Value}); }); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 44cf7c84..6a6c8a12 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -121,6 +121,8 @@ class UserSettings final : public QObject Q_PROPERTY(bool updateSpaceVias READ updateSpaceVias WRITE setUpdateSpaceVias NOTIFY updateSpaceViasChanged) Q_PROPERTY(bool expireEvents READ expireEvents WRITE setExpireEvents NOTIFY expireEventsChanged) + Q_PROPERTY(bool displayParentInSwitcher READ displayParentInSwitcher WRITE + setDisplayParentInSwitcher NOTIFY displayParentInSwitcherChanged) UserSettings(); @@ -228,6 +230,7 @@ public: void setExposeDBusApi(bool state); void setUpdateSpaceVias(bool state); void setExpireEvents(bool state); + void setDisplayParentInSwitcher(bool state); QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } bool messageHoverHighlight() const { return messageHoverHighlight_; } @@ -305,6 +308,7 @@ public: bool exposeDBusApi() const { return exposeDBusApi_; } bool updateSpaceVias() const { return updateSpaceVias_; } bool expireEvents() const { return expireEvents_; } + bool displayParentInSwitcher() const { return displayParentInSwitcher_; } signals: void groupViewStateChanged(bool state); @@ -371,6 +375,7 @@ signals: void exposeDBusApiChanged(bool state); void updateSpaceViasChanged(bool state); void expireEventsChanged(bool state); + void displayParentInSwitcherChanged(bool state); private: // Default to system theme if QT_QPA_PLATFORMTHEME var is set. @@ -447,6 +452,7 @@ private: bool exposeDBusApi_; bool updateSpaceVias_; bool expireEvents_; + bool displayParentInSwitcher_; QSettings settings; @@ -476,6 +482,7 @@ class UserSettingsModel : public QAbstractListModel PrivacyScreen, PrivacyScreenTimeout, ScrollbarsInRoomlist, + DisplayParentInSwitcher, #ifdef NHEKO_DBUS_SYS ExposeDBusApi, #endif From 10cd10606360d5724edf4ce1635f4d06fa1a96b7 Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Tue, 28 May 2024 17:52:07 -0700 Subject: [PATCH 4/6] fixup! remove unnecessary logging --- src/Cache.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Cache.cpp b/src/Cache.cpp index bd8d8f76..cafab20f 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2990,8 +2990,6 @@ Cache::roomNamesAndAliases() parentName = getRoomName(*parentId); } - nhlog::db()->info("{} has parent [{}]", room_id_str, parentName); - result.push_back(RoomNameAlias{ .id = std::move(room_id_str), .name = std::move(info.name), From 492511a2af103dc9b0061fa27744db17111fbf2a Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Fri, 14 Jun 2024 14:10:59 -0700 Subject: [PATCH 5/6] fixup! linter fixes --- src/Cache.cpp | 4 ++-- src/UserSettingsPage.cpp | 20 ++++++++++---------- src/timeline/TimelineViewManager.cpp | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Cache.cpp b/src/Cache.cpp index cafab20f..57e572aa 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2961,7 +2961,7 @@ Cache::roomNamesAndAliases() }; auto getRoomName = [&](const std::string &roomId) { - auto spaceDb = getStatesDb(txn, roomId); + auto spaceDb = getStatesDb(txn, roomId); auto membersDb = getMembersDb(txn, roomId); return Cache::getRoomName(txn, spaceDb, membersDb).toStdString(); }; @@ -2983,7 +2983,7 @@ Cache::roomNamesAndAliases() alias = aliases->content.alias; } - auto parentId = getParentRoomIdsWithTxn(room_id_str); + auto parentId = getParentRoomIdsWithTxn(room_id_str); auto parentName = std::string{}; if (parentId) { diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 0376606b..e2f1e100 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -65,16 +65,16 @@ UserSettings::load(std::optional profile) settings.value("user/timeline/message_hover_highlight", false).toBool(); enlargeEmojiOnlyMessages_ = settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool(); - markdown_ = settings.value("user/markdown_enabled", true).toBool(); - invertEnterKey_ = settings.value("user/invert_enter_key", false).toBool(); - bubbles_ = settings.value("user/bubbles_enabled", false).toBool(); - smallAvatars_ = settings.value("user/small_avatars_enabled", false).toBool(); - animateImagesOnHover_ = settings.value("user/animate_images_on_hover", false).toBool(); - typingNotifications_ = settings.value("user/typing_notifications", true).toBool(); - sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); - sortByAlphabet_ = settings.value("user/sort_by_alphabet", false).toBool(); - readReceipts_ = settings.value("user/read_receipts", true).toBool(); - theme_ = settings.value("user/theme", defaultTheme_).toString(); + markdown_ = settings.value("user/markdown_enabled", true).toBool(); + invertEnterKey_ = settings.value("user/invert_enter_key", false).toBool(); + bubbles_ = settings.value("user/bubbles_enabled", false).toBool(); + smallAvatars_ = settings.value("user/small_avatars_enabled", false).toBool(); + animateImagesOnHover_ = settings.value("user/animate_images_on_hover", false).toBool(); + typingNotifications_ = settings.value("user/typing_notifications", true).toBool(); + sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); + sortByAlphabet_ = settings.value("user/sort_by_alphabet", false).toBool(); + readReceipts_ = settings.value("user/read_receipts", true).toBool(); + theme_ = settings.value("user/theme", defaultTheme_).toString(); displayParentInSwitcher_ = settings.value("user/display_parent_on_room_switch", true).toBool(); font_ = settings.value("user/font_family", "").toString(); diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index fd1d6d4e..09af254c 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -636,7 +636,8 @@ TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t, #else void TimelineViewManager::fixImageRendering(QQuickTextDocument *, QQuickItem *) -{} +{ +} #endif using IgnoredUsers = mtx::events::EphemeralEvent; From 00f2fe7fe66321ca8773e377db4f0fa12bf5c64d Mon Sep 17 00:00:00 2001 From: Karthik Nishanth Date: Thu, 4 Jul 2024 10:38:32 -0700 Subject: [PATCH 6/6] wip change how we read parent room todo remove it from the cache --- src/RoomsModel.cpp | 22 +++++++++++++++++++--- src/RoomsModel.h | 5 ++++- src/timeline/TimelineViewManager.cpp | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/RoomsModel.cpp b/src/RoomsModel.cpp index 034a3ce2..d07277f2 100644 --- a/src/RoomsModel.cpp +++ b/src/RoomsModel.cpp @@ -8,11 +8,14 @@ #include "Cache_p.h" #include "CompletionModelRoles.h" +#include "RoomlistModel.h" +#include "TimelineModel.h" #include "UserSettingsPage.h" #include "Utils.h" -RoomsModel::RoomsModel(bool showOnlyRoomWithAliases, QObject *parent) +RoomsModel::RoomsModel(RoomlistModel &roomlistModel, bool showOnlyRoomWithAliases, QObject *parent) : QAbstractListModel(parent) + , roomListModel_(roomlistModel) , showOnlyRoomWithAliases_(showOnlyRoomWithAliases) { rooms = cache::client()->roomNamesAndAliases(); @@ -73,8 +76,21 @@ RoomsModel::data(const QModelIndex &index, int role) const return rooms[index.row()].is_tombstoned; case Roles::IsSpace: return rooms[index.row()].is_space; - case Roles::RoomParent: - return QString::fromStdString(rooms[index.row()].parent); + case Roles::RoomParent: { + const auto roomPtr = roomListModel_.getRoomById(QString::fromStdString(rooms[index.row()].id)); + if (auto &room = *roomPtr; roomPtr) { + if (const auto &parent = room.parentSpace(); parent) { + qInfo() << "Parent has name" << parent->roomName(); + return parent->roomName(); + } else { + qWarning() << "No parent for room" << "expected" << rooms[index.row()].parent; + } + } + else { + qWarning() << "No room with ID"; + } + return QString{}; + } } } return {}; diff --git a/src/RoomsModel.h b/src/RoomsModel.h index 5d3d3813..845f22ba 100644 --- a/src/RoomsModel.h +++ b/src/RoomsModel.h @@ -9,6 +9,8 @@ #include #include +class RoomlistModel; + class RoomsModel final : public QAbstractListModel { public: @@ -23,7 +25,7 @@ public: RoomParent, }; - RoomsModel(bool showOnlyRoomWithAliases = false, QObject *parent = nullptr); + RoomsModel(RoomlistModel &roomListModel, bool showOnlyRoomWithAliases = false, QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override { @@ -33,6 +35,7 @@ public: QVariant data(const QModelIndex &index, int role) const override; private: + RoomlistModel &roomListModel_; std::vector rooms; bool showOnlyRoomWithAliases_; }; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 09af254c..fd7a340f 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -517,12 +517,12 @@ TimelineViewManager::completerFor(const QString &completerName, const QString &r emojiModel->setParent(proxy); return proxy; } else if (completerName == QLatin1String("room")) { - auto roomModel = new RoomsModel(false); + auto roomModel = new RoomsModel(*rooms_, false); auto proxy = new CompletionProxyModel(roomModel, 4); roomModel->setParent(proxy); return proxy; } else if (completerName == QLatin1String("roomAliases")) { - auto roomModel = new RoomsModel(true); + auto roomModel = new RoomsModel(*rooms_, true); auto proxy = new CompletionProxyModel(roomModel); roomModel->setParent(proxy); return proxy;