diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index cdaf7260..3743eae0 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -785,11 +785,18 @@ ChatPage::kickUser(QString userid, QString reason)
{
auto room = currentRoom();
- if (QMessageBox::question(nullptr,
- tr("Confirm kick"),
- tr("Do you really want to kick %1 (%2)?")
- .arg(cache::displayName(room, userid), userid)) != QMessageBox::Yes)
+ bool confirmed;
+ reason =
+ QInputDialog::getText(nullptr,
+ tr("Reason for the kick"),
+ tr("Enter reason for kicking %1 (%2) or hit enter for no reason:")
+ .arg(cache::displayName(room, userid), userid),
+ QLineEdit::Normal,
+ reason,
+ &confirmed);
+ if (!confirmed) {
return;
+ }
http::client()->kick_user(
room.toStdString(),
@@ -809,12 +816,18 @@ ChatPage::banUser(QString userid, QString reason)
{
auto room = currentRoom();
- if (QMessageBox::question(
- nullptr,
- tr("Confirm ban"),
- tr("Do you really want to ban %1 (%2)?").arg(cache::displayName(room, userid), userid)) !=
- QMessageBox::Yes)
+ bool confirmed;
+ reason =
+ QInputDialog::getText(nullptr,
+ tr("Reason for the ban"),
+ tr("Enter reason for banning %1 (%2) or hit enter for no reason:")
+ .arg(cache::displayName(room, userid), userid),
+ QLineEdit::Normal,
+ reason,
+ &confirmed);
+ if (!confirmed) {
return;
+ }
http::client()->ban_user(
room.toStdString(),
diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp
index 6bed446e..6a83376c 100644
--- a/src/LoginPage.cpp
+++ b/src/LoginPage.cpp
@@ -19,6 +19,7 @@
#include "UserSettingsPage.h"
Q_DECLARE_METATYPE(LoginPage::LoginMethod)
+Q_DECLARE_METATYPE(SSOProvider)
using namespace mtx::identifiers;
@@ -28,6 +29,7 @@ LoginPage::LoginPage(QObject *parent)
{
[[maybe_unused]] static auto ignored =
qRegisterMetaType<LoginPage::LoginMethod>("LoginPage::LoginMethod");
+ [[maybe_unused]] static auto ignored2 = qRegisterMetaType<SSOProvider>();
connect(this, &LoginPage::versionOkCb, this, &LoginPage::versionOk, Qt::QueuedConnection);
connect(this, &LoginPage::versionErrorCb, this, &LoginPage::versionError, Qt::QueuedConnection);
@@ -161,27 +163,54 @@ LoginPage::checkHomeserverVersion()
return;
}
+ nhlog::net()->error("Error requesting versions: {}", *err);
+
emit versionErrorCb(
tr("An unknown error occured. Make sure the homeserver domain is valid."));
return;
}
- http::client()->get_login(
- [this](mtx::responses::LoginFlows flows, mtx::http::RequestErr err) {
- if (err || flows.flows.empty())
- emit versionOkCb(true, false);
+ http::client()->get_login([this](mtx::responses::LoginFlows flows,
+ mtx::http::RequestErr err) {
+ if (err || flows.flows.empty())
+ emit versionOkCb(true, false, {});
- bool ssoSupported = false;
- bool passwordSupported = false;
- for (const auto &flow : flows.flows) {
- if (flow.type == mtx::user_interactive::auth_types::sso) {
- ssoSupported = true;
- } else if (flow.type == mtx::user_interactive::auth_types::password) {
- passwordSupported = true;
- }
- }
- emit versionOkCb(passwordSupported, ssoSupported);
- });
+ QVariantList idps;
+ bool ssoSupported = false;
+ bool passwordSupported = false;
+ for (const auto &flow : flows.flows) {
+ if (flow.type == mtx::user_interactive::auth_types::sso) {
+ ssoSupported = true;
+
+ for (const auto &idp : flow.identity_providers) {
+ SSOProvider prov;
+ if (idp.brand == "apple")
+ prov.name_ = tr("Sign in with Apple");
+ else if (idp.brand == "facebook")
+ prov.name_ = tr("Continue with Facebook");
+ else if (idp.brand == "google")
+ prov.name_ = tr("Sign in with Google");
+ else if (idp.brand == "twitter")
+ prov.name_ = tr("Sign in with Twitter");
+ else
+ prov.name_ = tr("Login using %1").arg(QString::fromStdString(idp.name));
+
+ prov.avatarUrl_ = QString::fromStdString(idp.icon);
+ prov.id_ = QString::fromStdString(idp.id);
+ idps.push_back(QVariant::fromValue(prov));
+ }
+
+ if (flow.identity_providers.empty()) {
+ SSOProvider prov;
+ prov.name_ = tr("SSO LOGIN");
+ idps.push_back(QVariant::fromValue(prov));
+ }
+ } else if (flow.type == mtx::user_interactive::auth_types::password) {
+ passwordSupported = true;
+ }
+ }
+ emit versionOkCb(passwordSupported, ssoSupported, idps);
+ });
});
}
@@ -198,10 +227,11 @@ LoginPage::versionError(const QString &error)
}
void
-LoginPage::versionOk(bool passwordSupported, bool ssoSupported)
+LoginPage::versionOk(bool passwordSupported, bool ssoSupported, QVariantList idps)
{
passwordSupported_ = passwordSupported;
ssoSupported_ = ssoSupported;
+ identityProviders_ = idps;
lookingUpHs_ = false;
homeserverValid_ = true;
@@ -248,7 +278,7 @@ LoginPage::onLoginButtonClicked(LoginMethod loginMethod,
if (res.well_known) {
http::client()->set_server(res.well_known->homeserver.base_url);
- nhlog::net()->info("Login requested to user server: " +
+ nhlog::net()->info("Login requested to use server: " +
res.well_known->homeserver.base_url);
}
@@ -273,7 +303,7 @@ LoginPage::onLoginButtonClicked(LoginMethod loginMethod,
if (res.well_known) {
http::client()->set_server(res.well_known->homeserver.base_url);
- nhlog::net()->info("Login requested to user server: " +
+ nhlog::net()->info("Login requested to use server: " +
res.well_known->homeserver.base_url);
}
@@ -287,8 +317,9 @@ LoginPage::onLoginButtonClicked(LoginMethod loginMethod,
sso->deleteLater();
});
- QDesktopServices::openUrl(
- QString::fromStdString(http::client()->login_sso_redirect(sso->url())));
+ // password doubles as the idp id for SSO login
+ QDesktopServices::openUrl(QString::fromStdString(
+ http::client()->login_sso_redirect(sso->url(), password.toStdString())));
}
loggingIn_ = true;
diff --git a/src/LoginPage.h b/src/LoginPage.h
index 9a1b9653..47896fda 100644
--- a/src/LoginPage.h
+++ b/src/LoginPage.h
@@ -7,6 +7,7 @@
#pragma once
#include <QObject>
+#include <QVariantList>
namespace mtx {
namespace responses {
@@ -14,6 +15,23 @@ struct Login;
}
}
+struct SSOProvider
+{
+ Q_GADGET
+ Q_PROPERTY(QString avatarUrl READ avatarUrl CONSTANT)
+ Q_PROPERTY(QString name READ name CONSTANT)
+ Q_PROPERTY(QString id READ id CONSTANT)
+
+public:
+ [[nodiscard]] QString avatarUrl() const { return avatarUrl_; }
+ [[nodiscard]] QString name() const { return name_.toHtmlEscaped(); }
+ [[nodiscard]] QString id() const { return id_; }
+
+ QString avatarUrl_;
+ QString name_;
+ QString id_;
+};
+
class LoginPage : public QObject
{
Q_OBJECT
@@ -30,6 +48,8 @@ class LoginPage : public QObject
Q_PROPERTY(bool ssoSupported READ ssoSupported NOTIFY versionLookedUp)
Q_PROPERTY(bool homeserverNeeded READ homeserverNeeded NOTIFY versionLookedUp)
+ Q_PROPERTY(QVariantList identityProviders READ identityProviders NOTIFY versionLookedUp)
+
public:
enum class LoginMethod
{
@@ -51,6 +71,7 @@ public:
bool ssoSupported() const { return ssoSupported_; }
bool homeserverNeeded() const { return homeserverNeeded_; }
bool homeserverValid() const { return homeserverValid_; }
+ QVariantList identityProviders() const { return identityProviders_; }
QString homeserver() { return homeserver_; }
QString mxid() { return mxid_; }
@@ -89,7 +110,7 @@ signals:
//! Used to trigger the corresponding slot outside of the main thread.
void versionErrorCb(const QString &err);
- void versionOkCb(bool passwordSupported, bool ssoSupported);
+ void versionOkCb(bool passwordSupported, bool ssoSupported, QVariantList identityProviders);
void loginOk(const mtx::responses::Login &res);
@@ -116,7 +137,7 @@ public slots:
// Callback for errors produced during server probing
void versionError(const QString &error_message);
// Callback for successful server probing
- void versionOk(bool passwordSupported, bool ssoSupported);
+ void versionOk(bool passwordSupported, bool ssoSupported, QVariantList identityProviders);
private:
void checkHomeserverVersion();
@@ -137,6 +158,8 @@ private:
QString mxidError_;
QString error_;
+ QVariantList identityProviders_;
+
bool passwordSupported_ = true;
bool ssoSupported_ = false;
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index f3893998..73e556f7 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -338,8 +338,7 @@ MainWindow::showChatPage()
{
auto userid = QString::fromStdString(http::client()->user_id().to_string());
auto device_id = QString::fromStdString(http::client()->device_id());
- auto homeserver = QString::fromStdString(http::client()->server() + ":" +
- std::to_string(http::client()->port()));
+ auto homeserver = QString::fromStdString(http::client()->server_url());
auto token = QString::fromStdString(http::client()->access_token());
userSettings_.data()->setUserId(userid);
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index c7ac790a..1a24834e 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -79,15 +79,17 @@ UserSettings::load(std::optional<QString> profile)
sortByImportance_ = settings.value(QStringLiteral("user/sort_by_unread"), true).toBool();
readReceipts_ = settings.value(QStringLiteral("user/read_receipts"), true).toBool();
theme_ = settings.value(QStringLiteral("user/theme"), defaultTheme_).toString();
- font_ = settings.value(QStringLiteral("user/font_family"), "default").toString();
- avatarCircles_ = settings.value(QStringLiteral("user/avatar_circles"), true).toBool();
- useIdenticon_ = settings.value(QStringLiteral("user/use_identicon"), true).toBool();
- decryptSidebar_ = settings.value(QStringLiteral("user/decrypt_sidebar"), true).toBool();
- privacyScreen_ = settings.value(QStringLiteral("user/privacy_screen"), false).toBool();
+
+ font_ = settings.value(QStringLiteral("user/font_family"), "").toString();
+
+ avatarCircles_ = settings.value(QStringLiteral("user/avatar_circles"), true).toBool();
+ useIdenticon_ = settings.value(QStringLiteral("user/use_identicon"), true).toBool();
+ decryptSidebar_ = settings.value(QStringLiteral("user/decrypt_sidebar"), true).toBool();
+ privacyScreen_ = settings.value(QStringLiteral("user/privacy_screen"), false).toBool();
privacyScreenTimeout_ =
settings.value(QStringLiteral("user/privacy_screen_timeout"), 0).toInt();
mobileMode_ = settings.value(QStringLiteral("user/mobile_mode"), false).toBool();
- emojiFont_ = settings.value(QStringLiteral("user/emoji_font_family"), "default").toString();
+ emojiFont_ = settings.value(QStringLiteral("user/emoji_font_family"), "emoji").toString();
baseFontSize_ =
settings.value(QStringLiteral("user/font_size"), QFont().pointSizeF()).toDouble();
auto tempPresence =
@@ -419,6 +421,12 @@ UserSettings::setFontSize(double size)
if (size == baseFontSize_)
return;
baseFontSize_ = size;
+
+ const static auto defaultFamily = QFont().defaultFamily();
+ QFont f((font_.isEmpty() || font_ == QStringLiteral("default")) ? defaultFamily : font_);
+ f.setPointSizeF(fontSize());
+ QApplication::setFont(f);
+
emit fontSizeChanged(size);
save();
}
@@ -429,6 +437,12 @@ UserSettings::setFontFamily(QString family)
if (family == font_)
return;
font_ = family;
+
+ const static auto defaultFamily = QFont().defaultFamily();
+ QFont f((family.isEmpty() || family == QStringLiteral("default")) ? defaultFamily : family);
+ f.setPointSizeF(fontSize());
+ QApplication::setFont(f);
+
emit fontChanged(family);
save();
}
@@ -440,7 +454,7 @@ UserSettings::setEmojiFontFamily(QString family)
return;
if (family == tr("Default")) {
- emojiFont_ = QStringLiteral("default");
+ emojiFont_ = QStringLiteral("emoji");
} else {
emojiFont_ = family;
}
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index 4151356f..1293245c 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -208,7 +208,7 @@ EventStore::EventStore(std::string room_id, QObject *)
size_t index = related_text->content.formatted_body.find(txn_id);
if (index != std::string::npos) {
related_text->content.formatted_body.replace(
- index, event_id.length(), event_id);
+ index, txn_id.length(), event_id);
}
}
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 903f137f..8e6c7235 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1240,7 +1240,7 @@ TimelineModel::showReadReceipts(QString id)
}
void
-TimelineModel::redactEvent(const QString &id)
+TimelineModel::redactEvent(const QString &id, const QString &reason)
{
if (!id.isEmpty()) {
auto edits = events.edits(id.toStdString());
@@ -1255,7 +1255,8 @@ TimelineModel::redactEvent(const QString &id)
}
emit dataAtIdChanged(id);
- });
+ },
+ reason.toStdString());
// redact all edits to prevent leaks
for (const auto &e : edits) {
@@ -1271,7 +1272,8 @@ TimelineModel::redactEvent(const QString &id)
}
emit dataAtIdChanged(id);
- });
+ },
+ reason.toStdString());
}
}
}
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index e4e3fa9d..f47203f0 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -272,7 +272,7 @@ public:
Q_INVOKABLE void unpin(const QString &id);
Q_INVOKABLE void pin(const QString &id);
Q_INVOKABLE void showReadReceipts(QString id);
- Q_INVOKABLE void redactEvent(const QString &id);
+ Q_INVOKABLE void redactEvent(const QString &id, const QString &reason = "");
Q_INVOKABLE int idToIndex(const QString &id) const;
Q_INVOKABLE QString indexToId(int index) const;
Q_INVOKABLE void openMedia(const QString &eventId);
|