Add avatar support.
This commit is contained in:
parent
6a610e3808
commit
d4c2a1ed50
10
main.cpp
10
main.cpp
|
@ -1,9 +1,12 @@
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
#include <QQmlContext>
|
||||||
|
|
||||||
#include "matrix/controller.h"
|
#include "matrix/controller.h"
|
||||||
#include "matrix/roomlistmodel.h"
|
#include "matrix/roomlistmodel.h"
|
||||||
|
#include "matrix/imageprovider.h"
|
||||||
|
|
||||||
using namespace QMatrixClient;
|
using namespace QMatrixClient;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -25,6 +28,13 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterType<RoomListModel>("Matrique", 0, 1, "RoomListModel");
|
qmlRegisterType<RoomListModel>("Matrique", 0, 1, "RoomListModel");
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
Connection* m_connection = new Connection();
|
||||||
|
ImageProvider* m_provider = new ImageProvider();
|
||||||
|
m_provider->setConnection(m_connection);
|
||||||
|
|
||||||
|
engine.rootContext()->setContextProperty("m_connection", m_connection);
|
||||||
|
engine.addImageProvider(QLatin1String("mxc"), m_provider);
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
|
||||||
if (engine.rootObjects().isEmpty())
|
if (engine.rootObjects().isEmpty())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -16,7 +16,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
matrix/controller.cpp \
|
matrix/controller.cpp \
|
||||||
matrix/roomlistmodel.cpp
|
matrix/roomlistmodel.cpp \
|
||||||
|
matrix/imageprovider.cpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
res.qrc
|
res.qrc
|
||||||
|
@ -48,4 +49,5 @@ DISTFILES += \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
matrix/controller.h \
|
matrix/controller.h \
|
||||||
matrix/roomlistmodel.h
|
matrix/roomlistmodel.h \
|
||||||
|
matrix/imageprovider.h
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
#include "libqmatrixclient/connection.h"
|
#include "libqmatrixclient/connection.h"
|
||||||
|
|
||||||
Controller::Controller(QObject *parent) : QObject(parent) {
|
Controller::Controller(QObject *parent) : QObject(parent) {
|
||||||
connect(m_connection, &QMatrixClient::Connection::connected, this, &Controller::connected);
|
|
||||||
connect(m_connection, &QMatrixClient::Connection::resolveError, this, &Controller::reconnect);
|
|
||||||
connect(m_connection, &QMatrixClient::Connection::syncError, this, &Controller::reconnect);
|
|
||||||
connect(m_connection, &QMatrixClient::Connection::syncDone, this, &Controller::resync);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::~Controller() {
|
Controller::~Controller() {
|
||||||
|
@ -31,6 +28,18 @@ void Controller::login(QString home, QString user, QString pass) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::setConnection(QMatrixClient::Connection* conn) {
|
||||||
|
qDebug() << "Setting controller connection.";
|
||||||
|
m_connection = conn;
|
||||||
|
roomListModel = new RoomListModel(m_connection);
|
||||||
|
emit roomListModelChanged();
|
||||||
|
connect(m_connection, &QMatrixClient::Connection::connected, this, &Controller::connected);
|
||||||
|
connect(m_connection, &QMatrixClient::Connection::resolveError, this, &Controller::reconnect);
|
||||||
|
connect(m_connection, &QMatrixClient::Connection::syncError, this, &Controller::reconnect);
|
||||||
|
connect(m_connection, &QMatrixClient::Connection::syncDone, this, &Controller::resync);
|
||||||
|
emit connectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::logout() {
|
void Controller::logout() {
|
||||||
userID = "";
|
userID = "";
|
||||||
token = "";
|
token = "";
|
||||||
|
|
|
@ -15,13 +15,11 @@ class Controller : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(RoomListModel *roomListModel READ getRoomListModel NOTIFY roomListModelChanged)
|
Q_PROPERTY(RoomListModel *roomListModel READ getRoomListModel NOTIFY roomListModelChanged)
|
||||||
|
Q_PROPERTY(QMatrixClient::Connection *connection READ getConnection WRITE setConnection NOTIFY connectionChanged)
|
||||||
Q_PROPERTY(bool isLogin READ getIsLogin WRITE setIsLogin NOTIFY isLoginChanged)
|
Q_PROPERTY(bool isLogin READ getIsLogin WRITE setIsLogin NOTIFY isLoginChanged)
|
||||||
Q_PROPERTY(QString userID READ getUserID WRITE setUserID NOTIFY userIDChanged)
|
Q_PROPERTY(QString userID READ getUserID WRITE setUserID NOTIFY userIDChanged)
|
||||||
Q_PROPERTY(QByteArray token READ getToken WRITE setToken NOTIFY tokenChanged)
|
Q_PROPERTY(QByteArray token READ getToken WRITE setToken NOTIFY tokenChanged)
|
||||||
|
|
||||||
private:
|
|
||||||
QMatrixClient::Connection* m_connection = new QMatrixClient::Connection();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Controller(QObject *parent = nullptr);
|
explicit Controller(QObject *parent = nullptr);
|
||||||
~Controller();
|
~Controller();
|
||||||
|
@ -33,9 +31,13 @@ public:
|
||||||
// All the non-Q_INVOKABLE functions.
|
// All the non-Q_INVOKABLE functions.
|
||||||
|
|
||||||
// All the Q_PROPERTYs.
|
// All the Q_PROPERTYs.
|
||||||
RoomListModel* roomListModel = new RoomListModel(m_connection);
|
RoomListModel* roomListModel;
|
||||||
RoomListModel* getRoomListModel() { return roomListModel; }
|
RoomListModel* getRoomListModel() { return roomListModel; }
|
||||||
|
|
||||||
|
QMatrixClient::Connection* m_connection;
|
||||||
|
QMatrixClient::Connection* getConnection() { return m_connection; }
|
||||||
|
void setConnection(QMatrixClient::Connection* conn);
|
||||||
|
|
||||||
bool isLogin = false;
|
bool isLogin = false;
|
||||||
bool getIsLogin() { return isLogin; }
|
bool getIsLogin() { return isLogin; }
|
||||||
void setIsLogin(bool n) {
|
void setIsLogin(bool n) {
|
||||||
|
@ -70,6 +72,7 @@ private:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void roomListModelChanged();
|
void roomListModelChanged();
|
||||||
|
void connectionChanged();
|
||||||
void isLoginChanged();
|
void isLoginChanged();
|
||||||
void userIDChanged();
|
void userIDChanged();
|
||||||
void tokenChanged();
|
void tokenChanged();
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include "imageprovider.h"
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
|
#include "jobs/mediathumbnailjob.h"
|
||||||
|
|
||||||
|
#include <QtCore/QWaitCondition>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QMetaObject>
|
||||||
|
|
||||||
|
using QMatrixClient::MediaThumbnailJob;
|
||||||
|
|
||||||
|
ImageProvider::ImageProvider(QObject *parent)
|
||||||
|
: QQuickImageProvider(QQmlImageProviderBase::Image,
|
||||||
|
QQmlImageProviderBase::ForceAsynchronousImageLoading)
|
||||||
|
{
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
|
||||||
|
qRegisterMetaType<MediaThumbnailJob*>();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ImageProvider::requestImage(const QString& id,
|
||||||
|
QSize* pSize, const QSize& requestedSize)
|
||||||
|
{
|
||||||
|
if (!id.startsWith("mxc://"))
|
||||||
|
{
|
||||||
|
qWarning() << "ImageProvider: won't fetch an invalid id:" << id
|
||||||
|
<< "doesn't follow server/mediaId pattern";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl mxcUri { id };
|
||||||
|
qDebug() << "ImageProvider::requestImage:" << mxcUri.toString();
|
||||||
|
|
||||||
|
MediaThumbnailJob* job = nullptr;
|
||||||
|
QReadLocker locker(&m_lock);
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||||
|
QMetaObject::invokeMethod(m_connection,
|
||||||
|
[=] { return m_connection->getThumbnail(mxcUri, requestedSize); },
|
||||||
|
Qt::BlockingQueuedConnection, &job);
|
||||||
|
#else
|
||||||
|
QMetaObject::invokeMethod(m_connection, "getThumbnail",
|
||||||
|
Qt::BlockingQueuedConnection, Q_RETURN_ARG(MediaThumbnailJob*, job),
|
||||||
|
Q_ARG(QUrl, mxcUri), Q_ARG(QSize, requestedSize));
|
||||||
|
#endif
|
||||||
|
if (!job)
|
||||||
|
{
|
||||||
|
qDebug() << "ImageProvider: failed to send a request";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
QImage result;
|
||||||
|
{
|
||||||
|
QWaitCondition condition; // The most compact way to block on a signal
|
||||||
|
job->connect(job, &MediaThumbnailJob::finished, job, [&] {
|
||||||
|
result = job->thumbnail();
|
||||||
|
condition.wakeAll();
|
||||||
|
});
|
||||||
|
condition.wait(&m_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pSize != nullptr )
|
||||||
|
*pSize = result.size();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageProvider::setConnection(QMatrixClient::Connection* connection)
|
||||||
|
{
|
||||||
|
QWriteLocker locker(&m_lock);
|
||||||
|
|
||||||
|
m_connection = connection;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef IMAGEPROVIDER_H
|
||||||
|
#define IMAGEPROVIDER_H
|
||||||
|
|
||||||
|
#include <QtQuick/QQuickImageProvider>
|
||||||
|
#include <QtCore/QReadWriteLock>
|
||||||
|
|
||||||
|
namespace QMatrixClient {
|
||||||
|
class Connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImageProvider: public QQuickImageProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ImageProvider(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QImage requestImage(const QString& id, QSize* pSize,
|
||||||
|
const QSize& requestedSize) override;
|
||||||
|
|
||||||
|
void setConnection(QMatrixClient::Connection* connection);
|
||||||
|
|
||||||
|
void initializeEngine(QQmlEngine *engine, const char *uri);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMatrixClient::Connection* m_connection;
|
||||||
|
QReadWriteLock m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGEPROVIDER_H
|
|
@ -53,8 +53,8 @@ QVariant RoomListModel::data(const QModelIndex& index, int role) const {
|
||||||
if(role == ValueRole) {
|
if(role == ValueRole) {
|
||||||
return room->topic();
|
return room->topic();
|
||||||
}
|
}
|
||||||
if(role == IconRole) {
|
if(role == AvatarRole) {
|
||||||
return room->avatar(48);
|
return room->avatarUrl();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const {
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles[NameRole] = "name";
|
roles[NameRole] = "name";
|
||||||
roles[ValueRole] = "value";
|
roles[ValueRole] = "value";
|
||||||
roles[IconRole] = "icon";
|
roles[AvatarRole] = "avatar";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,3 @@ void RoomListModel::namesChanged(QMatrixClient::Room* room) {
|
||||||
void RoomListModel::unreadMessagesChanged(QMatrixClient::Room* room) {
|
void RoomListModel::unreadMessagesChanged(QMatrixClient::Room* room) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RoomModel::RoomModel(QString name, QString value) {
|
|
||||||
m_name = name;
|
|
||||||
m_value = value;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,28 +12,6 @@ namespace QMatrixClient {
|
||||||
class Room;
|
class Room;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RoomModel : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
Q_PROPERTY(QString name READ getName)
|
|
||||||
Q_PROPERTY(QString value READ getValue)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit RoomModel(QString name, QString value);
|
|
||||||
|
|
||||||
QString getName() { return m_name; }
|
|
||||||
QString getValue() { return m_value; }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void nameChanged();
|
|
||||||
void valueChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_name;
|
|
||||||
QString m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RoomListModel : public QAbstractListModel
|
class RoomListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -43,7 +21,7 @@ public:
|
||||||
~RoomListModel();
|
~RoomListModel();
|
||||||
|
|
||||||
enum RoomModelRoles {
|
enum RoomModelRoles {
|
||||||
NameRole, ValueRole, IconRole
|
NameRole, ValueRole, AvatarRole
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<int, QByteArray> roleNames() const;
|
QHash<int, QByteArray> roleNames() const;
|
||||||
|
|
|
@ -81,6 +81,7 @@ Item {
|
||||||
Text {
|
Text {
|
||||||
z: 10
|
z: 10
|
||||||
text: "Here? No, not here."
|
text: "Here? No, not here."
|
||||||
|
color: "#424242"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: listView.count === 0
|
visible: listView.count === 0
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ Item {
|
||||||
ImageStatus {
|
ImageStatus {
|
||||||
width: parent.height
|
width: parent.height
|
||||||
height: parent.height
|
height: parent.height
|
||||||
source: "qrc:/asset/img/avatar.png"
|
source: "image://mxc/" + avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
19
qml/main.qml
19
qml/main.qml
|
@ -18,17 +18,16 @@ ApplicationWindow {
|
||||||
title: qsTr("Matrique")
|
title: qsTr("Matrique")
|
||||||
|
|
||||||
Controller {
|
Controller {
|
||||||
id: controller
|
id: matrixController
|
||||||
|
connection: m_connection
|
||||||
onIsLoginChanged: console.log("Status:", isLogin)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings {
|
// Settings {
|
||||||
id: settings
|
// id: settings
|
||||||
|
|
||||||
property alias userID: controller.userID
|
// property var userID
|
||||||
property alias token: controller.token
|
// property var token
|
||||||
}
|
// }
|
||||||
|
|
||||||
FontLoader { id: materialFont; source: "qrc:/asset/font/material.ttf" }
|
FontLoader { id: materialFont; source: "qrc:/asset/font/material.ttf" }
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ ApplicationWindow {
|
||||||
|
|
||||||
page: Room {
|
page: Room {
|
||||||
id: roomPage
|
id: roomPage
|
||||||
roomListModel: controller.roomListModel
|
roomListModel: matrixController.roomListModel//BUG: It will cause random crash as roomListModel may not be initialized.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ ApplicationWindow {
|
||||||
|
|
||||||
page: Login {
|
page: Login {
|
||||||
id: loginPage
|
id: loginPage
|
||||||
controller: controller
|
controller: matrixController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue