summary refs log tree commit diff
path: root/src/timeline/TimelineViewManager.cpp
diff options
context:
space:
mode:
authorDeepBlueV7.X <nicolas.werner@hotmail.de>2021-06-13 01:44:25 +0000
committerGitHub <noreply@github.com>2021-06-13 01:44:25 +0000
commit5b4566d3f959e13b34d34a4156a0646b26c7fd08 (patch)
tree11d1b42e1d9f92977c48670605bb8a2e26ddd43c /src/timeline/TimelineViewManager.cpp
parentTranslated using Weblate (Esperanto) (diff)
parentFix button spacing (diff)
downloadnheko-5b4566d3f959e13b34d34a4156a0646b26c7fd08.tar.xz
Merge pull request #605 from Nheko-Reborn/qml-roomlist
Qml roomlist and stuff
Diffstat (limited to 'src/timeline/TimelineViewManager.cpp')
-rw-r--r--src/timeline/TimelineViewManager.cpp326
1 files changed, 93 insertions, 233 deletions
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp

index 0785e3e1..a45294d1 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -4,7 +4,6 @@ #include "TimelineViewManager.h" -#include <QDesktopServices> #include <QDropEvent> #include <QMetaType> #include <QPalette> @@ -32,6 +31,7 @@ #include "emoji/Provider.h" #include "ui/NhekoCursorShape.h" #include "ui/NhekoDropArea.h" +#include "ui/NhekoGlobalObject.h" Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents) Q_DECLARE_METATYPE(std::vector<DeviceInfo>) @@ -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(); @@ -143,10 +128,13 @@ TimelineViewManager::userStatus(QString id) const } TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *parent) - : imgProvider(new MxcImageProvider()) + : QObject(parent) + , imgProvider(new MxcImageProvider()) , colorImgProvider(new ColorImageProvider()) , blurhashProvider(new BlurhashProvider()) , callManager_(callManager) + , rooms_(new RoomlistModel(this)) + , communities_(new CommunitiesModel(this)) { qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>(); qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>(); @@ -204,6 +192,26 @@ 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 = new FilteredRoomlistModel(self->rooms_); + + connect(self->communities_, + &CommunitiesModel::currentTagIdChanged, + ptr, + &FilteredRoomlistModel::updateFilterTag); + connect(self->communities_, + &CommunitiesModel::hiddenTagsChanged, + ptr, + &FilteredRoomlistModel::updateHiddenTagsAndSpaces); + return ptr; + }); + qmlRegisterSingletonType<RoomlistModel>( + "im.nheko", 1, 0, "Communities", [](QQmlEngine *, QJSEngine *) -> QObject * { + auto ptr = self->communities_; + QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership); + return ptr; + }); qmlRegisterSingletonType<UserSettings>( "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { auto ptr = ChatPage::instance()->userSettings().data(); @@ -220,6 +228,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "im.nheko", 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) -> QObject * { return new Clipboard(); }); + qmlRegisterSingletonType<Nheko>( + "im.nheko", 1, 0, "Nheko", [](QQmlEngine *, QJSEngine *) -> QObject * { + return new Nheko(); + }); qRegisterMetaType<mtx::events::collections::TimelineEvents>(); qRegisterMetaType<std::vector<DeviceInfo>>(); @@ -235,7 +247,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par "Error: Only enums"); #ifdef USE_QUICK_VIEW - view = new QQuickView(); + view = new QQuickView(parent); container = QWidget::createWindowContainer(view, parent); #else view = new QQuickWidget(parent); @@ -252,13 +264,9 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par view->engine()->addImageProvider("MxcImage", imgProvider); view->engine()->addImageProvider("colorimage", colorImgProvider); view->engine()->addImageProvider("blurhash", blurhashProvider); - view->setSource(QUrl("qrc:///qml/TimelineView.qml")); + 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, @@ -329,100 +337,28 @@ TimelineViewManager::setVideoCallItem() } void -TimelineViewManager::sync(const mtx::responses::Rooms &rooms) +TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res) { - 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); + this->rooms_->sync(rooms_res); + this->communities_->sync(rooms_res); - 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); -} - -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); } } void -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(); - emit activeTimelineChanged(timeline_); - container->setFocus(); - nhlog::ui()->info("Activated room {}", room_id.toStdString()); - } -} - -void -TimelineViewManager::highlightRoom(const QString &room_id) -{ - ChatPage::instance()->highlightRoom(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(); - emit activeTimelineChanged(timeline_); + if (auto room = rooms_->getRoomById(room_id)) { + if (rooms_->currentRoom() != room) { + rooms_->setCurrentRoom(room_id); container->setFocus(); nhlog::ui()->info("Activated room {}", room_id.toStdString()); } - timeline_->showEvent(event_id); + room->showEvent(event_id); } } @@ -457,12 +393,14 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) auto imgDialog = new dialogs::ImageOverlay(pixmap); imgDialog->showFullScreen(); - connect(imgDialog, &dialogs::ImageOverlay::saving, timeline_, [this, eventId, imgDialog]() { + + auto room = rooms_->currentRoom(); + connect(imgDialog, &dialogs::ImageOverlay::saving, room, [eventId, imgDialog, room]() { // hide the overlay while presenting the save dialog for better // cross platform support. imgDialog->hide(); - if (!timeline_->saveMedia(eventId)) { + if (!room->saveMedia(eventId)) { imgDialog->show(); } else { imgDialog->close(); @@ -471,70 +409,20 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) } void -TimelineViewManager::openLink(QString link) const -{ - QUrl url(link); - if (url.scheme() == "https" && url.host() == "matrix.to") { - // handle matrix.to links internally - QString p = url.fragment(QUrl::FullyEncoded); - if (p.startsWith("/")) - p.remove(0, 1); - - auto temp = p.split("?"); - QString query; - if (temp.size() >= 2) - query = QUrl::fromPercentEncoding(temp.takeAt(1).toUtf8()); - - temp = temp.first().split("/"); - auto identifier = QUrl::fromPercentEncoding(temp.takeFirst().toUtf8()); - QString eventId = QUrl::fromPercentEncoding(temp.join('/').toUtf8()); - if (!identifier.isEmpty()) { - if (identifier.startsWith("@")) { - QByteArray uri = - "matrix:u/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } else if (identifier.startsWith("#")) { - QByteArray uri = - "matrix:r/" + QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!eventId.isEmpty()) - uri.append("/e/" + - QUrl::toPercentEncoding(eventId.remove(0, 1))); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } else if (identifier.startsWith("!")) { - QByteArray uri = "matrix:roomid/" + - QUrl::toPercentEncoding(identifier.remove(0, 1)); - if (!eventId.isEmpty()) - uri.append("/e/" + - QUrl::toPercentEncoding(eventId.remove(0, 1))); - if (!query.isEmpty()) - uri.append("?" + query.toUtf8()); - ChatPage::instance()->handleMatrixUri(QUrl::fromEncoded(uri)); - } - } - } else { - QDesktopServices::openUrl(url); - } -} - -void TimelineViewManager::openInviteUsersDialog() { MainWindow::instance()->openInviteUsersDialog( [this](const QStringList &invitees) { emit inviteUsers(invitees); }); } void -TimelineViewManager::openMemberListDialog() const +TimelineViewManager::openMemberListDialog(QString roomid) const { - MainWindow::instance()->openMemberListDialog(timeline_->roomId()); + MainWindow::instance()->openMemberListDialog(roomid); } void -TimelineViewManager::openLeaveRoomDialog() const +TimelineViewManager::openLeaveRoomDialog(QString roomid) const { - MainWindow::instance()->openLeaveRoomDialog(timeline_->roomId()); + MainWindow::instance()->openLeaveRoomDialog(roomid); } void @@ -550,17 +438,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; + } } } } @@ -593,26 +485,24 @@ 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) +TimelineViewManager::initializeRoomlist() { - for (const auto &roomId : roomIds) - addRoom(roomId); + rooms_->initializeRooms(); + communities_->initializeSidebar(); } void @@ -620,74 +510,42 @@ 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); } } void -TimelineViewManager::queueReactionMessage(const QString &reactedEvent, const QString &reactionKey) -{ - if (!timeline_) - return; - - auto reactions = timeline_->reactions(reactedEvent.toStdString()); - - QString selfReactedEvent; - for (const auto &reaction : reactions) { - if (reactionKey == reaction.key_) { - selfReactedEvent = reaction.selfReactedEvent_; - break; - } - } - - if (selfReactedEvent.startsWith("m")) - return; - - // If selfReactedEvent is empty, that means we haven't previously reacted - if (selfReactedEvent.isEmpty()) { - mtx::events::msg::Reaction reaction; - mtx::common::Relation rel; - rel.rel_type = mtx::common::RelationType::Annotation; - rel.event_id = reactedEvent.toStdString(); - rel.key = reactionKey.toStdString(); - reaction.relations.relations.push_back(rel); - - timeline_->sendMessageEvent(reaction, mtx::events::EventType::Reaction); - // Otherwise, we have previously reacted and the reaction should be redacted - } else { - timeline_->redactEvent(selfReactedEvent); - } -} -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 @@ -738,7 +596,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); @@ -781,12 +639,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); @@ -804,8 +665,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);