diff --git a/CMakeLists.txt b/CMakeLists.txt index ef57e213..a4331d25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -581,7 +581,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG 842e10c4ae36aba23a20849e766f0c54b19fd4b6 + GIT_TAG 6f908f379c6d7afb6117baee3a59c6f5e3adfdda ) set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml index 3d7b7d39..8b71d79b 100644 --- a/io.github.NhekoReborn.Nheko.yaml +++ b/io.github.NhekoReborn.Nheko.yaml @@ -203,7 +203,7 @@ modules: buildsystem: cmake-ninja name: mtxclient sources: - - commit: 842e10c4ae36aba23a20849e766f0c54b19fd4b6 + - commit: 6f908f379c6d7afb6117baee3a59c6f5e3adfdda #tag: v0.7.0 type: git url: https://github.com/Nheko-Reborn/mtxclient.git diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 5b7f70dd..2ea5df05 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -420,6 +420,48 @@ Item { } + DelegateChoice { + roleValue: MtxEvent.PolicyRuleUser + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + keepFullText: d.keepFullText + isStateEvent: d.isStateEvent + formatted: d.relatedEventCacheBuster, room.formatPolicyRule(d.eventId) + } + + } + + DelegateChoice { + roleValue: MtxEvent.PolicyRuleRoom + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + keepFullText: d.keepFullText + isStateEvent: d.isStateEvent + formatted: d.relatedEventCacheBuster, room.formatPolicyRule(d.eventId) + } + + } + + DelegateChoice { + roleValue: MtxEvent.PolicyRuleServer + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + keepFullText: d.keepFullText + isStateEvent: d.isStateEvent + formatted: d.relatedEventCacheBuster, room.formatPolicyRule(d.eventId) + } + + } + DelegateChoice { roleValue: MtxEvent.RoomJoinRules diff --git a/src/PowerlevelsEditModels.cpp b/src/PowerlevelsEditModels.cpp index 38ab42dc..fcfde26e 100644 --- a/src/PowerlevelsEditModels.cpp +++ b/src/PowerlevelsEditModels.cpp @@ -198,6 +198,13 @@ PowerlevelsTypeListModel::data(const QModelIndex &index, int role) const else if (type.type == "m.sticker") return tr("Send stickers"); + else if (type.type == "m.policy.rule.user") + return tr("Ban users using policy rules"); + else if (type.type == "m.policy.rule.room") + return tr("Ban rooms using policy rules"); + else if (type.type == "m.policy.rule.server") + return tr("Ban servers using policy rules"); + else if (type.type == "m.space.child") return tr("Edit child rooms"); else if (type.type == "m.space.parent") diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index ad0a8c11..767fdaa2 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -190,6 +190,12 @@ qml_mtx_events::toRoomEventType(mtx::events::EventType e) return qml_mtx_events::EventType::Sticker; case EventType::Tag: return qml_mtx_events::EventType::Tag; + case EventType::PolicyRuleUser: + return qml_mtx_events::EventType::PolicyRuleUser; + case EventType::PolicyRuleRoom: + return qml_mtx_events::EventType::PolicyRuleRoom; + case EventType::PolicyRuleServer: + return qml_mtx_events::EventType::PolicyRuleServer; case EventType::SpaceParent: return qml_mtx_events::EventType::SpaceParent; case EventType::SpaceChild: @@ -303,6 +309,12 @@ qml_mtx_events::fromRoomEventType(qml_mtx_events::EventType t) // m.tag case qml_mtx_events::Tag: return mtx::events::EventType::Tag; + case qml_mtx_events::PolicyRuleUser: + return mtx::events::EventType::PolicyRuleUser; + case qml_mtx_events::PolicyRuleRoom: + return mtx::events::EventType::PolicyRuleRoom; + case qml_mtx_events::PolicyRuleServer: + return mtx::events::EventType::PolicyRuleServer; // m.space.parent case qml_mtx_events::SpaceParent: return mtx::events::EventType::SpaceParent; @@ -2329,6 +2341,62 @@ TimelineModel::formatImagePackEvent(const QString &id) return msg; } +QString +TimelineModel::formatPolicyRule(const QString &id) +{ + mtx::events::collections::TimelineEvents *e = events.get(id.toStdString(), ""); + if (!e) + return {}; + + auto qsHtml = [](const std::string &s) { return QString::fromStdString(s).toHtmlEscaped(); }; + constexpr std::string_view unstable_ban = "org.matrix.mjolnir.ban"; + + if (auto userRule = + std::get_if>(e)) { + auto sender = utils::replaceEmoji(displayName(QString::fromStdString(userRule->sender))); + if (userRule->content.entity.empty() || + (userRule->content.recommendation != + mtx::events::state::policy_rule::recommendation::ban && + userRule->content.recommendation != unstable_ban)) { + return tr("%1 disabled the rule to ban users matching %2.") + .arg(sender, qsHtml(userRule->content.entity)); + } else { + return tr("%1 added a rule to ban users matching %2 for '%3'.") + .arg(sender, qsHtml(userRule->content.entity), qsHtml(userRule->content.reason)); + } + } else if (auto roomRule = + std::get_if>( + e)) { + auto sender = utils::replaceEmoji(displayName(QString::fromStdString(roomRule->sender))); + if (roomRule->content.entity.empty() || + (roomRule->content.recommendation != + mtx::events::state::policy_rule::recommendation::ban && + roomRule->content.recommendation != unstable_ban)) { + return tr("%1 disabled the rule to ban rooms matching %2.") + .arg(sender, qsHtml(roomRule->content.entity)); + } else { + return tr("%1 added a rule to ban rooms matching %2 for '%3'.") + .arg(sender, qsHtml(roomRule->content.entity), qsHtml(roomRule->content.reason)); + } + } else if (auto serverRule = + std::get_if>( + e)) { + auto sender = utils::replaceEmoji(displayName(QString::fromStdString(serverRule->sender))); + if (serverRule->content.entity.empty() || + (serverRule->content.recommendation != + mtx::events::state::policy_rule::recommendation::ban && + serverRule->content.recommendation != unstable_ban)) { + return tr("%1 disabled the rule to ban servers matching %2.") + .arg(sender, qsHtml(serverRule->content.entity)); + } else { + return tr("%1 added a rule to ban servers matching %2 for '%3'.") + .arg(sender, qsHtml(serverRule->content.entity), qsHtml(serverRule->content.reason)); + } + } + + return {}; +} + QVariantMap TimelineModel::formatRedactedEvent(const QString &id) { diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index dcafae80..6d424981 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -116,6 +116,12 @@ enum EventType ImagePackInAccountData, //! m.image_pack.rooms, currently im.ponies.emote_rooms ImagePackRooms, + // m.policy.rule.user + PolicyRuleUser, + // m.policy.rule.room + PolicyRuleRoom, + // m.policy.rule.server + PolicyRuleServer, // m.space.parent SpaceParent, // m.space.child @@ -264,6 +270,7 @@ public: Q_INVOKABLE QString formatGuestAccessEvent(const QString &id); Q_INVOKABLE QString formatPowerLevelEvent(const QString &id); Q_INVOKABLE QString formatImagePackEvent(const QString &id); + Q_INVOKABLE QString formatPolicyRule(const QString &id); Q_INVOKABLE QVariantMap formatRedactedEvent(const QString &id); Q_INVOKABLE void viewRawMessage(const QString &id);