diff --git a/resources/icons/ui/refresh.png b/resources/icons/ui/refresh.png new file mode 100644 index 00000000..64268203 Binary files /dev/null and b/resources/icons/ui/refresh.png differ 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();