Переглянути джерело

Merge pull request #3069 from nextcloud/feature/user-status

User status bug fixing...
allexzander 4 роки тому
батько
коміт
f6afb62a53

+ 1 - 1
src/gui/accountstate.cpp

@@ -227,7 +227,7 @@ bool AccountState::isDesktopNotificationsAllowed() const
     return _isDesktopNotificationsAllowed;
     return _isDesktopNotificationsAllowed;
 }
 }
 
 
-void AccountState::setDesktopNotificationsAllowed(const bool isAllowed)
+void AccountState::setDesktopNotificationsAllowed(bool isAllowed)
 {
 {
     _isDesktopNotificationsAllowed = isAllowed;
     _isDesktopNotificationsAllowed = isAllowed;
 }
 }

+ 1 - 1
src/gui/accountstate.h

@@ -182,7 +182,7 @@ public:
 
 
     /** Set desktop notifications status retrieved by the notificatons endpoint
     /** Set desktop notifications status retrieved by the notificatons endpoint
     */
     */
-    void setDesktopNotificationsAllowed(const bool isAllowed);
+    void setDesktopNotificationsAllowed(bool isAllowed);
 
 
     /** Fetch the user status (status, icon, message)
     /** Fetch the user status (status, icon, message)
     */
     */

+ 1 - 1
src/gui/tray/NotificationHandler.cpp

@@ -64,7 +64,7 @@ void ServerNotificationHandler::slotEtagResponseHeaderReceived(const QByteArray
     }
     }
 }
 }
 
 
-void ServerNotificationHandler::slotAllowDesktopNotificationsChanged(const bool isAllowed)
+void ServerNotificationHandler::slotAllowDesktopNotificationsChanged(bool isAllowed)
 {
 {
     auto *account = qvariant_cast<AccountState *>(sender()->property(propertyAccountStateC));
     auto *account = qvariant_cast<AccountState *>(sender()->property(propertyAccountStateC));
     if (account != nullptr) {
     if (account != nullptr) {

+ 1 - 1
src/gui/tray/NotificationHandler.h

@@ -26,7 +26,7 @@ private slots:
     void slotNotificationsReceived(const QJsonDocument &json, int statusCode);
     void slotNotificationsReceived(const QJsonDocument &json, int statusCode);
     void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode);
     void slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode);
     void slotIconDownloaded(QByteArray iconData);
     void slotIconDownloaded(QByteArray iconData);
-    void slotAllowDesktopNotificationsChanged(const bool isAllowed);
+    void slotAllowDesktopNotificationsChanged(bool isAllowed);
 
 
 private:
 private:
     QPointer<JsonApiJob> _notificationJob;
     QPointer<JsonApiJob> _notificationJob;

+ 3 - 2
src/gui/tray/UserModel.cpp

@@ -219,7 +219,8 @@ void User::slotRefreshActivities()
     _activityModel->slotRefreshActivity();
     _activityModel->slotRefreshActivity();
 }
 }
 
 
