diff options
| author | Linus Jahn <lnj@kaidan.im> | 2019-04-27 20:14:57 +0100 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2019-05-04 13:40:44 +0200 |
| commit | caeb6f2608ab0f6e769fb93fef14658bfe165378 (patch) | |
| tree | eab9704b81495a29eea09100db8b0fccadd31e34 | |
| parent | 537e325e2d44e696993b78ae2b8dd8437433c2b9 (diff) | |
| download | qxmpp-caeb6f2608ab0f6e769fb93fef14658bfe165378.tar.gz | |
Implement XEP-0382: Spoiler messages (v0.2.0)
This adds parsing and serialization of spoilers in the QXmppMessage class.
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | doc/xep.doc | 1 | ||||
| -rw-r--r-- | src/base/QXmppConstants.cpp | 2 | ||||
| -rw-r--r-- | src/base/QXmppConstants_p.h | 2 | ||||
| -rw-r--r-- | src/base/QXmppMessage.cpp | 62 | ||||
| -rw-r--r-- | src/base/QXmppMessage.h | 7 | ||||
| -rw-r--r-- | tests/qxmppmessage/tst_qxmppmessage.cpp | 41 |
7 files changed, 116 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 34514f47..147027e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ QXmpp 1.0.1 (UNRELEASED) New features: - Add support for SCRAM-SHA-1 and SCRAM-SHA-256 (#183, @jlaine) + - Add XEP-0382: Spoiler messages (v0.2.0) (#195, @lnjX) QXmpp 1.0.0 (Jan 8, 2019) ------------------------- diff --git a/doc/xep.doc b/doc/xep.doc index aecbac65..3b59b37b 100644 --- a/doc/xep.doc +++ b/doc/xep.doc @@ -41,6 +41,7 @@ Complete: - XEP-0313: Message Archive Management - XEP-0319: Last User Interaction in Presence - XEP-0352: Client State Indication +- XEP-0382: Spoiler messages (v0.2.0) Ongoing: - XEP-0009: Jabber-RPC (API is not finalized yet) diff --git a/src/base/QXmppConstants.cpp b/src/base/QXmppConstants.cpp index b5c2215b..190a10f5 100644 --- a/src/base/QXmppConstants.cpp +++ b/src/base/QXmppConstants.cpp @@ -141,6 +141,8 @@ const char* ns_mix_node_participants = "urn:xmpp:mix:nodes:participants"; const char* ns_mix_node_presence = "urn:xmpp:mix:nodes:presence"; const char* ns_mix_node_config = "urn:xmpp:mix:nodes:config"; const char* ns_mix_node_info = "urn:xmpp:mix:nodes:info"; +// XEP-0382: Spoiler messages +const char* ns_spoiler = "urn:xmpp:spoiler:0"; // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements const char* ns_mix_pam = "urn:xmpp:mix:pam:0"; const char* ns_mix_roster = "urn:xmpp:mix:roster:0"; diff --git a/src/base/QXmppConstants_p.h b/src/base/QXmppConstants_p.h index e425485c..04cb820f 100644 --- a/src/base/QXmppConstants_p.h +++ b/src/base/QXmppConstants_p.h @@ -153,6 +153,8 @@ extern const char* ns_mix_node_participants; extern const char* ns_mix_node_presence; extern const char* ns_mix_node_config; extern const char* ns_mix_node_info; +// XEP-0382: Spoiler messages +extern const char* ns_spoiler; // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements extern const char* ns_mix_pam; extern const char* ns_mix_roster; diff --git a/src/base/QXmppMessage.cpp b/src/base/QXmppMessage.cpp index 0bd28da6..dae2308b 100644 --- a/src/base/QXmppMessage.cpp +++ b/src/base/QXmppMessage.cpp @@ -106,6 +106,10 @@ public: // XEP-0369: Mediated Information eXchange (MIX) QString mixUserJid; QString mixUserNick; + + // XEP-0382: Spoiler messages + bool isSpoiler = false; + QString spoilerHint; }; /// Constructs a QXmppMessage. @@ -545,6 +549,52 @@ void QXmppMessage::setMixUserNick(const QString& mixUserNick) d->mixUserNick = mixUserNick; } +/// Returns true, if this is a spoiler message according to XEP-0382: Spoiler +/// messages. The spoiler hint however can still be empty. +/// +/// A spoiler message's content should not be visible to the user by default. + +bool QXmppMessage::isSpoiler() const +{ + return d->isSpoiler; +} + +/// Sets whether this is a spoiler message as specified in XEP-0382: Spoiler +/// messages. +/// +/// The content of spoiler messages will not be displayed by default to the +/// user. However, clients not supporting spoiler messages will still display +/// the content as usual. + +void QXmppMessage::setIsSpoiler(bool isSpoiler) +{ + d->isSpoiler = isSpoiler; +} + +/// Returns the spoiler hint as specified in XEP-0382: Spoiler messages. +/// +/// The hint may be empty, even if isSpoiler is true. + +QString QXmppMessage::spoilerHint() const +{ + return d->spoilerHint; +} + +/// Sets a spoiler hint for XEP-0382: Spoiler messages. If the spoiler hint +/// is not empty, isSpoiler will be set to true. +/// +/// A spoiler hint is optional for spoiler messages. +/// +/// Keep in mind that the spoiler hint is not displayed at all by clients not +/// supporting spoiler messages. + +void QXmppMessage::setSpoilerHint(const QString &spoilerHint) +{ + d->spoilerHint = spoilerHint; + if (!spoilerHint.isEmpty()) + d->isSpoiler = true; +} + /// \cond void QXmppMessage::parse(const QDomElement &element) { @@ -690,6 +740,10 @@ void QXmppMessage::parse(const QDomElement &element) } else if (xElement.tagName() == "mix" && xElement.namespaceURI() == ns_mix) { d->mixUserJid = xElement.firstChildElement("jid").text(); d->mixUserNick = xElement.firstChildElement("nick").text(); + // XEP-0382: Spoiler messages + } else if (xElement.tagName() == "spoiler" && xElement.namespaceURI() == ns_spoiler) { + d->isSpoiler = true; + d->spoilerHint = xElement.text(); } else if (!knownElems.contains(qMakePair(xElement.tagName(), xElement.namespaceURI())) && !knownElems.contains(qMakePair(xElement.tagName(), QString()))) { // other extensions @@ -836,6 +890,14 @@ void QXmppMessage::toXml(QXmlStreamWriter *xmlWriter) const xmlWriter->writeEndElement(); } + // XEP-0382: Spoiler messages + if (d->isSpoiler) { + xmlWriter->writeStartElement("spoiler"); + xmlWriter->writeAttribute("xmlns", ns_spoiler); + xmlWriter->writeCharacters(d->spoilerHint); + xmlWriter->writeEndElement(); + } + // other extensions QXmppStanza::extensionsToXml(xmlWriter); diff --git a/src/base/QXmppMessage.h b/src/base/QXmppMessage.h index 36f5d3e0..0101e211 100644 --- a/src/base/QXmppMessage.h +++ b/src/base/QXmppMessage.h @@ -150,6 +150,13 @@ public: QString mixUserNick() const; void setMixUserNick(const QString&); + // XEP-0382: Spoiler messages + bool isSpoiler() const; + void setIsSpoiler(bool); + + QString spoilerHint() const; + void setSpoilerHint(const QString&); + /// \cond void parse(const QDomElement &element); void toXml(QXmlStreamWriter *writer) const; diff --git a/tests/qxmppmessage/tst_qxmppmessage.cpp b/tests/qxmppmessage/tst_qxmppmessage.cpp index c026ad86..9e8786d6 100644 --- a/tests/qxmppmessage/tst_qxmppmessage.cpp +++ b/tests/qxmppmessage/tst_qxmppmessage.cpp @@ -49,6 +49,7 @@ private slots: void testOutOfBandUrl(); void testMessageCorrect(); void testMix(); + void testSpoiler(); }; void tst_QXmppMessage::testBasic_data() @@ -112,6 +113,7 @@ void tst_QXmppMessage::testBasic() QCOMPARE(message.isReceiptRequested(), false); QCOMPARE(message.receiptId(), QString()); QCOMPARE(message.xhtml(), QString()); + QVERIFY(!message.isSpoiler()); serializePacket(message, xml); } @@ -643,5 +645,44 @@ void tst_QXmppMessage::testMix() QCOMPARE(message.mixUserNick(), QString("erik")); } +void tst_QXmppMessage::testSpoiler() +{ + // test parsing with hint + const QByteArray xmlWithHint( + "<message to=\"foo@example.com/QXmpp\" from=\"bar@example.com/QXmpp\" type=\"normal\">" + "<body>And at the end of the story, both of them die! It is so tragic!</body>" + "<spoiler xmlns=\"urn:xmpp:spoiler:0\">Love story end</spoiler>" + "</message>"); + + QXmppMessage messageWithHint; + parsePacket(messageWithHint, xmlWithHint); + QVERIFY(messageWithHint.isSpoiler()); + QCOMPARE(messageWithHint.spoilerHint(), QString("Love story end")); + serializePacket(messageWithHint, xmlWithHint); + + // test parsing without hint + const QByteArray xmlWithoutHint( + "<message to=\"foo@example.com/QXmpp\" from=\"bar@example.com/QXmpp\" type=\"normal\">" + "<body>And at the end of the story, both of them die! It is so tragic!</body>" + "<spoiler xmlns=\"urn:xmpp:spoiler:0\"></spoiler>" + "</message>"); + + QXmppMessage messageWithoutHint; + parsePacket(messageWithoutHint, xmlWithoutHint); + QVERIFY(messageWithoutHint.isSpoiler()); + QCOMPARE(messageWithoutHint.spoilerHint(), QString("")); + serializePacket(messageWithoutHint, xmlWithoutHint); + + // test setters + QXmppMessage message; + message.setIsSpoiler(true); + QVERIFY(message.isSpoiler()); + + message.setIsSpoiler(false); + message.setSpoilerHint("test hint"); + QCOMPARE(message.spoilerHint(), QString("test hint")); + QVERIFY(message.isSpoiler()); +} + QTEST_MAIN(tst_QXmppMessage) #include "tst_qxmppmessage.moc" |
