diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | resources/qml/ElidedLabel.qml | 28 | ||||
-rw-r--r-- | resources/qml/ForwardCompleter.qml | 2 | ||||
-rw-r--r-- | resources/qml/RoomList.qml | 171 | ||||
-rw-r--r-- | resources/res.qrc | 1 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.cpp | 146 | ||||
-rw-r--r-- | src/timeline/RoomlistModel.h | 58 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.cpp | 180 | ||||
-rw-r--r-- | src/timeline/TimelineViewManager.h | 17 |
9 files changed, 440 insertions, 165 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5155af40..8b43559f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,6 +272,7 @@ set(SRC_FILES src/timeline/TimelineModel.cpp src/timeline/DelegateChooser.cpp src/timeline/Permissions.cpp + src/timeline/RoomlistModel.cpp # UI components src/ui/Avatar.cpp @@ -497,6 +498,7 @@ qt5_wrap_cpp(MOC_HEADERS src/timeline/TimelineModel.h src/timeline/DelegateChooser.h src/timeline/Permissions.h + src/timeline/RoomlistModel.h # UI components src/ui/Avatar.h diff --git a/resources/qml/ElidedLabel.qml b/resources/qml/ElidedLabel.qml new file mode 100644 index 00000000..5ae99de7 --- /dev/null +++ b/resources/qml/ElidedLabel.qml @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.9 +import QtQuick.Controls 2.13 +import im.nheko 1.0 + +Label { + id: root + + property alias fullText: metrics.text + property alias elideWidth: metrics.elideWidth + + color: Nheko.colors.text + text: metrics.elidedText + maximumLineCount: 1 + elide: Text.ElideRight + textFormat: Text.PlainText + + TextMetrics { + id: metrics + + font.pointSize: root.font.pointSize + elide: Text.ElideRight + } + +} diff --git a/resources/qml/ForwardCompleter.qml b/resources/qml/ForwardCompleter.qml index 59bfe94d..1ec18540 100644 --- a/resources/qml/ForwardCompleter.qml +++ b/resources/qml/ForwardCompleter.qml @@ -21,7 +21,7 @@ Popup { modal: true palette: Nheko.colors parent: Overlay.overlay - width: implicitWidth >= (timelineView.width * 0.8) ? implicitWidth : (timelineView.width * 0.8) + width: implicitWidth >= (timelineRoot.width * 0.8) ? implicitWidth : (timelineRoot.width * 0.8) height: implicitHeight + completerPopup.height + padding * 2 leftPadding: 10 rightPadding: 10 diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index 25abb4d1..87a27517 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -8,6 +8,132 @@ import QtQuick.Layouts 1.3 import im.nheko 1.0 Page { + ListView { + anchors.left: parent.left + anchors.right: parent.right + height: parent.height + model: Rooms + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + delegate: Rectangle { + color: Nheko.colors.window + height: fontMetrics.lineSpacing * 2.5 + Nheko.paddingMedium * 2 + width: ListView.view.width + + RowLayout { + //id: userInfoGrid + + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + + Avatar { + //userid: Nheko.currentUser.userid + + id: avatar + + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: fontMetrics.lineSpacing * 2.5 + Layout.preferredHeight: fontMetrics.lineSpacing * 2.5 + url: model.avatarUrl.replace("mxc://", "image://MxcImage/") + displayName: model.roomName + } + + ColumnLayout { + id: textContent + + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + Layout.minimumWidth: 100 + width: parent.width - avatar.width + Layout.preferredWidth: parent.width - avatar.width + spacing: 0 + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + Layout.alignment: Qt.AlignBottom + color: Nheko.colors.text + elideWidth: textContent.width - timestamp.width - Nheko.paddingMedium + fullText: model.roomName + ": " + model.notificationCount + } + + Item { + Layout.fillWidth: true + } + + Label { + id: timestamp + + Layout.alignment: Qt.AlignRight | Qt.AlignBottom + font.pixelSize: fontMetrics.font.pixelSize * 0.9 + color: Nheko.colors.buttonText + text: "14:32" + } + + } + + RowLayout { + Layout.fillWidth: true + spacing: 0 + + ElidedLabel { + color: Nheko.colors.buttonText + font.weight: Font.Thin + font.pixelSize: fontMetrics.font.pixelSize * 0.9 + elideWidth: textContent.width - notificationBubble.width + fullText: model.lastMessage + } + + Item { + Layout.fillWidth: true + } + + Rectangle { + id: notificationBubble + + Layout.alignment: Qt.AlignRight + height: fontMetrics.font.pixelSize * 1.3 + width: height + radius: height / 2 + color: Nheko.colors.highlight + + Label { + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.Fit + color: Nheko.colors.highlightedText + text: model.notificationCount + } + + } + + } + + } + + } + + Rectangle { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + height: parent.height - Nheko.paddingSmall * 2 + width: 3 + color: Nheko.colors.highlight + visible: model.hasUnreadMessages + } + + } + + } background: Rectangle { color: Nheko.theme.sidebarBackground @@ -34,8 +160,8 @@ Page { id: avatar Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: Nheko.avatarSize - Layout.preferredHeight: Nheko.avatarSize + Layout.preferredWidth: fontMetrics.lineSpacing * 2 + Layout.preferredHeight: fontMetrics.lineSpacing * 2 url: Nheko.currentUser.avatarUrl.replace("mxc://", "image://MxcImage/") displayName: Nheko.currentUser.displayName userid: Nheko.currentUser.userid @@ -46,50 +172,25 @@ Page { Layout.alignment: Qt.AlignLeft Layout.fillWidth: true - Layout.minimumWidth: 100 - width: parent.width - avatar.width - logoutButton.width - Layout.preferredWidth: parent.width - avatar.width - logoutButton.width + width: parent.width - avatar.width - logoutButton.width - Nheko.paddingMedium * 2 + Layout.preferredWidth: parent.width - avatar.width - logoutButton.width - Nheko.paddingMedium * 2 spacing: 0 - Label { + ElidedLabel { Layout.alignment: Qt.AlignBottom - color: Nheko.colors.text font.pointSize: fontMetrics.font.pointSize * 1.1 font.weight: Font.DemiBold - text: userNameText.elidedText - maximumLineCount: 1 - elide: Text.ElideRight - textFormat: Text.PlainText - - TextMetrics { - id: userNameText - - font.pointSize: fontMetrics.font.pointSize * 1.1 - elide: Text.ElideRight - elideWidth: col.width - text: Nheko.currentUser.displayName - } - + fullText: Nheko.currentUser.displayName + elideWidth: col.width } - Label { + ElidedLabel { Layout.alignment: Qt.AlignTop color: Nheko.colors.buttonText font.weight: Font.Thin - text: userIdText.elidedText - maximumLineCount: 1 - textFormat: Text.PlainText font.pointSize: fontMetrics.font.pointSize * 0.9 - - TextMetrics { - id: userIdText - - font.pointSize: fontMetrics.font.pointSize * 0.9 - elide: Text.ElideRight - elideWidth: col.width - text: Nheko.currentUser.userid - } - + elideWidth: col.width + fullText: Nheko.currentUser.userid } } diff --git a/resources/res.qrc b/resources/res.qrc index c146f2d9..79e63810 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -131,6 +131,7 @@ <file>qml/Completer.qml</file> <file>qml/EncryptionIndicator.qml</file> <file>qml/ImageButton.qml</file> + <file>qml/ElidedLabel.qml</file> <file>qml/MatrixText.qml</file> <file>qml/MatrixTextField.qml</file> <file>qml/ToggleButton.qml</file> diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp new file mode 100644 index 00000000..6a1fc3c5 --- /dev/null +++ b/src/timeline/RoomlistModel.cpp @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "RoomlistModel.h" + +#include "ChatPage.h" +#include "MatrixClient.h" +#include "MxcImageProvider.h" +#include "TimelineModel.h" +#include "TimelineViewManager.h" +#include "UserSettingsPage.h" + +RoomlistModel::RoomlistModel(TimelineViewManager *parent) + : manager(parent) +{ + connect(ChatPage::instance(), &ChatPage::decryptSidebarChanged, this, [this]() { + auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar(); + QHash<QString, QSharedPointer<TimelineModel>>::iterator i; + for (i = models.begin(); i != models.end(); ++i) { + auto ptr = i.value(); + + if (!ptr.isNull()) { + ptr->setDecryptDescription(decrypt); + ptr->updateLastMessage(); + } + } + }); +} + +QHash<int, QByteArray> +RoomlistModel::roleNames() const +{ + return { + {AvatarUrl, "avatarUrl"}, + {RoomName, "roomName"}, + {LastMessage, "lastMessage"}, + {HasUnreadMessages, "hasUnreadMessages"}, + {NotificationCount, "notificationCount"}, + }; +} + +QVariant +RoomlistModel::data(const QModelIndex &index, int role) const +{ + if (index.row() >= 0 && static_cast<size_t>(index.row()) < roomids.size()) { + auto room = models.value(roomids.at(index.row())); + switch (role) { + case Roles::AvatarUrl: + return room->roomAvatarUrl(); + case Roles::RoomName: + return room->roomName(); + case Roles::LastMessage: + return QString("Nico: Hahaha, this is funny!"); + case Roles::HasUnreadMessages: + return true; + case Roles::NotificationCount: + return 5; + default: + return {}; + } + } else { + return {}; + } +} + +void +RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) +{ + if (!models.contains(room_id)) { + QSharedPointer<TimelineModel> newRoom(new TimelineModel(manager, room_id)); + newRoom->setDecryptDescription( + ChatPage::instance()->userSettings()->decryptSidebar()); + + connect(newRoom.data(), + &TimelineModel::newEncryptedImage, + manager->imageProvider(), + &MxcImageProvider::addEncryptionInfo); + connect(newRoom.data(), + &TimelineModel::forwardToRoom, + manager, + &TimelineViewManager::forwardMessageToRoom); + + if (!suppressInsertNotification) + beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size()); + models.insert(room_id, std::move(newRoom)); + roomids.push_back(room_id); + if (!suppressInsertNotification) + endInsertRows(); + } +} + +void +RoomlistModel::sync(const mtx::responses::Rooms &rooms) +{ + for (const auto &[room_id, room] : rooms.join) { + // addRoom will only add the room, if it doesn't exist + addRoom(QString::fromStdString(room_id)); + const auto &room_model = models.value(QString::fromStdString(room_id)); + room_model->syncState(room.state); + room_model->addEvents(room.timeline); + connect(room_model.data(), + &TimelineModel::newCallEvent, + manager->callManager(), + &CallManager::syncEvent, + Qt::UniqueConnection); + + if (ChatPage::instance()->userSettings()->typingNotifications()) { + for (const auto &ev : room.ephemeral.events) { + if (auto t = std::get_if< + mtx::events::EphemeralEvent<mtx::events::ephemeral::Typing>>( + &ev)) { + std::vector<QString> typing; + typing.reserve(t->content.user_ids.size()); + for (const auto &user : t->content.user_ids) { + if (user != http::client()->user_id().to_string()) + typing.push_back( + QString::fromStdString(user)); + } + room_model->updateTypingUsers(typing); + } + } + } + } +} + +void +RoomlistModel::initializeRooms(const std::vector<QString> &roomIds_) +{ + beginResetModel(); + models.clear(); + roomids.clear(); + roomids = roomIds_; + for (const auto &id : roomIds_) + addRoom(id, true); + endResetModel(); +} + +void +RoomlistModel::clear() +{ + beginResetModel(); + models.clear(); + roomids.clear(); + endResetModel(); +} diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h new file mode 100644 index 00000000..44fcf032 --- /dev/null +++ b/src/timeline/RoomlistModel.h @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QAbstractListModel> +#include <QHash> +#include <QSharedPointer> +#include <QString> + +#include <mtx/responses/sync.hpp> + +class TimelineModel; +class TimelineViewManager; + +class RoomlistModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum Roles + { + AvatarUrl = Qt::UserRole, + RoomName, + LastMessage, + HasUnreadMessages, + NotificationCount, + }; + + RoomlistModel(TimelineViewManager *parent = nullptr); + QHash<int, QByteArray> roleNames() const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + (void)parent; + return (int)roomids.size(); + } + QVariant data(const QModelIndex &index, int role) const override; + QSharedPointer<TimelineModel> getRoomById(QString id) const + { + if (models.contains(id)) + return models.value(id); + else + return {}; + } + +public slots: + void initializeRooms(const std::vector<QString> &roomids); + void sync(const mtx::responses::Rooms &rooms); + void clear(); + +private: + void addRoom(const QString &room_id, bool suppressInsertNotification = false); + + TimelineViewManager *manager = nullptr; + std::vector<QString> roomids; + QHash<QString, QSharedPointer<TimelineModel>> models; +}; + diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index e8e57fd8..b0c13b03 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -87,21 +87,6 @@ removeReplyFallback(mtx::events::Event<T> &e) } void -TimelineViewManager::updateEncryptedDescriptions() -{ - auto decrypt = ChatPage::instance()->userSettings()->decryptSidebar(); - QHash<QString, QSharedPointer<TimelineModel>>::iterator i; - for (i = models.begin(); i != models.end(); ++i) { - auto ptr = i.value(); - - if (!ptr.isNull()) { - ptr->setDecryptDescription(decrypt); - ptr->updateLastMessage(); - } - } -} - -void TimelineViewManager::updateColorPalette() { userColors.clear(); @@ -148,6 +133,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par , colorImgProvider(new ColorImageProvider()) , blurhashProvider(new BlurhashProvider()) , callManager_(callManager) + , rooms(new RoomlistModel(this)) { qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>(); qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>(); @@ -205,6 +191,12 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership); return ptr; }); + qmlRegisterSingletonType<RoomlistModel>( + "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { + auto ptr = self->rooms; + QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership); + return ptr; + }); qmlRegisterSingletonType<UserSettings>( "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { auto ptr = ChatPage::instance()->userSettings().data(); @@ -260,10 +252,6 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par view->setSource(QUrl("qrc:///qml/Root.qml")); connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette); - connect(parent, - &ChatPage::decryptSidebarChanged, - this, - &TimelineViewManager::updateEncryptedDescriptions); connect( dynamic_cast<ChatPage *>(parent), &ChatPage::receivedRoomDeviceVerificationRequest, @@ -334,64 +322,13 @@ TimelineViewManager::setVideoCallItem() } void -TimelineViewManager::sync(const mtx::responses::Rooms &rooms) -{ - for (const auto &[room_id, room] : rooms.join) { - // addRoom will only add the room, if it doesn't exist - addRoom(QString::fromStdString(room_id)); - const auto &room_model = models.value(QString::fromStdString(room_id)); - if (!isInitialSync_) - connect(room_model.data(), - &TimelineModel::newCallEvent, - callManager_, - &CallManager::syncEvent); - room_model->syncState(room.state); - room_model->addEvents(room.timeline); - if (!isInitialSync_) - disconnect(room_model.data(), - &TimelineModel::newCallEvent, - callManager_, - &CallManager::syncEvent); - - if (ChatPage::instance()->userSettings()->typingNotifications()) { - for (const auto &ev : room.ephemeral.events) { - if (auto t = std::get_if< - mtx::events::EphemeralEvent<mtx::events::ephemeral::Typing>>( - &ev)) { - std::vector<QString> typing; - typing.reserve(t->content.user_ids.size()); - for (const auto &user : t->content.user_ids) { - if (user != http::client()->user_id().to_string()) - typing.push_back( - QString::fromStdString(user)); - } - room_model->updateTypingUsers(typing); - } - } - } - } - - this->isInitialSync_ = false; - emit initialSyncChanged(false); -} +TimelineViewManager::sync(const mtx::responses::Rooms &rooms_) +{ + this->rooms->sync(rooms_); -void -TimelineViewManager::addRoom(const QString &room_id) -{ - if (!models.contains(room_id)) { - QSharedPointer<TimelineModel> newRoom(new TimelineModel(this, room_id)); - newRoom->setDecryptDescription( - ChatPage::instance()->userSettings()->decryptSidebar()); - - connect(newRoom.data(), - &TimelineModel::newEncryptedImage, - imgProvider, - &MxcImageProvider::addEncryptionInfo); - connect(newRoom.data(), - &TimelineModel::forwardToRoom, - this, - &TimelineViewManager::forwardMessageToRoom); - models.insert(room_id, std::move(newRoom)); + if (isInitialSync_) { + this->isInitialSync_ = false; + emit initialSyncChanged(false); } } @@ -400,9 +337,8 @@ TimelineViewManager::setHistoryView(const QString &room_id) { nhlog::ui()->info("Trying to activate room {}", room_id.toStdString()); - auto room = models.find(room_id); - if (room != models.end()) { - timeline_ = room.value().data(); + if (auto room = rooms->getRoomById(room_id)) { + timeline_ = room.get(); emit activeTimelineChanged(timeline_); container->setFocus(); nhlog::ui()->info("Activated room {}", room_id.toStdString()); @@ -418,10 +354,9 @@ TimelineViewManager::highlightRoom(const QString &room_id) void TimelineViewManager::showEvent(const QString &room_id, const QString &event_id) { - auto room = models.find(room_id); - if (room != models.end()) { - if (timeline_ != room.value().data()) { - timeline_ = room.value().data(); + if (auto room = rooms->getRoomById(room_id)) { + if (timeline_ != room) { + timeline_ = room.get(); emit activeTimelineChanged(timeline_); container->setFocus(); nhlog::ui()->info("Activated room {}", room_id.toStdString()); @@ -505,17 +440,21 @@ TimelineViewManager::verifyUser(QString userid) if (std::find(room_members.begin(), room_members.end(), (userid).toStdString()) != room_members.end()) { - auto model = models.value(QString::fromStdString(room_id)); - auto flow = DeviceVerificationFlow::InitiateUserVerification( - this, model.data(), userid); - connect(model.data(), - &TimelineModel::updateFlowEventId, - this, - [this, flow](std::string eventId) { - dvList[QString::fromStdString(eventId)] = flow; - }); - emit newDeviceVerificationRequest(flow.data()); - return; + if (auto model = + rooms->getRoomById(QString::fromStdString(room_id))) { + auto flow = + DeviceVerificationFlow::InitiateUserVerification( + this, model.data(), userid); + connect(model.data(), + &TimelineModel::updateFlowEventId, + this, + [this, flow](std::string eventId) { + dvList[QString::fromStdString(eventId)] = + flow; + }); + emit newDeviceVerificationRequest(flow.data()); + return; + } } } } @@ -548,26 +487,23 @@ void TimelineViewManager::updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids) { - auto room = models.find(room_id); - if (room != models.end()) { - room.value()->markEventsAsRead(event_ids); + if (auto room = rooms->getRoomById(room_id)) { + room->markEventsAsRead(event_ids); } } void TimelineViewManager::receivedSessionKey(const std::string &room_id, const std::string &session_id) { - auto room = models.find(QString::fromStdString(room_id)); - if (room != models.end()) { - room.value()->receivedSessionKey(session_id); + if (auto room = rooms->getRoomById(QString::fromStdString(room_id))) { + room->receivedSessionKey(session_id); } } void TimelineViewManager::initWithMessages(const std::vector<QString> &roomIds) { - for (const auto &roomId : roomIds) - addRoom(roomId); + rooms->initializeRooms(roomIds); } void @@ -575,10 +511,9 @@ TimelineViewManager::queueReply(const QString &roomid, const QString &repliedToEvent, const QString &replyBody) { - auto room = models.find(roomid); - if (room != models.end()) { - room.value()->setReply(repliedToEvent); - room.value()->input()->message(replyBody); + if (auto room = rooms->getRoomById(roomid)) { + room->setReply(repliedToEvent); + room->input()->message(replyBody); } } @@ -620,29 +555,32 @@ void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallInvite &callInvite) { - models.value(roomid)->sendMessageEvent(callInvite, mtx::events::EventType::CallInvite); + if (auto room = rooms->getRoomById(roomid)) + room->sendMessageEvent(callInvite, mtx::events::EventType::CallInvite); } void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallCandidates &callCandidates) { - models.value(roomid)->sendMessageEvent(callCandidates, - mtx::events::EventType::CallCandidates); + if (auto room = rooms->getRoomById(roomid)) + room->sendMessageEvent(callCandidates, mtx::events::EventType::CallCandidates); } void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallAnswer &callAnswer) { - models.value(roomid)->sendMessageEvent(callAnswer, mtx::events::EventType::CallAnswer); + if (auto room = rooms->getRoomById(roomid)) + room->sendMessageEvent(callAnswer, mtx::events::EventType::CallAnswer); } void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &callHangUp) { - models.value(roomid)->sendMessageEvent(callHangUp, mtx::events::EventType::CallHangUp); + if (auto room = rooms->getRoomById(roomid)) + room->sendMessageEvent(callHangUp, mtx::events::EventType::CallHangUp); } void @@ -693,7 +631,7 @@ void TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEvents *e, QString roomId) { - auto room = models.find(roomId); + auto room = rooms->getRoomById(roomId); auto content = mtx::accessors::url(*e); std::optional<mtx::crypto::EncryptedFile> encryptionInfo = mtx::accessors::file(*e); @@ -736,12 +674,15 @@ TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEven ev.content.url = url; } - auto room = models.find(roomId); - removeReplyFallback(ev); - ev.content.relations.relations.clear(); - room.value()->sendMessageEvent( - ev.content, - mtx::events::EventType::RoomMessage); + if (auto room = rooms->getRoomById(roomId)) { + removeReplyFallback(ev); + ev.content.relations.relations + .clear(); + room->sendMessageEvent( + ev.content, + mtx::events::EventType:: + RoomMessage); + } } }, *e); @@ -759,8 +700,7 @@ TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEven mtx::events::EventType::RoomMessage) { e.content.relations.relations.clear(); removeReplyFallback(e); - room.value()->sendMessageEvent(e.content, - mtx::events::EventType::RoomMessage); + room->sendMessageEvent(e.content, mtx::events::EventType::RoomMessage); } }, *e); diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 0665b663..f4297243 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -22,6 +22,7 @@ #include "WebRTCSession.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" +#include "timeline/RoomlistModel.h" class MxcImageProvider; class BlurhashProvider; @@ -48,13 +49,15 @@ public: QWidget *getWidget() const { return container; } void sync(const mtx::responses::Rooms &rooms); - void addRoom(const QString &room_id); + + MxcImageProvider *imageProvider() { return imgProvider; } + CallManager *callManager() { return callManager_; } void clearAll() { timeline_ = nullptr; emit activeTimelineChanged(nullptr); - models.clear(); + rooms->clear(); } Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } @@ -109,11 +112,7 @@ public slots: void focusTimeline(); TimelineModel *getHistoryView(const QString &room_id) { - auto room = models.find(room_id); - if (room != models.end()) - return room.value().data(); - else - return nullptr; + return rooms->getRoomById(room_id).get(); } void updateColorPalette(); @@ -126,7 +125,6 @@ public slots: void queueCallMessage(const QString &roomid, const mtx::events::msg::CallAnswer &); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &); - void updateEncryptedDescriptions(); void setVideoCallItem(); void enableBackButton() @@ -163,7 +161,6 @@ private: ColorImageProvider *colorImgProvider; BlurhashProvider *blurhashProvider; - QHash<QString, QSharedPointer<TimelineModel>> models; TimelineModel *timeline_ = nullptr; CallManager *callManager_ = nullptr; @@ -171,6 +168,8 @@ private: bool isNarrowView_ = false; bool isWindowFocused_ = false; + RoomlistModel *rooms = nullptr; + QHash<QString, QColor> userColors; QHash<QString, QSharedPointer<DeviceVerificationFlow>> dvList; |