mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Add jdenticon support
This commit is contained in:
parent
e88ab89c18
commit
d2e193ff78
11 changed files with 176 additions and 31 deletions
|
@ -345,6 +345,7 @@ set(SRC_FILES
|
|||
src/DeviceVerificationFlow.cpp
|
||||
src/EventAccessors.cpp
|
||||
src/InviteesModel.cpp
|
||||
src/JdenticonProvider.cpp
|
||||
src/Logging.cpp
|
||||
src/LoginPage.cpp
|
||||
src/MainWindow.cpp
|
||||
|
@ -557,6 +558,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
|||
src/DeviceVerificationFlow.h
|
||||
src/ImagePackListModel.h
|
||||
src/InviteesModel.h
|
||||
src/JdenticonProvider.h
|
||||
src/LoginPage.h
|
||||
src/MainWindow.h
|
||||
src/MemberList.h
|
||||
|
|
|
@ -35,10 +35,17 @@ Rectangle {
|
|||
font.pixelSize: avatar.height / 2
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: img.status != Image.Ready
|
||||
visible: img.status != Image.Ready && !Settings.useIdenticon
|
||||
color: Nheko.colors.text
|
||||
}
|
||||
|
||||
Image {
|
||||
id: identicon
|
||||
anchors.fill: parent
|
||||
visible: img.status != Image.Ready && Settings.useIdenticon
|
||||
source: "image://jdenticon/" + userid
|
||||
}
|
||||
|
||||
Image {
|
||||
id: img
|
||||
|
||||
|
|
68
src/JdenticonProvider.cpp
Normal file
68
src/JdenticonProvider.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "JdenticonProvider.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
#include <QPluginLoader>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
#include <mtxclient/crypto/client.hpp>
|
||||
|
||||
#include "Cache.h"
|
||||
#include "Logging.h"
|
||||
#include "MatrixClient.h"
|
||||
#include "Utils.h"
|
||||
#include "jdenticoninterface.h"
|
||||
|
||||
JdenticonResponse::JdenticonResponse(const QString &key, const QSize &requestedSize)
|
||||
: m_key(key)
|
||||
, m_requestedSize(requestedSize.isValid() ? requestedSize : QSize(100, 100))
|
||||
, m_pixmap{m_requestedSize}
|
||||
, jdenticonInterface_{Jdenticon::getJdenticonInterface()}
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
void
|
||||
JdenticonResponse::run()
|
||||
{
|
||||
m_pixmap.fill(Qt::transparent);
|
||||
QPainter painter{&m_pixmap};
|
||||
QSvgRenderer renderer{
|
||||
jdenticonInterface_->generate(m_key, m_requestedSize.width()).toUtf8()};
|
||||
// m_image = QImage::fromData(jdenticonInterface_->generate(m_key,
|
||||
// size->width()).toUtf8());
|
||||
renderer.render(&painter);
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
namespace Jdenticon {
|
||||
JdenticonInterface *
|
||||
getJdenticonInterface()
|
||||
{
|
||||
static JdenticonInterface *interface = nullptr;
|
||||
|
||||
if (interface == nullptr) {
|
||||
QDir pluginsDir(qApp->applicationDirPath());
|
||||
|
||||
bool plugins = pluginsDir.cd("plugins");
|
||||
if (plugins) {
|
||||
for (QString fileName : pluginsDir.entryList(QDir::Files)) {
|
||||
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
|
||||
QObject *plugin = pluginLoader.instance();
|
||||
if (plugin) {
|
||||
interface = qobject_cast<JdenticonInterface *>(plugin);
|
||||
if (interface) {
|
||||
nhlog::ui()->info("Loaded jdenticon plugin.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
nhlog::ui()->info("jdenticon plugin not found.");
|
||||
}
|
||||
|
||||
return interface;
|
||||
}
|
||||
}
|
59
src/JdenticonProvider.h
Normal file
59
src/JdenticonProvider.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include <QImage>
|
||||
#include <QQuickAsyncImageProvider>
|
||||
#include <QQuickImageResponse>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <mtx/common.hpp>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "jdenticoninterface.h"
|
||||
|
||||
namespace Jdenticon {
|
||||
JdenticonInterface *
|
||||
getJdenticonInterface();
|
||||
}
|
||||
|
||||
class JdenticonResponse
|
||||
: public QQuickImageResponse
|
||||
, public QRunnable
|
||||
{
|
||||
public:
|
||||
JdenticonResponse(const QString &key, const QSize &requestedSize);
|
||||
|
||||
QQuickTextureFactory *textureFactory() const override
|
||||
{
|
||||
return QQuickTextureFactory::textureFactoryForImage(m_pixmap.toImage());
|
||||
}
|
||||
|
||||
void run() override;
|
||||
|
||||
QString m_key;
|
||||
QSize m_requestedSize;
|
||||
QPixmap m_pixmap;
|
||||
JdenticonInterface *jdenticonInterface_ = nullptr;
|
||||
};
|
||||
|
||||
class JdenticonProvider
|
||||
: public QObject
|
||||
, public QQuickAsyncImageProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static bool isAvailable() { return Jdenticon::getJdenticonInterface() != nullptr; }
|
||||
|
||||
public slots:
|
||||
QQuickImageResponse *requestImageResponse(const QString &key,
|
||||
const QSize &requestedSize) override
|
||||
{
|
||||
JdenticonResponse *response = new JdenticonResponse(key, requestedSize);
|
||||
pool.start(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private:
|
||||
QThreadPool pool;
|
||||
};
|
|
@ -16,6 +16,7 @@
|
|||
#include "Cache_p.h"
|
||||
#include "ChatPage.h"
|
||||
#include "Config.h"
|
||||
#include "JdenticonProvider.h"
|
||||
#include "Logging.h"
|
||||
#include "LoginPage.h"
|
||||
#include "MainWindow.h"
|
||||
|
@ -152,10 +153,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
showChatPage();
|
||||
}
|
||||
});
|
||||
|
||||
if (loadJdenticonPlugin()) {
|
||||
nhlog::ui()->info("loaded jdenticon.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -428,29 +425,6 @@ MainWindow::showDialog(QWidget *dialog)
|
|||
dialog->show();
|
||||
}
|
||||
|
||||
bool
|
||||
MainWindow::loadJdenticonPlugin()
|
||||
{
|
||||
QDir pluginsDir(qApp->applicationDirPath());
|
||||
|
||||
bool plugins = pluginsDir.cd("plugins");
|
||||
if (plugins) {
|
||||
foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
|
||||
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
|
||||
QObject *plugin = pluginLoader.instance();
|
||||
if (plugin) {
|
||||
jdenticonInteface_ = qobject_cast<JdenticonInterface *>(plugin);
|
||||
if (jdenticonInteface_) {
|
||||
nhlog::ui()->info("Found jdenticon plugin.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nhlog::ui()->info("jdenticon plugin not found.");
|
||||
return false;
|
||||
}
|
||||
void
|
||||
MainWindow::showWelcomePage()
|
||||
{
|
||||
|
|
|
@ -137,6 +137,4 @@ private:
|
|||
//! Overlay modal used to project other widgets.
|
||||
OverlayModal *modal_ = nullptr;
|
||||
LoadingIndicator *spinner_ = nullptr;
|
||||
|
||||
JdenticonInterface *jdenticonInteface_ = nullptr;
|
||||
};
|
||||
|
|
|
@ -86,6 +86,7 @@ UserSettings::load(std::optional<QString> profile)
|
|||
theme_ = settings.value("user/theme", defaultTheme_).toString();
|
||||
font_ = settings.value("user/font_family", "default").toString();
|
||||
avatarCircles_ = settings.value("user/avatar_circles", true).toBool();
|
||||
useIdenticon_ = settings.value("user/use_identicon", true).toBool();
|
||||
decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool();
|
||||
privacyScreen_ = settings.value("user/privacy_screen", false).toBool();
|
||||
privacyScreenTimeout_ = settings.value("user/privacy_screen_timeout", 0).toInt();
|
||||
|
@ -596,6 +597,15 @@ UserSettings::setDisableCertificateValidation(bool disabled)
|
|||
disableCertificateValidation_ = disabled;
|
||||
http::client()->verify_certificates(!disabled);
|
||||
emit disableCertificateValidationChanged(disabled);
|
||||
}
|
||||
|
||||
void
|
||||
UserSettings::setUseIdenticon(bool state)
|
||||
{
|
||||
if (state == useIdenticon_)
|
||||
return;
|
||||
useIdenticon_ = state;
|
||||
emit useIdenticonChanged(useIdenticon_);
|
||||
save();
|
||||
}
|
||||
|
||||
|
@ -674,6 +684,7 @@ UserSettings::save()
|
|||
settings.setValue("screen_share_hide_cursor", screenShareHideCursor_);
|
||||
settings.setValue("use_stun_server", useStunServer_);
|
||||
settings.setValue("currentProfile", profile_);
|
||||
settings.setValue("use_identicon", useIdenticon_);
|
||||
|
||||
settings.endGroup(); // user
|
||||
|
||||
|
@ -746,6 +757,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
trayToggle_ = new Toggle{this};
|
||||
startInTrayToggle_ = new Toggle{this};
|
||||
avatarCircles_ = new Toggle{this};
|
||||
useIdenticon_ = new Toggle{this};
|
||||
decryptSidebar_ = new Toggle(this);
|
||||
privacyScreen_ = new Toggle{this};
|
||||
onlyShareKeysWithVerifiedUsers_ = new Toggle(this);
|
||||
|
@ -779,6 +791,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
trayToggle_->setChecked(settings_->tray());
|
||||
startInTrayToggle_->setChecked(settings_->startInTray());
|
||||
avatarCircles_->setChecked(settings_->avatarCircles());
|
||||
useIdenticon_->setChecked(settings_->useIdenticon());
|
||||
decryptSidebar_->setChecked(settings_->decryptSidebar());
|
||||
privacyScreen_->setChecked(settings_->privacyScreen());
|
||||
onlyShareKeysWithVerifiedUsers_->setChecked(settings_->onlyShareKeysWithVerifiedUsers());
|
||||
|
@ -941,6 +954,12 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
boxWrap(tr("Circular Avatars"),
|
||||
avatarCircles_,
|
||||
tr("Change the appearance of user avatars in chats.\nOFF - square, ON - Circle."));
|
||||
if (JdenticonProvider::isAvailable())
|
||||
boxWrap(
|
||||
tr("Use identicons"),
|
||||
useIdenticon_,
|
||||
tr(
|
||||
"Display an identicon instead of a letter when a user has not set an avatar."));
|
||||
boxWrap(tr("Group's sidebar"),
|
||||
groupViewToggle_,
|
||||
tr("Show a column containing groups and tags next to the room list."));
|
||||
|
@ -1263,6 +1282,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
settings_->setAvatarCircles(enabled);
|
||||
});
|
||||
|
||||
connect(useIdenticon_, &Toggle::toggled, this, [this](bool enabled) {
|
||||
settings_->setUseIdenticon(enabled);
|
||||
});
|
||||
|
||||
connect(markdown_, &Toggle::toggled, this, [this](bool enabled) {
|
||||
settings_->setMarkdown(enabled);
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <QSharedPointer>
|
||||
#include <QWidget>
|
||||
|
||||
#include "JdenticonProvider.h"
|
||||
#include <optional>
|
||||
|
||||
class Toggle;
|
||||
|
@ -105,6 +106,8 @@ class UserSettings : public QObject
|
|||
Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)
|
||||
Q_PROPERTY(bool disableCertificateValidation READ disableCertificateValidation WRITE
|
||||
setDisableCertificateValidation NOTIFY disableCertificateValidationChanged)
|
||||
Q_PROPERTY(
|
||||
bool useIdenticon READ useIdenticon WRITE setUseIdenticon NOTIFY useIdenticonChanged)
|
||||
|
||||
UserSettings();
|
||||
|
||||
|
@ -172,6 +175,7 @@ public:
|
|||
void setHomeserver(QString homeserver);
|
||||
void setDisableCertificateValidation(bool disabled);
|
||||
void setHiddenTags(QStringList hiddenTags);
|
||||
void setUseIdenticon(bool state);
|
||||
|
||||
QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; }
|
||||
bool messageHoverHighlight() const { return messageHoverHighlight_; }
|
||||
|
@ -230,6 +234,7 @@ public:
|
|||
QString homeserver() const { return homeserver_; }
|
||||
bool disableCertificateValidation() const { return disableCertificateValidation_; }
|
||||
QStringList hiddenTags() const { return hiddenTags_; }
|
||||
bool useIdenticon() const { return useIdenticon_ && JdenticonProvider::isAvailable(); }
|
||||
|
||||
signals:
|
||||
void groupViewStateChanged(bool state);
|
||||
|
@ -277,6 +282,7 @@ signals:
|
|||
void deviceIdChanged(QString deviceId);
|
||||
void homeserverChanged(QString homeserver);
|
||||
void disableCertificateValidationChanged(bool disabled);
|
||||
void useIdenticonChanged(bool state);
|
||||
|
||||
private:
|
||||
// Default to system theme if QT_QPA_PLATFORMTHEME var is set.
|
||||
|
@ -330,6 +336,7 @@ private:
|
|||
QString deviceId_;
|
||||
QString homeserver_;
|
||||
QStringList hiddenTags_;
|
||||
bool useIdenticon_;
|
||||
|
||||
QSettings settings;
|
||||
|
||||
|
@ -391,6 +398,7 @@ private:
|
|||
Toggle *desktopNotifications_;
|
||||
Toggle *alertOnNotification_;
|
||||
Toggle *avatarCircles_;
|
||||
Toggle *useIdenticon_;
|
||||
Toggle *useStunServer_;
|
||||
Toggle *decryptSidebar_;
|
||||
Toggle *privacyScreen_;
|
||||
|
|
|
@ -141,6 +141,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
|
|||
, imgProvider(new MxcImageProvider())
|
||||
, colorImgProvider(new ColorImageProvider())
|
||||
, blurhashProvider(new BlurhashProvider())
|
||||
, jdenticonProvider(new JdenticonProvider())
|
||||
, callManager_(callManager)
|
||||
, rooms_(new RoomlistModel(this))
|
||||
, communities_(new CommunitiesModel(this))
|
||||
|
@ -310,6 +311,8 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
|
|||
view->engine()->addImageProvider("MxcImage", imgProvider);
|
||||
view->engine()->addImageProvider("colorimage", colorImgProvider);
|
||||
view->engine()->addImageProvider("blurhash", blurhashProvider);
|
||||
if (JdenticonProvider::isAvailable())
|
||||
view->engine()->addImageProvider("jdenticon", jdenticonProvider);
|
||||
view->setSource(QUrl("qrc:///qml/Root.qml"));
|
||||
|
||||
connect(parent, &ChatPage::themeChanged, this, &TimelineViewManager::updateColorPalette);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Cache.h"
|
||||
#include "CallManager.h"
|
||||
#include "JdenticonProvider.h"
|
||||
#include "Logging.h"
|
||||
#include "TimelineModel.h"
|
||||
#include "Utils.h"
|
||||
|
@ -141,6 +142,7 @@ private:
|
|||
MxcImageProvider *imgProvider;
|
||||
ColorImageProvider *colorImgProvider;
|
||||
BlurhashProvider *blurhashProvider;
|
||||
JdenticonProvider *jdenticonProvider;
|
||||
|
||||
CallManager *callManager_ = nullptr;
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ namespace ui {
|
|||
enum class AvatarType
|
||||
{
|
||||
Image,
|
||||
Letter
|
||||
Letter,
|
||||
Jdenticon
|
||||
};
|
||||
|
||||
// Default font size.
|
||||
|
|
Loading…
Reference in a new issue