-void User::slotRefreshUserStatus() {
+void User::slotRefreshUserStatus() 
+{
     // TODO: check for _account->account()->capabilities().userStatus() 
     // TODO: check for _account->account()->capabilities().userStatus() 
     if (_account.data() && _account.data()->isConnected()) {
     if (_account.data() && _account.data()->isConnected()) {
         _account.data()->fetchUserStatus();
         _account.data()->fetchUserStatus();
@@ -698,7 +699,7 @@ Q_INVOKABLE bool UserModel::isUserConnected(const int &id)
     return _users[id]->isConnected();
     return _users[id]->isConnected();
 }
 }
 
 
-Q_INVOKABLE QUrl UserModel::statusIcon(const int &id)
+Q_INVOKABLE QUrl UserModel::statusIcon(int id)
 {
 {
     if (id < 0 || id >= _users.size()) {
     if (id < 0 || id >= _users.size()) {
         return {};
         return {};

+ 1 - 1
src/gui/tray/UserModel.h

@@ -140,7 +140,7 @@ public:
     Q_INVOKABLE bool currentUserHasLocalFolder();
     Q_INVOKABLE bool currentUserHasLocalFolder();
     int currentUserId() const;
     int currentUserId() const;
     Q_INVOKABLE bool isUserConnected(const int &id);
     Q_INVOKABLE bool isUserConnected(const int &id);
-    Q_INVOKABLE QUrl statusIcon(const int &id);
+    Q_INVOKABLE QUrl statusIcon(int id);
     Q_INVOKABLE void switchCurrentUser(const int &id);
     Q_INVOKABLE void switchCurrentUser(const int &id);
     Q_INVOKABLE void login(const int &id);
     Q_INVOKABLE void login(const int &id);
     Q_INVOKABLE void logout(const int &id);
     Q_INVOKABLE void logout(const int &id);

+ 42 - 51
src/gui/tray/Window.qml

@@ -403,67 +403,57 @@ Window {
                     }
                     }
                 }
                 }
 
 
-                // Filler between account dropdown and header app buttons
-                Item {
-                    id: trayWindowHeaderSpacer
-                    Layout.fillWidth: true
-                }
-
-                HeaderButton {
-                    id: openLocalFolderButton
-
-                    visible: UserModel.currentUser.hasLocalFolder
-                    icon.source: "qrc:///client/theme/white/folder.svg"
-                    onClicked: UserModel.openCurrentAccountLocalFolder()
+                RowLayout {
+                    id: openLocalFolderRowLayout
+                    spacing: 0
+                    Layout.preferredWidth:  Style.trayWindowHeaderHeight
+                    Layout.preferredHeight: Style.trayWindowHeaderHeight
+                    
+                    HeaderButton {
+                        id: openLocalFolderButton
+                        visible: UserModel.currentUser.hasLocalFolder
+                        icon.source: "qrc:///client/theme/white/folder.svg"
+                        onClicked: UserModel.openCurrentAccountLocalFolder()
+                        
+                        Rectangle {
+                            id: folderStateIndicatorBackground
+                            width: Style.folderStateIndicatorSize
+                            height: width
+                            anchors.top: openLocalFolderButton.verticalCenter
+                            anchors.left: openLocalFolderButton.horizontalCenter
+                            color: Style.ncBlue
+                            radius: width*0.5
+                            z: 1
+                        }
+                   }
+
+                   Image {
+                        id: folderStateIndicator
+                        source: UserModel.isUserConnected(UserModel.currentUserId)
+                                ? Style.stateOnlineImageSource
+                                : Style.stateOfflineImageSource
+                        cache: false
+                        anchors.top: openLocalFolderButton.verticalCenter
+                        anchors.left: openLocalFolderButton.horizontalCenter
+                        
+                        sourceSize.width: Style.folderStateIndicatorSize
+                        sourceSize.height: Style.folderStateIndicatorSize
+    
+                        Accessible.role: Accessible.Indicator
+                        Accessible.name: UserModel.isUserConnected(UserModel.currentUserId()) ? qsTr("Connected") : qsTr("Disconnected")
+                    }
 
 
                     Accessible.role: Accessible.Button
                     Accessible.role: Accessible.Button
                     Accessible.name: qsTr("Open local folder of current account")
                     Accessible.name: qsTr("Open local folder of current account")
-                    Accessible.onPressAction: openLocalFolderButton.clicked()
-                }
-
-                Rectangle {
-                    id: folderStateIndicatorBackground
-                    width: Style.folderStateIndicatorSize
-                    height: width
-                    anchors.top: openLocalFolderButton.verticalCenter
-                    anchors.left: openLocalFolderButton.horizontalCenter
-                    color: Style.ncBlue
-                    radius: width*0.5
-                }
-
-                Rectangle {
-                    id: folderStateRectangle
-                    width: Style.folderStateIndicatorSize
-                    height: width
-                    anchors.bottom: openLocalFolderButton.bottom
-                    anchors.right: openLocalFolderButton.right
-                    color: openLocalFolderButton.containsMouse ? "white" : "transparent"
-                    opacity: 0.2
-                    radius: width*0.5
-                }
-
-                Image {
-                    id: folderStateIndicator
-                    source: UserModel.isUserConnected(UserModel.currentUserId)
-                            ? Style.stateOnlineImageSource
-                            : Style.stateOfflineImageSource
-                    cache: false
-                    x: folderStateIndicatorBackground.x
-                    y: folderStateIndicatorBackground.y
-                    sourceSize.width: Style.folderStateIndicatorSize
-                    sourceSize.height: Style.folderStateIndicatorSize
-
-                    Accessible.role: Accessible.Indicator
-                    Accessible.name: UserModel.isUserConnected(UserModel.currentUserId()) ? qsTr("Connected") : qsTr("Disconnected")
                 }
                 }
 
 
                 HeaderButton {
                 HeaderButton {
                     id: trayWindowTalkButton
                     id: trayWindowTalkButton
-
+                    
                     visible: UserModel.currentUser.serverHasTalk
                     visible: UserModel.currentUser.serverHasTalk
                     icon.source: "qrc:///client/theme/white/talk-app.svg"
                     icon.source: "qrc:///client/theme/white/talk-app.svg"
                     onClicked: UserModel.openCurrentAccountTalk()
                     onClicked: UserModel.openCurrentAccountTalk()
-
+                    
                     Accessible.role: Accessible.Button
                     Accessible.role: Accessible.Button
                     Accessible.name: qsTr("Open Nextcloud Talk in browser")
                     Accessible.name: qsTr("Open Nextcloud Talk in browser")
                     Accessible.onPressAction: trayWindowTalkButton.clicked()
                     Accessible.onPressAction: trayWindowTalkButton.clicked()
@@ -472,6 +462,7 @@ Window {
                 HeaderButton {
                 HeaderButton {
                     id: trayWindowAppsButton
                     id: trayWindowAppsButton
                     icon.source: "qrc:///client/theme/white/more-apps.svg"
                     icon.source: "qrc:///client/theme/white/more-apps.svg"
+  
                     onClicked: {
                     onClicked: {
                         if(appsMenu.count <= 0) {
                         if(appsMenu.count <= 0) {
                             UserModel.openCurrentAccountServer()
                             UserModel.openCurrentAccountServer()

+ 34 - 22
src/gui/userstatus.cpp

@@ -30,16 +30,37 @@ Q_LOGGING_CATEGORY(lcUserStatus, "nextcloud.gui.userstatus", QtInfoMsg)
 
 
 UserStatus::UserStatus(QObject *parent)
 UserStatus::UserStatus(QObject *parent)
     : QObject(parent)
     : QObject(parent)
-    , _message("")
 {
 {
 }
 }
 
 
 UserStatus::Status UserStatus::stringToEnum(const QString &status) const 
 UserStatus::Status UserStatus::stringToEnum(const QString &status) const 
 {
 {
+    // it needs to match the Status enum
+    const QHash<QString, Status> preDefinedStatus{{"online", Status::Online},
+                                               {"dnd", Status::DoNotDisturb}, //DoNotDisturb
+                                               {"away", Status::Away},
+                                               {"offline", Status::Offline},
+                                               {"invisible", Status::Invisible}};
+    
     // api should return invisible, dnd,... toLower() it is to make sure 
     // api should return invisible, dnd,... toLower() it is to make sure 
     // it matches _preDefinedStatus, otherwise the default is online (0)
     // 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);
+    const auto statusKey = status.isEmpty() ? QStringLiteral("online") : status.toLower();
+    return preDefinedStatus.value(statusKey, Status::Online);
+}
+
+QString UserStatus::enumToString(Status status) const 
+{
+    switch (status) {
+    case Status::Away:
+        return tr("Away");
+    case Status::DoNotDisturb:
+        return tr("Do not disturb");
+    case Status::Invisible:
+    case Status::Offline:
+        return tr("Offline");
+    default:
+        return tr("Online");
+    }
 }
 }
 
 
 void UserStatus::fetchUserStatus(AccountPtr account)
 void UserStatus::fetchUserStatus(AccountPtr account)
@@ -53,10 +74,9 @@ void UserStatus::fetchUserStatus(AccountPtr account)
     _job->start();
     _job->start();
 }
 }
 
 
-void UserStatus::slotFetchUserStatusFinished(const QJsonDocument &json, const int statusCode)
+void UserStatus::slotFetchUserStatusFinished(const QJsonDocument &json, int statusCode)
 {
 {
-    const QJsonObject defaultValues
-    {
+    const QJsonObject defaultValues {
         {"icon", ""},
         {"icon", ""},
         {"message", ""},
         {"message", ""},
         {"status", "online"}
         {"status", "online"}
@@ -66,19 +86,13 @@ void UserStatus::slotFetchUserStatusFinished(const QJsonDocument &json, const in
         qCInfo(lcUserStatus) << "Slot fetch UserStatus finished with status code" << statusCode;
         qCInfo(lcUserStatus) << "Slot fetch UserStatus finished with status code" << statusCode;
         qCInfo(lcUserStatus) << "Using then default values as if user has not set any status" << defaultValues;
         qCInfo(lcUserStatus) << "Using then default values as if user has not set any status" << defaultValues;
     }
     }
+    
     const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject(defaultValues);
     const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject(defaultValues);
     const auto emoji = retrievedData.value("icon").toString();
     const auto emoji = retrievedData.value("icon").toString();
     const auto message = retrievedData.value("message").toString();
     const auto message = retrievedData.value("message").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 == DoNotDisturb? tr("Do not disturb") 
-                                                : tr(qPrintable(statusString))
-                                : message;
+    _status = stringToEnum(retrievedData.value("status").toString());
+    const auto visibleStatusText = message.isEmpty() ? enumToString(_status) : message;
 
 
     _message = QString("%1 %2").arg(emoji, visibleStatusText);
     _message = QString("%1 %2").arg(emoji, visibleStatusText);
     emit fetchUserStatusFinished();
     emit fetchUserStatusFinished();
@@ -91,20 +105,18 @@ UserStatus::Status UserStatus::status() const
 
 
 QString UserStatus::message() const
 QString UserStatus::message() const
 {
 {
-    return _message;
+    return _message.trimmed();
 }
 }
 
 
 QUrl UserStatus::icon() const
 QUrl UserStatus::icon() const
 {
 {
     switch (_status) {
     switch (_status) {
-    case Online:
-        return Theme::instance()->statusOnlineImageSource();
-    case Away:
+    case Status::Away:
         return Theme::instance()->statusAwayImageSource();
         return Theme::instance()->statusAwayImageSource();
-    case DoNotDisturb:
+    case Status::DoNotDisturb:
         return Theme::instance()->statusDoNotDisturbImageSource();
         return Theme::instance()->statusDoNotDisturbImageSource();
-    case Invisible:
-    case Offline:
+    case Status::Invisible:
+    case Status::Offline:
         return Theme::instance()->statusInvisibleImageSource();
         return Theme::instance()->statusInvisibleImageSource();
     default:
     default:
         return Theme::instance()->statusOnlineImageSource();
         return Theme::instance()->statusOnlineImageSource();

+ 4 - 11
src/gui/userstatus.h

@@ -28,7 +28,7 @@ class UserStatus : public QObject
     
     
 public:
 public:
     explicit UserStatus(QObject *parent = nullptr);
     explicit UserStatus(QObject *parent = nullptr);
-    enum Status {
+    enum class Status {
         Online,
         Online,
         DoNotDisturb,
         DoNotDisturb,
         Away,
         Away,
@@ -42,23 +42,16 @@ public:
     QUrl icon() const;
     QUrl icon() const;
 
 
 private slots:
 private slots:
-    void slotFetchUserStatusFinished(const QJsonDocument &json, const int statusCode);
+    void slotFetchUserStatusFinished(const QJsonDocument &json, int statusCode);
 
 
 signals:
 signals:
     void fetchUserStatusFinished();
     void fetchUserStatusFinished();
 
 
 private:
 private:
     Status stringToEnum(const QString &status) const;
     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}};
-
+    QString enumToString(Status status) const;
     QPointer<JsonApiJob> _job; // the currently running job
     QPointer<JsonApiJob> _job; // the currently running job
-    Status _status{Status::Online};
+    Status _status = Status::Online;
     QString _message;
     QString _message;
 };
 };
 
 

+ 1 - 1
src/libsync/networkjobs.h

@@ -425,7 +425,7 @@ signals:
      * @brief desktopNotificationStatusReceived - signal to report if notifications are allowed
      * @brief desktopNotificationStatusReceived - signal to report if notifications are allowed
      * @param status - set desktop notifications allowed status 
      * @param status - set desktop notifications allowed status 
      */
      */
-    void allowDesktopNotificationsChanged(const bool isAllowed);
+    void allowDesktopNotificationsChanged(bool isAllowed);
 
 
 private:
 private:
     QUrlQuery _additionalParams;
     QUrlQuery _additionalParams;