summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChatPage.cpp2
-rw-r--r--src/FallbackAuth.cpp29
-rw-r--r--src/FallbackAuth.h32
-rw-r--r--src/UserSettingsPage.cpp39
-rw-r--r--src/UserSettingsPage.h9
-rw-r--r--src/dialogs/FallbackAuth.cpp75
-rw-r--r--src/dialogs/FallbackAuth.h30
-rw-r--r--src/encryption/VerificationManager.h1
-rw-r--r--src/timeline/TimelineModel.cpp26
-rw-r--r--src/timeline/TimelineModel.h3
-rw-r--r--src/timeline/TimelineViewManager.h1
-rw-r--r--src/ui/NhekoGlobalObject.cpp1
-rw-r--r--src/ui/UIA.cpp21
-rw-r--r--src/ui/UIA.h2
-rw-r--r--src/voip/ScreenCastPortal.cpp19
15 files changed, 136 insertions, 154 deletions
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 4686b0f5..06d88303 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -1269,7 +1269,7 @@ ChatPage::getBackupVersion()
                       nhlog::crypto()->info("Our backup key {} does not match the one "
                                             "used in the online backup {}",
                                             pubkey,
-                                            auth_data["public_key"]);
+                                            auth_data["public_key"].get<std::string>());
                       cache::client()->deleteBackupVersion();
                       return;
                   }
diff --git a/src/FallbackAuth.cpp b/src/FallbackAuth.cpp
new file mode 100644
index 00000000..5b668310
--- /dev/null
+++ b/src/FallbackAuth.cpp
@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "FallbackAuth.h"
+
+#include <QDesktopServices>
+#include <QUrl>
+
+#include "MatrixClient.h"
+
+FallbackAuth::FallbackAuth(const QString &session, const QString &authType, QObject *parent)
+  : QObject{parent}
+  , m_session{session}
+  , m_authType{authType}
+{
+}
+
+void
+FallbackAuth::openFallbackAuth()
+{
+    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(m_session, m_authType);
+
+    QDesktopServices::openUrl(url);
+}
diff --git a/src/FallbackAuth.h b/src/FallbackAuth.h
new file mode 100644
index 00000000..c3b042ce
--- /dev/null
+++ b/src/FallbackAuth.h
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <QQmlEngine>
+
+class FallbackAuth : public QObject
+{
+    Q_OBJECT
+    QML_ELEMENT
+    QML_UNCREATABLE("")
+
+    Q_PROPERTY(QString authType MEMBER m_authType CONSTANT)
+    Q_PROPERTY(QString session MEMBER m_session CONSTANT)
+
+public:
+    FallbackAuth(const QString &session, const QString &authType, QObject *parent = nullptr);
+
+    Q_INVOKABLE void openFallbackAuth();
+    Q_INVOKABLE void confirm() { emit confirmation(); }
+    Q_INVOKABLE void cancel() { emit cancelled(); }
+
+signals:
+    void confirmation();
+    void cancelled();
+
+private:
+    const QString m_session;
+    const QString m_authType;
+};
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index 7c30f877..5caa4838 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -1221,10 +1221,18 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
             return i->mobileMode();
         case FontSize:
             return i->fontSize();
