GH-3720 Fix UI inconsistencies with Modplatforms

Fixes GH-3118
Fixes GH-3720
Fixes GH-3731

Icons and Ok button state will now switch consistently when moving
between tabs. ATLaunchers packlist is now no longer redownloaded
each time you open its Tab. All lists are striped now. And all
search and filter fields now have a placeholder text.
This commit is contained in:
phit
2021-06-19 16:19:39 +02:00
parent 5f8d07c009
commit f7c144c393
15 changed files with 205 additions and 115 deletions
@@ -173,6 +173,14 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QStr
ui->iconButton->setIcon(QIcon(path));
}
void NewInstanceDialog::setSuggestedIcon(const QString &key)
{
auto icon = MMC->icons()->getIcon(key);
importIcon = false;
ui->iconButton->setIcon(icon);
}
InstanceTask * NewInstanceDialog::extractTask()
{
InstanceTask * extracted = creationTask.get();
+1
View File
@@ -43,6 +43,7 @@ public:
void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr);
void setSuggestedIconFromFile(const QString &path, const QString &name);
void setSuggestedIcon(const QString &key);
InstanceTask * extractTask();
@@ -71,6 +71,7 @@ void ImportPage::updateState()
{
QFileInfo fi(url.fileName());
dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
dialog->setSuggestedIcon("default");
}
}
else
@@ -83,6 +84,7 @@ void ImportPage::updateState()
// hook, line and sinker.
QFileInfo fi(url.fileName());
dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
dialog->setSuggestedIcon("default");
}
}
else
+11 -2
View File
@@ -82,10 +82,19 @@ BaseVersionPtr VanillaPage::selectedVersion() const
void VanillaPage::suggestCurrent()
{
if(m_selectedVersion && isOpened)
if (!isOpened)
{
dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
return;
}
if(!m_selectedVersion)
{
dialog->setSuggestedPack();
return;
}
dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
dialog->setSuggestedIcon("default");
}
void VanillaPage::setSelectedVersion(BaseVersionPtr version)
@@ -45,15 +45,29 @@ bool AtlPage::shouldDisplay() const
void AtlPage::openedImpl()
{
listModel->request();
if(!initialized)
{
listModel->request();
initialized = true;
}
suggestCurrent();
}
void AtlPage::suggestCurrent()
{
if(isOpened) {
dialog->setSuggestedPack(selected.name, new ATLauncher::PackInstallTask(this, selected.safeName, selectedVersion));
if(!isOpened)
{
return;
}
if (selectedVersion.isEmpty())
{
dialog->setSuggestedPack();
return;
}
dialog->setSuggestedPack(selected.name, new ATLauncher::PackInstallTask(this, selected.safeName, selectedVersion));
auto editedLogoName = selected.safeName;
auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(selected.safeName.toLower());
listModel->getLogo(selected.safeName, url, [this, editedLogoName](QString logo)
@@ -81,4 +81,6 @@ private:
ATLauncher::IndexedPack selected;
QString selectedVersion;
bool initialized = false;
};
@@ -21,6 +21,9 @@
<height>48</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
@@ -48,7 +51,14 @@
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
<item row="0" column="2">
<widget class="QComboBox" name="versionSelectionBox"/>
<widget class="QComboBox" name="versionSelectionBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
@@ -18,6 +18,8 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget *parent)
ui->packView->setModel(listModel);
ui->versionSelectionBox->setMaxVisibleItems(10);
// fix height for themes that dont respect max visible like fusion
ui->versionSelectionBox->setStyleSheet("combobox-popup: 0;");
// index is used to set the sorting with the curseforge api
ui->sortByBox->addItem(tr("Sort by featured"));
@@ -157,6 +159,12 @@ void FlamePage::suggestCurrent()
return;
}
if (selectedVersion.isEmpty())
{
dialog->setSuggestedPack();
return;
}
dialog->setSuggestedPack(current.name, new InstanceImportTask(selectedVersion));
QString editedLogoName;
editedLogoName = "curseforge_" + current.logoName.section(".", 0, 0);
+19 -12
View File
@@ -60,26 +60,33 @@ bool FtbPage::shouldDisplay() const
void FtbPage::openedImpl()
{
dialog->setSuggestedPack();
triggerSearch();
suggestCurrent();
}
void FtbPage::suggestCurrent()
{
if(isOpened)
if(!isOpened)
{
dialog->setSuggestedPack(selected.name, new ModpacksCH::PackInstallTask(selected, selectedVersion));
return;
}
for(auto art : selected.art) {
if(art.type == "square") {
QString editedLogoName;
editedLogoName = selected.name;
if (selectedVersion.isEmpty())
{
dialog->setSuggestedPack();
return;
}
listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName);
});
}
dialog->setSuggestedPack(selected.name, new ModpacksCH::PackInstallTask(selected, selectedVersion));
for(auto art : selected.art) {
if(art.type == "square") {
QString editedLogoName;
editedLogoName = selected.name;
listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName);
});
}
}
}
+8 -1
View File
@@ -32,7 +32,11 @@
</layout>
</item>
<item row="0" column="0">
<widget class="QLineEdit" name="searchEdit"/>
<widget class="QLineEdit" name="searchEdit">
<property name="placeholderText">
<string>Search and filter ...</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="searchButton">
@@ -51,6 +55,9 @@
<height>48</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
@@ -122,49 +122,50 @@ void Page::openedImpl()
void Page::suggestCurrent()
{
if(isOpened)
if(!isOpened)
{
if(!selected.broken)
{
dialog->setSuggestedPack(selected.name, new PackInstallTask(selected, selectedVersion));
QString editedLogoName;
if(selected.logo.toLower().startsWith("ftb"))
{
editedLogoName = selected.logo;
}
else
{
editedLogoName = "ftb_" + selected.logo;
}
return;
}
editedLogoName = editedLogoName.left(editedLogoName.lastIndexOf(".png"));
if(!selected.broken || !selectedVersion.isEmpty())
{
dialog->setSuggestedPack();
return;
}
if(selected.type == PackType::Public)
{
publicListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
else if (selected.type == PackType::ThirdParty)
{
thirdPartyModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
else if (selected.type == PackType::Private)
{
privateListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
}
else
dialog->setSuggestedPack(selected.name, new PackInstallTask(selected, selectedVersion));
QString editedLogoName;
if(selected.logo.toLower().startsWith("ftb"))
{
editedLogoName = selected.logo;
}
else
{
editedLogoName = "ftb_" + selected.logo;
}
editedLogoName = editedLogoName.left(editedLogoName.lastIndexOf(".png"));
if(selected.type == PackType::Public)
{
publicListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedPack();
}
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
else if (selected.type == PackType::ThirdParty)
{
thirdPartyModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
else if (selected.type == PackType::Private)
{
privateListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
});
}
}
@@ -29,6 +29,9 @@
<height>16777215</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
@@ -52,6 +55,9 @@
<height>16777215</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@@ -69,6 +75,9 @@
<height>16777215</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
@@ -72,7 +72,7 @@ int Technic::ListModel::rowCount(const QModelIndex&) const
void Technic::ListModel::searchWithTerm(const QString& term)
{
if(currentSearchTerm == term) {
if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) {
return;
}
currentSearchTerm = term;
@@ -93,9 +93,18 @@ void Technic::ListModel::searchWithTerm(const QString& term)
void Technic::ListModel::performSearch()
{
NetJob *netJob = new NetJob("Technic::Search");
auto searchUrl = QString(
"https://api.technicpack.net/search?build=multimc&q=%1"
).arg(currentSearchTerm);
QString searchUrl = "";
if (currentSearchTerm.isEmpty()) {
searchUrl = QString(
"https://api.technicpack.net/trending?build=multimc"
).arg(currentSearchTerm);
}
else
{
searchUrl = QString(
"https://api.technicpack.net/search?build=multimc&q=%1"
).arg(currentSearchTerm);
}
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
jobPtr->start();
@@ -60,7 +60,8 @@ bool TechnicPage::shouldDisplay() const
void TechnicPage::openedImpl()
{
dialog->setSuggestedPack();
suggestCurrent();
triggerSearch();
}
void TechnicPage::triggerSearch() {
@@ -95,8 +96,7 @@ void TechnicPage::suggestCurrent()
return;
}
QString editedLogoName;
editedLogoName = "technic_" + current.logoName.section(".", 0, 0);
QString editedLogoName = "technic_" + current.logoName.section(".", 0, 0);
model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
{
dialog->setSuggestedIconFromFile(logo, editedLogoName);
@@ -105,67 +105,66 @@ void TechnicPage::suggestCurrent()
if (current.metadataLoaded)
{
metadataLoaded();
return;
}
else
NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
QString slug = current.slug;
netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.technicpack.net/modpack/%1?build=multimc").arg(slug), response.get()));
QObject::connect(netJob, &NetJob::succeeded, this, [this, response, slug]
{
NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
QString slug = current.slug;
netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.technicpack.net/modpack/%1?build=multimc").arg(slug), response.get()));
QObject::connect(netJob, &NetJob::succeeded, this, [this, response, slug]
if (current.slug != slug)
{
if (current.slug != slug)
return;
}
QJsonParseError parse_error;
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
QJsonObject obj = doc.object();
if(parse_error.error != QJsonParseError::NoError)
{
qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
if (!obj.contains("url"))
{
qWarning() << "Json doesn't contain an url key";
return;
}
QJsonValueRef url = obj["url"];
if (url.isString())
{
current.url = url.toString();
}
else
{
if (!obj.contains("solder"))
{
qWarning() << "Json doesn't contain a valid url or solder key";
return;
}
QJsonParseError parse_error;
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
QJsonObject obj = doc.object();
if(parse_error.error != QJsonParseError::NoError)
QJsonValueRef solderUrl = obj["solder"];
if (solderUrl.isString())
{
qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
if (!obj.contains("url"))
{
qWarning() << "Json doesn't contain an url key";
return;
}
QJsonValueRef url = obj["url"];
if (url.isString())
{
current.url = url.toString();
current.url = solderUrl.toString();
current.isSolder = true;
}
else
{
if (!obj.contains("solder"))
{
qWarning() << "Json doesn't contain a valid url or solder key";
return;
}
QJsonValueRef solderUrl = obj["solder"];
if (solderUrl.isString())
{
current.url = solderUrl.toString();
current.isSolder = true;
}
else
{
qWarning() << "Json doesn't contain a valid url or solder key";
return;
}
qWarning() << "Json doesn't contain a valid url or solder key";
return;
}
}
current.minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
current.websiteUrl = Json::ensureString(obj, "platformUrl", QString(), "__placeholder__");
current.author = Json::ensureString(obj, "user", QString(), "__placeholder__");
current.description = Json::ensureString(obj, "description", QString(), "__placeholder__");
current.metadataLoaded = true;
metadataLoaded();
});
netJob->start();
}
current.minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
current.websiteUrl = Json::ensureString(obj, "platformUrl", QString(), "__placeholder__");
current.author = Json::ensureString(obj, "user", QString(), "__placeholder__");
current.description = Json::ensureString(obj, "description", QString(), "__placeholder__");
current.metadataLoaded = true;
metadataLoaded();
});
netJob->start();
}
// expects current.metadataLoaded to be true
@@ -27,7 +27,11 @@
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="searchEdit"/>
<widget class="QLineEdit" name="searchEdit">
<property name="placeholderText">
<string>Search and filter ...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="searchButton">