aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2019-04-27 20:14:57 +0100
committerJeremy Lainé <jeremy.laine@m4x.org>2019-05-04 13:40:44 +0200
commitcaeb6f2608ab0f6e769fb93fef14658bfe165378 (patch)
treeeab9704b81495a29eea09100db8b0fccadd31e34
parent537e325e2d44e696993b78ae2b8dd8437433c2b9 (diff)
downloadqxmpp-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.md1
-rw-r--r--doc/xep.doc1
-rw-r--r--src/base/QXmppConstants.cpp2
-rw-r--r--src/base/QXmppConstants_p.h2
-rw-r--r--src/base/QXmppMessage.cpp62
-rw-r--r--src/base/QXmppMessage.h7
-rw-r--r--tests/qxmppmessage/tst_qxmppmessage.cpp41
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"