Skip to content
This repository was archived by the owner on Mar 20, 2025. It is now read-only.

Commit 78c515c

Browse files
committed
Start implementing XEP-0449: Stickers
1 parent 9f9d672 commit 78c515c

File tree

8 files changed

+345
-0
lines changed

8 files changed

+345
-0
lines changed

doc/doap.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,14 @@ SPDX-License-Identifier: CC0-1.0
622622
<xmpp:since>1.5</xmpp:since>
623623
</xmpp:SupportedXep>
624624
</implements>
625+
<implements>
626+
<xmpp:SupportedXep>
627+
<xmpp:xep rdf:resource='https://xmpp.org/extensions/xep-0449.html'/>
628+
<xmpp:status>complete</xmpp:status>
629+
<xmpp:version>0.1</xmpp:version>
630+
<xmpp:since>1.5</xmpp:since>
631+
</xmpp:SupportedXep>
632+
</implements>
625633
<release>
626634
<Version>
627635
<revision>1.4.0</revision>

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ set(INSTALL_HEADER_FILES
8484
base/QXmppSocks.h
8585
base/QXmppStanza.h
8686
base/QXmppStartTlsPacket.h
87+
base/QXmppStickerPackItem.h
8788
base/QXmppStream.h
8889
base/QXmppStreamFeatures.h
8990
base/QXmppStun.h
@@ -212,6 +213,7 @@ set(SOURCE_FILES
212213
base/QXmppRpcIq.cpp
213214
base/QXmppSasl.cpp
214215
base/QXmppSessionIq.cpp
216+
base/QXmppStickerPackItem.cpp
215217
base/QXmppSocks.cpp
216218
base/QXmppStanza.cpp
217219
base/QXmppStartTlsPacket.cpp

src/base/QXmppConstants.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,7 @@ const char *ns_file_metadata = "urn:xmpp:file:metadata:0";
204204
const char *ns_sfs = "urn:xmpp:sfs:0";
205205
// XEP-0448: Encryption for stateless file sharing
206206
const char *ns_esfs = "urn:xmpp:esfs:0";
207+
// XEP-0449: Stickers
208+
const char *ns_stickers = "urn:xmpp:stickers:0";
207209
// XEP-0450: Automatic Trust Management (ATM)
208210
const char *ns_atm = "urn:xmpp:atm:1";

src/base/QXmppConstants_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ extern const char *ns_file_metadata;
216216
extern const char *ns_sfs;
217217
// XEP-0448: Encryption for stateless file sharing
218218
extern const char *ns_esfs;
219+
// XEP-0449: Stickers
220+
extern const char *ns_stickers;
219221
// XEP-0450: Automatic Trust Management (ATM)
220222
extern const char *ns_atm;
221223

src/base/QXmppMessage.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class QXmppMessagePrivate : public QSharedData
156156

157157
// XEP-0448: Encryption for stateless file sharing
158158
QVector<QXmppFileShare> sharedFiles;
159+
160+
// XEP-0449: Stickers
161+
std::optional<QString> stickerPackId;
159162
};
160163

161164
QXmppMessagePrivate::QXmppMessagePrivate()
@@ -1258,6 +1261,30 @@ void QXmppMessage::setSharedFiles(const QVector<QXmppFileShare> &sharedFiles)
12581261
d->sharedFiles = sharedFiles;
12591262
}
12601263

1264+
///
1265+
/// \brief Returns the sticker pack id for the sticker contained in this message
1266+
///
1267+
/// This is used for \xep{0449, Stickers}.
1268+
///
1269+
/// \since QXmpp 1.5
1270+
///
1271+
const std::optional<QString> &QXmppMessage::stickerPackId() const
1272+
{
1273+
return d->stickerPackId;
1274+
}
1275+
1276+
///
1277+
/// \brief Sets the sticker pack id for the sticker contained in this message
1278+
///
1279+
/// This is used for \xep{0449, Stickers}.
1280+
///
1281+
/// \since QXmpp 1.5
1282+
///
1283+
void QXmppMessage::setStickerPackId(const std::optional<QString> &stickerPackId)
1284+
{
1285+
d->stickerPackId = stickerPackId;
1286+
}
1287+
12611288
/// \cond
12621289
void QXmppMessage::parse(const QDomElement &element)
12631290
{
@@ -1552,6 +1579,12 @@ bool QXmppMessage::parseExtension(const QDomElement &element, QXmpp::SceMode sce
15521579
}
15531580
return true;
15541581
}
1582+
1583+
// XEP-0449: Stickers
1584+
if (checkElement(element, QStringLiteral("sticker"), ns_stickers)) {
1585+
d->stickerPackId = element.attribute("pack");
1586+
return true;
1587+
}
15551588
}
15561589
return false;
15571590
}
@@ -1804,5 +1837,12 @@ void QXmppMessage::serializeExtensions(QXmlStreamWriter *writer, QXmpp::SceMode
18041837
for (const auto &fileShare : d->sharedFiles) {
18051838
fileShare.toXml(writer);
18061839
}
1840+
1841+
// XEP-0449: Sticker
1842+
if (d->stickerPackId) {
1843+
writer->writeStartElement("sticker");
1844+
writer->writeDefaultNamespace(ns_stickers);
1845+
writer->writeAttribute("pack", *d->stickerPackId);
1846+
}
18071847
}
18081848
}

