diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/events/roompowerlevelsevent.cpp | 62 | ||||
-rw-r--r-- | lib/events/roompowerlevelsevent.h | 76 | ||||
-rw-r--r-- | lib/room.cpp | 16 |
4 files changed, 143 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 11d7d194..9a17e1f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,7 @@ set(lib_SRCS lib/events/roomtombstoneevent.cpp lib/events/roommessageevent.cpp lib/events/roommemberevent.cpp + lib/events/roompowerlevelsevent.cpp lib/events/typingevent.cpp lib/events/receiptevent.cpp lib/events/reactionevent.cpp diff --git a/lib/events/roompowerlevelsevent.cpp b/lib/events/roompowerlevelsevent.cpp new file mode 100644 index 00000000..0a401752 --- /dev/null +++ b/lib/events/roompowerlevelsevent.cpp @@ -0,0 +1,62 @@ +#include "roompowerlevelsevent.h" + +#include <QJsonDocument> + +using namespace Quotient; + +PowerLevelsEventContent::PowerLevelsEventContent(const QJsonObject& json) : + invite(json["invite"_ls].toInt(50)), + kick(json["kick"_ls].toInt(50)), + ban(json["ban"_ls].toInt(50)), + redact(json["redact"_ls].toInt(50)), + events(fromJson<QHash<QString, int>>(json["events"_ls])), + eventsDefault(json["events_default"_ls].toInt(0)), + stateDefault(json["state_default"_ls].toInt(0)), + users(fromJson<QHash<QString, int>>(json["users"_ls])), + usersDefault(json["users_default"_ls].toInt(0)), + notifications(Notifications{json["notifications"_ls].toObject()["room"_ls].toInt(50)}) +{ +} + +void PowerLevelsEventContent::fillJson(QJsonObject* o) const { + o->insert(QStringLiteral("invite"), invite); + o->insert(QStringLiteral("kick"), kick); + o->insert(QStringLiteral("ban"), ban); + o->insert(QStringLiteral("redact"), redact); + o->insert(QStringLiteral("events"), Quotient::toJson(events)); + o->insert(QStringLiteral("events_default"), eventsDefault); + o->insert(QStringLiteral("state_default"), stateDefault); + o->insert(QStringLiteral("users"), Quotient::toJson(users)); + o->insert(QStringLiteral("users_default"), usersDefault); + o->insert(QStringLiteral("notifications"), QJsonObject{{"room", notifications.room}}); +} + +int RoomPowerLevelsEvent::powerLevelForEvent(const QString &eventId) const { + auto e = events(); + + if (e.contains(eventId)) { + return e[eventId]; + } + + return eventsDefault(); +} + +int RoomPowerLevelsEvent::powerLevelForState(const QString &eventId) const { + auto e = events(); + + if (e.contains(eventId)) { + return e[eventId]; + } + + return stateDefault(); +} + +int RoomPowerLevelsEvent::powerLevelForUser(const QString &userId) const { + auto u = users(); + + if (u.contains(userId)) { + return u[userId]; + } + + return usersDefault(); +} diff --git a/lib/events/roompowerlevelsevent.h b/lib/events/roompowerlevelsevent.h new file mode 100644 index 00000000..f0f7207f --- /dev/null +++ b/lib/events/roompowerlevelsevent.h @@ -0,0 +1,76 @@ +#pragma once + +#include "eventcontent.h" +#include "stateevent.h" + +namespace Quotient { +class PowerLevelsEventContent : public EventContent::Base { +public: + struct Notifications { + int room; + }; + + explicit PowerLevelsEventContent(const QJsonObject& json); + + int invite; + int kick; + int ban; + + int redact; + + QHash<QString, int> events; + int eventsDefault; + int stateDefault; + + QHash<QString, int> users; + int usersDefault; + + Notifications notifications; + +protected: + void fillJson(QJsonObject* o) const override; +}; + +class RoomPowerLevelsEvent : public StateEvent<PowerLevelsEventContent> { + Q_GADGET +public: + DEFINE_EVENT_TYPEID("m.room.power_levels", RoomPowerLevelsEvent) + + explicit RoomPowerLevelsEvent(const QJsonObject& obj) + : StateEvent(typeId(), obj) + {} + + int invite() const { return content().invite; } + int kick() const { return content().kick; } + int ban() const { return content().ban; } + + int redact() const { return content().redact; } + + QHash<QString, int> events() const { return content().events; } + int eventsDefault() const { return content().eventsDefault; } + int stateDefault() const { return content().stateDefault; } + + QHash<QString, int> users() const { return content().users; } + int usersDefault() const { return content().usersDefault; } + + int roomNotification() const { return content().notifications.room; } + + int powerLevelForEvent(const QString& eventId) const; + int powerLevelForState(const QString& eventId) const; + int powerLevelForUser(const QString& userId) const; + +private: +}; + +template <> +class EventFactory<RoomPowerLevelsEvent> { +public: + static event_ptr_tt<RoomPowerLevelsEvent> make(const QJsonObject& json, + const QString&) + { + return makeEvent<RoomPowerLevelsEvent>(json); + } +}; + +REGISTER_EVENT_TYPE(RoomPowerLevelsEvent) +} // namespace Quotient diff --git a/lib/room.cpp b/lib/room.cpp index 696a5f1b..b29f6f48 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -52,6 +52,7 @@ #include "events/roomtombstoneevent.h" #include "events/simplestateevents.h" #include "events/typingevent.h" +#include "events/roompowerlevelsevent.h" #include "jobs/downloadfilejob.h" #include "jobs/mediathumbnailjob.h" #include "jobs/postreadmarkersjob.h" @@ -656,21 +657,12 @@ bool Room::canSwitchVersions() const // TODO, #276: m.room.power_levels const auto* plEvt = - d->currentState.value({ QStringLiteral("m.room.power_levels"), {} }); + d->getCurrentState<RoomPowerLevelsEvent>(); if (!plEvt) return true; - const auto plJson = plEvt->contentJson(); - const auto currentUserLevel = - plJson.value("users"_ls) - .toObject() - .value(localUser()->id()) - .toInt(plJson.value("users_default"_ls).toInt()); - const auto tombstonePowerLevel = - plJson.value("events"_ls) - .toObject() - .value("m.room.tombstone"_ls) - .toInt(plJson.value("state_default"_ls).toInt()); + const auto currentUserLevel = plEvt->powerLevelForUser(localUser()->id()); + const auto tombstonePowerLevel = plEvt->powerLevelForState("m.room.tombstone"_ls); return currentUserLevel >= tombstonePowerLevel; } |