From 5cd3e61cb0e39bdbbef0ccf3c252c3c65ba2824f Mon Sep 17 00:00:00 2001 From: tastytea Date: Tue, 11 Jan 2022 07:38:27 +0100 Subject: [PATCH] Add GUI to change hidden events per room This adds a dialog to the room settings in which the user can choose which of these three event types they want to hide (additionally to the default): - m.room.member - m.room.power_levels - m.sticker The current state is read when room settings are opened and saved when new settings are accepted. --- resources/qml/dialogs/HiddenEventsDialog.qml | 108 +++++++++++++++++++ resources/qml/dialogs/RoomSettings.qml | 17 ++- resources/res.qrc | 1 + src/ui/RoomSettings.cpp | 70 ++++++++++++ src/ui/RoomSettings.h | 5 + 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 resources/qml/dialogs/HiddenEventsDialog.qml diff --git a/resources/qml/dialogs/HiddenEventsDialog.qml b/resources/qml/dialogs/HiddenEventsDialog.qml new file mode 100644 index 00000000..cfe75b06 --- /dev/null +++ b/resources/qml/dialogs/HiddenEventsDialog.qml @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2022 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import ".." +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 +import im.nheko 1.0 + +ApplicationWindow { + id: hiddenEventsDialog + + property alias prompt: promptLabel.text + property var onAccepted: undefined + + modality: Qt.NonModal + flags: Qt.Dialog + minimumWidth: 250 + minimumHeight: 220 + Component.onCompleted: Nheko.reparent(hiddenEventsDialog) + title: qsTr("Hidden events settings for %1").arg(roomSettings.roomName) + + Shortcut { + sequence: StandardKey.Cancel + onActivated: dbb.rejected() + } + + ColumnLayout { + spacing: Nheko.paddingMedium + anchors.margins: Nheko.paddingMedium + anchors.fill: parent + + MatrixText { + id: promptLabel + font.pixelSize: Math.floor(fontMetrics.font.pixelSize * 1.2) + Layout.fillWidth: true + Layout.fillHeight: false + } + + GridLayout { + columns: 2 + rowSpacing: Nheko.paddingMedium + Layout.fillWidth: true + Layout.fillHeight: true + + MatrixText { + text: qsTr("User events") + ToolTip.text: qsTr("Joins, leaves, invites, knocks and bans") + ToolTip.visible: hh1.hovered + Layout.fillWidth: true + + HoverHandler { + id: hh1 + } + } + + ToggleButton { + id: toggleRoomMember + checked: roomSettings.eventHidden(0) + Layout.alignment: Qt.AlignRight + } + + MatrixText { + text: qsTr("Power level changes") + ToolTip.text: qsTr("Is sent when a moderator is added or removed or the permissions of a room are changed (happens a lot in some IRC rooms)") + ToolTip.visible: hh2.hovered + Layout.fillWidth: true + + HoverHandler { + id: hh2 + } + } + + ToggleButton { + id: toggleRoomPowerLevels + checked: roomSettings.eventHidden(1) + Layout.alignment: Qt.AlignRight + } + + MatrixText { + text: qsTr("Stickers") + Layout.fillWidth: true + } + + ToggleButton { + id: toggleSticker + Layout.alignment: Qt.AlignRight + checked: roomSettings.eventHidden(2) + } + } + } + + footer: DialogButtonBox { + id: dbb + + standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel + onAccepted: { + roomSettings.saveHiddenEventsSettings(toggleRoomMember.checked, toggleRoomPowerLevels.checked, toggleSticker.checked); + + hiddenEventsDialog.close(); + } + onRejected: { + hiddenEventsDialog.close(); + } + } + +} diff --git a/resources/qml/dialogs/RoomSettings.qml b/resources/qml/dialogs/RoomSettings.qml index fad7b4c7..dbf22b29 100644 --- a/resources/qml/dialogs/RoomSettings.qml +++ b/resources/qml/dialogs/RoomSettings.qml @@ -254,6 +254,22 @@ ApplicationWindow { Layout.alignment: Qt.AlignRight } + MatrixText { + text: qsTr("Hidden events") + } + + HiddenEventsDialog { + id: hiddenEventsDialog + prompt: qsTr("Select the events you want to hide from %1").arg(roomSettings.roomName) + } + + Button { + text: qsTr("Configure") + ToolTip.text: qsTr("Change which events are hidden in this room") + onClicked: hiddenEventsDialog.show() + Layout.alignment: Qt.AlignRight + } + Item { // for adding extra space between sections Layout.fillWidth: true @@ -302,5 +318,4 @@ ApplicationWindow { } } - } diff --git a/resources/res.qrc b/resources/res.qrc index 2fba5f4c..c8659150 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -152,6 +152,7 @@ qml/dialogs/RoomMembers.qml qml/dialogs/RoomSettings.qml qml/dialogs/UserProfile.qml + qml/dialogs/HiddenEventsDialog.qml qml/emoji/EmojiPicker.qml qml/emoji/StickerPicker.qml qml/ui/NhekoSlider.qml diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp index 5407edee..2180b5c1 100644 --- a/src/ui/RoomSettings.cpp +++ b/src/ui/RoomSettings.cpp @@ -12,14 +12,19 @@ #include #include #include +#include #include #include #include "Cache.h" +#include "Cache_p.h" #include "Config.h" #include "Logging.h" #include "MatrixClient.h" #include "Utils.h" +#include "mtx/events/event_type.hpp" +#include "mtx/events/nheko_extensions/hidden_events.hpp" +#include "mtxclient/http/client.hpp" #include "ui/TextField.h" using namespace mtx::events; @@ -224,6 +229,25 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent) accessRules_ = 4; } emit accessJoinRulesChanged(); + + // Get room's hidden events and store it in member variable. + using mtx::events::EventType; + if (auto hiddenEvents = + cache::client()->getAccountData(EventType::NhekoHiddenEvents, roomid_.toStdString())) { + if (auto tmp = std::get_if>(&*hiddenEvents)) { + const auto &types = tmp->content.hidden_event_types; + auto is_hidden{[&types](EventType searchFor) { + return std::find_if(types.begin(), types.end(), [&searchFor](const auto curType) { + return curType == searchFor; + }) != types.end(); + }}; + + hiddenEvents_ = {is_hidden(EventType::RoomMember), + is_hidden(EventType::RoomPowerLevels), + is_hidden(EventType::Sticker)}; + } + } } QString @@ -294,6 +318,20 @@ RoomSettings::accessJoinRules() return accessRules_; } +bool +RoomSettings::eventHidden(int index) +{ + try { + // Is empty if there are no preferences stored for this room. + if (!hiddenEvents_.empty()) { + return hiddenEvents_.at(index); + } + } catch (...) { + nhlog::db()->warn("Failed to retrieve hidden event setting at {}", index); + } + return false; +} + void RoomSettings::enableEncryption() { @@ -404,6 +442,38 @@ RoomSettings::openEditModal() }); } +void +RoomSettings::saveHiddenEventsSettings(const bool toggleRoomMember, + const bool toggleRoomPowerLevels, + const bool toggleSticker) +{ + const auto roomid = roomid_.toStdString(); + nhlog::ui()->debug("Setting events to hidden in room {}: m.room.member={}, " + "m.room.power_levels={}, m.sticker={}", + roomid, + toggleRoomMember, + toggleRoomPowerLevels, + toggleSticker); + + mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents; + hiddenEvents.hidden_event_types = { + EventType::Reaction, EventType::CallCandidates, EventType::Unsupported}; + if (toggleRoomMember) { + hiddenEvents.hidden_event_types.emplace_back(mtx::events::EventType::RoomMember); + } + if (toggleRoomPowerLevels) { + hiddenEvents.hidden_event_types.emplace_back(mtx::events::EventType::RoomPowerLevels); + } + if (toggleSticker) { + hiddenEvents.hidden_event_types.emplace_back(mtx::events::EventType::Sticker); + } + http::client()->put_room_account_data(roomid, hiddenEvents, [&roomid](mtx::http::RequestErr e) { + if (e) { + nhlog::net()->error("Failed to update room account data in {}: {}", roomid, *e); + } + }); +} + void RoomSettings::changeNotifications(int currentIndex) { diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h index 75b7bae0..ee353d44 100644 --- a/src/ui/RoomSettings.h +++ b/src/ui/RoomSettings.h @@ -11,6 +11,7 @@ #include #include +#include #include "CacheStructs.h" @@ -107,8 +108,11 @@ public: Q_INVOKABLE void enableEncryption(); Q_INVOKABLE void updateAvatar(); Q_INVOKABLE void openEditModal(); + Q_INVOKABLE void + saveHiddenEventsSettings(bool toggleRoomMember, bool toggleRoomPowerLevels, bool toggleSticker); Q_INVOKABLE void changeAccessRules(int index); Q_INVOKABLE void changeNotifications(int currentIndex); + Q_INVOKABLE bool eventHidden(int index); signals: void loadingChanged(); @@ -137,4 +141,5 @@ private: RoomInfo info_; int notifications_ = 0; int accessRules_ = 0; + std::vector hiddenEvents_; };