src/base/QXmppMessage.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ class QXMPP_EXPORT QXmppMessage : public QXmppStanza
257257
const QVector<QXmppFileShare> &sharedFiles() const;
258258
void setSharedFiles(const QVector<QXmppFileShare> &sharedFiles);
259259

260+
// XEP-0449: Stickers
261+
const std::optional<QString> &stickerPackId() const;
262+
void setStickerPackId(const std::optional<QString> &stickerPackId);
263+
260264
/// \cond
261265
#ifdef BUILD_OMEMO
262266
// XEP-0384: OMEMO Encryption

src/base/QXmppStickerPackItem.cpp

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
// SPDX-FileCopyrightText: 2022 Jonah Brüchert <[email protected]>
2+
//
3+
// SPDX-License-Identifier: LGPL-2.1-or-later
4+
5+
#include "QXmppStickerPackItem.h"
6+
7+
#include "QXmppConstants_p.h"
8+
#include "QXmppEncryptedFileSource.h"
9+
#include "QXmppFileMetadata.h"
10+
11+
#include <QXmlStreamWriter>
12+
13+
class QXmppStickerItemPrivate : public QSharedData
14+
{
15+
public:
16+
QXmppFileMetadata metadata;
17+
QVector<QXmppHttpFileSource> httpSources;
18+
QVector<QXmppEncryptedFileSource> encryptedSources;
19+
};
20+
21+
QXmppStickerItem::QXmppStickerItem()
22+
: d(new QXmppStickerItemPrivate())
23+
{
24+
}
25+
26+
///
27+
/// \class QXmppStickerItem
28+
///
29+
/// This class represents a single sticker when publishing or retrieving it.
30+
///
31+
32+
///
33+
/// \brief Returns metadata about the sticker file
34+
///
35+
const QXmppFileMetadata &QXmppStickerItem::metadata() const
36+
{
37+
return d->metadata;
38+
}
39+
40+
///
41+
/// \brief Sets metadata of this sticker file
42+
///
43+
void QXmppStickerItem::setMetadata(const QXmppFileMetadata &metadata)
44+
{
45+
d->metadata = metadata;
46+
}
47+
48+
///
49+
/// \brief Returns HTTP sources for the sticker file
50+
///
51+
const QVector<QXmppHttpFileSource> &QXmppStickerItem::httpSource() const
52+
{
53+
return d->httpSources;
54+
}
55+
56+
///
57+
/// \brief Sets the list of HTTP sources for this sticker file
58+
///
59+
void QXmppStickerItem::setHttpSources(const QVector<QXmppHttpFileSource> &httpSources)
60+
{
61+
d->httpSources = httpSources;
62+
}
63+
64+
///
65+
/// \brief Returns the list of encrypted sources for this sticker file
66+
///
67+
const QVector<QXmppEncryptedFileSource> &QXmppStickerItem::encryptedSources() const
68+
{
69+
return d->encryptedSources;
70+
}
71+
72+
///
73+
/// \brief Set the list of encrypted sources for this sticker file
74+
///
75+
void QXmppStickerItem::setEncryptedSources(const QVector<QXmppEncryptedFileSource> &encryptedSources)
76+
{
77+
d->encryptedSources = encryptedSources;
78+
}
79+
80+
QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppStickerItem)
81+
82+
/// \cond
83+
void QXmppStickerItem::toXml(QXmlStreamWriter *writer) const
84+
{
85+
writer->writeStartElement("item");
86+
d->metadata.toXml(writer);
87+
for (const auto &httpSource : d->httpSources) {
88+
httpSource.toXml(writer);
89+
}
90+
for (const auto &encryptedSource : d->encryptedSources) {
91+
encryptedSource.toXml(writer);
92+
}
93+
writer->writeEndElement();
94+
}
95+
96+
bool QXmppStickerItem::parse(const QDomElement &element)
97+
{
98+
auto fileElement = element.firstChildElement("file");
99+
d->metadata.parse(fileElement);
100+
101+
auto sources = element.firstChildElement("sources");
102+
for (auto sourceEl = sources.firstChildElement();
103+
!sourceEl.isNull();
104+
sourceEl = sourceEl.nextSiblingElement()) {
105+
if (sourceEl.tagName() == QStringLiteral("url-data")) {
106+
QXmppHttpFileSource source;
107+
if (source.parse(sourceEl)) {
108+
d->httpSources.push_back(std::move(source));
109+
}
110+
} else if (sourceEl.tagName() == QStringLiteral("encrypted")) {
111+
QXmppEncryptedFileSource source;
112+
if (source.parse(sourceEl)) {
113+
d->encryptedSources.push_back(std::move(source));
114+
}
115+
}
116+
}
117+
118+
return true;
119+
}
120+
/// \endcond
121+
122+
class QXmppStickerPackItemPrivate : public QSharedData
123+
{
124+
public:
125+
QString name;
126+
QString summary;
127+
QVector<QXmppStickerItem> items;
128+
};
129+
130+
QXmppStickerPackItem::QXmppStickerPackItem()
131+
: d(new QXmppStickerPackItemPrivate())
132+
{
133+
}
134+
135+
///
136+
/// \class QXmppStickerPackitem
137+
///
138+
/// A pubsub item for a sticker pack.
139+
///
140+
141+
///
142+
/// \brief Returns the name of the sticker pack
143+
///
144+
const QString &QXmppStickerPackItem::name() const
145+
{
146+
return d->name;
147+
}
148+
149+
///
150+
/// \brief Sets the name of the sticker pack
151+
///
152+
void QXmppStickerPackItem::setName(const QString &name)
153+
{
154+
d->name = name;
155+
}
156+
157+
///
158+
/// \brief Returns the summary of this sticker pack
159+
///
160+
const QString &QXmppStickerPackItem::summary() const
161+
{
162+
return d->summary;
163+
}
164+
165+
///
166+
/// \brief Sets the summary of the sticker pack
167+
///
168+
void QXmppStickerPackItem::setSummary(const QString &summary)
169+
{
170+
d->summary = summary;
171+
}
172+
173+
///
174+
/// \brief Returns the list of stickers of this pack
175+
///
176+
const QVector<QXmppStickerItem> &QXmppStickerPackItem::items() const
177+
{
178+
return d->items;
179+
}
180+
181+
///
182+
/// \brief Set the list of stickers for this pack
183+
///
184+
void QXmppStickerPackItem::setItems(const QVector<QXmppStickerItem> &items)
185+
{
186+
d->items = items;
187+
}
188+
189+
QXMPP_PRIVATE_DEFINE_RULE_OF_SIX(QXmppStickerPackItem)
190+
191+
void QXmppStickerPackItem::parsePayload(const QDomElement &payloadElement)
192+
{
193+
d->name = payloadElement.firstChildElement("name").text();
194+
d->summary = payloadElement.firstChildElement("summary").text();
195+
196+
for (auto firstChild = payloadElement.firstChildElement("item");
197+
!firstChild.isNull();
198+
firstChild.nextSibling()) {
199+
QXmppStickerItem stickerItem;
200+
stickerItem.parse(payloadElement);
201+
202+
d->items.push_back(std::move(stickerItem));
203+
}
204+
}
205+
206+
void QXmppStickerPackItem::serializePayload(QXmlStreamWriter *writer) const
207+
{
208+
writer->writeStartElement("pack");
209+
writer->writeDefaultNamespace(ns_stickers);
210+
211+
writer->writeTextElement("name", d->name);
212+
writer->writeTextElement("summary", d->summary);
213+
214+
for (const auto &item : d->items) {
215+
item.toXml(writer);
216+
}
217+
218+
writer->writeEndElement();
219+
}

0 commit comments

Comments
 (0)