summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-05-28 22:14:59 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-05-28 22:14:59 +0200
commit298822baeaffdc83386e003099e34819bcd7d18c (patch)
tree1caa2bc8475385b1743c9c82a8d98caae3e374fb /src
parentReimplement room context menus (diff)
downloadnheko-298822baeaffdc83386e003099e34819bcd7d18c.tar.xz
Move currentRoom/timeline handling to roomlist
Diffstat (limited to 'src')
-rw-r--r--src/ChatPage.cpp7
-rw-r--r--src/timeline/InputBar.cpp35
-rw-r--r--src/timeline/InputBar.h1
-rw-r--r--src/timeline/RoomlistModel.cpp18
-rw-r--r--src/timeline/RoomlistModel.h16
-rw-r--r--src/timeline/TimelineViewManager.cpp125
-rw-r--r--src/timeline/TimelineViewManager.h26
-rw-r--r--src/ui/NhekoDropArea.cpp2
8 files changed, 114 insertions, 116 deletions
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp

index 166c03ec..bee20d60 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp
@@ -215,8 +215,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent) this->current_room_ = room_id; }); connect(room_list_, &RoomList::roomChanged, splitter, &Splitter::showChatView); - connect( - room_list_, &RoomList::roomChanged, view_manager_, &TimelineViewManager::setHistoryView); connect(room_list_, &RoomList::acceptInvite, this, [this](const QString &room_id) { joinRoom(room_id); @@ -982,7 +980,7 @@ ChatPage::leaveRoom(const QString &room_id) void ChatPage::changeRoom(const QString &room_id) { - view_manager_->setHistoryView(room_id); + view_manager_->rooms()->setCurrentRoom(room_id); room_list_->highlightSelectedRoom(room_id); } @@ -1397,7 +1395,8 @@ ChatPage::handleMatrixUri(const QByteArray &uri) if (sigil1 == "u") { if (action.isEmpty()) { - view_manager_->activeTimeline()->openUserProfile(mxid1); + if (auto t = view_manager_->rooms()->currentRoom()) + t->openUserProfile(mxid1); } else if (action == "chat") { this->startChat(mxid1); } diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index cda38b75..a283d24e 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp
@@ -508,8 +508,7 @@ InputBar::command(QString command, QString args) } else if (command == "react") { auto eventId = room->reply(); if (!eventId.isEmpty()) - ChatPage::instance()->timelineManager()->queueReactionMessage( - eventId, args.trimmed()); + reaction(eventId, args.trimmed()); } else if (command == "join") { ChatPage::instance()->joinRoom(args); } else if (command == "part" || command == "leave") { @@ -715,3 +714,35 @@ InputBar::stopTyping() } }); } + +void +InputBar::reaction(const QString &reactedEvent, const QString &reactionKey) +{ + auto reactions = room->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); + + room->sendMessageEvent(reaction, mtx::events::EventType::Reaction); + // Otherwise, we have previously reacted and the reaction should be redacted + } else { + room->redactEvent(selfReactedEvent); + } +} diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
index 9db16bae..c9728379 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h
@@ -56,6 +56,7 @@ public slots: void message(QString body, MarkdownOverride useMarkdown = MarkdownOverride::NOT_SPECIFIED, bool rainbowify = false); + void reaction(const QString &reactedEvent, const QString &reactionKey); private slots: void startTyping(); diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index 63054aa9..ad4177a4 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp
@@ -341,6 +341,8 @@ RoomlistModel::clear() models.clear(); invites.clear(); roomids.clear(); + currentRoom_ = nullptr; + emit currentRoomChanged(); endResetModel(); } @@ -390,6 +392,17 @@ RoomlistModel::leave(QString roomid) } } +void +RoomlistModel::setCurrentRoom(QString roomid) +{ + nhlog::ui()->debug("Trying to switch to: {}", roomid.toStdString()); + if (models.contains(roomid)) { + currentRoom_ = models.value(roomid); + emit currentRoomChanged(); + nhlog::ui()->debug("Switched to: {}", roomid.toStdString()); + } +} + namespace { enum NotificationImportance : short { @@ -463,6 +476,11 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare invalidate(); }); + connect(roomlistmodel, + &RoomlistModel::currentRoomChanged, + this, + &FilteredRoomlistModel::currentRoomChanged); + sort(0); } diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h
index 2d1e5264..1c6fa833 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h
@@ -14,12 +14,14 @@ #include <mtx/responses/sync.hpp> -class TimelineModel; +#include "TimelineModel.h" + class TimelineViewManager; class RoomlistModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(TimelineModel *currentRoom READ currentRoom NOTIFY currentRoomChanged) public: enum Roles { @@ -69,12 +71,15 @@ public slots: void acceptInvite(QString roomid); void declineInvite(QString roomid); void leave(QString roomid); + TimelineModel *currentRoom() const { return currentRoom_.get(); } + void setCurrentRoom(QString roomid); private slots: void updateReadStatus(const std::map<QString, bool> roomReadStatus_); signals: void totalUnreadMessageCountUpdated(int unreadMessages); + void currentRoomChanged(); private: void addRoom(const QString &room_id, bool suppressInsertNotification = false); @@ -85,12 +90,15 @@ private: QHash<QString, QSharedPointer<TimelineModel>> models; std::map<QString, bool> roomReadStatus; + QSharedPointer<TimelineModel> currentRoom_; + friend class FilteredRoomlistModel; }; class FilteredRoomlistModel : public QSortFilterProxyModel { Q_OBJECT + Q_PROPERTY(TimelineModel *currentRoom READ currentRoom NOTIFY currentRoomChanged) public: FilteredRoomlistModel(RoomlistModel *model, QObject *parent = nullptr); bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; @@ -107,6 +115,12 @@ public slots: QStringList tags(); void toggleTag(QString roomid, QString tag, bool on); + TimelineModel *currentRoom() const { return roomlistmodel->currentRoom(); } + void setCurrentRoom(QString roomid) { roomlistmodel->setCurrentRoom(std::move(roomid)); } + +signals: + void currentRoomChanged(); + private: short int calculateImportance(const QModelIndex &idx) const; RoomlistModel *roomlistmodel; diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 9fa7f8b6..3b3ea423 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp
@@ -133,7 +133,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par , colorImgProvider(new ColorImageProvider()) , blurhashProvider(new BlurhashProvider()) , callManager_(callManager) - , rooms(new RoomlistModel(this)) + , rooms_(new RoomlistModel(this)) { qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>(); qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>(); @@ -193,7 +193,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par }); qmlRegisterSingletonType<RoomlistModel>( "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { - return new FilteredRoomlistModel(self->rooms); + return new FilteredRoomlistModel(self->rooms_); }); qmlRegisterSingletonType<UserSettings>( "im.nheko", 1, 0, "Settings", [](QQmlEngine *, QJSEngine *) -> QObject * { @@ -320,9 +320,9 @@ TimelineViewManager::setVideoCallItem() } void -TimelineViewManager::sync(const mtx::responses::Rooms &rooms_) +TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res) { - this->rooms->sync(rooms_); + this->rooms_->sync(rooms_res); if (isInitialSync_) { this->isInitialSync_ = false; @@ -331,36 +331,16 @@ TimelineViewManager::sync(const mtx::responses::Rooms &rooms_) } void -TimelineViewManager::setHistoryView(const QString &room_id) -{ - nhlog::ui()->info("Trying to activate room {}", room_id.toStdString()); - - if (auto room = rooms->getRoomById(room_id)) { - timeline_ = room.get(); - 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) { - if (auto room = rooms->getRoomById(room_id)) { - if (timeline_ != room) { - timeline_ = room.get(); - 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); } } @@ -395,17 +375,20 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) auto imgDialog = new dialogs::ImageOverlay(pixmap); imgDialog->showFullScreen(); - connect(imgDialog, &dialogs::ImageOverlay::saving, timeline_, [this, eventId, imgDialog]() { - // hide the overlay while presenting the save dialog for better - // cross platform support. - imgDialog->hide(); - - if (!timeline_->saveMedia(eventId)) { - imgDialog->show(); - } else { - imgDialog->close(); - } - }); + + auto room = rooms_->currentRoom(); + connect( + imgDialog, &dialogs::ImageOverlay::saving, room, [this, eventId, imgDialog, room]() { + // hide the overlay while presenting the save dialog for better + // cross platform support. + imgDialog->hide(); + + if (!room->saveMedia(eventId)) { + imgDialog->show(); + } else { + imgDialog->close(); + } + }); } void @@ -415,14 +398,14 @@ TimelineViewManager::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 @@ -439,7 +422,7 @@ TimelineViewManager::verifyUser(QString userid) room_members.end(), (userid).toStdString()) != room_members.end()) { if (auto model = - rooms->getRoomById(QString::fromStdString(room_id))) { + rooms_->getRoomById(QString::fromStdString(room_id))) { auto flow = DeviceVerificationFlow::InitiateUserVerification( this, model.data(), userid); @@ -485,7 +468,7 @@ void TimelineViewManager::updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids) { - if (auto room = rooms->getRoomById(room_id)) { + if (auto room = rooms_->getRoomById(room_id)) { room->markEventsAsRead(event_ids); } } @@ -493,7 +476,7 @@ TimelineViewManager::updateReadReceipts(const QString &room_id, void TimelineViewManager::receivedSessionKey(const std::string &room_id, const std::string &session_id) { - if (auto room = rooms->getRoomById(QString::fromStdString(room_id))) { + if (auto room = rooms_->getRoomById(QString::fromStdString(room_id))) { room->receivedSessionKey(session_id); } } @@ -501,7 +484,7 @@ TimelineViewManager::receivedSessionKey(const std::string &room_id, const std::s void TimelineViewManager::initializeRoomlist() { - rooms->initializeRooms(); + rooms_->initializeRooms(); } void @@ -509,51 +492,17 @@ TimelineViewManager::queueReply(const QString &roomid, const QString &repliedToEvent, const QString &replyBody) { - if (auto room = rooms->getRoomById(roomid)) { + 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) { - if (auto room = rooms->getRoomById(roomid)) + if (auto room = rooms_->getRoomById(roomid)) room->sendMessageEvent(callInvite, mtx::events::EventType::CallInvite); } @@ -561,7 +510,7 @@ void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallCandidates &callCandidates) { - if (auto room = rooms->getRoomById(roomid)) + if (auto room = rooms_->getRoomById(roomid)) room->sendMessageEvent(callCandidates, mtx::events::EventType::CallCandidates); } @@ -569,7 +518,7 @@ void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallAnswer &callAnswer) { - if (auto room = rooms->getRoomById(roomid)) + if (auto room = rooms_->getRoomById(roomid)) room->sendMessageEvent(callAnswer, mtx::events::EventType::CallAnswer); } @@ -577,7 +526,7 @@ void TimelineViewManager::queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &callHangUp) { - if (auto room = rooms->getRoomById(roomid)) + if (auto room = rooms_->getRoomById(roomid)) room->sendMessageEvent(callHangUp, mtx::events::EventType::CallHangUp); } @@ -629,7 +578,7 @@ void TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEvents *e, QString roomId) { - auto room = rooms->getRoomById(roomId); + auto room = rooms_->getRoomById(roomId); auto content = mtx::accessors::url(*e); std::optional<mtx::crypto::EncryptedFile> encryptionInfo = mtx::accessors::file(*e); @@ -672,7 +621,7 @@ TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEven ev.content.url = url; } - if (auto room = rooms->getRoomById(roomId)) { + if (auto room = rooms_->getRoomById(roomId)) { removeReplyFallback(ev); ev.content.relations.relations .clear(); diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 37e50804..c4707208 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h
@@ -36,8 +36,6 @@ class TimelineViewManager : public QObject Q_OBJECT Q_PROPERTY( - TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged) - Q_PROPERTY( bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) Q_PROPERTY( bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged) @@ -53,14 +51,8 @@ public: MxcImageProvider *imageProvider() { return imgProvider; } CallManager *callManager() { return callManager_; } - void clearAll() - { - timeline_ = nullptr; - emit activeTimelineChanged(nullptr); - rooms->clear(); - } + void clearAll() { rooms_->clear(); } - Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; } Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; } bool isNarrowView() const { return isNarrowView_; } bool isWindowFocused() const { return isWindowFocused_; } @@ -74,8 +66,8 @@ public: Q_INVOKABLE void focusMessageInput(); Q_INVOKABLE void openInviteUsersDialog(); - Q_INVOKABLE void openMemberListDialog() const; - Q_INVOKABLE void openLeaveRoomDialog() const; + Q_INVOKABLE void openMemberListDialog(QString roomid) const; + Q_INVOKABLE void openLeaveRoomDialog(QString roomid) const; Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); void verifyUser(QString userid); @@ -107,20 +99,13 @@ public slots: emit focusChanged(); } - void setHistoryView(const QString &room_id); - void highlightRoom(const QString &room_id); void showEvent(const QString &room_id, const QString &event_id); void focusTimeline(); - TimelineModel *getHistoryView(const QString &room_id) - { - return rooms->getRoomById(room_id).get(); - } void updateColorPalette(); void queueReply(const QString &roomid, const QString &repliedToEvent, const QString &replyBody); - void queueReactionMessage(const QString &reactedEvent, const QString &reactionKey); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallInvite &); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallCandidates &); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallAnswer &); @@ -147,6 +132,8 @@ public slots: QObject *completerFor(QString completerName, QString roomId = ""); void forwardMessageToRoom(mtx::events::collections::TimelineEvents *e, QString roomId); + RoomlistModel *rooms() { return rooms_; } + private slots: void openImageOverlayInternal(QString eventId, QImage img); @@ -162,14 +149,13 @@ private: ColorImageProvider *colorImgProvider; BlurhashProvider *blurhashProvider; - TimelineModel *timeline_ = nullptr; CallManager *callManager_ = nullptr; bool isInitialSync_ = true; bool isNarrowView_ = false; bool isWindowFocused_ = false; - RoomlistModel *rooms = nullptr; + RoomlistModel *rooms_ = nullptr; QHash<QString, QColor> userColors; diff --git a/src/ui/NhekoDropArea.cpp b/src/ui/NhekoDropArea.cpp
index 54f48d3c..bbcedd7e 100644 --- a/src/ui/NhekoDropArea.cpp +++ b/src/ui/NhekoDropArea.cpp
@@ -35,7 +35,7 @@ void NhekoDropArea::dropEvent(QDropEvent *event) { if (event) { - auto model = ChatPage::instance()->timelineManager()->getHistoryView(roomid_); + auto model = ChatPage::instance()->timelineManager()->rooms()->getRoomById(roomid_); if (model) { model->input()->insertMimeData(event->mimeData()); }