Flow2: Add poll status text, ProgressIndicator and countdown timer
authorMichael Schuster <michael@schuster.ms>
Sat, 21 Dec 2019 03:21:41 +0000 (04:21 +0100)
committerMichael Schuster <48932272+misch7@users.noreply.github.com>
Tue, 24 Dec 2019 06:46:57 +0000 (07:46 +0100)
Also enable / disable buttons during polling.

This aims to make the authentication status more transparent and should avoid the
impression that the client is perhaps doing nothing.

Signed-off-by: Michael Schuster <michael@schuster.ms>
src/gui/creds/flow2auth.cpp
src/gui/creds/flow2auth.h
src/gui/wizard/flow2authcredspage.cpp
src/gui/wizard/flow2authcredspage.h
src/gui/wizard/flow2authcredspage.ui
src/gui/wizard/flow2authwidget.cpp
src/gui/wizard/flow2authwidget.h
src/gui/wizard/flow2authwidget.ui

index 4a220ea22ed3215d182cd663b1eeaaf93892e306..f5e6423c5e6eec2d8cc8cf6950825f30499417dc 100644 (file)
@@ -99,8 +99,11 @@ void Flow2Auth::openBrowser()
         ConfigFile cfg;
         std::chrono::milliseconds polltime = cfg.remotePollInterval();
         qCInfo(lcFlow2auth) << "setting remote poll timer interval to" << polltime.count() << "msec";
-        _pollTimer.setInterval(polltime.count());
+        _pollTimer.setInterval(1000);
         QObject::connect(&_pollTimer, &QTimer::timeout, this, &Flow2Auth::slotPollTimerTimeout);
+        _secondsInterval = (polltime.count() / 1000);
+        _secondsLeft = _secondsInterval;
+        emit statusChanged(_secondsLeft);
         _pollTimer.start();
 
 
@@ -117,6 +120,14 @@ void Flow2Auth::slotPollTimerTimeout()
 {
     _pollTimer.stop();
 
+    _secondsLeft--;
+    emit statusChanged(_secondsLeft);
+
+    if(_secondsLeft > 0) {
+        _pollTimer.start();
+        return;
+    }
+
     // Step 2: Poll
     QNetworkRequest req;
     req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -160,6 +171,7 @@ void Flow2Auth::slotPollTimerTimeout()
             loginName.clear();
 
             // Failed: poll again
+            _secondsLeft = _secondsInterval;
             _pollTimer.start();
             return;
         }
@@ -180,8 +192,10 @@ void Flow2Auth::slotPollTimerTimeout()
 void Flow2Auth::slotPollNow()
 {
     // poll now if we're not already doing so
-    if(_pollTimer.isActive())
+    if(_pollTimer.isActive()) {
+        _secondsLeft = 1;
         slotPollTimerTimeout();
+    }
 }
 
 } // namespace OCC
index f36483d48a9495c8cd43517062cc27ca03f0f495..b53c32e8a14d4a64077028ac21f5878074f40ae0 100644 (file)
@@ -52,6 +52,8 @@ signals:
      */
     void result(Flow2Auth::Result result, const QString &user = QString(), const QString &appPassword = QString());
 
+    void statusChanged(int secondsLeft);
+
 public slots:
     void slotPollNow();
 
@@ -64,6 +66,8 @@ private:
     QString _pollToken;
     QString _pollEndpoint;
     QTimer _pollTimer;
+    int _secondsLeft;
+    int _secondsInterval;
 };
 
 
index db5fd45e8c5e48c77cc4dc4db357a33000a472dc..82406edc0db7d425b737db98184d5396adb5c620 100644 (file)
 #include "creds/credentialsfactory.h"
 #include "creds/webflowcredentials.h"
 
