diff --git a/src/dialogs/CreateRoom.h b/src/dialogs/CreateRoom.h
index 22ac6a43..a482a636 100644
--- a/src/dialogs/CreateRoom.h
+++ b/src/dialogs/CreateRoom.h
@@ -2,7 +2,7 @@
#include <QFrame>
-#include <mtx.hpp>
+#include <mtx/requests.hpp>
class QPushButton;
class TextField;
diff --git a/src/dialogs/FallbackAuth.cpp b/src/dialogs/FallbackAuth.cpp
new file mode 100644
index 00000000..a0633c1e
--- /dev/null
+++ b/src/dialogs/FallbackAuth.cpp
@@ -0,0 +1,69 @@
+#include <QDesktopServices>
+#include <QLabel>
+#include <QPushButton>
+#include <QUrl>
+#include <QVBoxLayout>
+
+#include "dialogs/FallbackAuth.h"
+
+#include "Config.h"
+#include "MatrixClient.h"
+
+using namespace dialogs;
+
+FallbackAuth::FallbackAuth(const QString &authType, const QString &session, QWidget *parent)
+ : QWidget(parent)
+{
+ setAutoFillBackground(true);
+ setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
+ setWindowModality(Qt::WindowModal);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ auto layout = new QVBoxLayout(this);
+ layout->setSpacing(conf::modals::WIDGET_SPACING);
+ layout->setMargin(conf::modals::WIDGET_MARGIN);
+
+ auto buttonLayout = new QHBoxLayout();
+ buttonLayout->setSpacing(8);
+ buttonLayout->setMargin(0);
+
+ openBtn_ = new QPushButton(tr("Open Fallback in Browser"), this);
+ cancelBtn_ = new QPushButton(tr("Cancel"), this);
+ confirmBtn_ = new QPushButton(tr("Confirm"), this);
+ confirmBtn_->setDefault(true);
+
+ buttonLayout->addStretch(1);
+ buttonLayout->addWidget(openBtn_);
+ buttonLayout->addWidget(cancelBtn_);
+ buttonLayout->addWidget(confirmBtn_);
+
+ QFont font;
+ font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO);
+
+ auto label = new QLabel(
+ tr("Open the fallback, follow the steps and confirm after completing them."), this);
+ label->setFont(font);
+
+ layout->addWidget(label);
+ layout->addLayout(buttonLayout);
+
+ connect(openBtn_, &QPushButton::clicked, [session, authType]() {
+ const auto url = QString("https://%1:%2/_matrix/client/r0/auth/%4/"
+ "fallback/web?session=%3")
+ .arg(QString::fromStdString(http::client()->server()))
+ .arg(http::client()->port())
+ .arg(session)
+ .arg(authType);
+
+ QDesktopServices::openUrl(url);
+ });
+
+ connect(confirmBtn_, &QPushButton::clicked, this, [this]() {
+ emit confirmation();
+ emit close();
+ });
+ connect(cancelBtn_, &QPushButton::clicked, this, [this]() {
+ emit cancel();
+ emit close();
+ });
+}
diff --git a/src/dialogs/FallbackAuth.h b/src/dialogs/FallbackAuth.h
new file mode 100644
index 00000000..245fa03e
--- /dev/null
+++ b/src/dialogs/FallbackAuth.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <QWidget>
+
+class QPushButton;
+class QLabel;
+
+namespace dialogs {
+
+class FallbackAuth : public QWidget
+{
+ Q_OBJECT
+
+public:
+ FallbackAuth(const QString &authType, const QString &session, QWidget *parent = nullptr);
+
+signals:
+ void confirmation();
+ void cancel();
+
+private:
+ QPushButton *openBtn_;
+ QPushButton *confirmBtn_;
+ QPushButton *cancelBtn_;
+};
+} // dialogs
diff --git a/src/dialogs/ImageOverlay.cpp b/src/dialogs/ImageOverlay.cpp
index dbf5bbe4..e075fb67 100644
--- a/src/dialogs/ImageOverlay.cpp
+++ b/src/dialogs/ImageOverlay.cpp
@@ -17,7 +17,9 @@
#include <QApplication>
#include <QDesktopWidget>
+#include <QGuiApplication>
#include <QPainter>
+#include <QScreen>
#include "dialogs/ImageOverlay.h"
@@ -30,7 +32,7 @@ ImageOverlay::ImageOverlay(QPixmap image, QWidget *parent)
, originalImage_{image}
{
setMouseTracking(true);
- setParent(0);
+ setParent(nullptr);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
@@ -39,11 +41,6 @@ ImageOverlay::ImageOverlay(QPixmap image, QWidget *parent)
setAttribute(Qt::WA_DeleteOnClose, true);
setWindowState(Qt::WindowFullScreen);
- screen_ = QApplication::desktop()->availableGeometry();
-
- move(QApplication::desktop()->mapToGlobal(screen_.topLeft()));
- resize(screen_.size());
-
connect(this, SIGNAL(closing()), this, SLOT(close()));
raise();
@@ -58,15 +55,15 @@ ImageOverlay::paintEvent(QPaintEvent *event)
painter.setRenderHint(QPainter::Antialiasing);
// Full screen overlay.
- painter.fillRect(QRect(0, 0, screen_.width(), screen_.height()), QColor(55, 55, 55, 170));
+ painter.fillRect(QRect(0, 0, width(), height()), QColor(55, 55, 55, 170));
// Left and Right margins
- int outer_margin = screen_.width() * 0.12;
+ int outer_margin = width() * 0.12;
int buttonSize = 36;
int margin = outer_margin * 0.1;
- int max_width = screen_.width() - 2 * outer_margin;
- int max_height = screen_.height();
+ int max_width = width() - 2 * outer_margin;
+ int max_height = height();
image_ = utils::scaleDown(max_width, max_height, originalImage_);
@@ -74,10 +71,9 @@ ImageOverlay::paintEvent(QPaintEvent *event)
int diff_y = max_height - image_.height();
content_ = QRect(outer_margin + diff_x / 2, diff_y / 2, image_.width(), image_.height());
- close_button_ =
- QRect(screen_.width() - margin - buttonSize, margin, buttonSize, buttonSize);
+ close_button_ = QRect(width() - margin - buttonSize, margin, buttonSize, buttonSize);
save_button_ =
- QRect(screen_.width() - (2 * margin) - (2 * buttonSize), margin, buttonSize, buttonSize);
+ QRect(width() - (2 * margin) - (2 * buttonSize), margin, buttonSize, buttonSize);
// Draw main content_.
painter.drawPixmap(content_, image_);
diff --git a/src/dialogs/ImageOverlay.h b/src/dialogs/ImageOverlay.h
index 26257fc1..bf566ce4 100644
--- a/src/dialogs/ImageOverlay.h
+++ b/src/dialogs/ImageOverlay.h
@@ -44,6 +44,5 @@ private:
QRect content_;
QRect close_button_;
QRect save_button_;
- QRect screen_;
};
} // dialogs
diff --git a/src/dialogs/InviteUsers.cpp b/src/dialogs/InviteUsers.cpp
index bacfe498..691035ce 100644
--- a/src/dialogs/InviteUsers.cpp
+++ b/src/dialogs/InviteUsers.cpp
@@ -13,7 +13,7 @@
#include "InviteeItem.h"
#include "ui/TextField.h"
-#include "mtx.hpp"
+#include <mtx/identifiers.hpp>
using namespace dialogs;
diff --git a/src/dialogs/MemberList.cpp b/src/dialogs/MemberList.cpp
index f4167143..54e7bf96 100644
--- a/src/dialogs/MemberList.cpp
+++ b/src/dialogs/MemberList.cpp
@@ -1,4 +1,5 @@
#include <QAbstractSlider>
+#include <QLabel>
#include <QListWidgetItem>
#include <QPainter>
#include <QPushButton>
@@ -9,10 +10,10 @@
#include "dialogs/MemberList.h"
-#include "AvatarProvider.h"
#include "Cache.h"
#include "ChatPage.h"
#include "Config.h"
+#include "Logging.h"
#include "Utils.h"
#include "ui/Avatar.h"
@@ -28,17 +29,10 @@ MemberItem::MemberItem(const RoomMember &member, QWidget *parent)
textLayout_->setMargin(0);
textLayout_->setSpacing(0);
- avatar_ = new Avatar(this);
- avatar_->setSize(44);
+ avatar_ = new Avatar(this, 44);
avatar_->setLetter(utils::firstChar(member.display_name));
- if (!member.avatar.isNull())
- avatar_->setImage(member.avatar);
- else
- AvatarProvider::resolve(ChatPage::instance()->currentRoom(),
- member.user_id,
- this,
- [this](const QImage &img) { avatar_->setImage(img); });
+ avatar_->setImage(ChatPage::instance()->currentRoom(), member.user_id);
QFont nameFont;
nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1);
@@ -97,7 +91,7 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
topLabel_->setAlignment(Qt::AlignCenter);
topLabel_->setFont(font);
- auto okBtn = new QPushButton("OK", this);
+ auto okBtn = new QPushButton(tr("OK"), this);
auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(15);
@@ -117,16 +111,16 @@ MemberList::MemberList(const QString &room_id, QWidget *parent)
const size_t numMembers = list_->count() - 1;
if (numMembers > 0)
- addUsers(cache::client()->getMembers(room_id_.toStdString(), numMembers));
+ addUsers(cache::getMembers(room_id_.toStdString(), numMembers));
});
try {
- addUsers(cache::client()->getMembers(room_id_.toStdString()));
+ addUsers(cache::getMembers(room_id_.toStdString()));
} catch (const lmdb::error &e) {
- qCritical() << e.what();
+ nhlog::db()->critical("Failed to retrieve members from cache: {}", e.what());
}
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &MemberList::close);
connect(okBtn, &QPushButton::clicked, this, &MemberList::close);
}
diff --git a/src/dialogs/PreviewUploadOverlay.cpp b/src/dialogs/PreviewUploadOverlay.cpp
index c404799e..42558d67 100644
--- a/src/dialogs/PreviewUploadOverlay.cpp
+++ b/src/dialogs/PreviewUploadOverlay.cpp
@@ -15,7 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <QApplication>
#include <QBuffer>
#include <QFile>
#include <QFileInfo>
@@ -135,6 +134,28 @@ PreviewUploadOverlay::setLabels(const QString &type, const QString &mime, uint64
}
void
+PreviewUploadOverlay::setPreview(const QImage &src, const QString &mime)
+{
+ auto const &split = mime.split('/');
+ auto const &type = split[1];
+
+ QBuffer buffer(&data_);
+ buffer.open(QIODevice::WriteOnly);
+ if (src.save(&buffer, type.toStdString().c_str()))
+ titleLabel_.setText(QString{tr(DEFAULT)}.arg("image"));
+ else
+ titleLabel_.setText(QString{tr(ERR_MSG)}.arg(type));
+
+ mediaType_ = split[0];
+ filePath_ = "clipboard." + type;
+ image_.convertFromImage(src);
+ isImage_ = true;
+
+ titleLabel_.setText(QString{tr(DEFAULT)}.arg("image"));
+ init();
+}
+
+void
PreviewUploadOverlay::setPreview(const QByteArray data, const QString &mime)
{
auto const &split = mime.split('/');
diff --git a/src/dialogs/PreviewUploadOverlay.h b/src/dialogs/PreviewUploadOverlay.h
index 8099d9c2..11cd49bc 100644
--- a/src/dialogs/PreviewUploadOverlay.h
+++ b/src/dialogs/PreviewUploadOverlay.h
@@ -17,6 +17,7 @@
#pragma once
+#include <QImage>
#include <QLabel>
#include <QLineEdit>
#include <QPixmap>
@@ -33,6 +34,7 @@ class PreviewUploadOverlay : public QWidget
public:
PreviewUploadOverlay(QWidget *parent = nullptr);
+ void setPreview(const QImage &src, const QString &mime);
void setPreview(const QByteArray data, const QString &mime);
void setPreview(const QString &path);
diff --git a/src/dialogs/ReCaptcha.cpp b/src/dialogs/ReCaptcha.cpp
index 7849aa4f..21dc8c77 100644
--- a/src/dialogs/ReCaptcha.cpp
+++ b/src/dialogs/ReCaptcha.cpp
@@ -60,5 +60,8 @@ ReCaptcha::ReCaptcha(const QString &session, QWidget *parent)
emit confirmation();
emit close();
});
- connect(cancelBtn_, &QPushButton::clicked, this, &dialogs::ReCaptcha::close);
+ connect(cancelBtn_, &QPushButton::clicked, this, [this]() {
+ emit cancel();
+ emit close();
+ });
}
diff --git a/src/dialogs/ReCaptcha.h b/src/dialogs/ReCaptcha.h
index f8407640..88ff3722 100644
--- a/src/dialogs/ReCaptcha.h
+++ b/src/dialogs/ReCaptcha.h
@@ -15,6 +15,7 @@ public:
signals:
void confirmation();
+ void cancel();
private:
QPushButton *openCaptchaBtn_;
diff --git a/src/dialogs/ReadReceipts.cpp b/src/dialogs/ReadReceipts.cpp
index dc4145db..0edd1ebf 100644
--- a/src/dialogs/ReadReceipts.cpp
+++ b/src/dialogs/ReadReceipts.cpp
@@ -35,10 +35,9 @@ ReceiptItem::ReceiptItem(QWidget *parent,
QFont nameFont;
nameFont.setPointSizeF(nameFont.pointSizeF() * 1.1);
- auto displayName = Cache::displayName(room_id, user_id);
+ auto displayName = cache::displayName(room_id, user_id);
- avatar_ = new Avatar(this);
- avatar_->setSize(44);
+ avatar_ = new Avatar(this, 44);
avatar_->setLetter(utils::firstChar(displayName));
// If it's a matrix id we use the second letter.
@@ -56,10 +55,7 @@ ReceiptItem::ReceiptItem(QWidget *parent,
topLayout_->addWidget(avatar_);
topLayout_->addLayout(textLayout_, 1);
- AvatarProvider::resolve(ChatPage::instance()->currentRoom(),
- user_id,
- this,
- [this](const QImage &img) { avatar_->setImage(img); });
+ avatar_->setImage(ChatPage::instance()->currentRoom(), user_id);
}
void
@@ -78,13 +74,15 @@ ReceiptItem::dateFormat(const QDateTime &then) const
auto days = then.daysTo(now);
if (days == 0)
- return QString("Today %1").arg(then.toString("HH:mm"));
+ return tr("Today %1").arg(then.time().toString(Qt::DefaultLocaleShortDate));
else if (days < 2)
- return QString("Yesterday %1").arg(then.toString("HH:mm"));
- else if (days < 365)
- return then.toString("dd/MM HH:mm");
+ return tr("Yesterday %1").arg(then.time().toString(Qt::DefaultLocaleShortDate));
+ else if (days < 7)
+ return QString("%1 %2")
+ .arg(then.toString("dddd"))
+ .arg(then.time().toString(Qt::DefaultLocaleShortDate));
- return then.toString("dd/MM/yy");
+ return then.toString(Qt::DefaultLocaleShortDate);
}
ReadReceipts::ReadReceipts(QWidget *parent)
@@ -131,7 +129,7 @@ ReadReceipts::ReadReceipts(QWidget *parent)
layout->addWidget(userList_);
layout->addLayout(buttonLayout);
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &ReadReceipts::close);
connect(okBtn, &QPushButton::clicked, this, &ReadReceipts::close);
}
diff --git a/src/dialogs/ReadReceipts.h b/src/dialogs/ReadReceipts.h
index 8e1b6b75..e298af0a 100644
--- a/src/dialogs/ReadReceipts.h
+++ b/src/dialogs/ReadReceipts.h
@@ -22,7 +22,7 @@ public:
const QString &room_id);
protected:
- void paintEvent(QPaintEvent *);
+ void paintEvent(QPaintEvent *) override;
private:
QString dateFormat(const QDateTime &then) const;
diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp
index f9b7e913..cc10ac91 100644
--- a/src/dialogs/RoomSettings.cpp
+++ b/src/dialogs/RoomSettings.cpp
@@ -11,11 +11,13 @@
#include <QPushButton>
#include <QShortcut>
#include <QShowEvent>
+#include <QStandardPaths>
#include <QStyleOption>
#include <QVBoxLayout>
#include "dialogs/RoomSettings.h"
+#include "Cache.h"
#include "ChatPage.h"
#include "Config.h"
#include "Logging.h"
@@ -199,12 +201,112 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
Qt::AlignBottom | Qt::AlignLeft);
roomIdLayout->addWidget(roomIdLabel, 0, Qt::AlignBottom | Qt::AlignRight);
+ auto roomVersionLabel = new QLabel(QString::fromStdString(info_.version), this);
+ roomVersionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ roomVersionLabel->setFont(monospaceFont);
+
+ auto roomVersionLayout = new QHBoxLayout;
+ roomVersionLayout->setMargin(0);
+ roomVersionLayout->addWidget(new QLabel(tr("Room Version"), this),
+ Qt::AlignBottom | Qt::AlignLeft);
+ roomVersionLayout->addWidget(roomVersionLabel, 0, Qt::AlignBottom | Qt::AlignRight);
+
auto notifLabel = new QLabel(tr("Notifications"), this);
- auto notifCombo = new QComboBox(this);
- notifCombo->setDisabled(true);
- notifCombo->addItem(tr("Muted"));
- notifCombo->addItem(tr("Mentions only"));
- notifCombo->addItem(tr("All messages"));
+ notifCombo = new QComboBox(this);
+ notifCombo->addItem(tr(
+ "Muted")); //{"conditions":[{"kind":"event_match","key":"room_id","pattern":"!jxlRxnrZCsjpjDubDX:matrix.org"}],"actions":["dont_notify"]}
+ notifCombo->addItem(tr("Mentions only")); // {"actions":["dont_notify"]}
+ notifCombo->addItem(tr("All messages")); // delete rule
+
+ connect(this, &RoomSettings::notifChanged, notifCombo, &QComboBox::setCurrentIndex);
+ http::client()->get_pushrules(
+ "global",
+ "override",
+ room_id_.toStdString(),
+ [this](const mtx::pushrules::PushRule &rule, mtx::http::RequestErr &err) {
+ if (err) {
+ if (err->status_code == boost::beast::http::status::not_found)
+ http::client()->get_pushrules(
+ "global",
+ "room",
+ room_id_.toStdString(),
+ [this](const mtx::pushrules::PushRule &rule,
+ mtx::http::RequestErr &err) {
+ if (err) {
+ emit notifChanged(2); // all messages
+ return;
+ }
+
+ if (rule.enabled)
+ emit notifChanged(1); // mentions only
+ });
+ return;
+ }
+
+ if (rule.enabled)
+ emit notifChanged(0); // muted
+ else
+ emit notifChanged(2); // all messages
+ });
+
+ connect(notifCombo, QOverload<int>::of(&QComboBox::activated), [this](int index) {
+ std::string room_id = room_id_.toStdString();
+ if (index == 0) {
+ // mute room
+ // delete old rule first, then add new rule
+ mtx::pushrules::PushRule rule;
+ rule.actions = {mtx::pushrules::actions::dont_notify{}};
+ mtx::pushrules::PushCondition condition;
+ condition.kind = "event_match";
+ condition.key = "room_id";
+ condition.pattern = room_id;
+ rule.conditions = {condition};
+
+ http::client()->put_pushrules(
+ "global",
+ "override",
+ room_id,
+ rule,
+ [room_id](mtx::http::RequestErr &err) {
+ if (err)
+ nhlog::net()->error(
+ "failed to set pushrule for room {}: {} {}",
+ room_id,
+ static_cast<int>(err->status_code),
+ err->matrix_error.error);
+ http::client()->delete_pushrules(
+ "global", "room", room_id, [room_id](mtx::http::RequestErr &) {
+ });
+ });
+ } else if (index == 1) {
+ // mentions only
+ // delete old rule first, then add new rule
+ mtx::pushrules::PushRule rule;
+ rule.actions = {mtx::pushrules::actions::dont_notify{}};
+ http::client()->put_pushrules(
+ "global", "room", room_id, rule, [room_id](mtx::http::RequestErr &err) {
+ if (err)
+ nhlog::net()->error(
+ "failed to set pushrule for room {}: {} {}",
+ room_id,
+ static_cast<int>(err->status_code),
+ err->matrix_error.error);
+ http::client()->delete_pushrules(
+ "global",
+ "override",
+ room_id,
+ [room_id](mtx::http::RequestErr &) {});
+ });
+ } else {
+ // all messages
+ http::client()->delete_pushrules(
+ "global", "override", room_id, [room_id](mtx::http::RequestErr &) {
+ http::client()->delete_pushrules(
+ "global", "room", room_id, [room_id](mtx::http::RequestErr &) {
+ });
+ });
+ }
+ });
auto notifOptionLayout_ = new QHBoxLayout;
notifOptionLayout_->setMargin(0);
@@ -238,10 +340,10 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
switch (index) {
case 0:
case 1:
- event.join_rule = JoinRule::Public;
+ event.join_rule = state::JoinRule::Public;
break;
default:
- event.join_rule = JoinRule::Invite;
+ event.join_rule = state::JoinRule::Invite;
}
return event;
@@ -250,7 +352,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
updateAccessRules(room_id_.toStdString(), join_rule, guest_access);
});
- if (info_.join_rule == JoinRule::Public) {
+ if (info_.join_rule == state::JoinRule::Public) {
if (info_.guest_access) {
accessCombo->setCurrentIndex(0);
} else {
@@ -332,7 +434,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
}
// Hide encryption option for public rooms.
- if (!usesEncryption_ && (info_.join_rule == JoinRule::Public)) {
+ if (!usesEncryption_ && (info_.join_rule == state::JoinRule::Public)) {
encryptionToggle_->hide();
encryptionLabel->hide();
@@ -340,12 +442,10 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
keyRequestsToggle_->hide();
}
- avatar_ = new Avatar(this);
- avatar_->setSize(128);
- if (avatarImg_.isNull())
- avatar_->setLetter(utils::firstChar(QString::fromStdString(info_.name)));
- else
- avatar_->setImage(avatarImg_);
+ avatar_ = new Avatar(this, 128);
+ avatar_->setLetter(utils::firstChar(QString::fromStdString(info_.name)));
+ if (!info_.avatar_url.empty())
+ avatar_->setImage(QString::fromStdString(info_.avatar_url));
if (canChangeAvatar(room_id_.toStdString(), utils::localUser().toStdString())) {
auto filter = new ClickableFilter(this);
@@ -400,6 +500,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
layout->addLayout(keyRequestsLayout);
layout->addWidget(infoLabel, Qt::AlignLeft);
layout->addLayout(roomIdLayout);
+ layout->addLayout(roomVersionLayout);
layout->addWidget(errorLabel_);
layout->addLayout(buttonLayout);
layout->addLayout(spinnerLayout);
@@ -427,7 +528,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
resetErrorLabel();
});
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &RoomSettings::close);
connect(okBtn, &QPushButton::clicked, this, &RoomSettings::close);
}
@@ -474,10 +575,10 @@ void
RoomSettings::retrieveRoomInfo()
{
try {
- usesEncryption_ = cache::client()->isRoomEncrypted(room_id_.toStdString());
- info_ = cache::client()->singleRoomInfo(room_id_.toStdString());
- setAvatar(QImage::fromData(cache::client()->image(info_.avatar_url)));
- } catch (const lmdb::error &e) {
+ usesEncryption_ = cache::isRoomEncrypted(room_id_.toStdString());
+ info_ = cache::singleRoomInfo(room_id_.toStdString());
+ setAvatar();
+ } catch (const lmdb::error &) {
nhlog::db()->warn("failed to retrieve room info from cache: {}",
room_id_.toStdString());
}
@@ -518,8 +619,7 @@ bool
RoomSettings::canChangeJoinRules(const std::string &room_id, const std::string &user_id) const
{
try {
- return cache::client()->hasEnoughPowerLevel(
- {EventType::RoomJoinRules}, room_id, user_id);
+ return cache::hasEnoughPowerLevel({EventType::RoomJoinRules}, room_id, user_id);
} catch (const lmdb::error &e) {
nhlog::db()->warn("lmdb error: {}", e.what());
}
@@ -531,7 +631,7 @@ bool
RoomSettings::canChangeNameAndTopic(const std::string &room_id, const std::string &user_id) const
{
try {
- return cache::client()->hasEnoughPowerLevel(
+ return cache::hasEnoughPowerLevel(
{EventType::RoomName, EventType::RoomTopic}, room_id, user_id);
} catch (const lmdb::error &e) {
nhlog::db()->warn("lmdb error: {}", e.what());
@@ -544,8 +644,7 @@ bool
RoomSettings::canChangeAvatar(const std::string &room_id, const std::string &user_id) const
{
try {
- return cache::client()->hasEnoughPowerLevel(
- {EventType::RoomAvatar}, room_id, user_id);
+ return cache::hasEnoughPowerLevel({EventType::RoomAvatar}, room_id, user_id);
} catch (const lmdb::error &e) {
nhlog::db()->warn("lmdb error: {}", e.what());
}
@@ -622,14 +721,12 @@ RoomSettings::displayErrorMessage(const QString &msg)
}
void
-RoomSettings::setAvatar(const QImage &img)
+RoomSettings::setAvatar()
{
stopLoadingSpinner();
- avatarImg_ = img;
-
if (avatar_)
- avatar_->setImage(img);
+ avatar_->setImage(QString::fromStdString(info_.avatar_url));
}
void
@@ -644,8 +741,10 @@ RoomSettings::resetErrorLabel()
void
RoomSettings::updateAvatar()
{
- const auto fileName =
- QFileDialog::getOpenFileName(this, tr("Select an avatar"), "", tr("All Files (*)"));
+ const QString picturesFolder =
+ QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
+ const QString fileName = QFileDialog::getOpenFileName(
+ this, tr("Select an avatar"), picturesFolder, tr("All Files (*)"));
if (fileName.isEmpty())
return;
@@ -657,12 +756,12 @@ RoomSettings::updateAvatar()
QFile file{fileName, this};
if (format != "image") {
- displayErrorMessage(tr("The selected media is not an image"));
+ displayErrorMessage(tr("The selected file is not an image"));
return;
}
if (!file.open(QIODevice::ReadOnly)) {
- displayErrorMessage(tr("Error while reading media: %1").arg(file.errorString()));
+ displayErrorMessage(tr("Error while reading file: %1").arg(file.errorString()));
return;
}
@@ -722,7 +821,7 @@ RoomSettings::updateAvatar()
return;
}
- emit proxy->avatarChanged(QImage::fromData(content));
+ emit proxy->avatarChanged();
});
});
}
diff --git a/src/dialogs/RoomSettings.h b/src/dialogs/RoomSettings.h
index 6667b68b..e41c866c 100644
--- a/src/dialogs/RoomSettings.h
+++ b/src/dialogs/RoomSettings.h
@@ -5,7 +5,9 @@
#include <QImage>
#include <QLabel>
-#include "Cache.h"
+#include <mtx/events/guest_access.hpp>
+
+#include "CacheStructs.h"
class Avatar;
class FlatButton;
@@ -33,7 +35,7 @@ signals:
void clicked();
protected:
- bool eventFilter(QObject *obj, QEvent *event)
+ bool eventFilter(QObject *obj, QEvent *event) override
{
if (event->type() == QEvent::MouseButtonRelease) {
emit clicked();
@@ -52,7 +54,7 @@ class ThreadProxy : public QObject
signals:
void error(const QString &msg);
- void avatarChanged(const QImage &img);
+ void avatarChanged();
void nameEventSent(const QString &);
void topicEventSent();
};
@@ -117,6 +119,7 @@ signals:
void enableEncryptionError(const QString &msg);
void showErrorMessage(const QString &msg);
void accessRulesUpdated();
+ void notifChanged(int index);
protected:
void showEvent(QShowEvent *event) override;
@@ -140,7 +143,7 @@ private:
void resetErrorLabel();
void displayErrorMessage(const QString &msg);
- void setAvatar(const QImage &img);
+ void setAvatar();
void setupEditButton();
//! Retrieve the current room information from cache.
void retrieveRoomInfo();
@@ -161,6 +164,7 @@ private:
QLabel *errorLabel_ = nullptr;
LoadingIndicator *spinner_ = nullptr;
+ QComboBox *notifCombo = nullptr;
QComboBox *accessCombo = nullptr;
Toggle *encryptionToggle_ = nullptr;
Toggle *keyRequestsToggle_ = nullptr;
diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp
index b8040f9f..f1dd77df 100644
--- a/src/dialogs/UserProfile.cpp
+++ b/src/dialogs/UserProfile.cpp
@@ -1,13 +1,12 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QListWidget>
-#include <QSettings>
#include <QShortcut>
#include <QVBoxLayout>
-#include "AvatarProvider.h"
#include "Cache.h"
#include "ChatPage.h"
+#include "Logging.h"
#include "MatrixClient.h"
#include "Utils.h"
#include "dialogs/UserProfile.h"
@@ -16,6 +15,8 @@
using namespace dialogs;
+Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
+
constexpr int BUTTON_SIZE = 36;
constexpr int BUTTON_RADIUS = BUTTON_SIZE / 2;
constexpr int WIDGET_MARGIN = 20;
@@ -49,7 +50,6 @@ UserProfile::UserProfile(QWidget *parent)
{
setAutoFillBackground(true);
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
- setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose, true);
QIcon banIcon, kickIcon, ignoreIcon, startChatIcon;
@@ -61,7 +61,6 @@ UserProfile::UserProfile(QWidget *parent)
banBtn_->setIcon(banIcon);
banBtn_->setIconSize(QSize(BUTTON_RADIUS, BUTTON_RADIUS));
banBtn_->setToolTip(tr("Ban the user from the room"));
- banBtn_->setDisabled(true); // Not used yet.
ignoreIcon.addFile(":/icons/icons/ui/volume-off-indicator.png");
ignoreBtn_ = new FlatButton(this);
@@ -79,7 +78,6 @@ UserProfile::UserProfile(QWidget *parent)
kickBtn_->setIcon(kickIcon);
kickBtn_->setIconSize(QSize(BUTTON_RADIUS, BUTTON_RADIUS));
kickBtn_->setToolTip(tr("Kick the user from the room"));
- kickBtn_->setDisabled(true); // Not used yet.
startChatIcon.addFile(":/icons/icons/ui/black-bubble-speech.png");
startChat_ = new FlatButton(this);
@@ -102,6 +100,13 @@ UserProfile::UserProfile(QWidget *parent)
emit ChatPage::instance()->createRoom(req);
});
+ connect(banBtn_, &QPushButton::clicked, this, [this] {
+ ChatPage::instance()->banUser(userIdLabel_->text(), "");
+ });
+ connect(kickBtn_, &QPushButton::clicked, this, [this] {
+ ChatPage::instance()->kickUser(userIdLabel_->text(), "");
+ });
+
// Button line
auto btnLayout = new QHBoxLayout;
btnLayout->addStretch(1);
@@ -114,9 +119,8 @@ UserProfile::UserProfile(QWidget *parent)
btnLayout->setSpacing(8);
btnLayout->setMargin(0);
- avatar_ = new Avatar(this);
+ avatar_ = new Avatar(this, 128);
avatar_->setLetter("X");
- avatar_->setSize(128);
QFont font;
font.setPointSizeF(font.pointSizeF() * 2);
@@ -167,10 +171,6 @@ UserProfile::UserProfile(QWidget *parent)
vlayout->setAlignment(avatar_, Qt::AlignCenter | Qt::AlignTop);
vlayout->setAlignment(userIdLabel_, Qt::AlignCenter | Qt::AlignTop);
- setAutoFillBackground(true);
- setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
- setWindowModality(Qt::WindowModal);
-
QFont largeFont;
largeFont.setPointSizeF(largeFont.pointSizeF() * 1.5);
@@ -181,9 +181,10 @@ UserProfile::UserProfile(QWidget *parent)
vlayout->setSpacing(WIDGET_SPACING);
vlayout->setContentsMargins(WIDGET_MARGIN, TOP_WIDGET_MARGIN, WIDGET_MARGIN, WIDGET_MARGIN);
- qRegisterMetaType<std::vector<DeviceInfo>>();
+ static auto ignored = qRegisterMetaType<std::vector<DeviceInfo>>();
+ (void)ignored;
- auto closeShortcut = new QShortcut(QKeySequence(tr("ESC")), this);
+ auto closeShortcut = new QShortcut(QKeySequence(QKeySequence::Cancel), this);
connect(closeShortcut, &QShortcut::activated, this, &UserProfile::close);
connect(okBtn, &QPushButton::clicked, this, &UserProfile::close);
}
@@ -204,22 +205,21 @@ UserProfile::init(const QString &userId, const QString &roomId)
{
resetToDefaults();
- auto displayName = Cache::displayName(roomId, userId);
+ auto displayName = cache::displayName(roomId, userId);
userIdLabel_->setText(userId);
displayNameLabel_->setText(displayName);
avatar_->setLetter(utils::firstChar(displayName));
- AvatarProvider::resolve(
- roomId, userId, this, [this](const QImage &img) { avatar_->setImage(img); });
+ avatar_->setImage(roomId, userId);
auto localUser = utils::localUser();
try {
bool hasMemberRights =
- cache::client()->hasEnoughPowerLevel({mtx::events::EventType::RoomMember},
- roomId.toStdString(),
- localUser.toStdString());
+ cache::hasEnoughPowerLevel({mtx::events::EventType::RoomMember},
+ roomId.toStdString(),
+ localUser.toStdString());
if (!hasMemberRights) {
kickBtn_->hide();
banBtn_->hide();
diff --git a/src/dialogs/UserProfile.h b/src/dialogs/UserProfile.h
index 0f684cda..81276d2a 100644
--- a/src/dialogs/UserProfile.h
+++ b/src/dialogs/UserProfile.h
@@ -15,8 +15,6 @@ struct DeviceInfo
QString display_name;
};
-Q_DECLARE_METATYPE(std::vector<DeviceInfo>)
-
class Proxy : public QObject
{
Q_OBJECT
|