diff --git a/CMakeLists.txt b/CMakeLists.txt index 69a46bde..e170495a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -276,6 +276,7 @@ set(SRC_FILES src/ui/ToggleButton.cpp src/ui/Theme.cpp src/ui/ThemeManager.cpp + src/ui/UserProfile.cpp src/AvatarProvider.cpp src/BlurhashProvider.cpp @@ -480,6 +481,7 @@ qt5_wrap_cpp(MOC_HEADERS src/ui/ToggleButton.h src/ui/Theme.h src/ui/ThemeManager.h + src/ui/UserProfile.h src/notifications/Manager.h diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index dd35473c..ed403aa9 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -286,7 +286,10 @@ Page { MouseArea { anchors.fill: parent - onClicked: chat.model.openUserProfile(modelData.userId) + onClicked: { + userProfile.user_data = modelData + userProfile.show() + } cursorShape: Qt.PointingHandCursor propagateComposedEvents: true } @@ -300,7 +303,10 @@ Page { MouseArea { anchors.fill: parent - onClicked: chat.model.openUserProfile(section.split(" ")[0]) + onClicked: { + userProfile.user_data = modelData + userProfile.show() + } cursorShape: Qt.PointingHandCursor propagateComposedEvents: true } @@ -314,6 +320,9 @@ Page { width: chat.delegateMaxWidth - parent.spacing*2 - userName.implicitWidth - avatarSize font.italic: true } + UserProfile{ + id: userProfile + } } } } diff --git a/resources/qml/UserProfile.qml b/resources/qml/UserProfile.qml new file mode 100644 index 00000000..f019ee25 --- /dev/null +++ b/resources/qml/UserProfile.qml @@ -0,0 +1,85 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import QtQuick.Window 2.3 + +ApplicationWindow{ + property var user_data + property var colors: currentActivePalette + + id:userProfileDialog + height: 500 + width: 500 + modality:Qt.WindowModal + Layout.alignment: Qt.AlignHCenter + palette: colors + + onAfterRendering: { + userProfileAvatar.url = chat.model.avatarUrl(user_data.userId).replace("mxc://", "image://MxcImage/") + userProfileName.text = user_data.userName + matrixUserID.text = user_data.userId + console.log("this is happening"); + } + + background: Item{ + id: userProfileItem + width: userProfileDialog.width + height: userProfileDialog.height + anchors.margins: { + top:20 + } + + ColumnLayout{ + anchors.fill: userProfileItem + width: userProfileDialog.width + spacing: 10 + + Avatar{ + id: userProfileAvatar + height: 130 + width: 130 + displayName: modelData.userName + Layout.alignment: Qt.AlignHCenter + } + + Label{ + id: userProfileName + fontSizeMode: Text.HorizontalFit + Layout.alignment: Qt.AlignHCenter + } + + Label{ + id: matrixUserID + fontSizeMode: Text.HorizontalFit + Layout.alignment: Qt.AlignHCenter + } + + ScrollView { + implicitHeight: userProfileDialog.height/2+20 + implicitWidth: userProfileDialog.width-20 + clip: true + Layout.alignment: Qt.AlignHCenter + ScrollBar.horizontal.policy: ScrollBar.AlwaysOn + ScrollBar.vertical.policy: ScrollBar.AlwaysOn + + Label { + text: "ABC" + font.pixelSize: 700 + } + } + + Button{ + text:"OK" + onClicked: userProfileDialog.close() + anchors.margins: { + right:10 + bottom:10 + } + + Layout.alignment: Qt.AlignRight | Qt.AlignBottom + } + } + + Item { Layout.fillHeight: true } + } +} diff --git a/resources/res.qrc b/resources/res.qrc index ec086b3a..cb724dd3 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -126,6 +126,7 @@ qml/TimelineRow.qml qml/emoji/EmojiButton.qml qml/emoji/EmojiPicker.qml + qml/UserProfile.qml qml/delegates/MessageDelegate.qml qml/delegates/TextMessage.qml qml/delegates/NoticeMessage.qml diff --git a/src/Olm.cpp b/src/Olm.cpp index 994a3a67..494bc201 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp @@ -52,6 +52,11 @@ handle_to_device_messages(const std::vectorwarn("validation error for olm message: {} {}", e.what(), j_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)) { @@ -368,6 +373,10 @@ handle_key_request_message(const mtx::events::DeviceEventwarn("requested session not found in room: {}", req.content.room_id); + + nhlog::crypto()->warn("requested session not found in room: {}", + req.content.room_id); + return; } @@ -390,6 +399,13 @@ handle_key_request_message(const mtx::events::DeviceEventdebug("ignoring all key requests for room {}", + req.content.room_id); + + nhlog::crypto()->debug("ignoring all key requests for room {}", + req.content.room_id); + nhlog::crypto()->debug("ignoring all key requests for room {}", req.content.room_id); return; diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp new file mode 100644 index 00000000..ac35f1d4 --- /dev/null +++ b/src/ui/UserProfile.cpp @@ -0,0 +1,58 @@ +#include "UserProfile.h" +#include "Logging.h" +#include "MatrixClient.h" +#include "Utils.h" + +UserProfile::UserProfile(QObject *parent) + : QObject(parent) +{} + +QMap +UserProfile::getDeviceList() +{ + return this->deviceList; +} + +void +UserProfile::fetchDeviceList(const QString &userId) +{ + auto localUser = utils::localUser(); + mtx::requests::QueryKeys req; + req.device_keys[userId.toStdString()] = {}; + + http::client()->query_keys( + req, + [user_id = userId.toStdString()](const mtx::responses::QueryKeys &res, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to query device keys: {} {}", + err->matrix_error.error, + static_cast(err->status_code)); + return; + } + + if (res.device_keys.empty() || + (res.device_keys.find(user_id) == res.device_keys.end())) { + nhlog::net()->warn("no devices retrieved {}", user_id); + return; + } + + auto devices = res.device_keys.at(user_id); + + std::vector deviceInfo; + for (const auto &d : devices) { + auto device = d.second; + + // TODO: Verify signatures and ignore those that don't pass. + deviceInfo.emplace_back(DeviceInfo{ + QString::fromStdString(d.first), + QString::fromStdString(device.unsigned_info.device_display_name)}); + } + + std::sort(deviceInfo.begin(), + deviceInfo.end(), + [](const DeviceInfo &a, const DeviceInfo &b) { + return a.device_id > b.device_id; + }); + }); +} diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h new file mode 100644 index 00000000..d003e6ca --- /dev/null +++ b/src/ui/UserProfile.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +struct DeviceInfo +{ + QString device_id; + QString display_name; +}; + +class UserProfile : public QObject +{ + Q_OBJECT + Q_PROPERTY(QMap deviceList READ getDeviceList NOTIFY DeviceListUpdated) + +public: + explicit UserProfile(QObject *parent = 0); + QMap getDeviceList(); + + Q_INVOKABLE void fetchDeviceList(const QString &userID); + +signals: + void DeviceListUpdated(); + +private: + QMap deviceList; +}; \ No newline at end of file