summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2022-02-12 19:27:51 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2022-02-12 19:48:53 +0100
commit47b822604d81a6c603ce6c9e868456c8ccc2e18d (patch)
tree73f06796cff7941b9f0e7ab2b2a9e59054da0afa /src
parentHidden events: Make reusable read function (diff)
downloadnheko-47b822604d81a6c603ce6c9e868456c8ccc2e18d.tar.xz
Hidden events: Refactor slightly for reusability
Diffstat (limited to 'src')
-rw-r--r--src/Cache.cpp56
-rw-r--r--src/MainWindow.cpp2
-rw-r--r--src/timeline/TimelineModel.cpp112
-rw-r--r--src/timeline/TimelineModel.h2
-rw-r--r--src/ui/HiddenEvents.cpp93
-rw-r--r--src/ui/HiddenEvents.h46
-rw-r--r--src/ui/RoomSettings.cpp50
-rw-r--r--src/ui/RoomSettings.h5
8 files changed, 243 insertions, 123 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 9f3ada58..6bad336a 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -173,24 +173,31 @@ Cache::isHiddenEvent(lmdb::txn &txn,
     }
 
     mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents;
-    hiddenEvents.hidden_event_types = {
-      EventType::Reaction, EventType::CallCandidates, EventType::Unsupported};
-
-    if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, ""))
-        hiddenEvents =
-          std::move(std::get<mtx::events::AccountDataEvent<
-                      mtx::events::account_data::nheko_extensions::HiddenEvents>>(*temp)
-                      .content);
-    if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, room_id))
-        hiddenEvents =
-          std::move(std::get<mtx::events::AccountDataEvent<
-                      mtx::events::account_data::nheko_extensions::HiddenEvents>>(*temp)
-                      .content);
+    hiddenEvents.hidden_event_types = std::vector{
+      EventType::Reaction,
+      EventType::CallCandidates,
+      EventType::Unsupported,
+    };
+
+    if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, "")) {
+        auto h = std::get<
+          mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::HiddenEvents>>(
+          *temp);
+        if (h.content.hidden_event_types)
+            hiddenEvents = std::move(h.content);
+    }
+    if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, room_id)) {
+        auto h = std::get<
+          mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::HiddenEvents>>(
+          *temp);
+        if (h.content.hidden_event_types)
+            hiddenEvents = std::move(h.content);
+    }
 
     return std::visit(
       [hiddenEvents](const auto &ev) {
-          return std::any_of(hiddenEvents.hidden_event_types.begin(),
-                             hiddenEvents.hidden_event_types.end(),
+          return std::any_of(hiddenEvents.hidden_event_types->begin(),
+                             hiddenEvents.hidden_event_types->end(),
                              [ev](EventType type) { return type == ev.type; });
       },
       e);
@@ -1515,6 +1522,16 @@ Cache::saveState(const mtx::responses::Sync &res)
         for (const auto &ev : res.account_data.events)
             std::visit(
               [&txn, &accountDataDb](const auto &event) {
+                  if constexpr (std::is_same_v<
+                                  std::remove_cv_t<std::remove_reference_t<decltype(event)>>,
+                                  AccountDataEvent<
+                                    mtx::events::account_data::nheko_extensions::HiddenEvents>>) {
+                      if (!event.content.hidden_event_types) {
+                          accountDataDb.del(txn, "im.nheko.hidden_events");
+                          return;
+                      }
+                  }
+
                   auto j = json(event);
                   accountDataDb.put(txn, j["type"].get<std::string>(), j.dump());
               },
@@ -1589,6 +1606,15 @@ Cache::saveState(const mtx::responses::Sync &res)
             for (const auto &evt : room.second.account_data.events) {
                 std::visit(
                   [&txn, &accountDataDb](const auto &event) {
+                      if constexpr (std::is_same_v<
+                                      std::remove_cv_t<std::remove_reference_t<decltype(event)>>,
+                                      AccountDataEvent<mtx::events::account_data::nheko_extensions::
+                                                         HiddenEvents>>) {
+                          if (!event.content.hidden_event_types) {
+                              accountDataDb.del(txn, "im.nheko.hidden_events");
+                              return;
+                          }
+                      }
                       auto j = json(event);
                       accountDataDb.put(txn, j["type"].get<std::string>(), j.dump());
                   },
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 83504d86..01a05891 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -44,6 +44,7 @@
 #include "encryption/SelfVerificationStatus.h"
 #include "timeline/DelegateChooser.h"
 #include "timeline/TimelineViewManager.h"
+#include "ui/HiddenEvents.h"
 #include "ui/MxcAnimatedImage.h"
 #include "ui/MxcMediaProxy.h"
 #include "ui/NhekoCursorShape.h"
@@ -168,6 +169,7 @@ MainWindow::registerQmlTypes()
     qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
     qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login");
     qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration");
+    qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents");
     qmlRegisterUncreatableType<DeviceVerificationFlow>(
       "im.nheko",
       1,
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index c7aa0fa2..662bbb38 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -50,59 +50,7 @@ struct RoomEventType
     template<class T>
     qml_mtx_events::EventType operator()(const mtx::events::Event<T> &e)
     {
-        using mtx::events::EventType;
-        switch (e.type) {
-        case EventType::RoomKeyRequest:
-            return qml_mtx_events::EventType::KeyRequest;
-        case EventType::Reaction:
-            return qml_mtx_events::EventType::Reaction;
-        case EventType::RoomAliases:
-            return qml_mtx_events::EventType::Aliases;
-        case EventType::RoomAvatar:
-            return qml_mtx_events::EventType::Avatar;
-        case EventType::RoomCanonicalAlias:
-            return qml_mtx_events::EventType::CanonicalAlias;
-        case EventType::RoomCreate:
-            return qml_mtx_events::EventType::RoomCreate;
-        case EventType::RoomEncrypted:
-            return qml_mtx_events::EventType::Encrypted;
-        case EventType::RoomEncryption:
-            return qml_mtx_events::EventType::Encryption;
-        case EventType::RoomGuestAccess:
-            return qml_mtx_events::EventType::RoomGuestAccess;
-        case EventType::RoomHistoryVisibility:
-            return qml_mtx_events::EventType::RoomHistoryVisibility;
-        case EventType::RoomJoinRules:
-            return qml_mtx_events::EventType::RoomJoinRules;
-        case EventType::RoomMember:
-            return qml_mtx_events::EventType::Member;
-        case EventType::RoomMessage:
-            return qml_mtx_events::EventType::UnknownMessage;
-        case EventType::RoomName:
-            return qml_mtx_events::EventType::Name;
-        case EventType::RoomPowerLevels:
-            return qml_mtx_events::EventType::PowerLevels;
-        case EventType::RoomTopic:
-            return qml_mtx_events::EventType::Topic;
-        case EventType::RoomTombstone:
-            return qml_mtx_events::EventType::Tombstone;
-        case EventType::RoomRedaction:
-            return qml_mtx_events::EventType::Redaction;
-        case EventType::RoomPinnedEvents:
-            return qml_mtx_events::EventType::PinnedEvents;
-        case EventType::Sticker:
-            return qml_mtx_events::EventType::Sticker;
-        case EventType::Tag:
-            return qml_mtx_events::EventType::Tag;
-        case EventType::SpaceParent:
-            return qml_mtx_events::EventType::SpaceParent;
-        case EventType::SpaceChild:
-            return qml_mtx_events::EventType::SpaceChild;
-        case EventType::Unsupported:
-            return qml_mtx_events::EventType::Unsupported;
-        default:
-            return qml_mtx_events::EventType::UnknownMessage;
-        }
+        return qml_mtx_events::toRoomEventType(e.type);
     }
     qml_mtx_events::EventType operator()(const mtx::events::Event<mtx::events::msg::Audio> &)
     {
@@ -199,6 +147,64 @@ struct RoomEventType
 }
 
 qml_mtx_events::EventType
+qml_mtx_events::toRoomEventType(mtx::events::EventType e)
+{
+    using mtx::events::EventType;
+    switch (e) {
+    case EventType::RoomKeyRequest:
+        return qml_mtx_events::EventType::KeyRequest;
+    case EventType::Reaction:
+        return qml_mtx_events::EventType::Reaction;
+    case EventType::RoomAliases:
+        return qml_mtx_events::EventType::Aliases;
+    case EventType::RoomAvatar:
+        return qml_mtx_events::EventType::Avatar;
+    case EventType::RoomCanonicalAlias:
+        return qml_mtx_events::EventType::CanonicalAlias;
+    case EventType::RoomCreate:
+        return qml_mtx_events::EventType::RoomCreate;
+    case EventType::RoomEncrypted:
+        return qml_mtx_events::EventType::Encrypted;
+    case EventType::RoomEncryption:
+        return qml_mtx_events::EventType::Encryption;
+    case EventType::RoomGuestAccess:
+        return qml_mtx_events::EventType::RoomGuestAccess;
+    case EventType::RoomHistoryVisibility:
+        return qml_mtx_events::EventType::RoomHistoryVisibility;
+    case EventType::RoomJoinRules:
+        return qml_mtx_events::EventType::RoomJoinRules;
+    case EventType::RoomMember:
+        return qml_mtx_events::EventType::Member;
+    case EventType::RoomMessage:
+        return qml_mtx_events::EventType::UnknownMessage;
+    case EventType::RoomName:
+        return qml_mtx_events::EventType::Name;
+    case EventType::RoomPowerLevels:
+        return qml_mtx_events::EventType::PowerLevels;
+    case EventType::RoomTopic:
+        return qml_mtx_events::EventType::Topic;
+    case EventType::RoomTombstone:
+        return qml_mtx_events::EventType::Tombstone;
+    case EventType::RoomRedaction:
+        return qml_mtx_events::EventType::Redaction;
+    case EventType::RoomPinnedEvents:
+        return qml_mtx_events::EventType::PinnedEvents;
+    case EventType::Sticker:
+        return qml_mtx_events::EventType::Sticker;
+    case EventType::Tag:
+        return qml_mtx_events::EventType::Tag;
+    case EventType::SpaceParent:
+        return qml_mtx_events::EventType::SpaceParent;
+    case EventType::SpaceChild:
+        return qml_mtx_events::EventType::SpaceChild;
+    case EventType::Unsupported:
+        return qml_mtx_events::EventType::Unsupported;
+    default:
+        return qml_mtx_events::EventType::UnknownMessage;
+    }
+}
+
+qml_mtx_events::EventType
 toRoomEventType(const mtx::events::collections::TimelineEvents &event)
 {
     return std::visit(RoomEventType{}, event);
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index f6cc1e6b..6cdff285 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -125,6 +125,8 @@ enum EventType
 };
 Q_ENUM_NS(EventType)
 mtx::events::EventType fromRoomEventType(qml_mtx_events::EventType);
+qml_mtx_events::EventType
+toRoomEventType(mtx::events::EventType e);
 
 enum EventState
 {
diff --git a/src/ui/HiddenEvents.cpp b/src/ui/HiddenEvents.cpp
new file mode 100644
index 00000000..a8da812e
--- /dev/null
+++ b/src/ui/HiddenEvents.cpp
@@ -0,0 +1,93 @@
+// SPDX-FileCopyrightText: 2022 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "HiddenEvents.h"
+
+#include "Cache_p.h"
+#include "MainWindow.h"
+#include "MatrixClient.h"
+
+void
+HiddenEvents::load()
+{
+    using namespace mtx::events;
+    mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents;
+    hiddenEvents.hidden_event_types = std::vector{
+      EventType::Reaction,
+      EventType::CallCandidates,
+      EventType::Unsupported,
+    };
+
+    if (auto temp =
+          cache::client()->getAccountData(mtx::events::EventType::NhekoHiddenEvents, "")) {
+        auto h = std::get<
+          mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::HiddenEvents>>(
+          *temp);
+        if (h.content.hidden_event_types)
+            hiddenEvents = std::move(h.content);
+    }
+
+    if (!roomid_.isEmpty()) {
+        if (auto temp = cache::client()->getAccountData(mtx::events::EventType::NhekoHiddenEvents,
+                                                        roomid_.toStdString())) {
+            auto h = std::get<mtx::events::AccountDataEvent<
+              mtx::events::account_data::nheko_extensions::HiddenEvents>>(*temp);
+            if (h.content.hidden_event_types)
+                hiddenEvents = std::move(h.content);
+        }
+    }
+
+    hiddenEvents_.clear();
+    hiddenEvents_ = std::move(hiddenEvents.hidden_event_types.value());
+    emit hiddenEventsChanged();
+}
+
+Q_INVOKABLE void
+HiddenEvents::toggle(int type)
+{
+    auto t = qml_mtx_events::fromRoomEventType(static_cast<qml_mtx_events::EventType>(type));
+    if (auto it = std::find(begin(hiddenEvents_), end(hiddenEvents_), t); it != end(hiddenEvents_))
+        hiddenEvents_.erase(it);
+    else
+        hiddenEvents_.push_back(t);
+    emit hiddenEventsChanged();
+}
+
+QVariantList
+HiddenEvents::hiddenEvents() const
+{
+    QVariantList l;
+    for (const auto &e : hiddenEvents_) {
+        l.push_back(qml_mtx_events::toRoomEventType(e));
+    }
+
+    return l;
+}
+
+void
+HiddenEvents::save()
+{
+    mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents;
+    hiddenEvents.hidden_event_types = hiddenEvents_;
+
+    if (roomid_.isEmpty())
+        http::client()->put_account_data(hiddenEvents, [](mtx::http::RequestErr e) {
+            if (e) {
+                nhlog::net()->error("Failed to set hidden events: {}", *e);
+                MainWindow::instance()->showNotification(
+                  tr("Failed to set hidden events: %1")
+                    .arg(QString::fromStdString(e->matrix_error.error)));
+            }
+        });
+    else
+        http::client()->put_room_account_data(
+          roomid_.toStdString(), hiddenEvents, [](mtx::http::RequestErr e) {
+              if (e) {
+                  nhlog::net()->error("Failed to set hidden events: {}", *e);
+                  MainWindow::instance()->showNotification(
+                    tr("Failed to set hidden events: %1")
+                      .arg(QString::fromStdString(e->matrix_error.error)));
+              }
+          });
+}
diff --git a/src/ui/HiddenEvents.h b/src/ui/HiddenEvents.h
new file mode 100644
index 00000000..928b14ba
--- /dev/null
+++ b/src/ui/HiddenEvents.h
@@ -0,0 +1,46 @@
+// SPDX-FileCopyrightText: 2022 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <QObject>
+#include <QString>
+#include <QVariantList>
+
+#include "timeline/TimelineModel.h"
+
+class HiddenEvents : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged REQUIRED)
+    Q_PROPERTY(QVariantList hiddenEvents READ hiddenEvents NOTIFY hiddenEventsChanged)
+public:
+    explicit HiddenEvents(QObject *p = nullptr)
+      : QObject(p)
+    {}
+
+    Q_INVOKABLE void toggle(int type);
+    Q_INVOKABLE void save();
+
+    [[nodiscard]] QString roomid() const { return roomid_; }
+    void setRoomid(const QString &r)
+    {
+        roomid_ = r;
+        emit roomidChanged();
+
+        load();
+    }
+
+    [[nodiscard]] QVariantList hiddenEvents() const;
+
+signals:
+    void roomidChanged();
+    void hiddenEventsChanged();
+
+private:
+    QString roomid_;
+    std::vector<mtx::events::EventType> hiddenEvents_;
+
+    void load();
+};
diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp
index b7fb0887..43a11b7f 100644
--- a/src/ui/RoomSettings.cpp
+++ b/src/ui/RoomSettings.cpp
@@ -13,7 +13,6 @@
 #include <QStandardPaths>
 #include <QVBoxLayout>
 #include <mtx/events/event_type.hpp>
-#include <mtx/events/nheko_extensions/hidden_events.hpp>
 #include <mtx/responses/common.hpp>
 #include <mtx/responses/media.hpp>
 #include <mtxclient/http/client.hpp>
@@ -228,8 +227,6 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
         accessRules_ = 4;
     }
     emit accessJoinRulesChanged();
-
-    readHiddenEventsSettings(roomid_);
 }
 
 QString
@@ -641,50 +638,3 @@ RoomSettings::updateAvatar()
             });
       });
 }
