From 456a41bcdf9c0bff99a20bb77d1039c89f2101eb Mon Sep 17 00:00:00 2001 From: Thulinma Date: Sun, 19 Sep 2021 22:55:12 +0200 Subject: [PATCH 1/3] Added support for refreshing the device list, marking current device with a checkmark instead of a lock --- resources/icons/ui/refresh.png | Bin 0 -> 1241 bytes resources/icons/ui/refresh.svg | 16 +++++++++++ resources/qml/dialogs/UserProfile.qml | 38 ++++++++++++++++++++------ resources/res.qrc | 1 + src/Cache.cpp | 10 +++++++ src/Cache_p.h | 1 + src/ui/UserProfile.cpp | 12 ++++++++ src/ui/UserProfile.h | 2 ++ 8 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 resources/icons/ui/refresh.png create mode 100644 resources/icons/ui/refresh.svg diff --git a/resources/icons/ui/refresh.png b/resources/icons/ui/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..642682032ab6d6ff73b0769bd2c420e89281d8a9 GIT binary patch literal 1241 zcmV;~1Sb25P)V3TT4R7iuwNQoe|g32h; zFiD}n2%lZ(wU0ocn5#rbO9T| zK0GTVva4B$jX0{9=vMYE9>N6$;#`C~aY+FmW4H#}F)W?%dKZD*#)BO z?N8iO7w;r&YqKshld-i6gtoF#tQWqhX19H=1WdzcT_7;4ZO2;~uWd^|KJNliNo;Z( z@l)_I?#Pm1`tVIoXFG9KdAi4O zx$tvJnt;c0I@%-@9-UyN&?%OlfSE#19^+sb52R4pf{OC$k}*6Vxp-7~NOh75Hb=&p zDFM^O_wwsfscb^o;>RT5@yLZ==-h9fG~&l3;QNS0gF?a5DN>0)lYmo_WS zJu<%N1Z;>{a8mQlhZL-dh%I*lVs8Jp(`jwUuMx53O28avHwv@ZO-bdBXCNZBSUWrk zS8BhhSYs#lmmn&J*An{PSQEZRcze@|W5UDlP{M$ku^e~dqLTcbzz%#=lD{53di3bg zqeqV(6OLLboTAj+i4RNi7sJ(fTG-%i#)$9&^;5#ANvdvZb(zXCvLj<`hieN`_S?TD z6xxUzWN+>F5H>aEBn)UIq3=dKDSK_>q+c1-=Cnzw1k~&l zb_v5*i?trAn2a0oaCOap1wVTPcefH>sb1JghHy~$R*wr0&RJDksNDI&)p(`dMXB$A z^JVL^W+{uaE%=}dM3pW+O9HkzdjMg57l>MtFRt_Ilnr26tazH2 zla0jJSRnsAaSGcd%n|2eU!?dNeZok6>}YM7c0@Q^P>7|%iL28>x3ocAV>3&b9QmsR zL0N53I8IySEW#LO3&%;XE8t_ga6lsEdBUIYR5jkNW(i(Z&Pk7hLZ`V*g3;Vg^zd_V zyD(mNtx)aF77j0+200000NkvXXu0mjf D1CLgK literal 0 HcmV?d00001 diff --git a/resources/icons/ui/refresh.svg b/resources/icons/ui/refresh.svg new file mode 100644 index 00000000..17c41496 --- /dev/null +++ b/resources/icons/ui/refresh.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/resources/qml/dialogs/UserProfile.qml b/resources/qml/dialogs/UserProfile.qml index 9bf548e3..86822bdf 100644 --- a/resources/qml/dialogs/UserProfile.qml +++ b/resources/qml/dialogs/UserProfile.qml @@ -249,6 +249,14 @@ ApplicationWindow { visible: !profile.isGlobalUserProfile && profile.room.permissions.canBan() } + ImageButton { + image: ":/icons/icons/ui/refresh.png" + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Refresh device list.") + onClicked: profile.refreshDevices(); + } + } } @@ -264,6 +272,9 @@ ApplicationWindow { delegate: RowLayout { + required property int verificationStatus + required property string deviceId + required property string deviceName width: devicelist.width spacing: 4 @@ -276,7 +287,7 @@ ApplicationWindow { elide: Text.ElideRight font.bold: true color: Nheko.colors.text - text: model.deviceId + text: deviceId } Text { @@ -284,7 +295,7 @@ ApplicationWindow { Layout.alignment: Qt.AlignRight elide: Text.ElideRight color: Nheko.colors.text - text: model.deviceName + text: deviceName } } @@ -292,19 +303,30 @@ ApplicationWindow { Image { Layout.preferredHeight: 16 Layout.preferredWidth: 16 - source: ((model.verificationStatus == VerificationStatus.VERIFIED) ? "image://colorimage/:/icons/icons/ui/lock.png?green" : ((model.verificationStatus == VerificationStatus.UNVERIFIED) ? "image://colorimage/:/icons/icons/ui/unlock.png?yellow" : "image://colorimage/:/icons/icons/ui/unlock.png?red")) + source: { + switch (verificationStatus){ + case VerificationStatus.VERIFIED: + return "image://colorimage/:/icons/icons/ui/lock.png?green"; + case VerificationStatus.UNVERIFIED: + return "image://colorimage/:/icons/icons/ui/unlock.png?yellow"; + case VerificationStatus.SELF: + return "image://colorimage/:/icons/icons/ui/checkmark.png?green"; + default: + return "image://colorimage/:/icons/icons/ui/unlock.png?red"; + } + } } Button { id: verifyButton - visible: (!profile.userVerificationEnabled && !profile.isSelf) || (profile.isSelf && (model.verificationStatus != VerificationStatus.VERIFIED || !profile.userVerificationEnabled)) - text: (model.verificationStatus != VerificationStatus.VERIFIED) ? qsTr("Verify") : qsTr("Unverify") + visible: (!profile.userVerificationEnabled && !profile.isSelf) || (profile.isSelf && (verificationStatus == VerificationStatus.UNVERIFIED || !profile.userVerificationEnabled)) + text: (verificationStatus != VerificationStatus.VERIFIED) ? qsTr("Verify") : qsTr("Unverify") onClicked: { - if (model.verificationStatus == VerificationStatus.VERIFIED) - profile.unverify(model.deviceId); + if (verificationStatus == VerificationStatus.VERIFIED) + profile.unverify(deviceId); else - profile.verify(model.deviceId); + profile.verify(deviceId); } } diff --git a/resources/res.qrc b/resources/res.qrc index a001a929..3bd301f7 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -72,6 +72,7 @@ icons/ui/screen-share.png icons/ui/toggle-camera-view.png icons/ui/video-call.png + icons/ui/refresh.png icons/emoji-categories/people.png icons/emoji-categories/people@2x.png icons/emoji-categories/nature.png diff --git a/src/Cache.cpp b/src/Cache.cpp index b124fe5e..ee0ca0c2 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -4045,6 +4045,16 @@ Cache::updateUserKeys(const std::string &sync_token, const mtx::responses::Query } } +void +Cache::markUserKeysOutOfDate(const std::vector &user_ids) +{ + auto currentBatchToken = nextBatchToken(); + auto txn = lmdb::txn::begin(env_); + auto db = getUserKeysDb(txn); + markUserKeysOutOfDate(txn, db, user_ids, currentBatchToken); + txn.commit(); +} + void Cache::markUserKeysOutOfDate(lmdb::txn &txn, lmdb::dbi &db, diff --git a/src/Cache_p.h b/src/Cache_p.h index a15010e6..52375d38 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -50,6 +50,7 @@ public: const std::string &room_id, bool verified_only); void updateUserKeys(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery); + void markUserKeysOutOfDate(const std::vector &user_ids); void markUserKeysOutOfDate(lmdb::txn &txn, lmdb::dbi &db, const std::vector &user_ids, diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index 58150ed7..62488954 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -151,6 +151,15 @@ UserProfile::isSelf() const return this->userid_ == utils::localUser(); } +void +UserProfile::refreshDevices() +{ + std::vector keysToRequest; + keysToRequest.push_back(this->userid_.toStdString()); + cache::client()->markUserKeysOutOfDate(keysToRequest); + fetchDeviceList(this->userid_); +} + void UserProfile::fetchDeviceList(const QString &userID) { @@ -205,6 +214,9 @@ UserProfile::fetchDeviceList(const QString &userID) device, DeviceId(device.device_id), UserId(other_user_id))) verified = verification::Status::VERIFIED; + if (isSelf() && device.device_id == ::http::client()->device_id()) + verified = verification::Status::SELF; + deviceInfo.push_back( {QString::fromStdString(d.first), QString::fromStdString(device.unsigned_info.device_display_name), diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h index a148c431..c83ec01e 100644 --- a/src/ui/UserProfile.h +++ b/src/ui/UserProfile.h @@ -18,6 +18,7 @@ Q_NAMESPACE enum Status { + SELF, VERIFIED, UNVERIFIED, BLOCKED @@ -118,6 +119,7 @@ public: Q_INVOKABLE void verify(QString device = ""); Q_INVOKABLE void unverify(QString device = ""); Q_INVOKABLE void fetchDeviceList(const QString &userID); + Q_INVOKABLE void refreshDevices(); Q_INVOKABLE void banUser(); // Q_INVOKABLE void ignoreUser(); Q_INVOKABLE void kickUser(); From 47db1e5c65eb5cb8b9b0d8d50fb33f69f9665f30 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 7 Oct 2021 19:55:27 +0200 Subject: [PATCH 2/3] Remove duplicated verification status calculation --- src/ui/UserProfile.cpp | 102 ++++++++++++++++++++--------------------- src/ui/UserProfile.h | 6 ++- 2 files changed, 55 insertions(+), 53 deletions(-) diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index 62488954..5ddf011f 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -34,6 +34,7 @@ UserProfile::UserProfile(QString roomid, this, &UserProfile::setGlobalUsername, Qt::QueuedConnection); + connect(this, &UserProfile::verificationStatiChanged, &UserProfile::updateVerificationStatus); if (isGlobalUserProfile()) { getGlobalProfileData(); @@ -48,22 +49,7 @@ UserProfile::UserProfile(QString roomid, if (user_id != this->userid_.toStdString()) return; - auto status = cache::verificationStatus(user_id); - if (!status) - return; - this->isUserVerified = status->user_verified; - emit userStatusChanged(); - - for (auto &deviceInfo : deviceList_.deviceList_) { - deviceInfo.verification_status = - std::find(status->verified_devices.begin(), - status->verified_devices.end(), - deviceInfo.device_id.toStdString()) == status->verified_devices.end() - ? verification::UNVERIFIED - : verification::VERIFIED; - } - deviceList_.reset(deviceList_.deviceList_); - emit devicesChanged(); + emit verificationStatiChanged(); }); fetchDeviceList(this->userid_); } @@ -170,20 +156,18 @@ UserProfile::fetchDeviceList(const QString &userID) cache::client()->query_keys( userID.toStdString(), - [other_user_id = userID.toStdString(), this](const UserKeyCache &other_user_keys, + [other_user_id = userID.toStdString(), this](const UserKeyCache &, mtx::http::RequestErr err) { if (err) { nhlog::net()->warn("failed to query device keys: {},{}", mtx::errors::to_string(err->matrix_error.errcode), static_cast(err->status_code)); - return; } // Ensure local key cache is up to date cache::client()->query_keys( utils::localUser().toStdString(), - [other_user_id, other_user_keys, this](const UserKeyCache &, - mtx::http::RequestErr err) { + [this](const UserKeyCache &, mtx::http::RequestErr err) { using namespace mtx; std::string local_user_id = utils::localUser().toStdString(); @@ -191,44 +175,58 @@ UserProfile::fetchDeviceList(const QString &userID) nhlog::net()->warn("failed to query device keys: {},{}", mtx::errors::to_string(err->matrix_error.errcode), static_cast(err->status_code)); - return; } - this->hasMasterKey = !other_user_keys.master_keys.keys.empty(); - - std::vector deviceInfo; - auto devices = other_user_keys.device_keys; - auto verificationStatus = cache::client()->verificationStatus(other_user_id); - - isUserVerified = verificationStatus.user_verified; - emit userStatusChanged(); - - for (const auto &d : devices) { - auto device = d.second; - verification::Status verified = verification::Status::UNVERIFIED; - - if (std::find(verificationStatus.verified_devices.begin(), - verificationStatus.verified_devices.end(), - device.device_id) != verificationStatus.verified_devices.end() && - mtx::crypto::verify_identity_signature( - device, DeviceId(device.device_id), UserId(other_user_id))) - verified = verification::Status::VERIFIED; - - if (isSelf() && device.device_id == ::http::client()->device_id()) - verified = verification::Status::SELF; - - deviceInfo.push_back( - {QString::fromStdString(d.first), - QString::fromStdString(device.unsigned_info.device_display_name), - verified}); - } - - this->deviceList_.queueReset(std::move(deviceInfo)); - emit devicesChanged(); + emit verificationStatiChanged(); }); }); } +void +UserProfile::updateVerificationStatus() +{ + if (!cache::client() || !cache::client()->isDatabaseReady()) + return; + + auto user_keys = cache::client()->userKeys(userid_.toStdString()); + if (!user_keys) { + this->hasMasterKey = false; + this->isUserVerified = crypto::Trust::Unverified; + this->deviceList_.reset({}); + emit userStatusChanged(); + return; + } + + this->hasMasterKey = !user_keys->master_keys.keys.empty(); + + std::vector deviceInfo; + auto devices = user_keys->device_keys; + auto verificationStatus = cache::client()->verificationStatus(userid_.toStdString()); + + this->isUserVerified = verificationStatus.user_verified; + emit userStatusChanged(); + + for (const auto &d : devices) { + auto device = d.second; + verification::Status verified = + std::find(verificationStatus.verified_devices.begin(), + verificationStatus.verified_devices.end(), + device.device_id) == verificationStatus.verified_devices.end() + ? verification::UNVERIFIED + : verification::VERIFIED; + + if (isSelf() && device.device_id == ::http::client()->device_id()) + verified = verification::Status::SELF; + + deviceInfo.push_back({QString::fromStdString(d.first), + QString::fromStdString(device.unsigned_info.device_display_name), + verified}); + } + + this->deviceList_.queueReset(std::move(deviceInfo)); + emit devicesChanged(); +} + void UserProfile::banUser() { diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h index c83ec01e..68f9c21b 100644 --- a/src/ui/UserProfile.h +++ b/src/ui/UserProfile.h @@ -137,11 +137,15 @@ signals: void globalUsernameRetrieved(const QString &globalUser); void devicesChanged(); + // internal + void verificationStatiChanged(); + public slots: void updateAvatarUrl(); -protected slots: +private slots: void setGlobalUsername(const QString &globalUser); + void updateVerificationStatus(); private: void updateRoomMemberState(mtx::events::state::Member member); From 569606f35b7b0ebbeba5eb5625a8f47fde4eb980 Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Thu, 7 Oct 2021 17:59:03 +0000 Subject: [PATCH 3/3] Simplify device list refresh logic --- resources/qml/dialogs/UserProfile.qml | 2 +- src/ui/UserProfile.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/qml/dialogs/UserProfile.qml b/resources/qml/dialogs/UserProfile.qml index 86822bdf..d5442382 100644 --- a/resources/qml/dialogs/UserProfile.qml +++ b/resources/qml/dialogs/UserProfile.qml @@ -320,7 +320,7 @@ ApplicationWindow { Button { id: verifyButton - visible: (!profile.userVerificationEnabled && !profile.isSelf) || (profile.isSelf && (verificationStatus == VerificationStatus.UNVERIFIED || !profile.userVerificationEnabled)) + visible: verificationStatus == VerificationStatus.UNVERIFIED && (profile.isSelf || !profile.userVerificationEnabled) text: (verificationStatus != VerificationStatus.VERIFIED) ? qsTr("Verify") : qsTr("Unverify") onClicked: { if (verificationStatus == VerificationStatus.VERIFIED) diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index 5ddf011f..31ae9f8b 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -140,9 +140,7 @@ UserProfile::isSelf() const void UserProfile::refreshDevices() { - std::vector keysToRequest; - keysToRequest.push_back(this->userid_.toStdString()); - cache::client()->markUserKeysOutOfDate(keysToRequest); + cache::client()->markUserKeysOutOfDate({this->userid_.toStdString()}); fetchDeviceList(this->userid_); }