From 7cc2f3361da6dbe6c88f42c60f4826139ab4357b Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Wed, 8 Mar 2023 09:50:38 +0100 Subject: [PATCH] feat(GODT-2444): added queue system for UserBadEvent from different accounts. --- .../bridge-gui-tester/Tabs/UsersTab.cpp | 17 ++++++ .../bridge-gui-tester/UserTable.cpp | 8 +++ .../bridge-gui/bridge-gui-tester/UserTable.h | 1 + .../bridge-gui/bridge-gui/QMLBackend.cpp | 52 +++++++++++++++---- .../bridge-gui/bridge-gui/QMLBackend.h | 2 + .../qml/Notifications/Notifications.qml | 4 +- 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp index 9c59083d..7c5fbce1 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp @@ -350,4 +350,21 @@ void UsersTab::configureUserAppleMail(QString const &userID, QString const &addr //**************************************************************************************************************************************************** void UsersTab::processBadEventUserFeedback(QString const &userID, bool doResync) { app().log().info(QString("Feedback received for bad event: doResync = %1, userID = %2").arg(doResync ? "true" : "false", userID)); + if (doResync) { + return; // we do not do any form of emulation for resync. + } + + SPUser user = users_.userWithID(userID); + if (!user) { + app().log().error(QString("%1(): could not find user with id %1.").arg(__func__, userID)); + } + + user->setState(UserState::SignedOut); + users_.touch(userID); + GRPCService &grpc = app().grpc(); + if (grpc.isStreaming()) { + grpc.sendEvent(newUserChangedEvent(userID)); + } + + this->updateGUIState(); } diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.cpp index b6ee1261..6213823c 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.cpp @@ -186,6 +186,14 @@ void UserTable::touch(qint32 index) { } +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +//**************************************************************************************************************************************************** +void UserTable::touch(QString const &userID) { + this->touch(this->indexOfUser(userID)); +} + + //**************************************************************************************************************************************************** /// \param[in] index The index of the user in the list. //**************************************************************************************************************************************************** diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.h b/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.h index 498d3a87..8df95785 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/UserTable.h @@ -43,6 +43,7 @@ public: // member functions. bridgepp::SPUser userWithUsername(QString const &username); ///< Return the user with a given username. qint32 indexOfUser(QString const &userID); ///< Return the index of a given User. void touch(qint32 index); ///< touch the user at a given index (indicates it has been modified). + void touch(QString const& userID); ///< touch the user with the given userID (indicates it has been modified). void remove(qint32 index); ///< Remove the user at a given index. QList users() const; ///< Return a copy of the user list. diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp index b2bd2373..1584c09f 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp @@ -822,6 +822,15 @@ void QMLBackend::setMailServerSettings(int imapPort, int smtpPort, bool useSSLFo void QMLBackend::sendBadEventUserFeedback(QString const &userID, bool doResync) { HANDLE_EXCEPTION( app().grpc().sendBadEventUserFeedback(userID, doResync); + + // Notification dialog has just been dismissed, we remove the userID from the queue, and if there are other events in the queue, we show + // the dialog again. + badEventDisplayQueue_.removeOne(userID); + if (!badEventDisplayQueue_.isEmpty()) { + // we introduce a small delay here, so that the user notices the dialog disappear and pops up again. + QTimer::singleShot(500, [&]() { this->displayBadEventDialog(badEventDisplayQueue_.front()); }); + + } ) } @@ -879,19 +888,23 @@ void QMLBackend::onLoginAlreadyLoggedIn(QString const &userID) { //**************************************************************************************************************************************************** /// \param[in] userID The userID. -/// \param[in] errorMessage. Unused //**************************************************************************************************************************************************** -void QMLBackend::onUserBadEvent(QString const &userID, QString const &errorMessage) { +void QMLBackend::onUserBadEvent(QString const &userID, QString const& ) { HANDLE_EXCEPTION( + if (badEventDisplayQueue_.contains(userID)) { + app().log().error("Received 'bad event' for a user that is already in the queue."); + return; + } + SPUser const user = users_->getUserWithID(userID); - if (!user) - app().log().error(QString("Received bad event for unknown user %1: %2").arg(user->id(), errorMessage)); -// user->setState(UserState::SignedOut); - emit userBadEvent(userID, - tr("Bridge ran into an internal error and it is not able to proceed with the account %1. Synchronize your local database now or logout" - " to do it later. Synchronization time depends on the size of your mailbox.").arg(user->primaryEmailOrUsername())); - emit selectUser(userID); - emit showMainWindow(); + if (!user) { + app().log().error(QString("Received bad event for unknown user %1.")); + } + + badEventDisplayQueue_.append(userID); + if (badEventDisplayQueue_.size() == 1) { // there was no other item is the queue, we can display the dialog immediately. + this->displayBadEventDialog(userID); + } ) } @@ -1006,3 +1019,22 @@ void QMLBackend::connectGrpcEvents() { connect(client, &GRPCClient::userBadEvent, this, &QMLBackend::onUserBadEvent); users_->connectGRPCEvents(); } + + +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +//**************************************************************************************************************************************************** +void QMLBackend::displayBadEventDialog(QString const &userID) { + HANDLE_EXCEPTION( + SPUser const user = users_->getUserWithID(userID); + if (!user) { + return; + } + + emit userBadEvent(userID, + tr("Bridge ran into an internal error and it is not able to proceed with the account %1. Synchronize your local database now or logout" + " to do it later. Synchronization time depends on the size of your mailbox.").arg(user->primaryEmailOrUsername())); + emit selectUser(userID); + emit showMainWindow(); + ) +} diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h index caa6bb25..aa0b872a 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h @@ -241,6 +241,7 @@ signals: // Signals received from the Go backend, to be forwarded to QML private: // member functions void retrieveUserList(); ///< Retrieve the list of users via gRPC. void connectGrpcEvents(); ///< Connect gRPC that need to be forwarded to QML via backend signals + void displayBadEventDialog(QString const& userID); ///< Displays the bad event dialog for a user. private: // data members UserList *users_ { nullptr }; ///< The user list. Owned by backend. @@ -253,6 +254,7 @@ private: // data members int smtpPort_ { 0 }; ///< The cached value for the SMTP port. bool useSSLForIMAP_ { false }; ///< The cached value for useSSLForIMAP. bool useSSLForSMTP_ { false }; ///< The cached value for useSSLForSMTP. + QList badEventDisplayQueue_; ///< THe queue for displaying 'bad event feedback request dialog'. friend class AppController; }; diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml index 3cdd5ff9..c1145dda 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml @@ -1126,8 +1126,8 @@ QtObject { text: qsTr("Synchronize") onTriggered: { - Backend.sendBadEventUserFeedback(root.userBadEvent.userID, true) root.userBadEvent.active = false + Backend.sendBadEventUserFeedback(root.userBadEvent.userID, true) } }, @@ -1135,8 +1135,8 @@ QtObject { text: qsTr("Logout") onTriggered: { - Backend.sendBadEventUserFeedback(root.userBadEvent.userID, false) root.userBadEvent.active = false + Backend.sendBadEventUserFeedback(root.userBadEvent.userID, false) } } ]