diff --git a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp index 22f5d4069..c34351bf2 100644 --- a/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp +++ b/launcher/minecraft/auth/steps/MSADeviceCodeStep.cpp @@ -135,9 +135,9 @@ void MSADeviceCodeStep::deviceAutorizationFinished() m_expiration_timer.setSingleShot(true); connect(&m_expiration_timer, &QTimer::timeout, this, &MSADeviceCodeStep::abort); m_expiration_timer.start(); - m_pool_timer.setTimerType(Qt::VeryCoarseTimer); m_pool_timer.setSingleShot(true); + connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser); startPoolTimer(); } @@ -157,8 +157,12 @@ void MSADeviceCodeStep::startPoolTimer() if (m_is_aborted) { return; } + if (m_expiration_timer.remainingTime() < interval * 1000) { + perform(); + return; + } + m_pool_timer.setInterval(interval * 1000); - connect(&m_pool_timer, &QTimer::timeout, this, &MSADeviceCodeStep::authenticateUser); m_pool_timer.start(); } diff --git a/launcher/resources/documents/documents.qrc b/launcher/resources/documents/documents.qrc index a5ff84390..489d1d5a2 100644 --- a/launcher/resources/documents/documents.qrc +++ b/launcher/resources/documents/documents.qrc @@ -2,7 +2,7 @@ ../../../COPYING.md - login-qr.png + login-qr.svg diff --git a/launcher/resources/documents/login-qr.svg b/launcher/resources/documents/login-qr.svg new file mode 100644 index 000000000..1b88e3c83 --- /dev/null +++ b/launcher/resources/documents/login-qr.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index 9c93df264..0a3bca86b 100644 --- a/launcher/ui/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp @@ -36,6 +36,7 @@ #include "MSALoginDialog.h" #include "Application.h" +#include "BuildConfig.h" #include "ui_MSALoginDialog.h" #include "DesktopServices.h" @@ -59,25 +60,40 @@ MSALoginDialog::MSALoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::MS font.setFixedPitch(true); ui->code->setFont(font); - ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false); + // ui->buttonBox->button(QDialogButtonBox::Help)->setDefault(false); connect(ui->copyCode, &QPushButton::clicked, this, [this] { QApplication::clipboard()->setText(ui->code->text()); }); - ui->qr->setPixmap(QPixmap(":/documents/login-qr.png")); + ui->qr->setPixmap(QIcon((":/documents/login-qr.svg")).pixmap(QSize(75, 75))); + ui->title->setText(tr("Login to %1").arg(BuildConfig.LAUNCHER_DISPLAYNAME)); + connect(ui->loginButton, &QPushButton::clicked, this, [this] { + if (m_url.isValid()) + DesktopServices::openUrl(m_url); + }); } int MSALoginDialog::exec() { // Setup the login task and start it m_account = MinecraftAccount::createBlankMSA(); - m_task = m_account->login(m_using_device_code); - connect(m_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed); - connect(m_task.get(), &Task::succeeded, this, &QDialog::accept); - connect(m_task.get(), &Task::aborted, this, &MSALoginDialog::reject); - connect(m_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus); - connect(m_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser); - connect(m_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra); - connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort); - m_task->start(); + m_authflow_task = m_account->login(false); + connect(m_authflow_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed); + connect(m_authflow_task.get(), &Task::succeeded, this, &QDialog::accept); + connect(m_authflow_task.get(), &Task::aborted, this, &MSALoginDialog::reject); + connect(m_authflow_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus); + connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser); + connect(m_authflow_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra); + connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort); + + m_devicecode_task.reset(new AuthFlow(m_account->accountData(), AuthFlow::Action::DeviceCode, this)); + connect(m_devicecode_task.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed); + connect(m_devicecode_task.get(), &Task::succeeded, this, &QDialog::accept); + connect(m_devicecode_task.get(), &Task::aborted, this, &MSALoginDialog::reject); + connect(m_devicecode_task.get(), &Task::status, this, &MSALoginDialog::onTaskStatus); + connect(m_devicecode_task.get(), &AuthFlow::authorizeWithBrowser, this, &MSALoginDialog::authorizeWithBrowser); + connect(m_devicecode_task.get(), &AuthFlow::authorizeWithBrowserWithExtra, this, &MSALoginDialog::authorizeWithBrowserWithExtra); + connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_devicecode_task.get(), &Task::abort); + QMetaObject::invokeMethod(m_authflow_task.get(), &Task::start, Qt::QueuedConnection); + QMetaObject::invokeMethod(m_devicecode_task.get(), &Task::start, Qt::QueuedConnection); return QDialog::exec(); } @@ -100,23 +116,29 @@ void MSALoginDialog::onTaskFailed(QString reason) processed += "
"; } } + auto task = qobject_cast(sender()); ui->status->setText(processed); - ui->loadingLabel->setText(m_task->getStatus()); - disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_task.get(), &Task::abort); + if (task) { + ui->loadingLabel->setText(task->getStatus()); + } + disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_authflow_task.get(), &Task::abort); + disconnect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, m_devicecode_task.get(), &Task::abort); connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &MSALoginDialog::reject); } void MSALoginDialog::authorizeWithBrowser(const QUrl& url) { - ui->stackedWidget->setCurrentIndex(2); - DesktopServices::openUrl(url); + ui->stackedWidget->setCurrentIndex(1); + // DesktopServices::openUrl(url); const auto uri = url.toString(); const auto linkString = QString("%2").arg(uri, uri); - ui->urlInfo->setText( - tr("Browser opened to complete the login process." - "

