diff --git a/Quotient/connection.cpp b/Quotient/connection.cpp index 8a8040744..ff2b58eea 100644 --- a/Quotient/connection.cpp +++ b/Quotient/connection.cpp @@ -33,6 +33,7 @@ #include "events/encryptionevent.h" #include "jobs/downloadfilejob.h" #include "jobs/mediathumbnailjob.h" +#include "events/presenceevent.h" // moc needs fully defined deps, see https://www.qt.io/blog/whats-new-in-qmetatype-qvariant #include "moc_connection.cpp" // NOLINT(bugprone-suspicious-include) @@ -637,7 +638,26 @@ void Connection::Private::consumeAccountData(Events&& accountDataEvents) void Connection::Private::consumePresenceData(Events&& presenceData) { - // To be implemented + for (const auto &event : presenceData) { + auto presenceEvent = eventCast(event); + auto sender = presenceEvent->fullJson()[u"sender"_s].toString(); // TODO ? + if (presenceEvent->currentlyActive()) { + forcePresentUsers += sender; + } else { + forcePresentUsers.removeAll(sender); + } + if (presenceEvent->presence() == u"online") { + presentUsers += sender; + } else { + presentUsers.removeAll(sender); + } + } + Q_EMIT q->presenceChanged(); +} + +bool Connection::isUserPresent(const QString &userId) const +{ + return d->forcePresentUsers.contains(userId) || d->presentUsers.contains(userId); } void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents) diff --git a/Quotient/connection.h b/Quotient/connection.h index 51007b516..0b6da23bc 100644 --- a/Quotient/connection.h +++ b/Quotient/connection.h @@ -807,6 +807,8 @@ public Q_SLOTS: static Connection* makeMockConnection(const QString& mxId, bool enableEncryption = true); + Q_INVOKABLE bool isUserPresent(const QString &userId) const; + Q_SIGNALS: //! \brief Initial server resolution has failed //! @@ -983,6 +985,8 @@ public Q_SLOTS: //! This does not mean that the server was reached, a sync was performed, or the state cache was loaded. void ready(); + void presenceChanged(); + friend class ::TestCrossSigning; protected: //! Access the underlying ConnectionData class diff --git a/Quotient/connection_p.h b/Quotient/connection_p.h index 559be7a2d..d2d175557 100644 --- a/Quotient/connection_p.h +++ b/Quotient/connection_p.h @@ -52,6 +52,8 @@ class Q_DECL_HIDDEN Quotient::Connection::Private { std::unordered_map accountData; QMetaObject::Connection syncLoopConnection {}; int syncTimeout = -1; + QStringList forcePresentUsers; + QStringList presentUsers; GetCapabilitiesJob::Capabilities capabilities{}; diff --git a/Quotient/events/presenceevent.h b/Quotient/events/presenceevent.h new file mode 100644 index 000000000..f9fdf078f --- /dev/null +++ b/Quotient/events/presenceevent.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: LGPL-2.0-or-later +// SPDX-FileCopyrightText: 2025 Tobias Fella + +#pragma once + +#include "event.h" + +namespace Quotient +{ + +class QUOTIENT_API PresenceEvent : public Quotient::Event { +public: + QUO_EVENT(PresenceEvent, "m.presence") + + using Event::Event; + + QUO_CONTENT_GETTER(QString, avatarUrl) + QUO_CONTENT_GETTER(bool, currentlyActive) + QUO_CONTENT_GETTER(QString, displayName) + QUO_CONTENT_GETTER(qint64, lastActiveTime) + QUO_CONTENT_GETTER(QString, presence) + QUO_CONTENT_GETTER(QString, statusMsg) +}; + +}