Add navigation widget for budget and game changers.

This commit is contained in:
Lukas Brübach 2025-04-18 00:45:00 +02:00
parent 375869f873
commit 2dd255f314
9 changed files with 43 additions and 33 deletions

View file

@ -6,7 +6,7 @@
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget( EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
QWidget *parent, QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails, const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QUrl baseUrl) QString baseUrl)
: QWidget(parent), commanderDetails(_commanderDetails) : QWidget(parent), commanderDetails(_commanderDetails)
{ {
layout = new QVBoxLayout(this); layout = new QVBoxLayout(this);

View file

@ -17,7 +17,7 @@ public:
explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget( explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget(
QWidget *parent, QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails, const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QUrl baseUrl); QString baseUrl);
void retranslateUi(); void retranslateUi();
private: private:

View file

@ -13,7 +13,7 @@
EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent, EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
EdhrecCommanderApiResponse response, EdhrecCommanderApiResponse response,
QUrl baseUrl) QString baseUrl)
: QWidget(parent) : QWidget(parent)
{ {
layout = new QHBoxLayout(this); layout = new QHBoxLayout(this);

View file

@ -14,7 +14,7 @@ class EdhrecCommanderApiResponseDisplayWidget : public QWidget
public: public:
explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent, explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
EdhrecCommanderApiResponse response, EdhrecCommanderApiResponse response,
QUrl baseUrl); QString baseUrl);
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
public slots: public slots:

View file

@ -5,10 +5,9 @@
EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigationWidget( EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigationWidget(
QWidget *parent, QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails, const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QUrl baseUrl) QString baseUrl)
: QWidget(parent), commanderDetails(_commanderDetails) : QWidget(parent), commanderDetails(_commanderDetails)
{ {
qInfo() << commanderDetails.getUrl();
layout = new QGridLayout(this); layout = new QGridLayout(this);
setLayout(layout); setLayout(layout);
@ -27,7 +26,7 @@ EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigation
for (int i = 0; i < gameChangerOptions.length(); i++) { for (int i = 0; i < gameChangerOptions.length(); i++) {
QString option = gameChangerOptions.at(i); QString option = gameChangerOptions.at(i);
QString label = option.isEmpty() ? "Any" : option.at(0).toUpper() + option.mid(1); QString label = option.isEmpty() ? "All" : option.at(0).toUpper() + option.mid(1);
QPushButton *btn = new QPushButton(label, this); QPushButton *btn = new QPushButton(label, this);
gameChangerButtons[option] = btn; gameChangerButtons[option] = btn;
layout->addWidget(btn, 2, i); layout->addWidget(btn, 2, i);
@ -76,7 +75,7 @@ EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigation
} }
retranslateUi(); retranslateUi();
applyOptionsFromUrl(baseUrl.toString()); applyOptionsFromUrl(baseUrl);
} }
void EdhrecCommanderApiResponseNavigationWidget::retranslateUi() void EdhrecCommanderApiResponseNavigationWidget::retranslateUi()
@ -89,32 +88,46 @@ void EdhrecCommanderApiResponseNavigationWidget::retranslateUi()
void EdhrecCommanderApiResponseNavigationWidget::applyOptionsFromUrl(const QString &url) void EdhrecCommanderApiResponseNavigationWidget::applyOptionsFromUrl(const QString &url)
{ {
// Example input: /commanders/kaalia-of-the-vast/core/budget QString cleanedUrl = url;
QStringList parts = url.split('/', Qt::SkipEmptyParts);
// Remove base and file extension
if (cleanedUrl.startsWith("https://json.edhrec.com/pages/"))
cleanedUrl = cleanedUrl.mid(QString("https://json.edhrec.com/pages/").length());
if (cleanedUrl.endsWith(".json"))
cleanedUrl.chop(5);
// Expecting something like: "commanders/the-ur-dragon/core/expensive"
QStringList parts = cleanedUrl.split('/', Qt::SkipEmptyParts);
// Make sure there's at least a base + commander name
if (parts.size() < 2) if (parts.size() < 2)
return; return;
// Extract extra segments, if any QString commanderName = parts[1];
QString gameChangerOpt, budgetOpt; QString gameChangerOpt, budgetOpt;
if (parts.size() >= 3) // Define valid sets
gameChangerOpt = parts[2]; // this would be "core", "upgraded", etc. QSet<QString> validGameChangers = {"core", "upgraded", "optimized"};
if (parts.size() >= 4) QSet<QString> validBudgets = {"budget", "expensive"};
budgetOpt = parts[3]; // "budget" or "expensive"
// Defensive: only accept known values // Check remaining parts after commander
for (int i = 2; i < parts.size(); ++i) {
QString part = parts[i].toLower();
if (validGameChangers.contains(part)) {
gameChangerOpt = part;
} else if (validBudgets.contains(part)) {
budgetOpt = part;
}
}
// Validate and apply
if (!gameChangerButtons.contains(gameChangerOpt)) if (!gameChangerButtons.contains(gameChangerOpt))
gameChangerOpt = ""; gameChangerOpt.clear();
if (!budgetButtons.contains(budgetOpt)) if (!budgetButtons.contains(budgetOpt))
budgetOpt = ""; budgetOpt.clear();
// Apply internal state
selectedGameChanger = gameChangerOpt; selectedGameChanger = gameChangerOpt;
selectedBudget = budgetOpt; selectedBudget = budgetOpt;
// Apply visual state
updateOptionButtonSelection(gameChangerButtons, selectedGameChanger); updateOptionButtonSelection(gameChangerButtons, selectedGameChanger);
updateOptionButtonSelection(budgetButtons, selectedBudget); updateOptionButtonSelection(budgetButtons, selectedBudget);
} }
@ -139,12 +152,7 @@ void EdhrecCommanderApiResponseNavigationWidget::actRequestCommanderNavigation()
void EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation() void EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation()
{ {
QString url = "/combos/" + commanderDetails.getSanitized(); emit requestUrl("/combos/" + commanderDetails.getSanitized());
if (!selectedGameChanger.isEmpty())
url += "/" + selectedGameChanger;
if (!selectedBudget.isEmpty())
url += "/" + selectedBudget;
emit requestUrl(url);
} }
void EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation() void EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation()