-
-void
-RoomSettings::saveHiddenEventsSettings(const QSet<QString> &events, const QString &roomId)
-{
-    account_data::nheko_extensions::HiddenEvents hiddenEvents;
-    hiddenEvents.hidden_event_types = {
-      EventType::Reaction, EventType::CallCandidates, EventType::Unsupported};
-    for (const auto &event : events) {
-        hiddenEvents.hidden_event_types.emplace_back(getEventType(event.toStdString()));
-    }
-
-    if (!roomId.isEmpty()) {
-        const auto rid = roomId.toStdString();
-        http::client()->put_room_account_data(rid, hiddenEvents, [&rid](mtx::http::RequestErr e) {
-            if (e) {
-                nhlog::net()->error(
-                  "Failed to update room account data with hidden events in {}: {}", rid, *e);
-            }
-        });
-    } else {
-        http::client()->put_account_data(hiddenEvents, [](mtx::http::RequestErr e) {
-            if (e) {
-                nhlog::net()->error("Failed to update account data with hidden events: {}", *e);
-            }
-        });
-    }
-}
-
-bool
-RoomSettings::eventHidden(const QString event) const
-{
-    return hiddenEvents_.contains(event);
-}
-
-void
-RoomSettings::readHiddenEventsSettings(const QString &roomId)
-{
-    if (auto hiddenEvents = cache::client()->getAccountData(
-          mtx::events::EventType::NhekoHiddenEvents, roomId.toStdString())) {
-        if (auto tmp = std::get_if<mtx::events::EphemeralEvent<
-              mtx::events::account_data::nheko_extensions::HiddenEvents>>(&*hiddenEvents)) {
-            for (const auto event : tmp->content.hidden_event_types) {
-                hiddenEvents_.insert(mtx::events::to_string(event).data());
-            }
-        }
-    }
-}
diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h
index 438ac979..f79aa3f7 100644
--- a/src/ui/RoomSettings.h
+++ b/src/ui/RoomSettings.h
@@ -111,9 +111,6 @@ public:
     Q_INVOKABLE void openEditModal();
     Q_INVOKABLE void changeAccessRules(int index);
     Q_INVOKABLE void changeNotifications(int currentIndex);
-    Q_INVOKABLE void
-    saveHiddenEventsSettings(const QSet<QString> &events, const QString &roomId = {});
-    Q_INVOKABLE bool eventHidden(QString event) const;
 
 signals:
     void loadingChanged();
@@ -134,7 +131,6 @@ private:
     void updateAccessRules(const std::string &room_id,
                            const mtx::events::state::JoinRules &,
                            const mtx::events::state::GuestAccess &);
-    void readHiddenEventsSettings(const QString &roomId = {});
 
 private:
     QString roomid_;
@@ -143,5 +139,4 @@ private:
     RoomInfo info_;
     int notifications_ = 0;
     int accessRules_   = 0;
-    QSet<QString> hiddenEvents_;
 };