diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index bfefd7bb..6670532c 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -1017,7 +1017,7 @@ ChatPage::trySync()
// TODO: fine grained error handling
try {
cache::saveState(res);
- olm::handle_to_device_messages(res.to_device);
+ olm::handle_to_device_messages(res.to_device.events);
auto updates = cache::roomUpdates(res);
@@ -1240,7 +1240,7 @@ ChatPage::initialSyncHandler(const mtx::responses::Sync &res, mtx::http::Request
try {
cache::saveState(res);
- olm::handle_to_device_messages(res.to_device);
+ olm::handle_to_device_messages(res.to_device.events);
emit initializeViews(std::move(res.rooms));
emit initializeRoomList(cache::roomInfo());
diff --git a/src/Olm.cpp b/src/Olm.cpp
index 8ea39566..2c4f6186 100644
--- a/src/Olm.cpp
+++ b/src/Olm.cpp
@@ -23,52 +23,55 @@ client()
}
void
-handle_to_device_messages(const std::vector<nlohmann::json> &msgs)
+handle_to_device_messages(const std::vector<mtx::events::collections::DeviceEvents> &msgs)
{
if (msgs.empty())
return;
nhlog::crypto()->info("received {} to_device messages", msgs.size());
+ nlohmann::json j_msg;
for (const auto &msg : msgs) {
- if (msg.count("type") == 0) {
+ j_msg = std::visit([](auto &e) { return json(e); }, std::move(msg));
+ if (j_msg.count("type") == 0) {
nhlog::crypto()->warn("received message with no type field: {}",
- msg.dump(2));
+ j_msg.dump(2));
continue;
}
- std::string msg_type = msg.at("type");
+ std::string msg_type = j_msg.at("type");
if (msg_type == to_string(mtx::events::EventType::RoomEncrypted)) {
try {
- OlmMessage olm_msg = msg;
+ OlmMessage olm_msg = j_msg;
handle_olm_message(std::move(olm_msg));
} catch (const nlohmann::json::exception &e) {
nhlog::crypto()->warn(
- "parsing error for olm message: {} {}", e.what(), msg.dump(2));
+ "parsing error for olm message: {} {}", e.what(), j_msg.dump(2));
} catch (const std::invalid_argument &e) {
- nhlog::crypto()->warn(
- "validation error for olm message: {} {}", e.what(), msg.dump(2));
+ nhlog::crypto()->warn("validation error for olm message: {} {}",
+ e.what(),
+ j_msg.dump(2));
}
} else if (msg_type == to_string(mtx::events::EventType::RoomKeyRequest)) {
- nhlog::crypto()->warn("handling key request event: {}", msg.dump(2));
+ nhlog::crypto()->warn("handling key request event: {}", j_msg.dump(2));
try {
- mtx::events::msg::KeyRequest req = msg;
- if (req.action == mtx::events::msg::RequestAction::Request)
- handle_key_request_message(std::move(req));
+ mtx::events::DeviceEvent<mtx::events::msg::KeyRequest> req = j_msg;
+ if (req.content.action == mtx::events::msg::RequestAction::Request)
+ handle_key_request_message(req);
else
nhlog::crypto()->warn(
"ignore key request (unhandled action): {}",
- req.request_id);
+ req.content.request_id);
} catch (const nlohmann::json::exception &e) {
nhlog::crypto()->warn(
"parsing error for key_request message: {} {}",
e.what(),
- msg.dump(2));
+ j_msg.dump(2));
}
} else {
- nhlog::crypto()->warn("unhandled event: {}", msg.dump(2));
+ nhlog::crypto()->warn("unhandled event: {}", j_msg.dump(2));
}
}
}
@@ -341,51 +344,53 @@ send_key_request_for(const std::string &room_id,
}
void
-handle_key_request_message(const mtx::events::msg::KeyRequest &req)
+handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyRequest> &req)
{
- if (req.algorithm != MEGOLM_ALGO) {
+ if (req.content.algorithm != MEGOLM_ALGO) {
nhlog::crypto()->debug("ignoring key request {} with invalid algorithm: {}",
- req.request_id,
- req.algorithm);
+ req.content.request_id,
+ req.content.algorithm);
return;
}
// Check if we were the sender of the session being requested.
- if (req.sender_key != olm::client()->identity_keys().curve25519) {
+ if (req.content.sender_key != olm::client()->identity_keys().curve25519) {
nhlog::crypto()->debug("ignoring key request {} because we were not the sender: "
"\nrequested({}) ours({})",
- req.request_id,
- req.sender_key,
+ req.content.request_id,
+ req.content.sender_key,
olm::client()->identity_keys().curve25519);
return;
}
// Check if we have the keys for the requested session.
- if (!cache::outboundMegolmSessionExists(req.room_id)) {
- nhlog::crypto()->warn("requested session not found in room: {}", req.room_id);
+ if (!cache::outboundMegolmSessionExists(req.content.room_id)) {
+ nhlog::crypto()->warn("requested session not found in room: {}",
+ req.content.room_id);
return;
}
// Check that the requested session_id and the one we have saved match.
- const auto session = cache::getOutboundMegolmSession(req.room_id);
- if (req.session_id != session.data.session_id) {
+ const auto session = cache::getOutboundMegolmSession(req.content.room_id);
+ if (req.content.session_id != session.data.session_id) {
nhlog::crypto()->warn("session id of retrieved session doesn't match the request: "
"requested({}), ours({})",
- req.session_id,
+ req.content.session_id,
session.data.session_id);
return;
}
- if (!cache::isRoomMember(req.sender, req.room_id)) {
+ if (!cache::isRoomMember(req.sender, req.content.room_id)) {
nhlog::crypto()->warn(
"user {} that requested the session key is not member of the room {}",
req.sender,
- req.room_id);
+ req.content.room_id);
return;
}
- if (!utils::respondsToKeyRequests(req.room_id)) {
- nhlog::crypto()->debug("ignoring all key requests for room {}", req.room_id);
+ if (!utils::respondsToKeyRequests(req.content.room_id)) {
+ nhlog::crypto()->debug("ignoring all key requests for room {}",
+ req.content.room_id);
return;
}
@@ -393,11 +398,11 @@ handle_key_request_message(const mtx::events::msg::KeyRequest &req)
// Prepare the m.room_key event.
//
auto payload = json{{"algorithm", "m.megolm.v1.aes-sha2"},
- {"room_id", req.room_id},
- {"session_id", req.session_id},
+ {"room_id", req.content.room_id},
+ {"session_id", req.content.session_id},
{"session_key", session.data.session_key}};
- send_megolm_key_to_device(req.sender, req.requesting_device_id, payload);
+ send_megolm_key_to_device(req.sender, req.content.requesting_device_id, payload);
}
void
diff --git a/src/Olm.h b/src/Olm.h
index 28521413..09038ad1 100644
--- a/src/Olm.h
+++ b/src/Olm.h
@@ -40,7 +40,7 @@ mtx::crypto::OlmClient *
client();
void
-handle_to_device_messages(const std::vector<nlohmann::json> &msgs);
+handle_to_device_messages(const std::vector<mtx::events::collections::DeviceEvents> &msgs);
nlohmann::json
try_olm_decryption(const std::string &sender_key,
@@ -77,7 +77,7 @@ send_key_request_for(const std::string &room_id,
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &);
void
-handle_key_request_message(const mtx::events::msg::KeyRequest &);
+handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyRequest> &);
void
send_megolm_key_to_device(const std::string &user_id,
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index e19aa876..6af08e12 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -51,11 +51,13 @@ void
UserSettings::load()
{
QSettings settings;
- isTrayEnabled_ = settings.value("user/window/tray", false).toBool();
- hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool();
- isStartInTrayEnabled_ = settings.value("user/window/start_in_tray", false).toBool();
- isGroupViewEnabled_ = settings.value("user/group_view", true).toBool();
- isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool();
+ isTrayEnabled_ = settings.value("user/window/tray", false).toBool();
+ hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool();
+ isStartInTrayEnabled_ = settings.value("user/window/start_in_tray", false).toBool();
+ isGroupViewEnabled_ = settings.value("user/group_view", true).toBool();
+ isButtonsInTimelineEnabled_ = settings.value("user/timeline/buttons", true).toBool();
+ isMessageHoverHighlightEnabled_ =
+ settings.value("user/timeline/message_hover_highlight", false).toBool();
isMarkdownEnabled_ = settings.value("user/markdown_enabled", true).toBool();
isTypingNotificationsEnabled_ = settings.value("user/typing_notifications", true).toBool();
sortByImportance_ = settings.value("user/sort_by_unread", true).toBool();
@@ -165,6 +167,7 @@ UserSettings::save()
settings.beginGroup("timeline");
settings.setValue("buttons", isButtonsInTimelineEnabled_);
+ settings.setValue("message_hover_highlight", isMessageHoverHighlightEnabled_);
settings.endGroup();
settings.setValue("avatar_circles", avatarCircles_);
@@ -235,6 +238,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
groupViewToggle_ = new Toggle{this};
timelineButtonsToggle_ = new Toggle{this};
typingNotifications_ = new Toggle{this};
+ messageHoverHighlight_ = new Toggle{this};
sortByImportance_ = new Toggle{this};
readReceipts_ = new Toggle{this};
markdownEnabled_ = new Toggle{this};
@@ -345,6 +349,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
boxWrap(tr("Read receipts"), readReceipts_);
boxWrap(tr("Send messages as Markdown"), markdownEnabled_);
boxWrap(tr("Desktop notifications"), desktopNotifications_);
+ boxWrap(tr("Highlight message on hover"), messageHoverHighlight_);
formLayout_->addRow(uiLabel_);
formLayout_->addRow(new HorizontalLine{this});
@@ -463,6 +468,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
settings_->setDesktopNotifications(!isDisabled);
});
+ connect(messageHoverHighlight_, &Toggle::toggled, this, [this](bool isDisabled) {
+ settings_->setMessageHoverHighlight(!isDisabled);
+ });
+
connect(
sessionKeysImportBtn, &QPushButton::clicked, this, &UserSettingsPage::importSessionKeys);
@@ -495,6 +504,7 @@ UserSettingsPage::showEvent(QShowEvent *)
readReceipts_->setState(!settings_->isReadReceiptsEnabled());
markdownEnabled_->setState(!settings_->isMarkdownEnabled());
desktopNotifications_->setState(!settings_->hasDesktopNotifications());
+ messageHoverHighlight_->setState(!settings_->isMessageHoverHighlightEnabled());
deviceIdValue_->setText(QString::fromStdString(http::client()->device_id()));
deviceFingerprintValue_->setText(
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index 6b9834ea..088bbfb5 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -44,6 +44,11 @@ public:
void load();
void applyTheme();
void setTheme(QString theme);
+ void setMessageHoverHighlight(bool state)
+ {
+ isMessageHoverHighlightEnabled_ = state;
+ save();
+ }
void setTray(bool state)
{
isTrayEnabled_ = state;
@@ -118,6 +123,7 @@ public:
}
QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; }
+ bool isMessageHoverHighlightEnabled() const { return isMessageHoverHighlightEnabled_; }
bool isTrayEnabled() const { return isTrayEnabled_; }
bool isStartInTrayEnabled() const { return isStartInTrayEnabled_; }
bool isGroupViewEnabled() const { return isGroupViewEnabled_; }
@@ -144,6 +150,7 @@ private:
? "light"
: "system";
QString theme_;
+ bool isMessageHoverHighlightEnabled_;
bool isTrayEnabled_;
bool isStartInTrayEnabled_;
bool isGroupViewEnabled_;
@@ -203,6 +210,7 @@ private:
Toggle *groupViewToggle_;
Toggle *timelineButtonsToggle_;
Toggle *typingNotifications_;
+ Toggle *messageHoverHighlight_;
Toggle *sortByImportance_;
Toggle *readReceipts_;
Toggle *markdownEnabled_;
diff --git a/src/main.cpp b/src/main.cpp
index 09c326f4..ec4f638d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -116,6 +116,7 @@ main(int argc, char *argv[])
QCoreApplication::setApplicationName("nheko");
QCoreApplication::setApplicationVersion(nheko::version);
QCoreApplication::setOrganizationName("nheko");
+ QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
SingleApplication app(argc,
|