GH-3392 checking for migration status and refresh button in accounts list
This commit is contained in:
parent
7239502675
commit
3171014301
@ -205,6 +205,18 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
|
|||||||
return account->profileName();
|
return account->profileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MigrationColumn: {
|
||||||
|
if(account->isMSA()) {
|
||||||
|
return tr("N/A", "Can Migrate?");
|
||||||
|
}
|
||||||
|
if (account->canMigrate()) {
|
||||||
|
return tr("Yes", "Can Migrate?");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return tr("No", "Can Migrate?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -238,6 +250,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
|||||||
return tr("Account");
|
return tr("Account");
|
||||||
case TypeColumn:
|
case TypeColumn:
|
||||||
return tr("Type");
|
return tr("Type");
|
||||||
|
case MigrationColumn:
|
||||||
|
return tr("Can Migrate?");
|
||||||
case ProfileNameColumn:
|
case ProfileNameColumn:
|
||||||
return tr("Profile");
|
return tr("Profile");
|
||||||
default:
|
default:
|
||||||
@ -251,6 +265,8 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
|||||||
return tr("User name of the account.");
|
return tr("User name of the account.");
|
||||||
case TypeColumn:
|
case TypeColumn:
|
||||||
return tr("Type of the account - Mojang or MSA.");
|
return tr("Type of the account - Mojang or MSA.");
|
||||||
|
case MigrationColumn:
|
||||||
|
return tr("Can this account migrate to Microsoft account?");
|
||||||
case ProfileNameColumn:
|
case ProfileNameColumn:
|
||||||
return tr("Name of the Minecraft profile associated with the account.");
|
return tr("Name of the Minecraft profile associated with the account.");
|
||||||
default:
|
default:
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
// TODO: Add icon column.
|
// TODO: Add icon column.
|
||||||
NameColumn = 0,
|
NameColumn = 0,
|
||||||
ProfileNameColumn,
|
ProfileNameColumn,
|
||||||
|
MigrationColumn,
|
||||||
TypeColumn,
|
TypeColumn,
|
||||||
|
|
||||||
NUM_COLUMNS
|
NUM_COLUMNS
|
||||||
|
@ -117,6 +117,14 @@ public: /* queries */
|
|||||||
return data.profileName();
|
return data.profileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canMigrate() const {
|
||||||
|
return data.canMigrateToMSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMSA() const {
|
||||||
|
return data.type == AccountType::MSA;
|
||||||
|
}
|
||||||
|
|
||||||
QString typeString() const {
|
QString typeString() const {
|
||||||
switch(data.type) {
|
switch(data.type) {
|
||||||
case AccountType::Mojang: {
|
case AccountType::Mojang: {
|
||||||
|
@ -192,6 +192,15 @@ bool getNumber(QJsonValue value, double & out) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool getBool(QJsonValue value, bool & out) {
|
||||||
|
if(!value.isBool()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out = value.toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
"IssueInstant":"2020-12-07T19:52:08.4463796Z",
|
"IssueInstant":"2020-12-07T19:52:08.4463796Z",
|
||||||
@ -693,6 +702,63 @@ void AuthContext::onMinecraftProfileDone(int, QNetworkReply::NetworkError error,
|
|||||||
changeState(STATE_FAILED_HARD, tr("Minecraft Java profile response could not be parsed"));
|
changeState(STATE_FAILED_HARD, tr("Minecraft Java profile response could not be parsed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_data->type == AccountType::Mojang) {
|
||||||
|
doMigrationEligibilityCheck();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doGetSkin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthContext::doMigrationEligibilityCheck() {
|
||||||
|
setStage(AuthStage::MigrationEligibility);
|
||||||
|
changeState(STATE_WORKING, tr("Starting check for migration eligibility"));
|
||||||
|
|
||||||
|
auto url = QUrl("https://api.minecraftservices.com/rollout/v1/msamigration");
|
||||||
|
QNetworkRequest request = QNetworkRequest(url);
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
|
||||||
|
|
||||||
|
Requestor *requestor = new Requestor(mgr, m_oauth2, this);
|
||||||
|
connect(requestor, &Requestor::finished, this, &AuthContext::onMigrationEligibilityCheckDone);
|
||||||
|
requestor->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseRolloutResponse(QByteArray & data, bool& result) {
|
||||||
|
qDebug() << "Parsing Rollout response...";
|
||||||
|
#ifndef NDEBUG
|
||||||
|
qDebug() << data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QJsonParseError jsonError;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);
|
||||||
|
if(jsonError.error) {
|
||||||
|
qWarning() << "Failed to parse response from https://api.minecraftservices.com/rollout/v1/msamigration as JSON: " << jsonError.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto obj = doc.object();
|
||||||
|
QString feature;
|
||||||
|
if(!getString(obj.value("feature"), feature)) {
|
||||||
|
qWarning() << "Rollout feature is not a string";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(feature != "msamigration") {
|
||||||
|
qWarning() << "Rollout feature is not what we expected (msamigration), but is instead \"" << feature << "\"";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!getBool(obj.value("rollout"), result)) {
|
||||||
|
qWarning() << "Rollout feature is not a string";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthContext::onMigrationEligibilityCheckDone(int, QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers) {
|
||||||
|
if (error == QNetworkReply::NoError) {
|
||||||
|
parseRolloutResponse(data, m_data->canMigrateToMSA);
|
||||||
|
}
|
||||||
doGetSkin();
|
doGetSkin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,6 +808,8 @@ QString AuthContext::getStateMessage() const {
|
|||||||
return tr("Logging in with XBox and Mojang services");
|
return tr("Logging in with XBox and Mojang services");
|
||||||
case AuthStage::MinecraftProfile:
|
case AuthStage::MinecraftProfile:
|
||||||
return tr("Getting Minecraft profile");
|
return tr("Getting Minecraft profile");
|
||||||
|
case AuthStage::MigrationEligibility:
|
||||||
|
return tr("Checking for migration eligibility");
|
||||||
case AuthStage::Skin:
|
case AuthStage::Skin:
|
||||||
return tr("Getting Minecraft skin");
|
return tr("Getting Minecraft skin");
|
||||||
case AuthStage::Complete:
|
case AuthStage::Complete:
|
||||||
|
@ -63,6 +63,9 @@ protected:
|
|||||||
void doMinecraftProfile();
|
void doMinecraftProfile();
|
||||||
Q_SLOT void onMinecraftProfileDone(int, QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
|
Q_SLOT void onMinecraftProfileDone(int, QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
|
||||||
|
|
||||||
|
void doMigrationEligibilityCheck();
|
||||||
|
Q_SLOT void onMigrationEligibilityCheckDone(int, QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
|
||||||
|
|
||||||
void doGetSkin();
|
void doGetSkin();
|
||||||
Q_SLOT void onSkinDone(int, QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
|
Q_SLOT void onSkinDone(int, QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
|
||||||
|
|
||||||
@ -86,6 +89,7 @@ protected:
|
|||||||
UserAuth,
|
UserAuth,
|
||||||
XboxAuth,
|
XboxAuth,
|
||||||
MinecraftProfile,
|
MinecraftProfile,
|
||||||
|
MigrationEligibility,
|
||||||
Skin,
|
Skin,
|
||||||
Complete
|
Complete
|
||||||
} m_stage = AuthStage::Initial;
|
} m_stage = AuthStage::Initial;
|
||||||
|
@ -153,6 +153,22 @@ void AccountListPage::on_actionRemove_triggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccountListPage::on_actionRefresh_triggered() {
|
||||||
|
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||||
|
if (selection.size() > 0) {
|
||||||
|
QModelIndex selected = selection.first();
|
||||||
|
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||||
|
AuthSessionPtr session = std::make_shared<AuthSession>();
|
||||||
|
auto task = account->refresh(session);
|
||||||
|
if (task) {
|
||||||
|
ProgressDialog progDialog(this);
|
||||||
|
progDialog.execWithTask(task.get());
|
||||||
|
// TODO: respond to results of the task
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AccountListPage::on_actionSetDefault_triggered()
|
void AccountListPage::on_actionSetDefault_triggered()
|
||||||
{
|
{
|
||||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||||
@ -178,6 +194,7 @@ void AccountListPage::updateButtonStates()
|
|||||||
ui->actionSetDefault->setEnabled(selection.size() > 0);
|
ui->actionSetDefault->setEnabled(selection.size() > 0);
|
||||||
ui->actionUploadSkin->setEnabled(selection.size() > 0);
|
ui->actionUploadSkin->setEnabled(selection.size() > 0);
|
||||||
ui->actionDeleteSkin->setEnabled(selection.size() > 0);
|
ui->actionDeleteSkin->setEnabled(selection.size() > 0);
|
||||||
|
ui->actionRefresh->setEnabled(selection.size() > 0);
|
||||||
|
|
||||||
if(m_accounts->activeAccount().get() == nullptr) {
|
if(m_accounts->activeAccount().get() == nullptr) {
|
||||||
ui->actionNoDefault->setEnabled(false);
|
ui->actionNoDefault->setEnabled(false);
|
||||||
|
@ -63,6 +63,7 @@ public slots:
|
|||||||
void on_actionAddMojang_triggered();
|
void on_actionAddMojang_triggered();
|
||||||
void on_actionAddMicrosoft_triggered();
|
void on_actionAddMicrosoft_triggered();
|
||||||
void on_actionRemove_triggered();
|
void on_actionRemove_triggered();
|
||||||
|
void on_actionRefresh_triggered();
|
||||||
void on_actionSetDefault_triggered();
|
void on_actionSetDefault_triggered();
|
||||||
void on_actionNoDefault_triggered();
|
void on_actionNoDefault_triggered();
|
||||||
void on_actionUploadSkin_triggered();
|
void on_actionUploadSkin_triggered();
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
<addaction name="actionAddMicrosoft"/>
|
<addaction name="actionAddMicrosoft"/>
|
||||||
<addaction name="actionAddMojang"/>
|
<addaction name="actionAddMojang"/>
|
||||||
|
<addaction name="actionRefresh"/>
|
||||||
<addaction name="actionRemove"/>
|
<addaction name="actionRemove"/>
|
||||||
<addaction name="actionSetDefault"/>
|
<addaction name="actionSetDefault"/>
|
||||||
<addaction name="actionNoDefault"/>
|
<addaction name="actionNoDefault"/>
|
||||||
@ -102,6 +103,14 @@
|
|||||||
<string>Add Microsoft</string>
|
<string>Add Microsoft</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionRefresh">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Refresh the account tokens</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
Loading…
Reference in New Issue
Block a user