This commit is contained in:
Karthik Nishanth 2024-11-19 16:30:40 -08:00 committed by GitHub
commit 7c734e71f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 122 additions and 14 deletions

View file

@ -249,6 +249,14 @@ Control {
text: model.roomName text: model.roomName
textFormat: Text.RichText textFormat: Text.RichText
} }
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
}
}
} }
} }
DelegateChoice { DelegateChoice {

View file

@ -32,6 +32,7 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <mtx/events/spaces.hpp>
#include <mtx/responses/common.hpp> #include <mtx/responses/common.hpp>
#include <mtx/responses/messages.hpp> #include <mtx/responses/messages.hpp>
@ -3095,6 +3096,26 @@ Cache::roomNamesAndAliases()
{ {
auto txn = ro_txn(db->env_); auto txn = ro_txn(db->env_);
auto getParentRoomIdsWithTxn = [&](const std::string &id) -> std::optional<std::string> {
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<std::string>(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<RoomNameAlias> result; std::vector<RoomNameAlias> result;
result.reserve(db->rooms.size(txn)); result.reserve(db->rooms.size(txn));
@ -3112,6 +3133,13 @@ Cache::roomNamesAndAliases()
alias = aliases->content.alias; alias = aliases->content.alias;
} }
auto parentId = getParentRoomIdsWithTxn(room_id_str);
auto parentName = std::string{};
if (parentId) {
parentName = getRoomName(*parentId);
}
result.push_back(RoomNameAlias{ result.push_back(RoomNameAlias{
.id = std::move(room_id_str), .id = std::move(room_id_str),
.name = std::move(info.name), .name = std::move(info.name),
@ -3119,6 +3147,7 @@ Cache::roomNamesAndAliases()
.recent_activity = info.approximate_last_modification_ts, .recent_activity = info.approximate_last_modification_ts,
.is_tombstoned = info.is_tombstoned, .is_tombstoned = info.is_tombstoned,
.is_space = info.is_space, .is_space = info.is_space,
.parent = std::move(parentName),
}); });
} catch (std::exception &e) { } catch (std::exception &e) {
nhlog::db()->warn("Failed to add room {} to result: {}", room_id, e.what()); nhlog::db()->warn("Failed to add room {} to result: {}", room_id, e.what());

View file

@ -111,6 +111,7 @@ struct RoomNameAlias
std::uint64_t recent_activity; std::uint64_t recent_activity;
bool is_tombstoned; bool is_tombstoned;
bool is_space; bool is_space;
std::string parent;
}; };
//! Basic information per member. //! Basic information per member.

View file

@ -8,11 +8,14 @@
#include "Cache_p.h" #include "Cache_p.h"
#include "CompletionModelRoles.h" #include "CompletionModelRoles.h"
#include "RoomlistModel.h"
#include "TimelineModel.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
#include "Utils.h" #include "Utils.h"
RoomsModel::RoomsModel(bool showOnlyRoomWithAliases, QObject *parent) RoomsModel::RoomsModel(RoomlistModel &roomlistModel, bool showOnlyRoomWithAliases, QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, roomListModel_(roomlistModel)
, showOnlyRoomWithAliases_(showOnlyRoomWithAliases) , showOnlyRoomWithAliases_(showOnlyRoomWithAliases)
{ {
rooms = cache::client()->roomNamesAndAliases(); rooms = cache::client()->roomNamesAndAliases();
@ -35,6 +38,7 @@ RoomsModel::roleNames() const
{Roles::AvatarUrl, "avatarUrl"}, {Roles::AvatarUrl, "avatarUrl"},
{Roles::RoomID, "roomid"}, {Roles::RoomID, "roomid"},
{Roles::RoomName, "roomName"}, {Roles::RoomName, "roomName"},
{Roles::RoomParent, "roomParent"},
{Roles::IsTombstoned, "isTombstoned"}, {Roles::IsTombstoned, "isTombstoned"},
{Roles::IsSpace, "isSpace"}, {Roles::IsSpace, "isSpace"},
}; };
@ -72,6 +76,21 @@ RoomsModel::data(const QModelIndex &index, int role) const
return rooms[index.row()].is_tombstoned; return rooms[index.row()].is_tombstoned;
case Roles::IsSpace: case Roles::IsSpace:
return rooms[index.row()].is_space; return rooms[index.row()].is_space;
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 {}; return {};

View file

@ -9,6 +9,8 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QString> #include <QString>
class RoomlistModel;
class RoomsModel final : public QAbstractListModel class RoomsModel final : public QAbstractListModel
{ {
public: public:
@ -20,9 +22,10 @@ public:
RoomName, RoomName,
IsTombstoned, IsTombstoned,
IsSpace, IsSpace,
RoomParent,
}; };
RoomsModel(bool showOnlyRoomWithAliases = false, QObject *parent = nullptr); RoomsModel(RoomlistModel &roomListModel, bool showOnlyRoomWithAliases = false, QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override int rowCount(const QModelIndex &parent = QModelIndex()) const override
{ {
@ -32,6 +35,7 @@ public:
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
private: private:
RoomlistModel &roomListModel_;
std::vector<RoomNameAlias> rooms; std::vector<RoomNameAlias> rooms;
bool showOnlyRoomWithAliases_; bool showOnlyRoomWithAliases_;
}; };

View file

@ -65,16 +65,17 @@ UserSettings::load(std::optional<QString> profile)
settings.value("user/timeline/message_hover_highlight", false).toBool(); settings.value("user/timeline/message_hover_highlight", false).toBool();
enlargeEmojiOnlyMessages_ = enlargeEmojiOnlyMessages_ =
settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool(); settings.value("user/timeline/enlarge_emoji_only_msg", false).toBool();
markdown_ = settings.value("user/markdown_enabled", true).toBool(); markdown_ = settings.value("user/markdown_enabled", true).toBool();
invertEnterKey_ = settings.value("user/invert_enter_key", false).toBool(); invertEnterKey_ = settings.value("user/invert_enter_key", false).toBool();
bubbles_ = settings.value("user/bubbles_enabled", false).toBool(); bubbles_ = settings.value("user/bubbles_enabled", false).toBool();
smallAvatars_ = settings.value("user/small_avatars_enabled", false).toBool(); smallAvatars_ = settings.value("user/small_avatars_enabled", false).toBool();
animateImagesOnHover_ = settings.value("user/animate_images_on_hover", false).toBool(); animateImagesOnHover_ = settings.value("user/animate_images_on_hover", false).toBool();
typingNotifications_ = settings.value("user/typing_notifications", true).toBool(); typingNotifications_ = settings.value("user/typing_notifications", true).toBool();
sortByImportance_ = settings.value("user/sort_by_unread", true).toBool(); sortByImportance_ = settings.value("user/sort_by_unread", true).toBool();
sortByAlphabet_ = settings.value("user/sort_by_alphabet", false).toBool(); sortByAlphabet_ = settings.value("user/sort_by_alphabet", false).toBool();
readReceipts_ = settings.value("user/read_receipts", true).toBool(); readReceipts_ = settings.value("user/read_receipts", true).toBool();
theme_ = settings.value("user/theme", defaultTheme_).toString(); 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(); font_ = settings.value("user/font_family", "").toString();
@ -873,6 +874,16 @@ UserSettings::setOpenVideoExternal(bool state)
save(); save();
} }
void
UserSettings::setDisplayParentInSwitcher(bool state)
{
if (state == displayParentInSwitcher_)
return;
displayParentInSwitcher_ = state;
emit displayParentInSwitcherChanged(displayParentInSwitcher_);
save();
}
void void
UserSettings::applyTheme() UserSettings::applyTheme()
{ {
@ -947,6 +958,7 @@ UserSettings::save()
settings.setValue("expose_dbus_api", exposeDBusApi_); settings.setValue("expose_dbus_api", exposeDBusApi_);
settings.setValue("space_background_maintenance", updateSpaceVias_); settings.setValue("space_background_maintenance", updateSpaceVias_);
settings.setValue("expired_events_background_maintenance", expireEvents_); settings.setValue("expired_events_background_maintenance", expireEvents_);
settings.setValue("display_parent_on_room_switch", displayParentInSwitcher_);
settings.endGroup(); // user settings.endGroup(); // user
@ -1033,6 +1045,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
return tr("Communities sidebar"); return tr("Communities sidebar");
case ScrollbarsInRoomlist: case ScrollbarsInRoomlist:
return tr("Scrollbars in room list"); return tr("Scrollbars in room list");
case DisplayParentInSwitcher:
return tr("Display room's parent in room switcher");
case Markdown: case Markdown:
return tr("Send messages as Markdown"); return tr("Send messages as Markdown");
case InvertEnterKey: case InvertEnterKey:
@ -1193,6 +1207,8 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
return i->groupView(); return i->groupView();
case ScrollbarsInRoomlist: case ScrollbarsInRoomlist:
return i->scrollbarsInRoomlist(); return i->scrollbarsInRoomlist();
case DisplayParentInSwitcher:
return i->displayParentInSwitcher();
case Markdown: case Markdown:
return i->markdown(); return i->markdown();
case InvertEnterKey: case InvertEnterKey:
@ -1357,6 +1373,10 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
return tr("Show a column containing communities and tags next to the room list."); return tr("Show a column containing communities and tags next to the room list.");
case ScrollbarsInRoomlist: case ScrollbarsInRoomlist:
return tr("Shows scrollbars in the room list and communities list."); 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: case Markdown:
return tr( return tr(
"Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain " "Allow using markdown in messages.\nWhen disabled, all messages are sent as a plain "
@ -1545,6 +1565,7 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
case StartInTray: case StartInTray:
case GroupView: case GroupView:
case ScrollbarsInRoomlist: case ScrollbarsInRoomlist:
case DisplayParentInSwitcher:
case Markdown: case Markdown:
case InvertEnterKey: case InvertEnterKey:
case Bubbles: case Bubbles:
@ -1803,6 +1824,13 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
} else } else
return false; return false;
} }
case DisplayParentInSwitcher: {
if (value.userType() == QMetaType::Bool) {
i->setDisplayParentInSwitcher(value.toBool());
return true;
} else
return false;
}
case Markdown: { case Markdown: {
if (value.userType() == QMetaType::Bool) { if (value.userType() == QMetaType::Bool) {
i->setMarkdown(value.toBool()); i->setMarkdown(value.toBool());
@ -2315,6 +2343,9 @@ UserSettingsModel::UserSettingsModel(QObject *p)
connect(s.get(), &UserSettings::scrollbarsInRoomlistChanged, this, [this]() { connect(s.get(), &UserSettings::scrollbarsInRoomlistChanged, this, [this]() {
emit dataChanged(index(ScrollbarsInRoomlist), index(ScrollbarsInRoomlist), {Value}); 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]() { connect(s.get(), &UserSettings::roomSortingChangedImportance, this, [this]() {
emit dataChanged(index(SortByImportance), index(SortByImportance), {Value}); emit dataChanged(index(SortByImportance), index(SortByImportance), {Value});
}); });

View file

@ -122,6 +122,8 @@ class UserSettings final : public QObject
Q_PROPERTY(bool updateSpaceVias READ updateSpaceVias WRITE setUpdateSpaceVias NOTIFY Q_PROPERTY(bool updateSpaceVias READ updateSpaceVias WRITE setUpdateSpaceVias NOTIFY
updateSpaceViasChanged) updateSpaceViasChanged)
Q_PROPERTY(bool expireEvents READ expireEvents WRITE setExpireEvents NOTIFY expireEventsChanged) Q_PROPERTY(bool expireEvents READ expireEvents WRITE setExpireEvents NOTIFY expireEventsChanged)
Q_PROPERTY(bool displayParentInSwitcher READ displayParentInSwitcher WRITE
setDisplayParentInSwitcher NOTIFY displayParentInSwitcherChanged)
UserSettings(); UserSettings();
@ -238,6 +240,7 @@ public:
void setExposeDBusApi(bool state); void setExposeDBusApi(bool state);
void setUpdateSpaceVias(bool state); void setUpdateSpaceVias(bool state);
void setExpireEvents(bool state); void setExpireEvents(bool state);
void setDisplayParentInSwitcher(bool state);
QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; } QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; }
bool messageHoverHighlight() const { return messageHoverHighlight_; } bool messageHoverHighlight() const { return messageHoverHighlight_; }
@ -316,6 +319,7 @@ public:
bool exposeDBusApi() const { return exposeDBusApi_; } bool exposeDBusApi() const { return exposeDBusApi_; }
bool updateSpaceVias() const { return updateSpaceVias_; } bool updateSpaceVias() const { return updateSpaceVias_; }
bool expireEvents() const { return expireEvents_; } bool expireEvents() const { return expireEvents_; }
bool displayParentInSwitcher() const { return displayParentInSwitcher_; }
signals: signals:
void groupViewStateChanged(bool state); void groupViewStateChanged(bool state);
@ -383,6 +387,7 @@ signals:
void exposeDBusApiChanged(bool state); void exposeDBusApiChanged(bool state);
void updateSpaceViasChanged(bool state); void updateSpaceViasChanged(bool state);
void expireEventsChanged(bool state); void expireEventsChanged(bool state);
void displayParentInSwitcherChanged(bool state);
private: private:
// Default to system theme if QT_QPA_PLATFORMTHEME var is set. // Default to system theme if QT_QPA_PLATFORMTHEME var is set.
@ -460,6 +465,7 @@ private:
bool exposeDBusApi_; bool exposeDBusApi_;
bool updateSpaceVias_; bool updateSpaceVias_;
bool expireEvents_; bool expireEvents_;
bool displayParentInSwitcher_;
QSettings settings; QSettings settings;
@ -489,6 +495,7 @@ class UserSettingsModel : public QAbstractListModel
PrivacyScreen, PrivacyScreen,
PrivacyScreenTimeout, PrivacyScreenTimeout,
ScrollbarsInRoomlist, ScrollbarsInRoomlist,
DisplayParentInSwitcher,
#ifdef NHEKO_DBUS_SYS #ifdef NHEKO_DBUS_SYS
ExposeDBusApi, ExposeDBusApi,
#endif #endif

View file

@ -517,12 +517,12 @@ TimelineViewManager::completerFor(const QString &completerName, const QString &r
emojiModel->setParent(proxy); emojiModel->setParent(proxy);
return proxy; return proxy;
} else if (completerName == QLatin1String("room")) { } else if (completerName == QLatin1String("room")) {
auto roomModel = new RoomsModel(false); auto roomModel = new RoomsModel(*rooms_, false);
auto proxy = new CompletionProxyModel(roomModel, 4); auto proxy = new CompletionProxyModel(roomModel, 4);
roomModel->setParent(proxy); roomModel->setParent(proxy);
return proxy; return proxy;
} else if (completerName == QLatin1String("roomAliases")) { } else if (completerName == QLatin1String("roomAliases")) {
auto roomModel = new RoomsModel(true); auto roomModel = new RoomsModel(*rooms_, true);
auto proxy = new CompletionProxyModel(roomModel); auto proxy = new CompletionProxyModel(roomModel);
roomModel->setParent(proxy); roomModel->setParent(proxy);
return proxy; return proxy;
@ -620,6 +620,9 @@ TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEven
} }
//! WORKAROUND(Nico): for https://bugreports.qt.io/browse/QTBUG-93281 //! 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 void
TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t, TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t,
[[maybe_unused]] QQuickItem *i) [[maybe_unused]] QQuickItem *i)
@ -630,6 +633,12 @@ TimelineViewManager::fixImageRendering([[maybe_unused]] QQuickTextDocument *t,
} }
#endif #endif
} }
#else
void
TimelineViewManager::fixImageRendering(QQuickTextDocument *, QQuickItem *)
{
}
#endif
using IgnoredUsers = mtx::events::EphemeralEvent<mtx::events::account_data::IgnoredUsers>; using IgnoredUsers = mtx::events::EphemeralEvent<mtx::events::account_data::IgnoredUsers>;