From f79990e13fffd36a5d2aa4153ef06b48c0eeebe4 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Mon, 5 Jul 2021 15:25:54 +0200 Subject: RosterManager: Add QFuture-based requests --- src/client/QXmppRosterManager.cpp | 117 ++++++++++++++++++++++++++++++++++++++ src/client/QXmppRosterManager.h | 13 +++++ 2 files changed, 130 insertions(+) (limited to 'src/client') 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" @@ -260,6 +261,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::addRosterItem(const QString &bareJid, const QString &name, const QSet &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::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::renameRosterItem(const QString &bareJid, const QString &name) +{ + using Error = QXmppStanza::Error; + if (!d->entries.contains(bareJid)) { + return QXmpp::Private::makeReadyFuture( + 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 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 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. /// 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 + #include #include #include +template +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; + QXmppRosterManager(QXmppClient *stream); ~QXmppRosterManager() override; @@ -84,6 +91,12 @@ public: QXmppPresence getPresence(const QString &bareJid, const QString &resource) const; + QFuture addRosterItem(const QString &bareJid, const QString &name = {}, const QSet &groups = {}); + QFuture removeRosterItem(const QString &bareJid); + QFuture renameRosterItem(const QString &bareJid, const QString &name); + QFuture subscribeTo(const QString &bareJid, const QString &reason = {}); + QFuture unsubscribeFrom(const QString &bareJid, const QString &reason = {}); + /// \cond bool handleStanza(const QDomElement &element) override; /// \endcond -- cgit v1.2.3