Qt: Match achievements login between settings/setup wizard

This commit is contained in:
Stenzek
2026-07-04 20:07:04 +10:00
parent 5d46613107
commit fb994670e6
3 changed files with 146 additions and 73 deletions
+56 -24
View File
@@ -547,8 +547,13 @@ void SetupWizardDialog::setupAchievementsPage(bool initial)
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.enable, "Cheevos", "Enabled", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.hardcoreMode, "Cheevos", "ChallengeMode", false);
connect(m_ui.enable, &QCheckBox::checkStateChanged, this, &SetupWizardDialog::updateAchievementsEnableState);
connect(m_ui.loginButton, &QPushButton::clicked, this, &SetupWizardDialog::onAchievementsLoginLogoutClicked);
connect(m_ui.viewProfile, &QPushButton::clicked, this, &SetupWizardDialog::onAchievementsViewProfileClicked);
connect(m_ui.achievementsLoginButton, &QPushButton::clicked, this, &SetupWizardDialog::onAchievementsLoginPressed);
connect(m_ui.achievementsLogoutButton, &QPushButton::clicked, this,
&SetupWizardDialog::onAchievementsLogoutPressed);
connect(m_ui.achievementsRegisterUserButton, &QPushButton::clicked, this,
&SetupWizardDialog::onAchievementsRegisterUserPressed);
connect(m_ui.achievementsViewProfileButton, &QPushButton::clicked, this,
&SetupWizardDialog::onAchievementsViewProfilePressed);
}
updateAchievementsEnableState();
@@ -563,8 +568,25 @@ void SetupWizardDialog::updateAchievementsEnableState()
void SetupWizardDialog::updateAchievementsLoginState()
{
const std::string username(Core::GetBaseStringSettingValue("Cheevos", "Username"));
const bool logged_in = !username.empty();
m_ui.achievementsUserBadge->setPixmap(QPixmap(QtHost::GetResourceQPath("images/ra-generic-user.png", true)));
QString qusername;
QString qbadge_path;
{
const auto lock = Achievements::GetLock();
if (Achievements::IsLoggedIn())
{
qusername = QString::fromStdString(Achievements::GetLoggedInUserName());
QtUtils::SetLabelPixmapPathOrURL(m_ui.achievementsUserBadge, Achievements::GetLoggedInUserIconURL(), true);
}
else
{
qusername = QString::fromStdString(Core::GetBaseStringSettingValue("Cheevos", "Username"));
}
}
const bool logged_in = !qusername.isEmpty();
if (logged_in)
{
@@ -572,57 +594,67 @@ void SetupWizardDialog::updateAchievementsLoginState()
StringUtil::FromChars<u64>(Core::GetBaseStringSettingValue("Cheevos", "LoginTimestamp", "0")).value_or(0);
const QString login_timestamp =
QtHost::FormatNumber(Host::NumberFormatType::ShortDateTime, static_cast<s64>(login_unix_timestamp));
m_ui.loginStatus->setText(
tr("Username: %1\nLogin token generated on %2.").arg(QString::fromStdString(username)).arg(login_timestamp));
m_ui.loginButton->setText(tr("Logout"));
m_ui.achievementsLoginStatus->setText(
tr("Logged in as %1\nToken generated at %2").arg(qusername).arg(login_timestamp));
}
else
{
m_ui.loginStatus->setText(tr("Not Logged In."));
m_ui.loginButton->setText(tr("Login..."));
m_ui.achievementsLoginStatus->setText(tr("Not Logged In."));
}
m_ui.viewProfile->setEnabled(logged_in);
m_ui.achievementsViewProfileButton->setVisible(logged_in);
m_ui.achievementsViewProfileButton->setEnabled(logged_in);
m_ui.achievementsLogoutButton->setVisible(logged_in);
m_ui.achievementsLogoutButton->setEnabled(logged_in);
m_ui.achievementsRegisterUserButton->setVisible(!logged_in);
m_ui.achievementsRegisterUserButton->setEnabled(!logged_in);
m_ui.achievementsLoginButton->setVisible(!logged_in);
m_ui.achievementsLoginButton->setEnabled(!logged_in);
}
void SetupWizardDialog::onAchievementsLoginLogoutClicked()
void SetupWizardDialog::onAchievementsLoginPressed()
{
if (!Core::GetBaseStringSettingValue("Cheevos", "Username").empty())
{
Host::RunOnCoreThread([]() { Achievements::Logout(); }, true);
updateAchievementsLoginState();
return;
}
AchievementLoginDialog* login = new AchievementLoginDialog(this, Achievements::LoginRequestReason::UserInitiated);
connect(login, &AchievementLoginDialog::accepted, this, &SetupWizardDialog::onAchievementsLoginCompleted);
login->open();
}
void SetupWizardDialog::onAchievementsLogoutPressed()
{
if (Core::GetBaseStringSettingValue("Cheevos", "Username").empty())
return;
// Really should do this on the core thread, but it's luckily not doing anything at this point.
Achievements::Logout();
updateAchievementsLoginState();
}
void SetupWizardDialog::onAchievementsLoginCompleted()
{
updateAchievementsEnableState();
updateAchievementsLoginState();
// Login can enable achievements/hardcore.
if (!m_ui.enable->isChecked() && Core::GetBaseBoolSettingValue("Cheevos", "Enabled", false))
{
m_ui.enable->setChecked(true);
updateAchievementsLoginState();
updateAchievementsEnableState();
}
if (!m_ui.hardcoreMode->isChecked() && Core::GetBaseBoolSettingValue("Cheevos", "ChallengeMode", false))
m_ui.hardcoreMode->setChecked(true);
}
void SetupWizardDialog::onAchievementsViewProfileClicked()
void SetupWizardDialog::onAchievementsRegisterUserPressed()
{
QtUtils::OpenURL(this, QUrl(QString::fromLatin1(Achievements::RA_REGISTER_URL)));
}
void SetupWizardDialog::onAchievementsViewProfilePressed()
{
const std::string username(Core::GetBaseStringSettingValue("Cheevos", "Username"));
if (username.empty())
return;
const QByteArray encoded_username(QUrl::toPercentEncoding(QString::fromStdString(username)));
QtUtils::OpenURL(
this, QUrl(QStringLiteral("https://retroachievements.org/user/%1").arg(QString::fromUtf8(encoded_username))));
QtUtils::OpenURL(this, QUrl(QString::fromStdString(Achievements::GetProfileURL(username))));
}
void SetupWizardDialog::setupGameListViewPage()
+4 -2
View File
@@ -73,9 +73,11 @@ private:
void openAutomaticMappingMenu(u32 port, QLabel* update_label);
void doDeviceAutomaticBinding(u32 port, QLabel* update_label, const QString& device);
void onAchievementsLoginLogoutClicked();
void onAchievementsLoginPressed();
void onAchievementsLogoutPressed();
void onAchievementsLoginCompleted();
void onAchievementsViewProfileClicked();
void onAchievementsRegisterUserPressed();
void onAchievementsViewProfilePressed();
void updateAchievementsEnableState();
void updateAchievementsLoginState();
+86 -47
View File
@@ -1130,13 +1130,98 @@
<item>
<widget class="QLabel" name="achievementsDescription">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DuckStation supports earning achievements and leaderboard tracking with RetroAchievements.&lt;/p&gt;&lt;p&gt;If you have a RetroAchievements account, you can use the form below to log in. If not, you can register at &lt;a href=&quot;https://retroachievements.org/createaccount.php&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#99ebff;&quot;&gt;https://retroachievements.org/createaccount.php&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A RetroAchievements account is &lt;span style=&quot; font-weight:700;&quot;&gt;not&lt;/span&gt; required to use DuckStation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DuckStation supports earning achievements and leaderboard tracking with RetroAchievements.&lt;/p&gt;&lt;p&gt;If you have a RetroAchievements account, you can use the form below to log in. If not, you can register by clicking the Register button below.&lt;/p&gt;&lt;p&gt;A RetroAchievements account is &lt;span style=&quot; font-weight:700;&quot;&gt;not&lt;/span&gt; required to use DuckStation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="achievementsLoginBox">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0,0,0">
<property name="spacing">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="achievementsUserBadge">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="achievementsLoginStatus">
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="achievementsRegisterUserButton">
<property name="text">
<string>Register</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/user-add-line.svg</normaloff>:/icons/monochrome/svg/user-add-line.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="achievementsViewProfileButton">
<property name="text">
<string>View Profile...</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/id-card-line.svg</normaloff>:/icons/monochrome/svg/id-card-line.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="achievementsLoginButton">
<property name="text">
<string>Login...</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/login-box-line.svg</normaloff>:/icons/monochrome/svg/login-box-line.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="achievementsLogoutButton">
<property name="text">
<string>Logout</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/logout-box-line.svg</normaloff>:/icons/monochrome/svg/logout-box-line.svg</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="achievementsSettingsGroup">
<property name="title">
@@ -1160,52 +1245,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="loginBox">
<property name="title">
<string>Account</string>
</property>
<layout class="QHBoxLayout" name="achievementsAccountLayout" stretch="1,0">
<item>
<widget class="QLabel" name="loginStatus">
<property name="text">
<string>Username:
Login token generated at:</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="achievementsAccountButtonsLayout">
<item>
<widget class="QPushButton" name="viewProfile">
<property name="text">
<string>View Profile...</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/id-card-line.svg</normaloff>:/icons/monochrome/svg/id-card-line.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loginButton">
<property name="text">
<string>Login...</string>
</property>
<property name="icon">
<iconset resource="resources/duckstation-qt.qrc">
<normaloff>:/icons/monochrome/svg/login-box-line.svg</normaloff>:/icons/monochrome/svg/login-box-line.svg</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="achievementsPageSpacer">
<property name="orientation">