-        case Font:
-            return data(index, Values).toStringList().indexOf(i->font());
-        case EmojiFont:
-            return data(index, Values).toStringList().indexOf(i->emojiFont());
+        case Font: {
+            if (i->font().isEmpty())
+                return 0;
+            else
+                return data(index, Values).toStringList().indexOf(i->font());
+        }
+        case EmojiFont: {
+            if (i->emojiFont().isEmpty())
+                return 0;
+            else
+                return data(index, Values).toStringList().indexOf(i->emojiFont());
+        }
         case Ringtone: {
             auto v = i->ringtone();
             if (v == QStringView(u"Mute"))
@@ -1612,10 +1620,16 @@ UserSettingsModel::data(const QModelIndex &index, int role) const
             return vecToList(CallDevices::instance().frameRates(
               i->camera().toStdString(), i->cameraResolution().toStdString()));
 
-        case Font:
-            return QFontDatabase::families();
-        case EmojiFont:
-            return QFontDatabase::families(QFontDatabase::WritingSystem::Symbol);
+        case Font: {
+            auto fonts = QFontDatabase::families();
+            fonts.prepend(tr("System font"));
+            return fonts;
+        }
+        case EmojiFont: {
+            auto fonts = QFontDatabase::families(QFontDatabase::WritingSystem::Symbol);
+            fonts.prepend(tr("System emoji font"));
+            return fonts;
+        }
         case Ringtone: {
             QStringList l{
               QStringLiteral("Mute"),
@@ -1908,15 +1922,20 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int
         }
         case Font: {
             if (value.userType() == QMetaType::Int) {
-                i->setFontFamily(QFontDatabase::families().at(value.toInt()));
+                // Special handling to grab our injected system font option
+                auto v = value.toInt();
+                i->setFontFamily(v == 0 ? QString{} : QFontDatabase::families().at(v - 1));
                 return true;
             } else
                 return false;
         }
         case EmojiFont: {
             if (value.userType() == QMetaType::Int) {
+                // More special handling for the default font option
+                auto v = value.toInt();
                 i->setEmojiFontFamily(
-                  QFontDatabase::families(QFontDatabase::WritingSystem::Symbol).at(value.toInt()));
+                  v == 0 ? QStringLiteral("emoji")
+                         : QFontDatabase::families(QFontDatabase::WritingSystem::Symbol).at(v - 1));
                 return true;
             } else
                 return false;
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index 4e2691e5..71eb039b 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -12,15 +12,6 @@
 
 #include <optional>
 
-class Toggle;
-class QLabel;
-class QFormLayout;
-class QComboBox;
-class QFontComboBox;
-class QSpinBox;
-class QHBoxLayout;
-class QVBoxLayout;
-
 class UserSettings final : public QObject
 {
     Q_OBJECT
diff --git a/src/dialogs/FallbackAuth.cpp b/src/dialogs/FallbackAuth.cpp
deleted file mode 100644
index 9d59fc97..00000000
--- a/src/dialogs/FallbackAuth.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-FileCopyrightText: Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#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->setContentsMargins(conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN,
-                               conf::modals::WIDGET_MARGIN);
-
-    auto buttonLayout = new QHBoxLayout();
-    buttonLayout->setSpacing(8);
-    buttonLayout->setContentsMargins(0, 0, 0, 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, 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
deleted file mode 100644
index 62092b08..00000000
--- a/src/dialogs/FallbackAuth.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-FileCopyrightText: Nheko Contributors
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <QWidget>
-
-class QPushButton;
-class QLabel;
-
-namespace dialogs {
-
-class FallbackAuth final : 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/encryption/VerificationManager.h b/src/encryption/VerificationManager.h
index cdc8af30..24e1a206 100644
--- a/src/encryption/VerificationManager.h
+++ b/src/encryption/VerificationManager.h
@@ -14,7 +14,6 @@
 
 class DeviceVerificationFlow;
 class TimelineModel;
-class TimelineModel;
 class TimelineViewManager;
 class RoomlistModel;
 
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 752aedb0..b2a036c5 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -535,6 +535,7 @@ TimelineModel::roleNames() const
       {IsSender, "isSender"},
       {UserId, "userId"},
       {UserName, "userName"},
+      {UserPowerlevel, "userPowerlevel"},
       {Day, "day"},
       {Timestamp, "timestamp"},
       {Url, "url"},
@@ -597,6 +598,14 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
         return QVariant(QString::fromStdString(acc::sender(event)));
     case UserName:
         return QVariant(displayName(QString::fromStdString(acc::sender(event))));
+    case UserPowerlevel: {
+        return static_cast<qlonglong>(mtx::events::state::PowerLevels{
+          cache::client()
+            ->getStateEvent<mtx::events::state::PowerLevels>(room_id_.toStdString())
+            .value_or(mtx::events::StateEvent<mtx::events::state::PowerLevels>{})
+            .content}
+                                        .user_level(acc::sender(event)));
+    }
 
     case Day: {
         QDateTime prevDate = origin_server_ts(event);
@@ -1284,13 +1293,20 @@ TimelineModel::updateLastMessage()
 void
 TimelineModel::setCurrentIndex(int index)
 {
+    setCurrentIndex(index, false);
+}
+
+void
+TimelineModel::setCurrentIndex(int index, bool ignoreInactiveState)
+{
     auto oldIndex = idToIndex(currentId);
     currentId     = indexToId(index);
     if (index != oldIndex)
         emit currentIndexChanged(index);
 
-    if (!QGuiApplication::focusWindow() || !QGuiApplication::focusWindow()->isActive() ||
-        MainWindow::instance()->windowForRoom(roomId()) != QGuiApplication::focusWindow())
+    if (!ignoreInactiveState &&
+        (!QGuiApplication::focusWindow() || !QGuiApplication::focusWindow()->isActive() ||
+         MainWindow::instance()->windowForRoom(roomId()) != QGuiApplication::focusWindow()))
         return;
 
     if (!currentId.startsWith('m')) {
@@ -1562,6 +1578,12 @@ TimelineModel::markEventsAsRead(const std::vector<QString> &event_ids)
 }
 
 void
+TimelineModel::markRoomAsRead()
+{
+    setCurrentIndex(0, true);
+}
+
+void
 TimelineModel::updateLastReadId(const QString &currentRoomId)
 {
     if (currentRoomId == room_id_) {
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index fd1a4396..fccc99eb 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -241,6 +241,7 @@ public:
         IsSender,
         UserId,
         UserName,
+        UserPowerlevel,
         Day,
         Timestamp,
         Url,
@@ -386,9 +387,11 @@ public:
 
 public slots:
     void setCurrentIndex(int index);
+    void setCurrentIndex(int index, bool ignoreInactiveState);
     int currentIndex() const { return idToIndex(currentId); }
     void eventShown();
     void markEventsAsRead(const std::vector<QString> &event_ids);
+    void markRoomAsRead();
     void updateLastReadId(const QString &currentRoomId);
     void lastReadIdOnWindowFocus();
     void checkAfterFetch();
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 53179b44..f3bd04a2 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -7,7 +7,6 @@
 #include <QHash>
 #include <QQuickItem>
 #include <QQuickTextDocument>
-#include <QWidget>
 
 #include <mtx/common.hpp>
 #include <mtx/responses/messages.hpp>
diff --git a/src/ui/NhekoGlobalObject.cpp b/src/ui/NhekoGlobalObject.cpp
index 1bab73b5..54c4c1c9 100644
--- a/src/ui/NhekoGlobalObject.cpp
+++ b/src/ui/NhekoGlobalObject.cpp
@@ -153,7 +153,6 @@ Nheko::createRoom(bool space,
     if (space) {
         req.creation_content       = mtx::events::state::Create{};
         req.creation_content->type = mtx::events::state::room_type::space;
-        req.creation_content->creator.clear();
         req.creation_content->room_version.clear();
     }
 
diff --git a/src/ui/UIA.cpp b/src/ui/UIA.cpp
index 9654c9aa..4c1d35b9 100644
--- a/src/ui/UIA.cpp
+++ b/src/ui/UIA.cpp
@@ -13,8 +13,6 @@
 
 #include "Logging.h"
 #include "MatrixClient.h"
-#include "ReCaptcha.h"
-#include "dialogs/FallbackAuth.h"
 
 UIA *
 UIA::instance()
@@ -132,23 +130,18 @@ UIA::genericHandler(QString context)
                 }
             } else {
                 // use fallback
-                auto dialog = new dialogs::FallbackAuth(QString::fromStdString(current_stage),
-                                                        QString::fromStdString(u.session),
-                                                        nullptr);
-                dialog->setWindowTitle(context);
-
-                connect(dialog, &dialogs::FallbackAuth::confirmation, this, [h, u, dialog]() {
-                    dialog->close();
-                    dialog->deleteLater();
+                auto fallback = new FallbackAuth(QString::fromStdString(u.session),
+                                                 QString::fromStdString(current_stage),
+                                                 nullptr);
+                QQmlEngine::setObjectOwnership(fallback, QQmlEngine::JavaScriptOwnership);
+                connect(fallback, &FallbackAuth::confirmation, this, [h, u]() {
                     h.next(mtx::user_interactive::Auth{u.session,
                                                        mtx::user_interactive::auth::Fallback{}});
                 });
-
-                connect(dialog, &dialogs::FallbackAuth::cancel, this, [this]() {
+                connect(fallback, &FallbackAuth::cancelled, this, [this]() {
                     emit error(tr("Registration aborted"));
                 });
-
-                dialog->show();
+                emit fallbackAuth(fallback);
             }
         });
     });
diff --git a/src/ui/UIA.h b/src/ui/UIA.h
index 5b5eb9f4..2bff6948 100644
--- a/src/ui/UIA.h
+++ b/src/ui/UIA.h
@@ -9,6 +9,7 @@
 
 #include <mtxclient/http/client.hpp>
 
+#include "FallbackAuth.h"
 #include "ReCaptcha.h"
 
 class UIA final : public QObject
@@ -62,6 +63,7 @@ signals:
     void email();
     void phoneNumber();
     void reCaptcha(ReCaptcha *recaptcha);
+    void fallbackAuth(FallbackAuth *fallback);
 
     void confirm3pidToken();
     void prompt3pidToken();
diff --git a/src/voip/ScreenCastPortal.cpp b/src/voip/ScreenCastPortal.cpp
index 6cd91e51..83f7595b 100644
--- a/src/voip/ScreenCastPortal.cpp
+++ b/src/voip/ScreenCastPortal.cpp
@@ -420,16 +420,15 @@ ScreenCastPortal::start()
 
     QDBusPendingCall pendingCall     = QDBusConnection::sessionBus().asyncCall(msg);
     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
-    connect(
-      watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
-          self->deleteLater();
-          QDBusPendingReply<QDBusObjectPath> reply = *self;
+    connect(watcher, &QDBusPendingCallWatcher::finished, this, [](QDBusPendingCallWatcher *self) {
+        self->deleteLater();
+        QDBusPendingReply<QDBusObjectPath> reply = *self;
 
-          if (!reply.isValid()) {
-              nhlog::ui()->error("org.freedesktop.portal.ScreenCast (Start): {}",
-                                 reply.error().message().toStdString());
-          }
-      });
+        if (!reply.isValid()) {
+            nhlog::ui()->error("org.freedesktop.portal.ScreenCast (Start): {}",
+                               reply.error().message().toStdString());
+        }
+    });
 }
 
 struct PipeWireStream
@@ -502,7 +501,7 @@ ScreenCastPortal::openPipeWireRemote()
                                  reply.error().message().toStdString());
               close();
           } else {
-              stream.fd = std::move(reply.value());
+              stream.fd = reply.value();
               nhlog::ui()->error("org.freedesktop.portal.ScreenCast: fd = {}",
                                  stream.fd.fileDescriptor());
               state = State::Started;