diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp index 06e27ace..ecd8e38d 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp @@ -53,6 +53,7 @@ void GRPCQtProxy::connectSignals() { connect(this, &GRPCQtProxy::logoutUserReceived, &usersTab, &UsersTab::logoutUser); connect(this, &GRPCQtProxy::setUserSplitModeReceived, &usersTab, &UsersTab::setUserSplitMode); connect(this, &GRPCQtProxy::configureUserAppleMailReceived, &usersTab, &UsersTab::configureUserAppleMail); + connect(this, &GRPCQtProxy::sendBadEventUserFeedbackReceived, &usersTab, &UsersTab::processBadEventUserFeedback); } @@ -178,6 +179,15 @@ void GRPCQtProxy::setUserSplitMode(QString const &userID, bool makeItActive) { } +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +/// \param[in] doResync Did the user request a resync? +//**************************************************************************************************************************************************** +void GRPCQtProxy::sendBadEventUserFeedback(QString const &userID, bool doResync) { + emit sendBadEventUserFeedbackReceived(userID, doResync); +} + + //**************************************************************************************************************************************************** /// \param[in] userID The userID. //**************************************************************************************************************************************************** diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h index b424ceed..783cee0b 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h @@ -52,6 +52,7 @@ public: // member functions. void setDiskCachePath(QString const &path); ///< Forwards a setDiskCachePath call via a Qt signal. void setIsAutomaticUpdateOn(bool on); ///< Forwards a SetIsAutomaticUpdateOn call via a Qt signal. void setUserSplitMode(QString const &userID, bool makeItActive); ///< Forwards a setUserSplitMode call via a Qt signal. + void sendBadEventUserFeedback(QString const &userID, bool doResync); ///< Forwards a sendBadEventUserFeedback call via a Qt signal. void logoutUser(QString const &userID); ///< Forwards a logoutUser call via a Qt signal. void removeUser(QString const &userID); ///< Forwards a removeUser call via a Qt signal. void configureUserAppleMail(QString const &userID, QString const &address); ///< Forwards a configureUserAppleMail call via a Qt signal. @@ -72,6 +73,7 @@ signals: void setDiskCachePathReceived(QString const &path); ///< Signal for the setDiskCachePath gRPC call. void setIsAutomaticUpdateOnReceived(bool on); ///< Signal for the SetIsAutomaticUpdateOn gRPC call. void setUserSplitModeReceived(QString const &userID, bool makeItActive); ///< Signal for the SetUserSplitModeReceived gRPC call. + void sendBadEventUserFeedbackReceived(QString const &userID, bool doResync); ///< Signal for the SendBadEventUserFeedback gRPC call. void logoutUserReceived(QString const &userID); ///< Signal for the LogoutUserReceived gRPC call. void removeUserReceived(QString const &userID); ///< Signal for the RemoveUserReceived gRPC call. void configureUserAppleMailReceived(QString const &userID, QString const &address); ///< Signal for the ConfigureAppleMail gRPC call. diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp index 36c7a0ef..7ffd5424 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp @@ -694,6 +694,17 @@ Status GRPCService::SetUserSplitMode(ServerContext *, UserSplitModeRequest const } +//**************************************************************************************************************************************************** +/// \param[in] request The request. +/// \return The status for the call. +//**************************************************************************************************************************************************** +Status GRPCService::SendBadEventUserFeedback(ServerContext *, UserBadEventFeedbackRequest const *request, Empty *) { + app().log().debug(__FUNCTION__); + qtProxy_.sendBadEventUserFeedback(QString::fromStdString(request->userid()), request->doresync()); + return Status::OK; +} + + //**************************************************************************************************************************************************** /// \param[in] request The request. /// \return The status for the call. diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h index 9c2a390c..c3c4aea4 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h @@ -88,12 +88,12 @@ public: // member functions. grpc::Status GetUserList(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::grpc::UserListResponse *response) override; grpc::Status GetUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::grpc::User *response) override; grpc::Status SetUserSplitMode(::grpc::ServerContext *, ::grpc::UserSplitModeRequest const *request, ::google::protobuf::Empty *) override; + grpc::Status SendBadEventUserFeedback(::grpc::ServerContext *context, ::grpc::UserBadEventFeedbackRequest const *request, ::google::protobuf::Empty *response) override; grpc::Status LogoutUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override; grpc::Status RemoveUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override; grpc::Status ConfigureUserAppleMail(::grpc::ServerContext *, ::grpc::ConfigureAppleMailRequest const *request, ::google::protobuf::Empty *) override; grpc::Status RunEventStream(::grpc::ServerContext *ctx, ::grpc::EventStreamRequest const *request, ::grpc::ServerWriter<::grpc::StreamEvent> *writer) override; grpc::Status StopEventStream(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override; - bool sendEvent(bridgepp::SPStreamEvent const &event); ///< Queue an event for sending through the event stream. private: // member functions 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 6bce0797..9c59083d 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp @@ -144,9 +144,6 @@ void UsersTab::onSendUserBadEvent() { app().log().error(QString("%1 failed. User is already signed out").arg(__FUNCTION__)); } - user->setState(UserState::SignedOut); - users_.touch(index); - GRPCService &grpc = app().grpc(); if (grpc.isStreaming()) { QString const userID = user->id(); @@ -344,5 +341,13 @@ void UsersTab::removeUser(QString const &userID) { //**************************************************************************************************************************************************** void UsersTab::configureUserAppleMail(QString const &userID, QString const &address) { app().log().info(QString("Apple mail configuration was requested for user %1, address %2").arg(userID, address)); - +} + + +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +/// \param[in] doResync Did the user request a resync? +//**************************************************************************************************************************************************** +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)); } diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.h b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.h index 94258b86..e137c2bc 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.h @@ -54,6 +54,7 @@ public slots: void logoutUser(QString const &userID); ///< slot for the logging out of a user. void removeUser(QString const &userID); ///< Slot for the removal of a user. void configureUserAppleMail(QString const &userID, QString const &address); ///< Slot for the configuration of Apple mail. + void processBadEventUserFeedback(QString const& userID, bool doResync); ///< Slot for the reception of a bad event user feedback. private slots: void onAddUserButton(); ///< Add a user to the user list. diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp index 66edd2c5..b2bd2373 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp @@ -815,6 +815,17 @@ void QMLBackend::setMailServerSettings(int imapPort, int smtpPort, bool useSSLFo } +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +/// \param[in] doResync Did the user request a resync. +//**************************************************************************************************************************************************** +void QMLBackend::sendBadEventUserFeedback(QString const &userID, bool doResync) { + HANDLE_EXCEPTION( + app().grpc().sendBadEventUserFeedback(userID, doResync); + ) +} + + //**************************************************************************************************************************************************** /// \param[in] imapPort The IMAP port. /// \param[in] smtpPort The SMTP port. @@ -874,12 +885,11 @@ void QMLBackend::onUserBadEvent(QString const &userID, QString const &errorMessa HANDLE_EXCEPTION( SPUser const user = users_->getUserWithID(userID); if (!user) - app().log().error(QString("Received bad event for unknown user %1").arg(user->id())); - user->setState(UserState::SignedOut); - emit userBadEvent( - tr("Internal error: %1 was automatically logged out. Please log in again or report this problem if the issue persists.").arg(user->primaryEmailOrUsername()), - errorMessage - ); + 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(); ) diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h index d02ba37b..caa6bb25 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h @@ -173,6 +173,7 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge void onResetFinished(); ///< Slot for the reset finish signal. void onVersionChanged(); ///< Slot for the version change signal. void setMailServerSettings(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) const; ///< Forwards a connection mode change request from QML to gRPC + void sendBadEventUserFeedback(QString const &userID, bool doResync); ///< Slot the providing user feedback for a bad event. public slots: // slot for signals received from gRPC that need transformation instead of simple forwarding void onMailServerSettingsChanged(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP); ///< Slot for the ConnectionModeChanged gRPC event. @@ -222,7 +223,7 @@ signals: // Signals received from the Go backend, to be forwarded to QML void addressChangedLogout(QString const &address); ///< Signal for the 'addressChangedLogout' gRPC stream event. void apiCertIssue(); ///< Signal for the 'apiCertIssue' gRPC stream event. void userDisconnected(QString const &username); ///< Signal for the 'userDisconnected' gRPC stream event. - void userBadEvent(QString const &description, QString const &errorMessage); ///< Signal for the 'userBadEvent' gRPC stream event. + void userBadEvent(QString const &userID, QString const &description); ///< Signal for the 'userBadEvent' gRPC stream event. void internetOff(); ///< Signal for the 'internetOff' gRPC stream event. void internetOn(); ///< Signal for the 'internetOn' gRPC stream event. void resetFinished(); ///< Signal for the 'resetFinished' gRPC stream event. 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 f7ac3d20..3cdd5ff9 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml @@ -1103,43 +1103,39 @@ QtObject { } property Notification userBadEvent: Notification { - title: qsTr("Your account was logged out") + title: qsTr("Internal error") brief: title description: "#PlaceHolderText" icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Connection | Notifications.Group.Dialogs - property var bugReportMsg: "Reporting an issue:\n\n\"%1\"\n\nError: %2\n\nThe issue persists even after loggin back in." - property var errorMessage: "" + property var userID: "" Connections { target: Backend - function onUserBadEvent(description, errorMessage) { - root.userBadEvent.description = description - root.userBadEvent.errorMessage = errorMessage + function onUserBadEvent(userID, errorMessage) { + root.userBadEvent.userID = userID + root.userBadEvent.description = errorMessage root.userBadEvent.active = true } } action: [ Action { - text: qsTr("OK") + text: qsTr("Synchronize") onTriggered: { + Backend.sendBadEventUserFeedback(root.userBadEvent.userID, true) root.userBadEvent.active = false } }, Action { - text: qsTr("Report") + text: qsTr("Logout") onTriggered: { - root.frontendMain.showBugReportAndPrefill( - root.userBadEvent.bugReportMsg. - arg( root.userBadEvent.description). - arg(root.userBadEvent.errorMessage) - ) + Backend.sendBadEventUserFeedback(root.userBadEvent.userID, false) root.userBadEvent.active = false } } diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp index adcc145c..ff7df494 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp @@ -675,6 +675,18 @@ grpc::Status GRPCClient::setUserSplitMode(QString const &userID, bool active) { } +//**************************************************************************************************************************************************** +/// \param[in] userID The userID. +/// \param[in] doResync Did the user request a resync. +//**************************************************************************************************************************************************** +grpc::Status GRPCClient::sendBadEventUserFeedback(QString const &userID, bool doResync) { + UserBadEventFeedbackRequest request; + request.set_userid(userID.toStdString()); + request.set_doresync(doResync); + return this->logGRPCCallStatus(stub_->SendBadEventUserFeedback(this->clientContext().get(), request, &empty), __FUNCTION__); +} + + //**************************************************************************************************************************************************** /// \param[out] outUsers The user list. /// \return The status code for the gRPC call. diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h index 0484ad25..e16451e6 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h @@ -173,6 +173,7 @@ public: // user related calls grpc::Status removeUser(QString const &userID); ///< Performs the 'removeUser' call. grpc::Status configureAppleMail(QString const &userID, QString const &address); ///< Performs the 'configureAppleMail' call. grpc::Status setUserSplitMode(QString const &userID, bool active); ///< Performs the 'SetUserSplitMode' call. + grpc::Status sendBadEventUserFeedback(QString const& userID, bool doResync); ///< Performs the 'SendBadEventUserFeedback' call. signals: void toggleSplitModeFinished(QString const &userID);