add modrinth modpack filter

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2024-10-04 17:06:47 +03:00
parent dfe3cd849d
commit 859fac604b
13 changed files with 170 additions and 88 deletions

View File

@ -35,6 +35,8 @@
*/
#include "ModrinthPage.h"
#include "Version.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "ui/dialogs/CustomMessageBox.h"
#include "ui_ModrinthPage.h"
@ -58,6 +60,7 @@ ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent)
: QWidget(parent), ui(new Ui::ModrinthPage), dialog(dialog), m_fetch_progress(this, false)
{
ui->setupUi(this);
createFilterWidget();
ui->searchEdit->installEventFilter(this);
m_model = new Modrinth::ModpackListModel(this);
@ -126,6 +129,16 @@ bool ModrinthPage::eventFilter(QObject* watched, QEvent* event)
return QObject::eventFilter(watched, event);
}
bool checkVersionFilters(const Modrinth::ModpackVersion& v, std::shared_ptr<ModFilterWidget::Filter> filter)
{
if (!filter)
return true;
return ((!filter->loaders || !v.loaders || filter->loaders & v.loaders) && // loaders
(filter->releases.empty() || // releases
std::find(filter->releases.cbegin(), filter->releases.cend(), v.version_type) != filter->releases.cend()) &&
checkMcVersions(filter->versions, { v.gameVersion })); // gameVersion}
}
void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelIndex prev)
{
ui->versionSelectionBox->clear();
@ -190,7 +203,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
} else
updateUI();
if (!current.versionsLoaded) {
if (!current.versionsLoaded || m_filterWidget->changed()) {
qDebug() << "Loading modrinth modpack versions";
auto netJob = new NetJob(QString("Modrinth::PackVersions(%1)").arg(current.name), APPLICATION->network());
@ -221,6 +234,16 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
qDebug() << *response;
qWarning() << "Error while reading modrinth modpack version: " << e.cause();
}
auto pred = [this](const Modrinth::ModpackVersion& v) { return !checkVersionFilters(v, m_filterWidget->getFilter()); };
#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
current.versions.removeIf(pred);
#else
for (auto it = current.versions.begin(); it != current.versions.end();)
if (pred(*it))
it = current.versions.erase(it);
else
++it;
#endif
for (auto version : current.versions) {
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
auto mcVersion = !version.gameVersion.isEmpty() && !version.name.contains(version.gameVersion)
@ -338,7 +361,11 @@ void ModrinthPage::suggestCurrent()
void ModrinthPage::triggerSearch()
{
m_model->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex());
ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
ui->packView->clearSelection();
ui->packDescription->clear();
ui->versionSelectionBox->clear();
m_model->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex(), m_filterWidget->getFilter(), m_filterWidget->changed());
m_fetch_progress.watch(m_model->activeSearchJob().get());
}
@ -361,3 +388,25 @@ QString ModrinthPage::getSerachTerm() const
{
return ui->searchEdit->text();
}
void ModrinthPage::createFilterWidget()
{
auto widget = ModFilterWidget::create(nullptr, false, this);
m_filterWidget.swap(widget);
auto old = ui->splitter->replaceWidget(0, m_filterWidget.get());
// because we replaced the widget we also need to delete it
if (old) {
delete old;
}
connect(ui->filterButton, &QPushButton::clicked, this, [this] { m_filterWidget->setHidden(!m_filterWidget->isHidden()); });
connect(m_filterWidget.get(), &ModFilterWidget::filterChanged, this, &ModrinthPage::triggerSearch);
auto response = std::make_shared<QByteArray>();
m_categoriesTask = ModrinthAPI::getModCategories(response);
QObject::connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
auto categories = ModrinthAPI::loadCategories(response, "modpack");
m_filterWidget->setCategories(categories);
});
m_categoriesTask->start();
}