diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index ea231b03..8a33dc2b 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -67,73 +67,72 @@ template<typename T>
static constexpr bool
messageWithFileAndUrl(const mtx::events::Event<T> &)
{
- return is_detected<file_t, T>::value && is_detected<url_t, T>::value;
+ return is_detected<file_t, T>::value && is_detected<url_t, T>::value;
}
template<typename T>
static constexpr void
removeReplyFallback(mtx::events::Event<T> &e)
{
- if constexpr (is_detected<body_t, T>::value) {
- if constexpr (std::is_same_v<std::optional<std::string>,
- std::remove_cv_t<decltype(e.content.body)>>) {
- if (e.content.body) {
- e.content.body = utils::stripReplyFromBody(e.content.body);
- }
- } else if constexpr (std::is_same_v<std::string,
- std::remove_cv_t<decltype(e.content.body)>>) {
- e.content.body = utils::stripReplyFromBody(e.content.body);
- }
+ if constexpr (is_detected<body_t, T>::value) {
+ if constexpr (std::is_same_v<std::optional<std::string>,
+ std::remove_cv_t<decltype(e.content.body)>>) {
+ if (e.content.body) {
+ e.content.body = utils::stripReplyFromBody(e.content.body);
+ }
+ } else if constexpr (std::is_same_v<std::string,
+ std::remove_cv_t<decltype(e.content.body)>>) {
+ e.content.body = utils::stripReplyFromBody(e.content.body);
}
+ }
- if constexpr (is_detected<formatted_body_t, T>::value) {
- if (e.content.format == "org.matrix.custom.html") {
- e.content.formatted_body =
- utils::stripReplyFromFormattedBody(e.content.formatted_body);
- }
+ if constexpr (is_detected<formatted_body_t, T>::value) {
+ if (e.content.format == "org.matrix.custom.html") {
+ e.content.formatted_body = utils::stripReplyFromFormattedBody(e.content.formatted_body);
}
+ }
}
}
void
TimelineViewManager::updateColorPalette()
{
- userColors.clear();
+ userColors.clear();
- if (ChatPage::instance()->userSettings()->theme() == "light") {
- view->rootContext()->setContextProperty("currentActivePalette", QPalette());
- view->rootContext()->setContextProperty("currentInactivePalette", QPalette());
- } else if (ChatPage::instance()->userSettings()->theme() == "dark") {
- view->rootContext()->setContextProperty("currentActivePalette", QPalette());
- view->rootContext()->setContextProperty("currentInactivePalette", QPalette());
- } else {
- view->rootContext()->setContextProperty("currentActivePalette", QPalette());
- view->rootContext()->setContextProperty("currentInactivePalette", nullptr);
- }
+ if (ChatPage::instance()->userSettings()->theme() == "light") {
+ view->rootContext()->setContextProperty("currentActivePalette", QPalette());
+ view->rootContext()->setContextProperty("currentInactivePalette", QPalette());
+ } else if (ChatPage::instance()->userSettings()->theme() == "dark") {
+ view->rootContext()->setContextProperty("currentActivePalette", QPalette());
+ view->rootContext()->setContextProperty("currentInactivePalette", QPalette());
+ } else {
+ view->rootContext()->setContextProperty("currentActivePalette", QPalette());
+ view->rootContext()->setContextProperty("currentInactivePalette", nullptr);
+ }
}
QColor
TimelineViewManager::userColor(QString id, QColor background)
{
- if (!userColors.contains(id))
- userColors.insert(id, QColor(utils::generateContrastingHexColor(id, background)));
- return userColors.value(id);
+ if (!userColors.contains(id))
+ userColors.insert(id, QColor(utils::generateContrastingHexColor(id, background)));
+ return userColors.value(id);
}
QString
TimelineViewManager::userPresence(QString id) const
{
- if (id.isEmpty())
- return "";
- else
- return QString::fromStdString(
- mtx::presence::to_string(cache::presenceState(id.toStdString())));
+ if (id.isEmpty())
+ return "";
+ else
+ return QString::fromStdString(
+ mtx::presence::to_string(cache::presenceState(id.toStdString())));
}
QString
TimelineViewManager::userStatus(QString id) const
{
- return QString::fromStdString(cache::statusMessage(id.toStdString()));
+ return QString::fromStdString(cache::statusMessage(id.toStdString()));
}
TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *parent)
@@ -146,453 +145,432 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
, rooms_(new RoomlistModel(this))
, communities_(new CommunitiesModel(this))
{
- qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationDone>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationKey>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationMac>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
- qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
- qRegisterMetaType<CombinedImagePackModel *>();
-
- qRegisterMetaType<std::vector<mtx::responses::PublicRoomsChunk>>();
-
- qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject,
- "im.nheko",
- 1,
- 0,
- "MtxEvent",
- "Can't instantiate enum!");
- qmlRegisterUncreatableMetaObject(
- olm::staticMetaObject, "im.nheko", 1, 0, "Olm", "Can't instantiate enum!");
- qmlRegisterUncreatableMetaObject(
- crypto::staticMetaObject, "im.nheko", 1, 0, "Crypto", "Can't instantiate enum!");
- qmlRegisterUncreatableMetaObject(verification::staticMetaObject,
- "im.nheko",
- 1,
- 0,
- "VerificationStatus",
- "Can't instantiate enum!");
-
- qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
- qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
- qmlRegisterType<NhekoDropArea>("im.nheko", 1, 0, "NhekoDropArea");
- qmlRegisterType<NhekoCursorShape>("im.nheko", 1, 0, "CursorShape");
- qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage");
- qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia");
- qmlRegisterUncreatableType<DeviceVerificationFlow>(
- "im.nheko", 1, 0, "DeviceVerificationFlow", "Can't create verification flow from QML!");
- qmlRegisterUncreatableType<UserProfile>(
- "im.nheko",
- 1,
- 0,
- "UserProfileModel",
- "UserProfile needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<MemberList>(
- "im.nheko", 1, 0, "MemberList", "MemberList needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<RoomSettings>(
- "im.nheko",
- 1,
- 0,
- "RoomSettingsModel",
- "Room Settings needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<TimelineModel>(
- "im.nheko", 1, 0, "Room", "Room needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<ImagePackListModel>(
- "im.nheko",
- 1,
- 0,
- "ImagePackListModel",
- "ImagePackListModel needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<SingleImagePackModel>(
- "im.nheko",
- 1,
- 0,
- "SingleImagePackModel",
- "SingleImagePackModel needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<InviteesModel>(
- "im.nheko",
- 1,
- 0,
- "InviteesModel",
- "InviteesModel needs to be instantiated on the C++ side");
- qmlRegisterUncreatableType<ReadReceiptsProxy>(
- "im.nheko",
- 1,
- 0,
- "ReadReceiptsProxy",
- "ReadReceiptsProxy needs to be instantiated on the C++ side");
-
- static auto self = this;
- qmlRegisterSingletonType<MainWindow>(
- "im.nheko", 1, 0, "MainWindow", [](QQmlEngine *, QJSEngine *) -> QObject * {
- auto ptr = MainWindow::instance();
- QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
- return ptr;
- });
- qmlRegisterSingletonType<TimelineViewManager>(
- "im.nheko", 1, 0, "TimelineManager", [](QQmlEngine *, QJSEngine *) -> QObject * {
- auto ptr = self;
- 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();
- QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
- return ptr;
- });
- qmlRegisterSingletonType<CallManager>(
- "im.nheko", 1, 0, "CallManager", [](QQmlEngine *, QJSEngine *) -> QObject * {
- auto ptr = ChatPage::instance()->callManager();
- QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
- return ptr;
- });
- qmlRegisterSingletonType<Clipboard>(
- "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>>();
-
- qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
- qmlRegisterUncreatableType<emoji::Emoji>(
- "im.nheko.EmojiModel", 1, 0, "Emoji", "Used by emoji models");
- qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
- "im.nheko.EmojiModel",
- 1,
- 0,
- "EmojiCategory",
- "Error: Only enums");
-
- qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
+ qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationDone>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationKey>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationMac>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
+ qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
+ qRegisterMetaType<CombinedImagePackModel *>();
+
+ qRegisterMetaType<std::vector<mtx::responses::PublicRoomsChunk>>();
+
+ qmlRegisterUncreatableMetaObject(
+ qml_mtx_events::staticMetaObject, "im.nheko", 1, 0, "MtxEvent", "Can't instantiate enum!");
+ qmlRegisterUncreatableMetaObject(
+ olm::staticMetaObject, "im.nheko", 1, 0, "Olm", "Can't instantiate enum!");
+ qmlRegisterUncreatableMetaObject(
+ crypto::staticMetaObject, "im.nheko", 1, 0, "Crypto", "Can't instantiate enum!");
+ qmlRegisterUncreatableMetaObject(verification::staticMetaObject,
+ "im.nheko",
+ 1,
+ 0,
+ "VerificationStatus",
+ "Can't instantiate enum!");
+
+ qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
+ qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
+ qmlRegisterType<NhekoDropArea>("im.nheko", 1, 0, "NhekoDropArea");
+ qmlRegisterType<NhekoCursorShape>("im.nheko", 1, 0, "CursorShape");
+ qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage");
+ qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia");
+ qmlRegisterUncreatableType<DeviceVerificationFlow>(
+ "im.nheko", 1, 0, "DeviceVerificationFlow", "Can't create verification flow from QML!");
+ qmlRegisterUncreatableType<UserProfile>(
+ "im.nheko", 1, 0, "UserProfileModel", "UserProfile needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<MemberList>(
+ "im.nheko", 1, 0, "MemberList", "MemberList needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<RoomSettings>(
+ "im.nheko",
+ 1,
+ 0,
+ "RoomSettingsModel",
+ "Room Settings needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<TimelineModel>(
+ "im.nheko", 1, 0, "Room", "Room needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<ImagePackListModel>(
+ "im.nheko",
+ 1,
+ 0,
+ "ImagePackListModel",
+ "ImagePackListModel needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<SingleImagePackModel>(
+ "im.nheko",
+ 1,
+ 0,
+ "SingleImagePackModel",
+ "SingleImagePackModel needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<InviteesModel>(
+ "im.nheko", 1, 0, "InviteesModel", "InviteesModel needs to be instantiated on the C++ side");
+ qmlRegisterUncreatableType<ReadReceiptsProxy>(
+ "im.nheko",
+ 1,
+ 0,
+ "ReadReceiptsProxy",
+ "ReadReceiptsProxy needs to be instantiated on the C++ side");
+
+ static auto self = this;
+ qmlRegisterSingletonType<MainWindow>(
+ "im.nheko", 1, 0, "MainWindow", [](QQmlEngine *, QJSEngine *) -> QObject * {
+ auto ptr = MainWindow::instance();
+ QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
+ return ptr;
+ });
+ qmlRegisterSingletonType<TimelineViewManager>(
+ "im.nheko", 1, 0, "TimelineManager", [](QQmlEngine *, QJSEngine *) -> QObject * {
+ auto ptr = self;
+ 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();
+ QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
+ return ptr;
+ });
+ qmlRegisterSingletonType<CallManager>(
+ "im.nheko", 1, 0, "CallManager", [](QQmlEngine *, QJSEngine *) -> QObject * {
+ auto ptr = ChatPage::instance()->callManager();
+ QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
+ return ptr;
+ });
+ qmlRegisterSingletonType<Clipboard>(
+ "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>>();
+
+ qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
+ qmlRegisterUncreatableType<emoji::Emoji>(
+ "im.nheko.EmojiModel", 1, 0, "Emoji", "Used by emoji models");
+ qmlRegisterUncreatableMetaObject(
+ emoji::staticMetaObject, "im.nheko.EmojiModel", 1, 0, "EmojiCategory", "Error: Only enums");
+
+ qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
#ifdef USE_QUICK_VIEW
- view = new QQuickView(parent);
- container = QWidget::createWindowContainer(view, parent);
+ view = new QQuickView(parent);
+ container = QWidget::createWindowContainer(view, parent);
#else
- view = new QQuickWidget(parent);
- container = view;
- view->setResizeMode(QQuickWidget::SizeRootObjectToView);
- container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
- connect(view, &QQuickWidget::statusChanged, this, [](QQuickWidget::Status status) {
- nhlog::ui()->debug("Status changed to {}", status);
- });
+ view = new QQuickWidget(parent);
+ container = view;
+ view->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ connect(view, &QQuickWidget::statusChanged, this, [](QQuickWidget::Status status) {
+ nhlog::ui()->debug("Status changed to {}", status);
+ });
#endif
- container->setMinimumSize(200, 200);
- updateColorPalette();
- view->engine()->addImageProvider("MxcImage", imgProvider);
- view->engine()->addImageProvider("colorimage", colorImgProvider);
- view->engine()->addImageProvider("blurhash", blurhashProvider);
- if (JdenticonProvider::isAvailable())
- view->engine()->addImageProvider("jdenticon", jdenticonProvider);
- view->setSource(QUrl("qrc:///qml/Root.qml"));
-
- connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette);
- connect(
- dynamic_cast<ChatPage *>(parent),
- &ChatPage::receivedRoomDeviceVerificationRequest,
- this,
- [this](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &message,
- TimelineModel *model) {
- if (this->isInitialSync_)
- return;
-
- auto event_id = QString::fromStdString(message.event_id);
- if (!this->dvList.contains(event_id)) {
- if (auto flow = DeviceVerificationFlow::NewInRoomVerification(
- this,
- model,
- message.content,
- QString::fromStdString(message.sender),
- event_id)) {
- dvList[event_id] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
- connect(dynamic_cast<ChatPage *>(parent),
- &ChatPage::receivedDeviceVerificationRequest,
- this,
- [this](const mtx::events::msg::KeyVerificationRequest &msg, std::string sender) {
- if (this->isInitialSync_)
- return;
-
- if (!msg.transaction_id)
- return;
-
- auto txnid = QString::fromStdString(msg.transaction_id.value());
- if (!this->dvList.contains(txnid)) {
- if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
- this, msg, QString::fromStdString(sender), txnid)) {
- dvList[txnid] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
- connect(dynamic_cast<ChatPage *>(parent),
- &ChatPage::receivedDeviceVerificationStart,
- this,
- [this](const mtx::events::msg::KeyVerificationStart &msg, std::string sender) {
- if (this->isInitialSync_)
- return;
-
- if (!msg.transaction_id)
- return;
-
- auto txnid = QString::fromStdString(msg.transaction_id.value());
- if (!this->dvList.contains(txnid)) {
- if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
- this, msg, QString::fromStdString(sender), txnid)) {
- dvList[txnid] = flow;
- emit newDeviceVerificationRequest(flow.data());
- }
- }
- });
- connect(parent, &ChatPage::loggedOut, this, [this]() {
- isInitialSync_ = true;
- emit initialSyncChanged(true);
- });
+ container->setMinimumSize(200, 200);
+ updateColorPalette();
+ view->engine()->addImageProvider("MxcImage", imgProvider);
+ view->engine()->addImageProvider("colorimage", colorImgProvider);
+ view->engine()->addImageProvider("blurhash", blurhashProvider);
+ if (JdenticonProvider::isAvailable())
+ view->engine()->addImageProvider("jdenticon", jdenticonProvider);
+ view->setSource(QUrl("qrc:///qml/Root.qml"));
+
+ connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette);
+ connect(dynamic_cast<ChatPage *>(parent),
+ &ChatPage::receivedRoomDeviceVerificationRequest,
+ this,
+ [this](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &message,
+ TimelineModel *model) {
+ if (this->isInitialSync_)
+ return;
+
+ auto event_id = QString::fromStdString(message.event_id);
+ if (!this->dvList.contains(event_id)) {
+ if (auto flow = DeviceVerificationFlow::NewInRoomVerification(
+ this,
+ model,
+ message.content,
+ QString::fromStdString(message.sender),
+ event_id)) {
+ dvList[event_id] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+ });
+ connect(dynamic_cast<ChatPage *>(parent),
+ &ChatPage::receivedDeviceVerificationRequest,
+ this,
+ [this](const mtx::events::msg::KeyVerificationRequest &msg, std::string sender) {
+ if (this->isInitialSync_)
+ return;
+
+ if (!msg.transaction_id)
+ return;
+
+ auto txnid = QString::fromStdString(msg.transaction_id.value());
+ if (!this->dvList.contains(txnid)) {
+ if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
+ this, msg, QString::fromStdString(sender), txnid)) {
+ dvList[txnid] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+ });
+ connect(dynamic_cast<ChatPage *>(parent),
+ &ChatPage::receivedDeviceVerificationStart,
+ this,
+ [this](const mtx::events::msg::KeyVerificationStart &msg, std::string sender) {
+ if (this->isInitialSync_)
+ return;
+
+ if (!msg.transaction_id)
+ return;
+
+ auto txnid = QString::fromStdString(msg.transaction_id.value());
+ if (!this->dvList.contains(txnid)) {
+ if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
+ this, msg, QString::fromStdString(sender), txnid)) {
+ dvList[txnid] = flow;
+ emit newDeviceVerificationRequest(flow.data());
+ }
+ }
+ });
+ connect(parent, &ChatPage::loggedOut, this, [this]() {
+ isInitialSync_ = true;
+ emit initialSyncChanged(true);
+ });
- connect(this,
- &TimelineViewManager::openImageOverlayInternalCb,
- this,
- &TimelineViewManager::openImageOverlayInternal);
+ connect(this,
+ &TimelineViewManager::openImageOverlayInternalCb,
+ this,
+ &TimelineViewManager::openImageOverlayInternal);
}
void
TimelineViewManager::openRoomMembers(TimelineModel *room)
{
- if (!room)
- return;
- MemberList *memberList = new MemberList(room->roomId(), this);
- emit openRoomMembersDialog(memberList, room);
+ if (!room)
+ return;
+ MemberList *memberList = new MemberList(room->roomId(), this);
+ emit openRoomMembersDialog(memberList, room);
}
void
TimelineViewManager::openRoomSettings(QString room_id)
{
- RoomSettings *settings = new RoomSettings(room_id, this);
- connect(rooms_->getRoomById(room_id).data(),
- &TimelineModel::roomAvatarUrlChanged,
- settings,
- &RoomSettings::avatarChanged);
- emit openRoomSettingsDialog(settings);
+ RoomSettings *settings = new RoomSettings(room_id, this);
+ connect(rooms_->getRoomById(room_id).data(),
+ &TimelineModel::roomAvatarUrlChanged,
+ settings,
+ &RoomSettings::avatarChanged);
+ emit openRoomSettingsDialog(settings);
}
void
TimelineViewManager::openInviteUsers(QString roomId)
{
- InviteesModel *model = new InviteesModel{this};
- connect(model, &InviteesModel::accept, this, [this, model, roomId]() {
- emit inviteUsers(roomId, model->mxids());
- });
- emit openInviteUsersDialog(model);
+ InviteesModel *model = new InviteesModel{this};
+ connect(model, &InviteesModel::accept, this, [this, model, roomId]() {
+ emit inviteUsers(roomId, model->mxids());
+ });
+ emit openInviteUsersDialog(model);
}
void
TimelineViewManager::openGlobalUserProfile(QString userId)
{
- UserProfile *profile = new UserProfile{QString{}, userId, this};
- emit openProfile(profile);
+ UserProfile *profile = new UserProfile{QString{}, userId, this};
+ emit openProfile(profile);
}
void
TimelineViewManager::setVideoCallItem()
{
- WebRTCSession::instance().setVideoItem(
- view->rootObject()->findChild<QQuickItem *>("videoCallItem"));
+ WebRTCSession::instance().setVideoItem(
+ view->rootObject()->findChild<QQuickItem *>("videoCallItem"));
}
void
TimelineViewManager::sync(const mtx::responses::Rooms &rooms_res)
{
- this->rooms_->sync(rooms_res);
- this->communities_->sync(rooms_res);
+ this->rooms_->sync(rooms_res);
+ this->communities_->sync(rooms_res);
- if (isInitialSync_) {
- this->isInitialSync_ = false;
- emit initialSyncChanged(false);
- }
+ if (isInitialSync_) {
+ this->isInitialSync_ = false;
+ emit initialSyncChanged(false);
+ }
}
void
TimelineViewManager::showEvent(const QString &room_id, const QString &event_id)
{
- 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());
- }
-
- room->showEvent(event_id);
+ 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());
}
+
+ room->showEvent(event_id);
+ }
}
QString
TimelineViewManager::escapeEmoji(QString str) const
{
- return utils::replaceEmoji(str);
+ return utils::replaceEmoji(str);
}
void
TimelineViewManager::openImageOverlay(QString mxcUrl, QString eventId)
{
- if (mxcUrl.isEmpty()) {
- return;
- }
+ if (mxcUrl.isEmpty()) {
+ return;
+ }
- MxcImageProvider::download(
- mxcUrl.remove("mxc://"), QSize(), [this, eventId](QString, QSize, QImage img, QString) {
- if (img.isNull()) {
- nhlog::ui()->error("Error when retrieving image for overlay.");
- return;
- }
+ MxcImageProvider::download(
+ mxcUrl.remove("mxc://"), QSize(), [this, eventId](QString, QSize, QImage img, QString) {
+ if (img.isNull()) {
+ nhlog::ui()->error("Error when retrieving image for overlay.");
+ return;
+ }
- emit openImageOverlayInternalCb(eventId, std::move(img));
- });
+ emit openImageOverlayInternalCb(eventId, std::move(img));
+ });
}
void
TimelineViewManager::openImagePackSettings(QString roomid)
{
- emit showImagePackSettings(new ImagePackListModel(roomid.toStdString(), this));
+ emit showImagePackSettings(new ImagePackListModel(roomid.toStdString(), this));
}
void
TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img)
{
- auto pixmap = QPixmap::fromImage(img);
+ auto pixmap = QPixmap::fromImage(img);
- auto imgDialog = new dialogs::ImageOverlay(pixmap);
- imgDialog->showFullScreen();
+ auto imgDialog = new dialogs::ImageOverlay(pixmap);
+ imgDialog->showFullScreen();
- 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();
+ 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 (!room->saveMedia(eventId)) {
- imgDialog->show();
- } else {
- imgDialog->close();
- }
- });
+ if (!room->saveMedia(eventId)) {
+ imgDialog->show();
+ } else {
+ imgDialog->close();
+ }
+ });
}
void
TimelineViewManager::openLeaveRoomDialog(QString roomid) const
{
- MainWindow::instance()->openLeaveRoomDialog(roomid);
+ MainWindow::instance()->openLeaveRoomDialog(roomid);
}
void
TimelineViewManager::verifyUser(QString userid)
{
- auto joined_rooms = cache::joinedRooms();
- auto room_infos = cache::getRoomInfo(joined_rooms);
-
- for (std::string room_id : joined_rooms) {
- if ((room_infos[QString::fromStdString(room_id)].member_count == 2) &&
- cache::isRoomEncrypted(room_id)) {
- auto room_members = cache::roomMembers(room_id);
- if (std::find(room_members.begin(),
- room_members.end(),
- (userid).toStdString()) != room_members.end()) {
- 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;
- }
- }
+ auto joined_rooms = cache::joinedRooms();
+ auto room_infos = cache::getRoomInfo(joined_rooms);
+
+ for (std::string room_id : joined_rooms) {
+ if ((room_infos[QString::fromStdString(room_id)].member_count == 2) &&
+ cache::isRoomEncrypted(room_id)) {
+ auto room_members = cache::roomMembers(room_id);
+ if (std::find(room_members.begin(), room_members.end(), (userid).toStdString()) !=
+ room_members.end()) {
+ 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;
}
+ }
}
+ }
- emit ChatPage::instance()->showNotification(
- tr("No encrypted private chat found with this user. Create an "
- "encrypted private chat with this user and try again."));
+ emit ChatPage::instance()->showNotification(
+ tr("No encrypted private chat found with this user. Create an "
+ "encrypted private chat with this user and try again."));
}
void
TimelineViewManager::removeVerificationFlow(DeviceVerificationFlow *flow)
{
- for (auto it = dvList.keyValueBegin(); it != dvList.keyValueEnd(); ++it) {
- if ((*it).second == flow) {
- dvList.remove((*it).first);
- return;
- }
+ for (auto it = dvList.keyValueBegin(); it != dvList.keyValueEnd(); ++it) {
+ if ((*it).second == flow) {
+ dvList.remove((*it).first);
+ return;
}
+ }
}
void
TimelineViewManager::verifyDevice(QString userid, QString deviceid)
{
- auto flow = DeviceVerificationFlow::InitiateDeviceVerification(this, userid, deviceid);
- this->dvList[flow->transactionId()] = flow;
- emit newDeviceVerificationRequest(flow.data());
+ auto flow = DeviceVerificationFlow::InitiateDeviceVerification(this, userid, deviceid);
+ this->dvList[flow->transactionId()] = flow;
+ emit newDeviceVerificationRequest(flow.data());
}
void
TimelineViewManager::updateReadReceipts(const QString &room_id,
const std::vector<QString> &event_ids)
{
- if (auto room = rooms_->getRoomById(room_id)) {
- room->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)
{
- if (auto room = rooms_->getRoomById(QString::fromStdString(room_id))) {
- room->receivedSessionKey(session_id);
- }
+ if (auto room = rooms_->getRoomById(QString::fromStdString(room_id))) {
+ room->receivedSessionKey(session_id);
+ }
}
void
TimelineViewManager::initializeRoomlist()
{
- rooms_->initializeRooms();
- communities_->initializeSidebar();
+ rooms_->initializeRooms();
+ communities_->initializeSidebar();
}
void
@@ -600,178 +578,175 @@ TimelineViewManager::queueReply(const QString &roomid,
const QString &repliedToEvent,
const QString &replyBody)
{
- if (auto room = rooms_->getRoomById(roomid)) {
- room->setReply(repliedToEvent);
- room->input()->message(replyBody);
- }
+ if (auto room = rooms_->getRoomById(roomid)) {
+ room->setReply(repliedToEvent);
+ room->input()->message(replyBody);
+ }
}
void
TimelineViewManager::queueCallMessage(const QString &roomid,
const mtx::events::msg::CallInvite &callInvite)
{
- if (auto room = rooms_->getRoomById(roomid))
- room->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)
{
- if (auto room = rooms_->getRoomById(roomid))
- room->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)
{
- if (auto room = rooms_->getRoomById(roomid))
- room->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)
{
- if (auto room = rooms_->getRoomById(roomid))
- room->sendMessageEvent(callHangUp, mtx::events::EventType::CallHangUp);
+ if (auto room = rooms_->getRoomById(roomid))
+ room->sendMessageEvent(callHangUp, mtx::events::EventType::CallHangUp);
}
void
TimelineViewManager::focusMessageInput()
{
- emit focusInput();
+ emit focusInput();
}
QObject *
TimelineViewManager::completerFor(QString completerName, QString roomId)
{
- if (completerName == "user") {
- auto userModel = new UsersModel(roomId.toStdString());
- auto proxy = new CompletionProxyModel(userModel);
- userModel->setParent(proxy);
- return proxy;
- } else if (completerName == "emoji") {
- auto emojiModel = new emoji::EmojiModel();
- auto proxy = new CompletionProxyModel(emojiModel);
- emojiModel->setParent(proxy);
- return proxy;
- } else if (completerName == "allemoji") {
- auto emojiModel = new emoji::EmojiModel();
- auto proxy = new CompletionProxyModel(emojiModel, 1, static_cast<size_t>(-1) / 4);
- emojiModel->setParent(proxy);
- return proxy;
- } else if (completerName == "room") {
- auto roomModel = new RoomsModel(false);
- auto proxy = new CompletionProxyModel(roomModel, 4);
- roomModel->setParent(proxy);
- return proxy;
- } else if (completerName == "roomAliases") {
- auto roomModel = new RoomsModel(true);
- auto proxy = new CompletionProxyModel(roomModel);
- roomModel->setParent(proxy);
- return proxy;
- } else if (completerName == "stickers") {
- auto stickerModel = new CombinedImagePackModel(roomId.toStdString(), true);
- auto proxy = new CompletionProxyModel(stickerModel, 1, static_cast<size_t>(-1) / 4);
- stickerModel->setParent(proxy);
- return proxy;
- }
- return nullptr;
+ if (completerName == "user") {
+ auto userModel = new UsersModel(roomId.toStdString());
+ auto proxy = new CompletionProxyModel(userModel);
+ userModel->setParent(proxy);
+ return proxy;
+ } else if (completerName == "emoji") {
+ auto emojiModel = new emoji::EmojiModel();
+ auto proxy = new CompletionProxyModel(emojiModel);
+ emojiModel->setParent(proxy);
+ return proxy;
+ } else if (completerName == "allemoji") {
+ auto emojiModel = new emoji::EmojiModel();
+ auto proxy = new CompletionProxyModel(emojiModel, 1, static_cast<size_t>(-1) / 4);
+ emojiModel->setParent(proxy);
+ return proxy;
+ } else if (completerName == "room") {
+ auto roomModel = new RoomsModel(false);
+ auto proxy = new CompletionProxyModel(roomModel, 4);
+ roomModel->setParent(proxy);
+ return proxy;
+ } else if (completerName == "roomAliases") {
+ auto roomModel = new RoomsModel(true);
+ auto proxy = new CompletionProxyModel(roomModel);
+ roomModel->setParent(proxy);
+ return proxy;
+ } else if (completerName == "stickers") {
+ auto stickerModel = new CombinedImagePackModel(roomId.toStdString(), true);
+ auto proxy = new CompletionProxyModel(stickerModel, 1, static_cast<size_t>(-1) / 4);
+ stickerModel->setParent(proxy);
+ return proxy;
+ }
+ return nullptr;
}
void
TimelineViewManager::focusTimeline()
{
- getWidget()->setFocus();
+ getWidget()->setFocus();
}
void
TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEvents *e,
QString roomId)
{
- auto room = rooms_->getRoomById(roomId);
- auto content = mtx::accessors::url(*e);
- std::optional<mtx::crypto::EncryptedFile> encryptionInfo = mtx::accessors::file(*e);
-
- if (encryptionInfo) {
- http::client()->download(
- content,
- [this, roomId, e, encryptionInfo](const std::string &res,
- const std::string &content_type,
- const std::string &originalFilename,
- mtx::http::RequestErr err) {
- if (err)
- return;
-
- auto data = mtx::crypto::to_string(
- mtx::crypto::decrypt_file(res, encryptionInfo.value()));
-
- http::client()->upload(
- data,
- content_type,
- originalFilename,
- [this, roomId, e](const mtx::responses::ContentURI &res,
- mtx::http::RequestErr err) mutable {
- if (err) {
- nhlog::net()->warn("failed to upload media: {} {} ({})",
- err->matrix_error.error,
- to_string(err->matrix_error.errcode),
- static_cast<int>(err->status_code));
- return;
- }
-
- std::visit(
- [this, roomId, url = res.content_uri](auto ev) {
- if constexpr (mtx::events::message_content_to_type<
- decltype(ev.content)> ==
- mtx::events::EventType::RoomMessage) {
- if constexpr (messageWithFileAndUrl(ev)) {
- ev.content.relations.relations
- .clear();
- ev.content.file.reset();
- ev.content.url = url;
- }
-
- if (auto room = rooms_->getRoomById(roomId)) {
- removeReplyFallback(ev);
- ev.content.relations.relations
- .clear();
- room->sendMessageEvent(
- ev.content,
- mtx::events::EventType::
- RoomMessage);
- }
- }
- },
- *e);
- });
+ auto room = rooms_->getRoomById(roomId);
+ auto content = mtx::accessors::url(*e);
+ std::optional<mtx::crypto::EncryptedFile> encryptionInfo = mtx::accessors::file(*e);
+
+ if (encryptionInfo) {
+ http::client()->download(
+ content,
+ [this, roomId, e, encryptionInfo](const std::string &res,
+ const std::string &content_type,
+ const std::string &originalFilename,
+ mtx::http::RequestErr err) {
+ if (err)
+ return;
+
+ auto data =
+ mtx::crypto::to_string(mtx::crypto::decrypt_file(res, encryptionInfo.value()));
+
+ http::client()->upload(
+ data,
+ content_type,
+ originalFilename,
+ [this, roomId, e](const mtx::responses::ContentURI &res,
+ mtx::http::RequestErr err) mutable {
+ if (err) {
+ nhlog::net()->warn("failed to upload media: {} {} ({})",
+ err->matrix_error.error,
+ to_string(err->matrix_error.errcode),
+ static_cast<int>(err->status_code));
+ return;
+ }
+
+ std::visit(
+ [this, roomId, url = res.content_uri](auto ev) {
+ using namespace mtx::events;
+ if constexpr (EventType::RoomMessage ==
+ message_content_to_type<decltype(ev.content)> ||
+ EventType::Sticker ==
+ message_content_to_type<decltype(ev.content)>) {
+ if constexpr (messageWithFileAndUrl(ev)) {
+ ev.content.relations.relations.clear();
+ ev.content.file.reset();
+ ev.content.url = url;
+ }
+
+ if (auto room = rooms_->getRoomById(roomId)) {
+ removeReplyFallback(ev);
+ ev.content.relations.relations.clear();
+ room->sendMessageEvent(ev.content,
+ mtx::events::EventType::RoomMessage);
+ }
+ }
+ },
+ *e);
+ });
- return;
- });
+ return;
+ });
- return;
- }
+ return;
+ }
- std::visit(
- [room](auto e) {
- if constexpr (mtx::events::message_content_to_type<decltype(e.content)> ==
- mtx::events::EventType::RoomMessage) {
- e.content.relations.relations.clear();
- removeReplyFallback(e);
- room->sendMessageEvent(e.content, mtx::events::EventType::RoomMessage);
- }
- },
- *e);
+ std::visit(
+ [room](auto e) {
+ if constexpr (mtx::events::message_content_to_type<decltype(e.content)> ==
+ mtx::events::EventType::RoomMessage) {
+ e.content.relations.relations.clear();
+ removeReplyFallback(e);
+ room->sendMessageEvent(e.content, mtx::events::EventType::RoomMessage);
+ }
+ },
+ *e);
}
//! WORKAROUND(Nico): for https://bugreports.qt.io/browse/QTBUG-93281
void
TimelineViewManager::fixImageRendering(QQuickTextDocument *t, QQuickItem *i)
{
- if (t) {
- QObject::connect(
- t->textDocument(), SIGNAL(imagesLoaded()), i, SLOT(updateWholeDocument()));
- }
+ if (t) {
+ QObject::connect(t->textDocument(), SIGNAL(imagesLoaded()), i, SLOT(updateWholeDocument()));
+ }
}
|