diff --git a/CMakeLists.txt b/CMakeLists.txt
index e170495a..654eae37 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -277,6 +277,7 @@ set(SRC_FILES
src/ui/Theme.cpp
src/ui/ThemeManager.cpp
src/ui/UserProfile.cpp
+ src/ui/UserProfileModel.cpp
src/AvatarProvider.cpp
src/BlurhashProvider.cpp
@@ -482,6 +483,7 @@ qt5_wrap_cpp(MOC_HEADERS
src/ui/Theme.h
src/ui/ThemeManager.h
src/ui/UserProfile.h
+ src/ui/UserProfileModel.h
src/notifications/Manager.h
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index ed403aa9..e4c820f8 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -273,6 +273,9 @@ Page {
color: colors.base
}
}
+
+ property variant userProfile
+
Row {
height: userName.height
spacing: 8
@@ -287,8 +290,10 @@ Page {
MouseArea {
anchors.fill: parent
onClicked: {
- userProfile.user_data = modelData
- userProfile.show()
+ if(userProfile) userProfile.destroy()
+ var component = Qt.createComponent("UserProfile.qml");
+ userProfile = component.createObject(timelineRoot,{user_data : modelData});
+ userProfile.show();
}
cursorShape: Qt.PointingHandCursor
propagateComposedEvents: true
@@ -303,26 +308,17 @@ Page {
MouseArea {
anchors.fill: parent
+ Layout.alignment: Qt.AlignHCenter
onClicked: {
- userProfile.user_data = modelData
- userProfile.show()
+ if(userProfile) userProfile.destroy()
+ var component = Qt.createComponent("UserProfile.qml")
+ userProfile = component.createObject(timelineRoot,{user_data : modelData})
+ userProfile.show()
}
cursorShape: Qt.PointingHandCursor
propagateComposedEvents: true
}
}
-
- Label {
- color: colors.buttonText
- text: timelineManager.userStatus(modelData.userId)
- textFormat: Text.PlainText
- elide: Text.ElideRight
- 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
index ae91abc4..f29fb4c1 100644
--- a/resources/qml/UserProfile.qml
+++ b/resources/qml/UserProfile.qml
@@ -16,25 +16,16 @@ ApplicationWindow{
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
- userProfile.userId = user_data.userId
- log_devices()
- }
-
- function log_devices()
- {
- console.log(userProfile.deviceList);
- userProfile.deviceList.forEach((item,index)=>{
- console.log(item.device_id)
- console.log(item.display_name)
- })
- }
-
- UserProfileContent{
- id: userProfile
+ UserProfileList{
+ id: userProfileList
+ userId: user_data.userId
+ onUserIdChanged : {
+ console.log(userId)
+ userProfileList.updateDeviceList()
+ }
+ onDeviceListUpdated : {
+ modelDeviceList.deviceList = userProfileList
+ }
}
background: Item{
@@ -52,6 +43,7 @@ ApplicationWindow{
Avatar{
id: userProfileAvatar
+ url:chat.model.avatarUrl(user_data.userId).replace("mxc://", "image://MxcImage/")
height: 130
width: 130
displayName: modelData.userName
@@ -60,12 +52,14 @@ ApplicationWindow{
Label{
id: userProfileName
+ text: user_data.userName
fontSizeMode: Text.HorizontalFit
Layout.alignment: Qt.AlignHCenter
}
Label{
id: matrixUserID
+ text: user_data.userId
fontSizeMode: Text.HorizontalFit
Layout.alignment: Qt.AlignHCenter
}
@@ -78,9 +72,29 @@ ApplicationWindow{
ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
- Label {
- text: "ABC"
- font.pixelSize: 700
+ ListView{
+ id: deviceList
+ anchors.fill: parent
+ clip: true
+ spacing: 10
+
+ model: UserProfileModel{
+ id: modelDeviceList
+ }
+
+ delegate: RowLayout{
+ width: parent.width
+ Text{
+ Layout.fillWidth: true
+ color: colors.text
+ text: deviceID
+ }
+ Text{
+ Layout.fillWidth: true
+ color:colors.text
+ text: displayName
+ }
+ }
}
}
diff --git a/src/Olm.cpp b/src/Olm.cpp
index 494bc201..74fbac9a 100644
--- a/src/Olm.cpp
+++ b/src/Olm.cpp
@@ -56,7 +56,6 @@ handle_to_device_messages(const std::vector<mtx::events::collections::DeviceEven
nhlog::crypto()->warn("validation error for olm message: {} {}",
e.what(),
j_msg.dump(2));
-
}
} else if (msg_type == to_string(mtx::events::EventType::RoomKeyRequest)) {
@@ -399,7 +398,6 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR
}
if (!utils::respondsToKeyRequests(req.content.room_id)) {
-
nhlog::crypto()->debug("ignoring all key requests for room {}",
req.content.room_id);
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 227b410f..f4d1c00e 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -3,6 +3,7 @@
#include <QMetaType>
#include <QPalette>
#include <QQmlContext>
+#include <QQmlEngine>
#include "BlurhashProvider.h"
#include "ChatPage.h"
@@ -16,6 +17,8 @@
#include "emoji/EmojiModel.h"
#include "emoji/Provider.h"
#include "../ui/UserProfile.h"
+#include "src/ui/UserProfile.h"
+#include "src/ui/UserProfileModel.h"
Q_DECLARE_METATYPE(mtx::events::collections::TimelineEvents)
@@ -87,8 +90,9 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
qmlRegisterType<DeviceVerificationFlow>("im.nheko", 1, 0, "DeviceVerificationFlow");
- qmlRegisterType<UserProfile>("im.nheko",1,0,"UserProfileContent");
- qRegisterMetaType<DeviceInfo>();
+ qmlRegisterType<UserProfileModel>("im.nheko", 1, 0, "UserProfileModel");
+ qmlRegisterType<UserProfile>("im.nheko", 1, 0, "UserProfileList");
+
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
qmlRegisterType<emoji::EmojiProxyModel>("im.nheko.EmojiModel", 1, 0, "EmojiProxyModel");
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index 30785699..588d6969 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -2,29 +2,32 @@
#include "Logging.h"
#include "Utils.h"
#include "mtx/responses/crypto.hpp"
-#include <iostream>
UserProfile::UserProfile(QObject *parent)
: QObject(parent)
{}
QVector<DeviceInfo>
-UserProfile::getDeviceList(){
- UserProfile::fetchDeviceList(this->userId);
+UserProfile::getDeviceList()
+{
return this->deviceList;
}
QString
-UserProfile::getUserId (){
+UserProfile::getUserId()
+{
return this->userId;
}
void
-UserProfile::setUserId (const QString &user_id){
- if(this->userId != userId)
+UserProfile::setUserId(const QString &user_id)
+{
+ if (this->userId != userId)
return;
- else
+ else {
this->userId = user_id;
+ emit UserProfile::userIdChanged();
+ }
}
void
@@ -37,11 +40,11 @@ UserProfile::fetchDeviceList(const QString &userID)
http::client()->query_keys(
req,
- [user_id = userID.toStdString(),this](const mtx::responses::QueryKeys &res,
- mtx::http::RequestErr err) {
+ [user_id = userID.toStdString(), this](const mtx::responses::QueryKeys &res,
+ mtx::http::RequestErr err) {
if (err) {
- nhlog::net()->warn("failed to query device keys: {} {}",
- err->matrix_error.error,
+ nhlog::net()->warn("failed to query device keys: {},{}",
+ err->matrix_error.errcode,
static_cast<int>(err->status_code));
return;
}
@@ -53,17 +56,16 @@ UserProfile::fetchDeviceList(const QString &userID)
}
auto devices = res.device_keys.at(user_id);
-
QVector<DeviceInfo> deviceInfo;
+
for (const auto &d : devices) {
auto device = d.second;
// TODO: Verify signatures and ignore those that don't pass.
- // std::cout<<d.first<<std::endl;
- // std::cout<<device.unsigned_info.device_display_name<<std::endl;
- DeviceInfo newdevice(QString::fromStdString(d.first),QString::fromStdString(device.unsigned_info.device_display_name))
- newdevice->device_id = QString::fromStdString(d.first);
- newdevice->display_name = QString::fromStdString(device.unsigned_info.device_display_name)
+ DeviceInfo newdevice(
+ QString::fromStdString(d.first),
+ QString::fromStdString(device.unsigned_info.device_display_name));
+ QString::fromStdString(device.unsigned_info.device_display_name);
deviceInfo.append(std::move(newdevice));
}
@@ -74,7 +76,13 @@ UserProfile::fetchDeviceList(const QString &userID)
return a.device_id > b.device_id;
});
- this->deviceList = deviceInfo;
- emit UserProfile::deviceListUpdated();
+ this->deviceList = std::move(deviceInfo);
+ emit UserProfile::deviceListUpdated();
});
}
+
+void
+UserProfile::updateDeviceList()
+{
+ fetchDeviceList(this->userId);
+}
diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h
index bbf57c7b..c37e23ae 100644
--- a/src/ui/UserProfile.h
+++ b/src/ui/UserProfile.h
@@ -2,33 +2,29 @@
#include <QObject>
#include <QString>
+#include <QVector>
#include "MatrixClient.h"
class DeviceInfo
{
public:
- explicit DeviceInfo(QString device_id,QString display_name){
- this->device_id = device_id;
- this->display_name = display_name;
- }
- ~DeviceInfo() = default;
- DeviceInfo(const DeviceInfo &device){
- this->device_id = device.device_id;
- this->display_name = device.display_name;
- }
+ DeviceInfo(const QString deviceID, const QString displayName)
+ : device_id(deviceID)
+ , display_name(displayName)
+ {}
+
+ DeviceInfo() {}
QString device_id;
QString display_name;
};
-Q_DECLARE_METATYPE(DeviceInfo);
class UserProfile : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString userId READ getUserId WRITE setUserId NOTIFY userIdChanged)
Q_PROPERTY(QVector<DeviceInfo> deviceList READ getDeviceList NOTIFY deviceListUpdated)
- Q_PROPERTY(QString userId READ getUserId WRITE setUserId)
-
public:
// constructor
explicit UserProfile(QObject *parent = 0);
@@ -39,8 +35,10 @@ public:
void setUserId(const QString &userId);
Q_INVOKABLE void fetchDeviceList(const QString &userID);
+ Q_INVOKABLE void updateDeviceList();
signals:
+ void userIdChanged();
void deviceListUpdated();
private:
diff --git a/src/ui/UserProfileModel.cpp b/src/ui/UserProfileModel.cpp
new file mode 100644
index 00000000..ec0456cd
--- /dev/null
+++ b/src/ui/UserProfileModel.cpp
@@ -0,0 +1,66 @@
+#include "UserProfileModel.h"
+#include "UserProfile.h"
+#include <QModelIndex>
+
+UserProfileModel::UserProfileModel(QObject *parent)
+ : QAbstractListModel(parent)
+ , deviceList(nullptr)
+{}
+
+int
+UserProfileModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid() || !this->deviceList)
+ return 0;
+ return this->deviceList->getDeviceList().size();
+}
+
+QVariant
+UserProfileModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid() || !this->deviceList)
+ return QVariant();
+
+ const DeviceInfo device = this->deviceList->getDeviceList().at(index.row());
+ switch (role) {
+ case DEVICEID:
+ return QVariant(device.device_id);
+ case DISPLAYNAME:
+ return QVariant(device.display_name);
+ }
+ return QVariant();
+}
+
+QHash<int, QByteArray>
+UserProfileModel::roleNames() const
+{
+ QHash<int, QByteArray> names;
+ names[DEVICEID] = "deviceID";
+ names[DISPLAYNAME] = "displayName";
+ return names;
+}
+
+UserProfile *
+UserProfileModel::getList() const
+{
+ return (this->deviceList);
+}
+
+void
+UserProfileModel::setList(UserProfile *devices)
+{
+ beginResetModel();
+
+ if (devices)
+ devices->disconnect(this);
+
+ if (this->deviceList) {
+ const int index = this->deviceList->getDeviceList().size();
+ beginInsertRows(QModelIndex(), index, index);
+ endInsertRows();
+ }
+
+ this->deviceList = devices;
+
+ endResetModel();
+}
\ No newline at end of file
diff --git a/src/ui/UserProfileModel.h b/src/ui/UserProfileModel.h
new file mode 100644
index 00000000..c21a806d
--- /dev/null
+++ b/src/ui/UserProfileModel.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <QAbstractListModel>
+
+class UserProfile; // forward declaration of the class UserProfile
+
+class UserProfileModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(UserProfile *deviceList READ getList WRITE setList)
+
+public:
+ explicit UserProfileModel(QObject *parent = nullptr);
+
+ enum
+ {
+ DEVICEID,
+ DISPLAYNAME
+ };
+ UserProfile *getList() const;
+ void setList(UserProfile *devices);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ virtual QHash<int, QByteArray> roleNames() const override;
+
+private:
+ UserProfile *deviceList;
+};
\ No newline at end of file
|