View file

@ -15,7 +15,7 @@ public:
explicit EdhrecCommanderApiResponseNavigationWidget( explicit EdhrecCommanderApiResponseNavigationWidget(
QWidget *parent, QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails, const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QUrl baseUrl); QString baseUrl);
void retranslateUi(); void retranslateUi();
void applyOptionsFromUrl(const QString &url); void applyOptionsFromUrl(const QString &url);

View file

@ -76,7 +76,7 @@ void TabEdhRec::processApiJson(QNetworkReply *reply)
EdhrecCommanderApiResponse deckData; EdhrecCommanderApiResponse deckData;
deckData.fromJson(jsonObj); deckData.fromJson(jsonObj);
displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData, reply->url()); displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData, reply->url().toString());
// flowWidget->addWidget(displayWidget); // flowWidget->addWidget(displayWidget);
setCentralWidget(displayWidget); setCentralWidget(displayWidget);

View file

@ -215,7 +215,8 @@ void TabEdhRecMain::processApiJson(QNetworkReply *reply)
if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/year.json")) { if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/year.json")) {
processTopCommandersResponse(jsonObj); processTopCommandersResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/")) {
processCommanderResponse(jsonObj); qInfo() << "Received top kek";
processCommanderResponse(jsonObj, responseUrl);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/cards/")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/cards/")) {
processCommanderResponse(jsonObj); processCommanderResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags/")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags/")) {
@ -225,6 +226,7 @@ void TabEdhRecMain::processApiJson(QNetworkReply *reply)
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/top/year.json")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/top/year.json")) {
processTopCardsResponse(jsonObj); processTopCardsResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/combos/")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/combos/")) {
qInfo() << "Received combos";
processCommanderResponse(jsonObj); processCommanderResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/average-decks/")) { } else if (responseUrl.startsWith("https://json.edhrec.com/pages/average-decks/")) {
processAverageDeckResponse(jsonObj); processAverageDeckResponse(jsonObj);
@ -316,7 +318,7 @@ void TabEdhRecMain::processTopCommandersResponse(QJsonObject reply)
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
} }
void TabEdhRecMain::processCommanderResponse(QJsonObject reply) void TabEdhRecMain::processCommanderResponse(QJsonObject reply, QString responseUrl)
{ {
EdhrecCommanderApiResponse deckData; EdhrecCommanderApiResponse deckData;
deckData.fromJson(reply); deckData.fromJson(reply);
@ -333,7 +335,7 @@ void TabEdhRecMain::processCommanderResponse(QJsonObject reply)
currentPageLayout = new QVBoxLayout(currentPageDisplay); currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout); currentPageDisplay->setLayout(currentPageLayout);
auto display = new EdhrecCommanderApiResponseDisplayWidget(currentPageDisplay, deckData, QUrl("")); auto display = new EdhrecCommanderApiResponseDisplayWidget(currentPageDisplay, deckData, responseUrl);
currentPageLayout->addWidget(display); currentPageLayout->addWidget(display);
mainLayout->addWidget(currentPageDisplay); mainLayout->addWidget(currentPageDisplay);

View file

@ -29,6 +29,7 @@ public:
public slots: public slots:
void processApiJson(QNetworkReply *reply); void processApiJson(QNetworkReply *reply);
void processCommanderResponse(QJsonObject reply, QString responseUrl = "");
void processTopCardsResponse(QJsonObject reply); void processTopCardsResponse(QJsonObject reply);
void processTopTagsResponse(QJsonObject reply); void processTopTagsResponse(QJsonObject reply);
void processTopCommandersResponse(QJsonObject reply); void processTopCommandersResponse(QJsonObject reply);
@ -55,7 +56,6 @@ private:
CardInfoPtr cardToQuery; CardInfoPtr cardToQuery;
EdhrecCommanderApiResponseDisplayWidget *displayWidget; EdhrecCommanderApiResponseDisplayWidget *displayWidget;
void processCommanderResponse(QJsonObject reply);
}; };
#endif // TAB_EDHREC_MAIN_H #endif // TAB_EDHREC_MAIN_H