- User QHash to map status strings and Status enum.
Signed-off-by: Camila <hello@camila.codes>
#include "logger.h"
#include "configfile.h"
#include "ocsnavigationappsjob.h"
-#include "userstatus.h"
#include <QSettings>
#include <QTimer>
, _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay
, _remoteWipe(new RemoteWipe(_account))
, _userStatus(new UserStatus(this))
- , _notificationStatus("online")
+ , _isDesktopNotificationsAllowed(true)
{
qRegisterMetaType<AccountState *>("AccountState*");
emit stateChanged(_state);
}
-QString AccountState::status() const
+UserStatus::Status AccountState::status() const
{
return _userStatus->status();
}
_navigationAppsEtagResponseHeader = value;
}
-QString AccountState::notificationStatus() const
+bool AccountState::isDesktopNotificationsAllowed() const
{
- return _notificationStatus;
+ return _isDesktopNotificationsAllowed;
}
-void AccountState::setNotificationStatus(const QString &status)
+void AccountState::setDesktopNotificationsAllowed(const bool isAllowed)
{
- _notificationStatus = status;
+ _isDesktopNotificationsAllowed = isAllowed;
}
void AccountState::checkConnectivity()
void AccountState::fetchUserStatus()
{
- connect(_userStatus, &UserStatus::fetchUserStatusFinished, this, &AccountState::userStatusChanged);
+ connect(_userStatus, &UserStatus::fetchUserStatusFinished, this, &AccountState::statusChanged);
_userStatus->fetchUserStatus(_account);
}
#include <QPointer>
#include "connectionvalidator.h"
#include "creds/abstractcredentials.h"
+#include "userstatus.h"
#include <memory>
class QSettings;
class Account;
class AccountApp;
class RemoteWipe;
-class UserStatus;
using AccountStatePtr = QExplicitlySharedDataPointer<AccountState>;
using AccountAppList = QList<AccountApp *>;
///Asks for user credentials
void handleInvalidCredentials();
- /** Returns the user status (online, dnd, away, offline, invisible)
+ /** Returns the user status (Online, Dnd, Away, Offline, Invisible)
* https://gist.github.com/georgehrke/55a0412007f13be1551d1f9436a39675
*/
- QString status() const;
+ UserStatus::Status status() const;
/** Returns the user status Message (emoji + text)
*/
*/
QUrl statusIcon() const;
- /** Returns the user status retrieved by the notificatons endpoint: dnd or online
+ /** Returns the notifications status retrieved by the notificatons endpoint
* https://github.com/nextcloud/desktop/issues/2318#issuecomment-680698429
*/
- QString notificationStatus() const;
+ bool isDesktopNotificationsAllowed() const;
- /** Set new user status retrieved by the notificatons endpoint: dnd or online
+ /** Set desktop notifications status retrieved by the notificatons endpoint
*/
- void setNotificationStatus(const QString &status);
+ void setDesktopNotificationsAllowed(const bool isAllowed);
/** Fetch the user status (status, icon, message)
*/
void stateChanged(State state);
void isConnectedChanged();
void hasFetchedNavigationApps();
- void userStatusChanged();
+ void statusChanged();
protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors);
AccountAppList _apps;
UserStatus *_userStatus;
- QString _notificationStatus;
+ bool _isDesktopNotificationsAllowed;
};
class AccountApp : public QObject
this, &ServerNotificationHandler::slotNotificationsReceived);
QObject::connect(_notificationJob.data(), &JsonApiJob::etagResponseHeaderReceived,
this, &ServerNotificationHandler::slotEtagResponseHeaderReceived);
- QObject::connect(_notificationJob.data(), &JsonApiJob::desktopNotificationStatusReceived,
- this, &ServerNotificationHandler::slotDesktopNotificationStatusReceived);
+ QObject::connect(_notificationJob.data(), &JsonApiJob::allowDesktopNotificationsChanged,
+ this, &ServerNotificationHandler::slotAllowDesktopNotificationsChanged);
_notificationJob->setProperty(propertyAccountStateC, QVariant::fromValue<AccountState *>(_accountState));
_notificationJob->addRawHeader("If-None-Match", _accountState->notificationsEtagResponseHeader());
_notificationJob->start();
}
}
-void ServerNotificationHandler::slotDesktopNotificationStatusReceived(const bool status)
+void ServerNotificationHandler::slotAllowDesktopNotificationsChanged(const bool isAllowed)
{
auto *account = qvariant_cast<AccountState *>(sender()->property(propertyAccountStateC));
if (account != nullptr) {
- account->setDesktopNotificationsStatus(status);
+ account->setDesktopNotificationsAllowed(isAllowed);
}
}
void slotNotificationsReceived(const QJsonDocument &json, int statusCode);
void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode);
void slotIconDownloaded(QByteArray iconData);
- void slotDesktopNotificationStatusReceived(const bool status);
+ void slotAllowDesktopNotificationsChanged(const bool isAllowed);
private:
QPointer<JsonApiJob> _notificationJob;
connect(this, &User::guiLog, Logger::instance(), &Logger::guiLog);
connect(_account->account().data(), &Account::accountChangedAvatar, this, &User::avatarChanged);
- connect(_account.data(), &AccountState::userStatusChanged, this, &User::userStatusChanged);
+ connect(_account.data(), &AccountState::statusChanged, this, &User::statusChanged);
connect(_activityModel, &ActivityListModel::sendNotificationRequest, this, &User::slotSendNotificationRequest);
}
return serverUrl;
}
-QString User::status() const
+UserStatus::Status User::status() const
{
return _account->status();
}
bool User::isDesktopNotificationsAllowed() const
{
- return _account.data()->notificationStatus() == "online";
+ return _account.data()->isDesktopNotificationsAllowed();
}
void User::removeAccount() const
emit dataChanged(index(row, 0), index(row, 0), {UserModel::AvatarRole});
});
- connect(u, &User::userStatusChanged, this, [this, row] {
+ connect(u, &User::statusChanged, this, [this, row] {
emit dataChanged(index(row, 0), index(row, 0), {UserModel::StatusIconRole,
UserModel::StatusMessageRole});
});
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString server READ server CONSTANT)
- Q_PROPERTY(QUrl statusIcon READ statusIcon NOTIFY userStatusChanged)
- Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY userStatusChanged)
+ Q_PROPERTY(QUrl statusIcon READ statusIcon NOTIFY statusChanged)
+ Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusChanged)
Q_PROPERTY(bool hasLocalFolder READ hasLocalFolder NOTIFY hasLocalFolderChanged)
Q_PROPERTY(bool serverHasTalk READ serverHasTalk NOTIFY serverHasTalkChanged)
Q_PROPERTY(QString avatar READ avatarUrl NOTIFY avatarChanged)
void removeAccount() const;
QString avatarUrl() const;
bool isDesktopNotificationsAllowed() const;
- QString status() const;
+ UserStatus::Status status() const;
QString statusMessage() const;
QUrl statusIcon() const;
void serverHasTalkChanged();
void avatarChanged();
void accountStateChanged(int state);
- void userStatusChanged();
+ void statusChanged();
public slots:
void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item);
UserStatus::UserStatus(QObject *parent)
: QObject(parent)
- , _status("online")
, _message("")
{
+}
+UserStatus::Status UserStatus::stringToEnum(const QString &status) const
+{
+ // api should return invisible, dnd,... toLower() it is to make sure
+ // it matches _preDefinedStatus, otherwise the default is online (0)
+ const auto statusEnum = _preDefinedStatus.value(status.isEmpty()? "online" : status.toLower(), 0);
+ return static_cast<Status>(statusEnum);
}
void UserStatus::fetchUserStatus(AccountPtr account)
const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject();
const auto emoji = retrievedData.value("icon").toString();
const auto message = retrievedData.value("message").toString();
- _status = retrievedData.value("status").toString();
+ auto statusString = retrievedData.value("status").toString();
+ _status = stringToEnum(statusString);
+
+ // to display it to the user like 'Invisible' instead of 'invisible'
+ statusString.replace(0, 1, statusString.at(0).toUpper());
const auto visibleStatusText = message.isEmpty()
- ? _status == "dnd"? tr("Do not disturb") : _status
+ ? _status == DoNotDisturb? tr("Do not disturb")
+ : tr(qPrintable(statusString))
: message;
_message = QString("%1 %2").arg(emoji, visibleStatusText);
emit fetchUserStatusFinished();
}
-QString UserStatus::status() const
+UserStatus::Status UserStatus::status() const
{
return _status;
}
QUrl UserStatus::icon() const
{
- // online, away, dnd, invisible, offline
- if(_status == "online") {
+ switch (_status) {
+ case Online:
return Theme::instance()->statusOnlineImageSource();
- } else if (_status == "away") {
+ case Away:
return Theme::instance()->statusAwayImageSource();
- } else if (_status == "dnd") {
+ case DoNotDisturb:
return Theme::instance()->statusDoNotDisturbImageSource();
- } else if (_status == "invisible") {
- return Theme::instance()->statusInvisibleImageSource();
- } else if (_status == "offline") {
+ case Invisible:
+ case Offline:
return Theme::instance()->statusInvisibleImageSource();
+ default:
+ return Theme::instance()->statusOnlineImageSource();
}
-
- return Theme::instance()->statusOnlineImageSource();
}
} // namespace OCC
#include <QObject>
#include <QPointer>
+#include <QVariant>
+#include <QMetaEnum>
#include "accountfwd.h"
namespace OCC {
class UserStatus : public QObject
{
Q_OBJECT
-
+
public:
explicit UserStatus(QObject *parent = nullptr);
+ enum Status {
+ Online,
+ DoNotDisturb,
+ Away,
+ Offline,
+ Invisible
+ };
+ Q_ENUM(Status);
void fetchUserStatus(AccountPtr account);
- QString status() const;
+ Status status() const;
QString message() const;
QUrl icon() const;
void fetchUserStatusFinished();
private:
+ Status stringToEnum(const QString &status) const;
+
+ // it needs to match the Status enum
+ const QHash<QString, int> _preDefinedStatus{{"online", 0},
+ {"dnd", 1}, //DoNotDisturb
+ {"away", 2},
+ {"offline", 3},
+ {"invisible", 4}};
+
QPointer<JsonApiJob> _job; // the currently running job
- QString _status;
+ Status _status{Status::Online};
QString _message;
};
if(reply()->rawHeaderList().contains("ETag"))
emit etagResponseHeaderReceived(reply()->rawHeader("ETag"), statusCode);
- const auto desktopNotificationStatus = reply()->rawHeader(QByteArray("X-Nextcloud-User-Status"));
- if(!desktopNotificationStatus.isEmpty()) {
- emit desktopNotificationStatusReceived(desktopNotificationStatus == "online");
+ const auto desktopNotificationsAllowed = reply()->rawHeader(QByteArray("X-Nextcloud-User-Status"));
+ if(!desktopNotificationsAllowed.isEmpty()) {
+ emit allowDesktopNotificationsChanged(desktopNotificationsAllowed == "online");
}
QJsonParseError error;
void etagResponseHeaderReceived(const QByteArray &value, int statusCode);
/**
- * @brief desktopNotificationStatusReceived - signal to report the if user is online or dnd
+ * @brief desktopNotificationStatusReceived - signal to report if notifications are allowed
* @param status - set desktop notifications allowed status
*/
- void desktopNotificationStatusReceived(const bool status);
+ void allowDesktopNotificationsChanged(const bool isAllowed);
private:
QUrlQuery _additionalParams;