aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2021-07-05 15:25:54 +0200
committerLinus Jahn <lnj@kaidan.im>2021-07-05 18:07:28 +0200
commitf79990e13fffd36a5d2aa4153ef06b48c0eeebe4 (patch)
treeb3519ead4994bb35aff38d20f367317defee5238 /src/client
parent28aad17d6d928ee0a983d7032ae0f11fbc71bb06 (diff)
downloadqxmpp-f79990e13fffd36a5d2aa4153ef06b48c0eeebe4.tar.gz
RosterManager: Add QFuture-based requests
Diffstat (limited to 'src/client')
-rw-r--r--src/client/QXmppRosterManager.cpp117
-rw-r--r--src/client/QXmppRosterManager.h13
2 files changed, 130 insertions, 0 deletions
diff --git a/src/client/QXmppRosterManager.cpp b/src/client/QXmppRosterManager.cpp
index 10f98a15..0f1f0df1 100644
--- a/src/client/QXmppRosterManager.cpp
+++ b/src/client/QXmppRosterManager.cpp
@@ -26,6 +26,7 @@
#include "QXmppRosterManager.h"
#include "QXmppClient.h"
+#include "QXmppFutureUtils_p.h"
#include "QXmppPresence.h"
#include "QXmppRosterIq.h"
#include "QXmppUtils.h"
@@ -261,6 +262,122 @@ void QXmppRosterManager::_q_presenceReceived(const QXmppPresence &presence)
}
///
+/// Adds a new item to the roster without sending any subscription requests.
+///
+/// As a result, the server will initiate a roster push, causing the
+/// itemAdded() or itemChanged() signal to be emitted.
+///
+/// \param bareJid
+/// \param name Optional name for the item.
+/// \param groups Optional groups for the item.
+///
+/// \since QXmpp 1.5
+///
+QFuture<QXmppRosterManager::Result> QXmppRosterManager::addRosterItem(const QString &bareJid, const QString &name, const QSet<QString> &groups)
+{
+ QXmppRosterIq::Item item;
+ item.setBareJid(bareJid);
+ item.setName(name);
+ item.setGroups(groups);
+ item.setSubscriptionType(QXmppRosterIq::Item::NotSet);
+
+ QXmppRosterIq iq;
+ iq.setType(QXmppIq::Set);
+ iq.addItem(item);
+ return client()->sendGenericIq(iq);
+}
+
+///
+/// Removes a roster item and cancels subscriptions to and from the contact.
+///
+/// As a result, the server will initiate a roster push, causing the
+/// itemRemoved() signal to be emitted.
+///
+/// \param bareJid
+///
+/// \since QXmpp 1.5
+///
+QFuture<QXmppRosterManager::Result> QXmppRosterManager::removeRosterItem(const QString &bareJid)
+{
+ QXmppRosterIq::Item item;
+ item.setBareJid(bareJid);
+ item.setSubscriptionType(QXmppRosterIq::Item::Remove);
+
+ QXmppRosterIq iq;
+ iq.setType(QXmppIq::Set);
+ iq.addItem(item);
+ return client()->sendGenericIq(iq);
+}
+
+///
+/// Renames a roster item.
+///
+/// As a result, the server will initiate a roster push, causing the
+/// itemChanged() signal to be emitted.
+///
+/// \param bareJid
+/// \param name
+///
+/// \since QXmpp 1.5
+///
+QFuture<QXmppRosterManager::Result> QXmppRosterManager::renameRosterItem(const QString &bareJid, const QString &name)
+{
+ using Error = QXmppStanza::Error;
+ if (!d->entries.contains(bareJid)) {
+ return QXmpp::Private::makeReadyFuture<Result>(
+ Error(Error::Modify, Error::ItemNotFound,
+ QStringLiteral("The roster doesn't contain this user.")));
+ }
+
+ auto item = d->entries.value(bareJid);
+ item.setName(name);
+
+ // If there is a pending subscription, do not include the corresponding attribute in the stanza.
+ if (!item.subscriptionStatus().isEmpty()) {
+ item.setSubscriptionStatus({});
+ }
+
+ QXmppRosterIq iq;
+ iq.setType(QXmppIq::Set);
+ iq.addItem(item);
+ return client()->sendGenericIq(iq);
+}
+
+///
+/// Requests a subscription to the given contact.
+///
+/// As a result, the server will initiate a roster push, causing the
+/// itemAdded() or itemChanged() signal to be emitted.
+///
+/// \since QXmpp 1.5
+///
+QFuture<QXmpp::PacketState> QXmppRosterManager::subscribeTo(const QString &bareJid, const QString &reason)
+{
+ QXmppPresence packet;
+ packet.setTo(QXmppUtils::jidToBareJid(bareJid));
+ packet.setType(QXmppPresence::Subscribe);
+ packet.setStatusText(reason);
+ return client()->send(packet);
+}
+
+///
+/// Removes a subscription to the given contact.
+///
+/// As a result, the server will initiate a roster push, causing the
+/// itemChanged() signal to be emitted.
+///
+/// \since QXmpp 1.5
+///
+QFuture<QXmpp::PacketState> QXmppRosterManager::unsubscribeFrom(const QString &bareJid, const QString &reason)
+{
+ QXmppPresence packet;
+ packet.setTo(QXmppUtils::jidToBareJid(bareJid));
+ packet.setType(QXmppPresence::Unsubscribe);
+ packet.setStatusText(reason);
+ return client()->send(packet);
+}
+
+///
/// Refuses a subscription request.
///
/// You can call this method in reply to the subscriptionRequest() signal.
diff --git a/src/client/QXmppRosterManager.h b/src/client/QXmppRosterManager.h
index 81f0538a..09c32ea0 100644
--- a/src/client/QXmppRosterManager.h
+++ b/src/client/QXmppRosterManager.h
@@ -30,10 +30,14 @@
#include "QXmppPresence.h"
#include "QXmppRosterIq.h"
+#include <variant>
+
#include <QMap>
#include <QObject>
#include <QStringList>
+template<typename T>
+class QFuture;
class QXmppRosterManagerPrivate;
///
@@ -71,6 +75,9 @@ class QXMPP_EXPORT QXmppRosterManager : public QXmppClientExtension
Q_OBJECT
public:
+ /// Empty result containing QXmpp::Success or a QXmppStanza::Error
+ using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
+
QXmppRosterManager(QXmppClient *stream);
~QXmppRosterManager() override;
@@ -84,6 +91,12 @@ public:
QXmppPresence getPresence(const QString &bareJid,
const QString &resource) const;
+ QFuture<Result> addRosterItem(const QString &bareJid, const QString &name = {}, const QSet<QString> &groups = {});
+ QFuture<Result> removeRosterItem(const QString &bareJid);
+ QFuture<Result> renameRosterItem(const QString &bareJid, const QString &name);
+ QFuture<QXmpp::PacketState> subscribeTo(const QString &bareJid, const QString &reason = {});
+ QFuture<QXmpp::PacketState> unsubscribeFrom(const QString &bareJid, const QString &reason = {});
+
/// \cond
bool handleStanza(const QDomElement &element) override;
/// \endcond