+#include "QProgressIndicator.h"
+
 namespace OCC {
 
 Flow2AuthCredsPage::Flow2AuthCredsPage()
     : AbstractCredentialsWizardPage()
     , _ui()
+    , _progressIndi(new QProgressIndicator(this))
 {
     _ui.setupUi(this);
 
@@ -49,6 +52,9 @@ Flow2AuthCredsPage::Flow2AuthCredsPage()
 
     connect(_ui.openLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthCredsPage::slotOpenBrowser);
     connect(_ui.copyLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthCredsPage::slotCopyLinkToClipboard);
+
+    _ui.horizontalLayout->addWidget(_progressIndi);
+    stopSpinner(false);
 }
 
 void Flow2AuthCredsPage::initializePage()
@@ -58,6 +64,7 @@ void Flow2AuthCredsPage::initializePage()
     ocWizard->account()->setCredentials(CredentialsFactory::create("http"));
     _asyncAuth.reset(new Flow2Auth(ocWizard->account().data(), this));
     connect(_asyncAuth.data(), &Flow2Auth::result, this, &Flow2AuthCredsPage::asyncAuthResult, Qt::QueuedConnection);
+    connect(_asyncAuth.data(), &Flow2Auth::statusChanged, this, &Flow2AuthCredsPage::slotStatusChanged);
     connect(this, &Flow2AuthCredsPage::pollNow, _asyncAuth.data(), &Flow2Auth::slotPollNow);
     _asyncAuth->start();
 
@@ -79,6 +86,8 @@ void OCC::Flow2AuthCredsPage::cleanupPage()
 void Flow2AuthCredsPage::asyncAuthResult(Flow2Auth::Result r, const QString &user,
     const QString &appPassword)
 {
+    stopSpinner(false);
+
     switch (r) {
     case Flow2Auth::NotSupported: {
         /* Flow2Auth not supported (can't open browser) */
@@ -160,4 +169,38 @@ void Flow2AuthCredsPage::slotPollNow()
     emit pollNow();
 }
 
+void Flow2AuthCredsPage::slotStatusChanged(int secondsLeft)
+{
+    const bool pollingNow = (secondsLeft == 0);
+
+    _ui.statusLabel->setText(tr("Polling for authorization") + (pollingNow ? "" : QString(" " + tr("in %1 seconds").arg(secondsLeft))) + "...");
+
+    if(pollingNow)
+        startSpinner();
+    else
+        stopSpinner(true);
+}
+
+void Flow2AuthCredsPage::startSpinner()
+{
+    _ui.horizontalLayout->setEnabled(true);
+    _ui.statusLabel->setVisible(true);
+    _progressIndi->setVisible(true);
+    _progressIndi->startAnimation();
+
+    _ui.openLinkButton->setEnabled(false);
+    _ui.copyLinkButton->setEnabled(false);
+}
+
+void Flow2AuthCredsPage::stopSpinner(bool showStatusLabel)
+{
+    _ui.horizontalLayout->setEnabled(false);
+    _ui.statusLabel->setVisible(showStatusLabel);
+    _progressIndi->setVisible(false);
+    _progressIndi->stopAnimation();
+
+    _ui.openLinkButton->setEnabled(true);
+    _ui.copyLinkButton->setEnabled(true);
+}
+
 } // namespace OCC
index 204e2e315c3adfef09f93594bfc30e82d484eb77..100b569abd78fc5dafe038d5318b57afb528960c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ui_flow2authcredspage.h"
 
+class QProgressIndicator;
 
 namespace OCC {
 
@@ -47,6 +48,7 @@ public:
 public Q_SLOTS:
     void asyncAuthResult(Flow2Auth::Result, const QString &user, const QString &appPassword);
     void slotPollNow();
+    void slotStatusChanged(int secondsLeft);
 
 signals:
     void connectToOCUrl(const QString &);
@@ -61,6 +63,12 @@ public:
 protected slots:
     void slotOpenBrowser();
     void slotCopyLinkToClipboard();
+
+private:
+    void startSpinner();
+    void stopSpinner(bool showStatusLabel);
+
+    QProgressIndicator *_progressIndi;
 };
 
 } // namespace OCC
index 788d5ab9b0067621e1871a5d5fad0b6944d389ca..7fe3587f3815c61715fc8fe233f6e37978d8f25d 100644 (file)
      </property>
     </widget>
    </item>
+   <item>
+    <spacer name="verticalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QLabel" name="statusLabel">
+     <property name="text">
+      <string notr="true">TextLabel</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout"/>
+   </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
index fdade8b3bc2296777bebb1701ff3eb4e62a8924c..d1464525e6fa08831063b78828e0100849777f8c 100644 (file)
@@ -28,6 +28,8 @@
 #include "theme.h"
 #include "wizard/owncloudwizardcommon.h"
 
+#include "QProgressIndicator.h"
+
 namespace OCC {
 
 Q_LOGGING_CATEGORY(lcFlow2AuthWidget, "gui.wizard.flow2authwidget", QtInfoMsg)
@@ -37,6 +39,7 @@ Flow2AuthWidget::Flow2AuthWidget(Account *account, QWidget *parent)
     : QWidget(parent)
     , _account(account)
     , _ui()
+    , _progressIndi(new QProgressIndicator(this))
 {
     _ui.setupUi(this);
 
@@ -53,8 +56,12 @@ Flow2AuthWidget::Flow2AuthWidget(Account *account, QWidget *parent)
     connect(_ui.openLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotOpenBrowser);
     connect(_ui.copyLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotCopyLinkToClipboard);
 
+    _ui.horizontalLayout->addWidget(_progressIndi);
+    stopSpinner(false);
+
     _asyncAuth.reset(new Flow2Auth(_account, this));
     connect(_asyncAuth.data(), &Flow2Auth::result, this, &Flow2AuthWidget::asyncAuthResult, Qt::QueuedConnection);
+    connect(_asyncAuth.data(), &Flow2Auth::statusChanged, this, &Flow2AuthWidget::slotStatusChanged);
     connect(this, &Flow2AuthWidget::pollNow, _asyncAuth.data(), &Flow2Auth::slotPollNow);
     _asyncAuth->start();
 }
@@ -62,6 +69,8 @@ Flow2AuthWidget::Flow2AuthWidget(Account *account, QWidget *parent)
 void Flow2AuthWidget::asyncAuthResult(Flow2Auth::Result r, const QString &user,
     const QString &appPassword)
 {
+    stopSpinner(false);
+
     switch (r) {
     case Flow2Auth::NotSupported:
         /* Flow2Auth can't open browser */
@@ -118,4 +127,38 @@ void Flow2AuthWidget::slotPollNow()
     emit pollNow();
 }
 
+void Flow2AuthWidget::slotStatusChanged(int secondsLeft)
+{
+    const bool pollingNow = (secondsLeft == 0);
+
+    _ui.statusLabel->setText(tr("Polling for authorization") + (pollingNow ? "" : QString(" " + tr("in %1 seconds").arg(secondsLeft))) + "...");
+
+    if(pollingNow)
+        startSpinner();
+    else
+        stopSpinner(true);
+}
+
+void Flow2AuthWidget::startSpinner()
+{
+    _ui.horizontalLayout->setEnabled(true);
+    _ui.statusLabel->setVisible(true);
+    _progressIndi->setVisible(true);
+    _progressIndi->startAnimation();
+
+    _ui.openLinkButton->setEnabled(false);
+    _ui.copyLinkButton->setEnabled(false);
+}
+
+void Flow2AuthWidget::stopSpinner(bool showStatusLabel)
+{
+    _ui.horizontalLayout->setEnabled(false);
+    _ui.statusLabel->setVisible(showStatusLabel);
+    _progressIndi->setVisible(false);
+    _progressIndi->stopAnimation();
+
+    _ui.openLinkButton->setEnabled(true);
+    _ui.copyLinkButton->setEnabled(true);
+}
+
 } // namespace OCC
index 367545986797f833ed8b18c5ae3b7e20cb429a8a..dfbba8aa027f5d6929480bfd53bb3318bb10729f 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "ui_flow2authwidget.h"
 
+class QProgressIndicator;
+
 namespace OCC {
 
 class Flow2AuthWidget : public QWidget
@@ -36,6 +38,7 @@ public:
 public Q_SLOTS:
     void asyncAuthResult(Flow2Auth::Result, const QString &user, const QString &appPassword);
     void slotPollNow();
+    void slotStatusChanged(int secondsLeft);
 
 signals:
     void urlCatched(const QString user, const QString pass, const QString host);
@@ -51,6 +54,12 @@ private:
 protected slots:
     void slotOpenBrowser();
     void slotCopyLinkToClipboard();
+
+private:
+    void startSpinner();
+    void stopSpinner(bool showStatusLabel);
+
+    QProgressIndicator *_progressIndi;
 };
 
 } // namespace OCC
index 819790807ced7304d41a89623a46f92bd867b450..45664bc7d65a32645b58c8cf33cb94927b1fb649 100644 (file)
      </property>
     </widget>
    </item>
+   <item>
+    <spacer name="verticalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>10</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QLabel" name="statusLabel">
+     <property name="text">
+      <string notr="true">TextLabel</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout"/>
+   </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">