diff --git a/launcher/include/account.h b/launcher/include/account.h
index 1ce7b91..851adfc 100644
--- a/launcher/include/account.h
+++ b/launcher/include/account.h
@@ -74,6 +74,8 @@ public:
Q_INVOKABLE QString getPassword();
void setPassword(const QString &password);
+ void setAvatarUrl(const QString &url);
+
Q_INVOKABLE QString getOTP();
Q_INVOKABLE void setOTPSecret(const QString &secret);
@@ -101,7 +103,6 @@ Q_SIGNALS:
bool needsPasswordChanged();
private:
- void fetchAvatar();
QCoro::Task<> fetchPassword();
/**
diff --git a/launcher/include/accountmanager.h b/launcher/include/accountmanager.h
index 1b2c25b..8e374fe 100644
--- a/launcher/include/accountmanager.h
+++ b/launcher/include/accountmanager.h
@@ -43,6 +43,8 @@ public:
Q_SIGNALS:
void accountsChanged();
+ void accountAdded(Account *account);
+ void accountLodestoneIdChanged(Account *account);
private:
void insertAccount(Account *account);
diff --git a/launcher/include/launchercore.h b/launcher/include/launchercore.h
index d272152..a41ae45 100755
--- a/launcher/include/launchercore.h
+++ b/launcher/include/launchercore.h
@@ -99,7 +99,10 @@ public:
Q_INVOKABLE BenchmarkInstaller *createBenchmarkInstaller(Profile *profile);
Q_INVOKABLE BenchmarkInstaller *createBenchmarkInstallerFromExisting(Profile *profile, const QString &filePath);
+ /// Fetches the avatar for @p account
+ void fetchAvatar(Account *account);
Q_INVOKABLE void clearAvatarCache();
+
Q_INVOKABLE void refreshNews();
Q_INVOKABLE void refreshLogoImage();
diff --git a/launcher/src/account.cpp b/launcher/src/account.cpp
index e306ce6..159b264 100644
--- a/launcher/src/account.cpp
+++ b/launcher/src/account.cpp
@@ -21,7 +21,6 @@ Account::Account(LauncherCore &launcher, const QString &key, QObject *parent)
, m_key(key)
, m_launcher(launcher)
{
- fetchAvatar();
fetchPassword();
}
@@ -68,7 +67,6 @@ void Account::setLodestoneId(const QString &id)
if (m_config.lodestoneId() != id) {
m_config.setLodestoneId(id);
m_config.save();
- fetchAvatar();
Q_EMIT lodestoneIdChanged();
}
}
@@ -191,6 +189,14 @@ void Account::setPassword(const QString &password)
}
}
+void Account::setAvatarUrl(const QString &url)
+{
+ if (m_avatarUrl != url) {
+ m_avatarUrl = url;
+ Q_EMIT avatarUrlChanged();
+ }
+}
+
QString Account::getOTP()
{
const auto otpSecret = QCoro::waitFor(getKeychainValue(QStringLiteral("otp-secret")));
@@ -227,60 +233,6 @@ QString Account::getConfigPath() const
return getConfigDir().absolutePath();
}
-void Account::fetchAvatar()
-{
- if (lodestoneId().isEmpty()) {
- return;
- }
-
- const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
- Utility::createPathIfNeeded(cacheLocation);
-
- const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, lodestoneId());
- if (!QFile(filename).exists()) {
- qDebug(ASTRA_LOG) << "Did not find lodestone character " << lodestoneId() << " in cache, fetching from Lodestone.";
-
- QUrl url;
- url.setScheme(m_launcher.settings()->preferredProtocol());
- url.setHost(QStringLiteral("na.%1").arg(m_launcher.settings()->mainServer())); // TODO: NA isnt the only thing in the world...
- url.setPath(QStringLiteral("/lodestone/character/%1").arg(lodestoneId()));
-
- const QNetworkRequest request(url);
- Utility::printRequest(QStringLiteral("GET"), request);
-
- const auto reply = m_launcher.mgr()->get(request);
- connect(reply, &QNetworkReply::finished, [this, filename, reply] {
- const QString document = QString::fromUtf8(reply->readAll());
- if (!document.isEmpty()) {
- const static QRegularExpression re(
- QStringLiteral(R"lit(
]*class=["|']frame__chara__face["|'][^>]*>\s*
![]()
]*src=["|']([^"']*))lit"));
- const QRegularExpressionMatch match = re.match(document);
-
- if (match.hasCaptured(1)) {
- const QString newAvatarUrl = match.captured(1);
-
- const auto avatarRequest = QNetworkRequest(QUrl(newAvatarUrl));
- Utility::printRequest(QStringLiteral("GET"), avatarRequest);
-
- auto avatarReply = m_launcher.mgr()->get(avatarRequest);
- connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply] {
- QFile file(filename);
- file.open(QIODevice::ReadWrite);
- file.write(avatarReply->readAll());
- file.close();
-
- m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
- Q_EMIT avatarUrlChanged();
- });
- }
- }
- });
- } else {
- m_avatarUrl = QStringLiteral("file:///%1").arg(filename);
- Q_EMIT avatarUrlChanged();
- }
-}
-
void Account::setKeychainValue(const QString &key, const QString &value)
{
if (m_launcher.isSteamDeck()) {
diff --git a/launcher/src/accountmanager.cpp b/launcher/src/accountmanager.cpp
index ec174cd..aa896a6 100644
--- a/launcher/src/accountmanager.cpp
+++ b/launcher/src/accountmanager.cpp
@@ -111,10 +111,14 @@ void AccountManager::deleteAccount(Account *account)
void AccountManager::insertAccount(Account *account)
{
+ connect(account, &Account::avatarUrlChanged, this, [this, account] {
+ Q_EMIT accountLodestoneIdChanged(account);
+ });
beginInsertRows(QModelIndex(), static_cast
(m_accounts.size()), static_cast(m_accounts.size()));
m_accounts.append(account);
endInsertRows();
Q_EMIT accountsChanged();
+ Q_EMIT accountAdded(account);
}
bool AccountManager::hasAnyAccounts() const
diff --git a/launcher/src/launchercore.cpp b/launcher/src/launchercore.cpp
index d8fed35..cd3d89f 100755
--- a/launcher/src/launchercore.cpp
+++ b/launcher/src/launchercore.cpp
@@ -40,6 +40,9 @@ LauncherCore::LauncherCore()
m_accountManager = new AccountManager(*this, this);
m_runner = new GameRunner(*this, this);
+ connect(m_accountManager, &AccountManager::accountAdded, this, &LauncherCore::fetchAvatar);
+ connect(m_accountManager, &AccountManager::accountLodestoneIdChanged, this, &LauncherCore::fetchAvatar);
+
connect(this, &LauncherCore::gameClosed, this, &LauncherCore::handleGameExit);
#ifdef BUILD_SYNC
@@ -154,6 +157,58 @@ BenchmarkInstaller *LauncherCore::createBenchmarkInstallerFromExisting(Profile *
return new BenchmarkInstaller(*this, *profile, filePath, this);
}
+void LauncherCore::fetchAvatar(Account *account)
+{
+ if (account->lodestoneId().isEmpty()) {
+ return;
+ }
+
+ const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");
+ Utility::createPathIfNeeded(cacheLocation);
+
+ const QString filename = QStringLiteral("%1/%2.jpg").arg(cacheLocation, account->lodestoneId());
+ if (!QFile(filename).exists()) {
+ qDebug(ASTRA_LOG) << "Did not find lodestone character " << account->lodestoneId() << " in cache, fetching from Lodestone.";
+
+ QUrl url;
+ url.setScheme(settings()->preferredProtocol());
+ url.setHost(QStringLiteral("na.%1").arg(settings()->mainServer())); // TODO: NA isnt the only thing in the world...
+ url.setPath(QStringLiteral("/lodestone/character/%1").arg(account->lodestoneId()));
+
+ const QNetworkRequest request(url);
+ Utility::printRequest(QStringLiteral("GET"), request);
+
+ const auto reply = mgr()->get(request);
+ connect(reply, &QNetworkReply::finished, [this, filename, reply, account] {
+ const QString document = QString::fromUtf8(reply->readAll());
+ if (!document.isEmpty()) {
+ const static QRegularExpression re(
+ QStringLiteral(R"lit(]*class=["|']frame__chara__face["|'][^>]*>\s*
![]()
]*src=["|']([^"']*))lit"));
+ const QRegularExpressionMatch match = re.match(document);
+
+ if (match.hasCaptured(1)) {
+ const QString newAvatarUrl = match.captured(1);
+
+ const auto avatarRequest = QNetworkRequest(QUrl(newAvatarUrl));
+ Utility::printRequest(QStringLiteral("GET"), avatarRequest);
+
+ auto avatarReply = mgr()->get(avatarRequest);
+ connect(avatarReply, &QNetworkReply::finished, [this, filename, avatarReply, account] {
+ QFile file(filename);
+ file.open(QIODevice::ReadWrite);
+ file.write(avatarReply->readAll());
+ file.close();
+
+ account->setAvatarUrl(QStringLiteral("file:///%1").arg(filename));
+ });
+ }
+ }
+ });
+ } else {
+ account->setAvatarUrl(QStringLiteral("file:///%1").arg(filename));
+ }
+}
+
void LauncherCore::clearAvatarCache()
{
const QString cacheLocation = QStandardPaths::standardLocations(QStandardPaths::CacheLocation)[0] + QStringLiteral("/avatars");