- AccountState controls UserStatus.
- Display user status in the system tray menu next to user's avatar.
Signed-off-by: Camila <hello@camila.codes>
systray.cpp
thumbnailjob.cpp
userinfo.cpp
+ userstatus.cpp
accountstate.cpp
addcertificatedialog.cpp
authenticationdialog.cpp
#include "logger.h"
#include "configfile.h"
#include "ocsnavigationappsjob.h"
+#include "userstatus.h"
#include <QSettings>
#include <QTimer>
, _waitingForNewCredentials(false)
, _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay
, _remoteWipe(new RemoteWipe(_account))
+ , _userStatus(new UserStatus(this, this))
{
qRegisterMetaType<AccountState *>("AccountState*");
emit stateChanged(_state);
}
+QString AccountState::currentUserStatus() const
+{
+ return _userStatus->currentUserStatus();
+}
+
QString AccountState::stateString(State state)
{
switch (state) {
job->getNavigationApps();
}
+void AccountState::fetchCurrentUserStatus() {
+ _userStatus->fetchCurrentUserStatus();
+}
+
void AccountState::slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode){
if(statusCode == 200){
qCDebug(lcAccountState) << "New navigation apps ETag Response Header received " << value;
class Account;
class AccountApp;
class RemoteWipe;
+class UserStatus;
using AccountStatePtr = QExplicitlySharedDataPointer<AccountState>;
using AccountAppList = QList<AccountApp *>;
///Asks for user credentials
void handleInvalidCredentials();
+ QString currentUserStatus() const;
+
+ void fetchCurrentUserStatus();
+
public slots:
/// Triggers a ping to the server to update state and
/// connection status and errors.
void stateChanged(State state);
void isConnectedChanged();
void hasFetchedNavigationApps();
+ void userStatusChanged();
protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors);
*/
AccountAppList _apps;
+ UserStatus *_userStatus;
};
class AccountApp : public QObject
font.pixelSize: 12\r
font.bold: true\r
}\r
+ Label {\r
+ id: userStatus\r
+ width: 128\r
+ text: status\r
+ elide: Text.ElideRight\r
+ color: "black"\r
+ font.pixelSize: 10\r
+ }\r
Label {\r
id: accountServer\r
width: 128\r
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(_activityModel, &ActivityListModel::sendNotificationRequest, this, &User::slotSendNotificationRequest);
}
// Assemble a tray notification for the NEW notification
ConfigFile cfg;
- if (cfg.optionalServerNotifications()) {
+ if (cfg.optionalServerNotifications() /*and header is not X-Nextcloud-User-Status*/) {
if (AccountManager::instance()->accounts().count() == 1) {
emit guiLog(activity._subject, "");
} else {
slotRefreshActivities();
}
slotRefreshNotifications();
+ _account.data()->fetchCurrentUserStatus();
timer.start();
}
}
return serverUrl;
}
+QString User::currentUserStatus() const
+{
+ return _account->currentUserStatus();
+}
+
QImage User::avatar() const
{
return AvatarJob::makeCircularAvatar(_account->account()->avatar());
emit dataChanged(index(row, 0), index(row, 0), {UserModel::AvatarRole});
});
+ connect(u, &User::userStatusChanged, this, [this, row] {
+ emit dataChanged(index(row, 0), index(row, 0), {UserModel::StatusRole});
+ });
+
_users << u;
if (isCurrent) {
_currentUserId = _users.indexOf(_users.last());
return _users[index.row()]->name();
} else if (role == ServerRole) {
return _users[index.row()]->server();
+ } else if (role == StatusRole) {
+ return _users[index.row()]->currentUserStatus();
} else if (role == AvatarRole) {
return _users[index.row()]->avatarUrl();
} else if (role == IsCurrentUserRole) {
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[ServerRole] = "server";
+ roles[StatusRole] = "status";
roles[AvatarRole] = "avatar";
roles[IsCurrentUserRole] = "isCurrentUser";
roles[IsConnectedRole] = "isConnected";
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString server READ server CONSTANT)
+ Q_PROPERTY(QString status READ currentUserStatus NOTIFY userStatusChanged)
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 openLocalFolder();
QString name() const;
QString server(bool shortened = true) const;
+ QString currentUserStatus() const;
bool hasLocalFolder() const;
bool serverHasTalk() const;
AccountApp *talkApp() const;
void serverHasTalkChanged();
void avatarChanged();
void accountStateChanged(int state);
+ void userStatusChanged();
public slots:
void slotItemCompleted(const QString &folder, const SyncFileItemPtr &item);
enum UserRoles {
NameRole = Qt::UserRole + 1,
ServerRole,
+ StatusRole,
AvatarRole,
IsCurrentUserRole,
IsConnectedRole,
font.bold: true\r
}\r
Label {\r
- id: currentAccountServer\r
+ id: currentUserStatus\r
width: Style.currentAccountLabelWidth\r
- text: UserModel.currentUser.server\r
+ text: UserModel.currentUser.status\r
elide: Text.ElideRight\r
color: Style.ncTextColor\r
font.pixelSize: Style.subLinePixelSize\r
--- /dev/null
+/*
+ * Copyright (C) by Camila <hello@camila.codes>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "userstatus.h"
+#include "account.h"
+#include "accountstate.h"
+#include "networkjobs.h"
+#include "folderman.h"
+#include "creds/abstractcredentials.h"
+#include <theme.h>
+
+#include <QTimer>
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace OCC {
+
+UserStatus::UserStatus(AccountState *accountState, QObject *parent)
+ : QObject(parent)
+ , _accountState(accountState)
+{
+ connect(this, &UserStatus::fetchedCurrentUserStatus, _accountState, &AccountState::userStatusChanged);
+}
+
+void UserStatus::fetchCurrentUserStatus()
+{
+ if (_job) {
+ _job->deleteLater();
+ }
+
+ AccountPtr account = _accountState->account();
+ _job = new JsonApiJob(account, QStringLiteral("/ocs/v2.php/apps/user_status/api/v1/user_status"), this);
+ connect(_job.data(), &JsonApiJob::jsonReceived, this, &UserStatus::slotFetchedCurrentStatus);
+ _job->start();
+}
+
+void UserStatus::slotFetchedCurrentStatus(const QJsonDocument &json)
+{
+ const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject();
+ const auto icon = retrievedData.value("icon").toString();
+ const auto message = retrievedData.value("message").toString();
+ auto status = retrievedData.value("status").toString();
+
+ if(message.isEmpty()) {
+ if(status == "dnd") {
+ status = tr("Do not disturb");
+ }
+ } else {
+ status = message;
+ }
+
+ _currentUserStatus = QString("%1 %2").arg(icon, status);
+ emit fetchedCurrentUserStatus();
+}
+
+QString UserStatus::currentUserStatus() const
+{
+ return _currentUserStatus;
+}
+
+} // namespace OCC
--- /dev/null
+/*
+ * Copyright (C) by Camila <hello@camila.codes>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef USERSTATUS_H
+#define USERSTATUS_H
+
+#include <QObject>
+#include <QPointer>
+#include <QVariant>
+
+namespace OCC {
+class AccountState;
+class JsonApiJob;
+
+class UserStatus : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit UserStatus(AccountState *accountState, QObject *parent = nullptr);
+ void fetchCurrentUserStatus();
+ QString currentUserStatus() const;
+
+private slots:
+ void slotFetchedCurrentStatus(const QJsonDocument &json);
+
+signals:
+ void fetchedCurrentUserStatus();
+
+private:
+ QPointer<AccountState> _accountState;
+ QPointer<JsonApiJob> _job; // the currently running job
+ QString _currentUserStatus;
+};
+
+
+} // namespace OCC
+
+#endif //USERSTATUS_H