" - "If your browser hasn't opened, please manually open the following link and choose your account:

")); - ui->url->setText(linkString); + m_url = url; + ui->link->setText(linkString); + // ui->urlInfo->setText( + // tr("Browser opened to complete the login process." + // "

" + // "If your browser hasn't opened, please manually open the following link and choose your account:

")); + // ui->url->setText(linkString); } void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, int expiresIn) @@ -125,8 +147,13 @@ void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, in const auto linkString = QString("%2").arg(url, url); ui->code->setText(code); - ui->codeInfo->setText(tr("

Enter this code into %1 and choose your account.

").arg(linkString)); - ui->qr->setVisible(url == "https://www.microsoft.com/link"); + auto isDefaultUrl = url == "https://www.microsoft.com/link"; + ui->qr->setVisible(isDefaultUrl); + if (isDefaultUrl) { + ui->qrMessage->setText(tr("Open %1 or scan the QR and enter the above code.").arg(linkString)); + } else { + ui->qrMessage->setText(tr("Open %1 and enter the above code.").arg(linkString)); + } } void MSALoginDialog::onTaskStatus(QString status) @@ -136,10 +163,9 @@ void MSALoginDialog::onTaskStatus(QString status) } // Public interface -MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent, bool usingDeviceCode) +MinecraftAccountPtr MSALoginDialog::newAccount(QWidget* parent) { MSALoginDialog dlg(parent); - dlg.m_using_device_code = usingDeviceCode; if (dlg.exec() == QDialog::Accepted) { return dlg.m_account; } diff --git a/launcher/ui/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h index cf806d88b..70f480ca9 100644 --- a/launcher/ui/dialogs/MSALoginDialog.h +++ b/launcher/ui/dialogs/MSALoginDialog.h @@ -32,7 +32,7 @@ class MSALoginDialog : public QDialog { public: ~MSALoginDialog(); - static MinecraftAccountPtr newAccount(QWidget* parent, bool usingDeviceCode = false); + static MinecraftAccountPtr newAccount(QWidget* parent); int exec() override; private: @@ -47,7 +47,8 @@ class MSALoginDialog : public QDialog { private: Ui::MSALoginDialog* ui; MinecraftAccountPtr m_account; - shared_qobject_ptr m_task; + shared_qobject_ptr m_devicecode_task; + shared_qobject_ptr m_authflow_task; - bool m_using_device_code = false; + QUrl m_url; }; diff --git a/launcher/ui/dialogs/MSALoginDialog.ui b/launcher/ui/dialogs/MSALoginDialog.ui index afd97e348..b2ad80270 100644 --- a/launcher/ui/dialogs/MSALoginDialog.ui +++ b/launcher/ui/dialogs/MSALoginDialog.ui @@ -6,18 +6,18 @@ 0 0 - 500 - 300 + 772 + 326 Add Microsoft Account - + - 2 + 1 @@ -49,6 +49,9 @@ Qt::AlignCenter + + true + @@ -59,6 +62,9 @@ Qt::AlignCenter + + true + @@ -76,253 +82,349 @@ - - + + - - - Qt::Vertical - - - - 20 - 40 - - - - - - + - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 16 + 75 + true + + + + Login to Prismlauncher + + + Qt::AlignCenter + + + true + + + + + + + TextLabel + + + Qt::AlignCenter + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 250 + 40 + + + + Login with Microsoft + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - 40 - 75 - true - - - - IBeamCursor - - - CODE - - - Qt::AlignCenter - - - Qt::TextBrowserInteraction - - + + + + + + + + 0 + 0 + + + + 1 + + + Qt::Vertical + + + + + + + + + Or + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + 1 + + + Qt::Vertical + + + + + + - - - Copy code to clipboard - - - - - - - .. - - - - 22 - 22 - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + 75 + + + + + 100 + 100 + + + + + + + true + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 30 + 75 + true + + + + IBeamCursor + + + CODE + + + Qt::AlignCenter + + + Qt::TextBrowserInteraction + + + + + + + Copy code to clipboard + + + + + + + .. + + + + 22 + 22 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + TextLabel + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - - false - - - - Information - - - Qt::AlignCenter - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 100 - 100 - - - - - - - :/assets/login-qr.png - - - true - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - false - - - - Information - - - Qt::AlignCenter - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse - - - - - - - url - - - Qt::AlignCenter - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -330,10 +432,7 @@ - QDialogButtonBox::Cancel|QDialogButtonBox::Help - - - false + QDialogButtonBox::Cancel diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index d2350fb70..041b8faff 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -130,19 +130,7 @@ void AccountListPage::listChanged() void AccountListPage::on_actionAddMicrosoft_triggered() { - QMessageBox box(this); - box.setWindowTitle(tr("Add account")); - box.setText(tr("Where would you like to login?")); - box.setIcon(QMessageBox::Question); - auto authCode = box.addButton(tr("On this device"), QMessageBox::ButtonRole::NoRole); - auto deviceCode = box.addButton(tr("On another device"), QMessageBox::ButtonRole::YesRole); - auto cancel = box.addButton(tr("Cancel"), QMessageBox::ButtonRole::RejectRole); - box.setDefaultButton(authCode); - box.exec(); - if ((box.clickedButton() != deviceCode && box.clickedButton() != authCode) || box.clickedButton() == cancel) - return; - MinecraftAccountPtr account = MSALoginDialog::newAccount(this, box.clickedButton() == deviceCode); - + auto account = MSALoginDialog::newAccount(this); if (account) { m_accounts->addAccount(account); if (m_accounts->count() == 1) {