2023-01-20 07:09:01 +01:00
|
|
|
// Copyright (C) 2023 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
|
|
|
|
|
|
|
|
|
#include "authwidget.h"
|
|
|
|
|
|
|
|
|
|
#include "copilotclient.h"
|
|
|
|
|
#include "copilottr.h"
|
|
|
|
|
|
|
|
|
|
#include <utils/layoutbuilder.h>
|
|
|
|
|
#include <utils/stringutils.h>
|
|
|
|
|
|
|
|
|
|
#include <languageclient/languageclientmanager.h>
|
|
|
|
|
|
|
|
|
|
#include <QDesktopServices>
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
|
|
|
|
using namespace LanguageClient;
|
2023-03-06 19:37:55 +01:00
|
|
|
using namespace Copilot::Internal;
|
2023-01-20 07:09:01 +01:00
|
|
|
|
|
|
|
|
namespace Copilot {
|
|
|
|
|
|
|
|
|
|
AuthWidget::AuthWidget(QWidget *parent)
|
|
|
|
|
: QWidget(parent)
|
|
|
|
|
{
|
|
|
|
|
using namespace Utils::Layouting;
|
|
|
|
|
|
2023-03-06 19:37:55 +01:00
|
|
|
m_button = new QPushButton(Tr::tr("Sign in"));
|
|
|
|
|
m_button->setEnabled(false);
|
2023-01-20 07:09:01 +01:00
|
|
|
m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Small);
|
2023-03-06 19:37:55 +01:00
|
|
|
m_progressIndicator->setVisible(false);
|
2023-01-20 07:09:01 +01:00
|
|
|
m_statusLabel = new QLabel();
|
2023-03-06 19:37:55 +01:00
|
|
|
m_statusLabel->setVisible(false);
|
2023-01-20 07:09:01 +01:00
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
Column {
|
|
|
|
|
Row {
|
|
|
|
|
m_button, m_progressIndicator, st
|
|
|
|
|
},
|
|
|
|
|
m_statusLabel
|
|
|
|
|
}.attachTo(this);
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
connect(m_button, &QPushButton::clicked, this, [this]() {
|
|
|
|
|
if (m_status == Status::SignedIn)
|
|
|
|
|
signOut();
|
|
|
|
|
else if (m_status == Status::SignedOut)
|
|
|
|
|
signIn();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-24 13:09:44 +02:00
|
|
|
AuthWidget::~AuthWidget()
|
|
|
|
|
{
|
|
|
|
|
if (m_client)
|
|
|
|
|
LanguageClientManager::shutdownClient(m_client);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-20 07:09:01 +01:00
|
|
|
void AuthWidget::setState(const QString &buttonText, bool working)
|
|
|
|
|
{
|
|
|
|
|
m_button->setText(buttonText);
|
2023-03-06 19:37:55 +01:00
|
|
|
m_button->setVisible(true);
|
2023-01-20 07:09:01 +01:00
|
|
|
m_progressIndicator->setVisible(working);
|
|
|
|
|
m_statusLabel->setVisible(!m_statusLabel->text().isEmpty());
|
|
|
|
|
m_button->setEnabled(!working);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
void AuthWidget::checkStatus()
|
2023-01-20 07:09:01 +01:00
|
|
|
{
|
2023-03-09 12:26:42 +01:00
|
|
|
QTC_ASSERT(m_client && m_client->reachable(), return);
|
2023-01-20 07:09:01 +01:00
|
|
|
|
2023-03-06 19:37:55 +01:00
|
|
|
setState("Checking status ...", true);
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
m_client->requestCheckStatus(false, [this](const CheckStatusRequest::Response &response) {
|
2023-01-20 07:09:01 +01:00
|
|
|
if (response.error()) {
|
|
|
|
|
setState("failed: " + response.error()->message(), false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const CheckStatusResponse result = *response.result();
|
|
|
|
|
|
|
|
|
|
if (result.user().isEmpty()) {
|
|
|
|
|
setState("Sign in", false);
|
|
|
|
|
m_status = Status::SignedOut;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setState("Sign out " + result.user(), false);
|
|
|
|
|
m_status = Status::SignedIn;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
void AuthWidget::updateClient(const Utils::FilePath &nodeJs, const Utils::FilePath &agent)
|
|
|
|
|
{
|
|
|
|
|
LanguageClientManager::shutdownClient(m_client);
|
|
|
|
|
m_client = nullptr;
|
|
|
|
|
setState(Tr::tr("Sign in"), true);
|
|
|
|
|
if (!nodeJs.exists() || !agent.exists())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_client = new CopilotClient(nodeJs, agent);
|
|
|
|
|
connect(m_client, &Client::initialized, this, &AuthWidget::checkStatus);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-20 07:09:01 +01:00
|
|
|
void AuthWidget::signIn()
|
|
|
|
|
{
|
|
|
|
|
qCritical() << "Not implemented";
|
2023-03-09 12:26:42 +01:00
|
|
|
QTC_ASSERT(m_client && m_client->reachable(), return);
|
2023-01-20 07:09:01 +01:00
|
|
|
|
|
|
|
|
setState("Signing in ...", true);
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
m_client->requestSignInInitiate([this](const SignInInitiateRequest::Response &response) {
|
2023-01-20 07:09:01 +01:00
|
|
|
QTC_ASSERT(!response.error(), return);
|
|
|
|
|
|
|
|
|
|
Utils::setClipboardAndSelection(response.result()->userCode());
|
|
|
|
|
|
|
|
|
|
QDesktopServices::openUrl(QUrl(response.result()->verificationUri()));
|
|
|
|
|
|
|
|
|
|
m_statusLabel->setText(Tr::tr("A browser window will open, enter the code %1 when "
|
|
|
|
|
"asked.\nThe code has been copied to your clipboard.")
|
|
|
|
|
.arg(response.result()->userCode()));
|
|
|
|
|
m_statusLabel->setVisible(true);
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
m_client
|
|
|
|
|
->requestSignInConfirm(response.result()->userCode(),
|
|
|
|
|
[this](const SignInConfirmRequest::Response &response) {
|
|
|
|
|
m_statusLabel->setText("");
|
|
|
|
|
|
|
|
|
|
if (response.error()) {
|
|
|
|
|
QMessageBox::critical(this,
|
|
|
|
|
Tr::tr("Login failed"),
|
|
|
|
|
Tr::tr(
|
|
|
|
|
"The login request failed: ")
|
|
|
|
|
+ response.error()->message());
|
|
|
|
|
setState("Sign in", false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setState("Sign Out " + response.result()->user(), false);
|
|
|
|
|
});
|
2023-01-20 07:09:01 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AuthWidget::signOut()
|
|
|
|
|
{
|
2023-03-09 12:26:42 +01:00
|
|
|
QTC_ASSERT(m_client && m_client->reachable(), return);
|
2023-01-20 07:09:01 +01:00
|
|
|
|
|
|
|
|
setState("Signing out ...", true);
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
m_client->requestSignOut([this](const SignOutRequest::Response &response) {
|
2023-01-20 07:09:01 +01:00
|
|
|
QTC_ASSERT(!response.error(), return);
|
|
|
|
|
QTC_ASSERT(response.result()->status() == "NotSignedIn", return);
|
|
|
|
|
|
2023-03-09 12:26:42 +01:00
|
|
|
checkStatus();
|
2023-01-20 07:09:01 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Copilot
|