diff --git a/tools/chatgui/src/avatars/avatarmanager.cpp b/tools/chatgui/src/avatars/avatarmanager.cpp index 28f13374..e56efd3e 100644 --- a/tools/chatgui/src/avatars/avatarmanager.cpp +++ b/tools/chatgui/src/avatars/avatarmanager.cpp @@ -45,7 +45,7 @@ AvatarManager::~AvatarManager() { } void AvatarManager::initialize() { - if (!m_db || !m_db->isOpen() || m_ready || !m_directory.isEmpty()) return; + if (!m_db || !m_db->isOpen() || !m_db->myNodeId() || m_ready || !m_directory.isEmpty()) return; const QString base = m_db->dbPath().isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) : m_db->dbPath(); m_directory = base + QStringLiteral("/avatar_cache/") + QString::number(m_db->myNodeId(), 16); m_defaultServer = m_db->getUiState("avatar_default_server").toULongLong(nullptr, 16); diff --git a/tools/chatgui/src/memberlistmodel.cpp b/tools/chatgui/src/memberlistmodel.cpp index ef4b91e7..93a2f156 100644 --- a/tools/chatgui/src/memberlistmodel.cpp +++ b/tools/chatgui/src/memberlistmodel.cpp @@ -3,6 +3,7 @@ #include "avatars/avatarmanager.h" #include "../transport/gui_bridge.h" #include +#include #include #include #include diff --git a/tools/chatgui/src/settingsdialog.cpp b/tools/chatgui/src/settingsdialog.cpp index 58130d64..d1eaa8a8 100644 --- a/tools/chatgui/src/settingsdialog.cpp +++ b/tools/chatgui/src/settingsdialog.cpp @@ -9,6 +9,7 @@ #include "audiodevicesettingspage.h" #include "storagesettingspage.h" #include "radiosettingspage.h" +#include "avatars/avatarmanager.h" #include "ptt_hotkey_manager.h" #include "connmonitorwindow.h" #include "../transport/gui_bridge.h" @@ -31,6 +32,7 @@ extern "C" { #include #include #include +#include SettingsDialog::SettingsDialog(const QString& configPath, DbManager* db, UtunNode* node, AudioRecorder* recorder, QWidget* parent) @@ -86,6 +88,40 @@ SettingsDialog::SettingsDialog(const QString& configPath, DbManager* db, UtunNod " padding: 6px 10px; font-size: 13px; background: palette(base); }"); profLayout->addRow(nameLabel, m_nicknameEdit); + if (auto* avatars = AvatarManager::instance()) { + auto* controls = new QWidget(profilePage); auto* box = new QVBoxLayout(controls); box->setContentsMargins(0, 0, 0, 0); + auto* preview = new QLabel(controls); preview->setFixedSize(64, 64); preview->setAlignment(Qt::AlignCenter); + auto* server = new QComboBox(controls); server->setObjectName(QStringLiteral("avatarServer")); + auto* buttons = new QHBoxLayout; + auto* upload = new QPushButton(QCoreApplication::translate("ChatGui", "Upload avatar"), controls); + auto* clear = new QPushButton(QCoreApplication::translate("ChatGui", "Remove avatar"), controls); + upload->setObjectName(QStringLiteral("uploadAvatar")); clear->setObjectName(QStringLiteral("removeAvatar")); + auto* status = new QLabel(controls); status->setWordWrap(true); status->setObjectName(QStringLiteral("avatarStatus")); + auto* note = new QLabel(QCoreApplication::translate("ChatGui", "Avatar changes apply immediately in channels with the selected storage server."), controls); + note->setWordWrap(true); box->addWidget(preview); box->addWidget(server); + buttons->addWidget(upload); buttons->addWidget(clear); box->addLayout(buttons); box->addWidget(status); box->addWidget(note); + profLayout->addRow(QCoreApplication::translate("ChatGui", "Avatar:"), controls); + auto update = [avatars, server, preview, upload] { + const quint64 selected = server->currentData().toULongLong(); server->clear(); + const auto servers = avatars->servers(); + for (auto it = servers.begin(); it != servers.end(); ++it) + server->addItem(QString("%1 ยท %2").arg(it.value(), QString::number(it.key(), 16)), QVariant::fromValue(it.key())); + int index = server->findData(QVariant::fromValue(selected)); if (index >= 0) server->setCurrentIndex(index); + upload->setEnabled(server->count() && gui_bridge_is_uasync_ready()); + const QImage image = avatars->defaultImage(); + preview->setPixmap(image.isNull() ? QPixmap() : QPixmap::fromImage(image).scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + if (image.isNull()) preview->setText(QCoreApplication::translate("ChatGui", "No avatar")); + }; + connect(avatars, &AvatarManager::serversChanged, controls, update); + connect(avatars, &AvatarManager::statusChanged, status, &QLabel::setText); + connect(upload, &QPushButton::clicked, controls, [avatars, server, controls] { + const QString path = QFileDialog::getOpenFileName(controls, QCoreApplication::translate("ChatGui", "Choose avatar"), {}, + QCoreApplication::translate("ChatGui", "Images (*.png *.jpg *.jpeg *.webp)")); + if (!path.isEmpty()) avatars->uploadDefault(path, server->currentData().toULongLong()); + }); + connect(clear, &QPushButton::clicked, avatars, &AvatarManager::clearDefault); update(); + } + m_languageCombo = new QComboBox(profilePage); m_languageCombo->setObjectName(QStringLiteral("languageCombo")); m_languageCombo->addItem(QCoreApplication::translate("ChatGui", "System language"), QStringLiteral("system"));