aboutsummaryrefslogtreecommitdiff
path: root/lib/events
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2020-11-08 18:57:44 +0100
committerKitsune Ral <Kitsune-Ral@users.sf.net>2020-11-08 18:57:44 +0100
commitf4db6988bf2fd71f74ac851557d82c6f65cc89b1 (patch)
treedcad7010f50fa44a984b9dd02b904e88551f5037 /lib/events
parent7355e2f801eb85e771a6c454c77f9eb62398f38b (diff)
downloadlibquotient-f4db6988bf2fd71f74ac851557d82c6f65cc89b1.tar.gz
libquotient-f4db6988bf2fd71f74ac851557d82c6f65cc89b1.zip
More robust member profile data retrieval
MemberEventContent: displayname and avatarUrl are now Omittables; CS API doesn't guarantee their presence (see also https://github.com/matrix-org/matrix-doc/issues/1375) but Quotient used to assume they are always there, causing #412. RoomMemberEvent: displayname() -> newDisplayName() and avatarUrl() -> newAvatarUrl(), to emphasise the actual semantics (and also the changed interface). The old signatures still work but are deprecated. Instead of roomMembername() (with weird camel-casing), three new methods in addition to safeMemberName() are introduced to Room: - memberName() - produces the "best known" display name for a given member; User::name() uses it to avoid the pitfall of #412. - disambiguatedMemberName() - this is what roomMembername() used to be; not recommended for direct use when UI is concerned. - safeMemberName() - remains as is, with the fix to the documentation that used to mislead that the function returns HTML-escaped content (it didn't, and doesn't). - htmlSafeMemberName() - does what safeMemberName() claimed to do. Respectively, memberNames() is deprecated in favor of safeMemberNames() and htmlSafeMemberNames(). The corresponding Q_PROPERTY uses safeMemberNames() now. Similar to memberName(), Room has got memberAvatarUrl() to spare User class from diving into Room state to find the member avatar URL. Closes #412.
Diffstat (limited to 'lib/events')
-rw-r--r--lib/events/roommemberevent.cpp28
-rw-r--r--lib/events/roommemberevent.h18
2 files changed, 31 insertions, 15 deletions
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index 35cbdb3a..f6b29f7f 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -50,10 +50,13 @@ using namespace Quotient;
MemberEventContent::MemberEventContent(const QJsonObject& json)
: membership(fromJson<MembershipType>(json["membership"_ls]))
, isDirect(json["is_direct"_ls].toBool())
- , displayName(sanitized(json["displayname"_ls].toString()))
- , avatarUrl(json["avatar_url"_ls].toString())
+ , displayName(fromJson<Omittable<QString>>(json["displayname"_ls]))
+ , avatarUrl(fromJson<Omittable<QUrl>>(json["avatar_url"_ls]))
, reason(json["reason"_ls].toString())
-{}
+{
+ if (displayName)
+ displayName = sanitized(*displayName);
+}
void MemberEventContent::fillJson(QJsonObject* o) const
{
@@ -62,9 +65,10 @@ void MemberEventContent::fillJson(QJsonObject* o) const
"The key 'membership' must be explicit in MemberEventContent");
if (membership != MembershipType::Undefined)
o->insert(QStringLiteral("membership"), membershipStrings[membership]);
- o->insert(QStringLiteral("displayname"), displayName);
- if (avatarUrl.isValid())
- o->insert(QStringLiteral("avatar_url"), avatarUrl.toString());
+ if (displayName)
+ o->insert(QStringLiteral("displayname"), *displayName);
+ if (avatarUrl && avatarUrl->isValid())
+ o->insert(QStringLiteral("avatar_url"), avatarUrl->toString());
if (!reason.isEmpty())
o->insert(QStringLiteral("reason"), reason);
}
@@ -111,12 +115,16 @@ bool RoomMemberEvent::isUnban() const
bool RoomMemberEvent::isRename() const
{
- auto prevName = prevContent() ? prevContent()->displayName : QString();
- return displayName() != prevName;
+ auto prevName = prevContent() && prevContent()->displayName
+ ? *prevContent()->displayName
+ : QString();
+ return newDisplayName() != prevName;
}
bool RoomMemberEvent::isAvatarUpdate() const
{
- auto prevAvatarUrl = prevContent() ? prevContent()->avatarUrl : QUrl();
- return avatarUrl() != prevAvatarUrl;
+ auto prevAvatarUrl = prevContent() && prevContent()->avatarUrl
+ ? *prevContent()->avatarUrl
+ : QUrl();
+ return newAvatarUrl() != prevAvatarUrl;
}
diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h
index 783b8207..35fd69a9 100644
--- a/lib/events/roommemberevent.h
+++ b/lib/events/roommemberevent.h
@@ -24,7 +24,7 @@
namespace Quotient {
class MemberEventContent : public EventContent::Base {
public:
- enum MembershipType : size_t {
+ enum MembershipType : unsigned char {
Invite = 0,
Join,
Knock,
@@ -38,8 +38,8 @@ public:
MembershipType membership;
bool isDirect = false;
- QString displayName;
- QUrl avatarUrl;
+ Omittable<QString> displayName;
+ Omittable<QUrl> avatarUrl;
QString reason;
protected:
@@ -84,8 +84,16 @@ public:
MembershipType membership() const { return content().membership; }
QString userId() const { return fullJson()[StateKeyKeyL].toString(); }
bool isDirect() const { return content().isDirect; }
- QString displayName() const { return content().displayName; }
- QUrl avatarUrl() const { return content().avatarUrl; }
+ Omittable<QString> newDisplayName() const { return content().displayName; }
+ Omittable<QUrl> newAvatarUrl() const { return content().avatarUrl; }
+ [[deprecated("Use newDisplayName() instead")]] QString displayName() const
+ {
+ return newDisplayName().value_or(QString());
+ }
+ [[deprecated("Use newAvatarUrl() instead")]] QUrl avatarUrl() const
+ {
+ return newAvatarUrl().value_or(QUrl());
+ }
QString reason() const { return content().reason; }
bool changesMembership() const;
bool isBan() const;