refactor(RD): decouple ResourceModels from ResourcePages
This makes it so that we don't need a reference to the parent page in the model. It will be useful once we change the page from a widget-based one to a QML page. It also makes tasks be created in the dialog instead of the page, so that the dialog can also have the necessary information to mark versions as selected / deselected easily. It also makes the task pointers into smart pointers. Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
39b7ac90d4
commit
45d1319891
@ -32,6 +32,7 @@ class ResourceDownloadTask : public SequentialTask {
|
|||||||
public:
|
public:
|
||||||
explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr<ResourceFolderModel> packs, bool is_indexed = true);
|
explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr<ResourceFolderModel> packs, bool is_indexed = true);
|
||||||
const QString& getFilename() const { return m_pack_version.fileName; }
|
const QString& getFilename() const { return m_pack_version.fileName; }
|
||||||
|
const QVariant& getVersionID() const { return m_pack_version.fileId; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModPlatform::IndexedPack m_pack;
|
ModPlatform::IndexedPack m_pack;
|
||||||
|
@ -65,6 +65,9 @@ struct IndexedVersion {
|
|||||||
QString hash;
|
QString hash;
|
||||||
bool is_preferred = true;
|
bool is_preferred = true;
|
||||||
QString changelog;
|
QString changelog;
|
||||||
|
|
||||||
|
// For internal use, not provided by APIs
|
||||||
|
bool is_currently_selected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtraPackData {
|
struct ExtraPackData {
|
||||||
@ -95,6 +98,23 @@ struct IndexedPack {
|
|||||||
// Don't load by default, since some modplatform don't have that info
|
// Don't load by default, since some modplatform don't have that info
|
||||||
bool extraDataLoaded = true;
|
bool extraDataLoaded = true;
|
||||||
ExtraPackData extraData;
|
ExtraPackData extraData;
|
||||||
|
|
||||||
|
// For internal use, not provided by APIs
|
||||||
|
[[nodiscard]] bool isVersionSelected(size_t index) const
|
||||||
|
{
|
||||||
|
if (!versionsLoaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return versions.at(index).is_currently_selected;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool isAnyVersionSelected() const
|
||||||
|
{
|
||||||
|
if (!versionsLoaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::any_of(versions.constBegin(), versions.constEnd(),
|
||||||
|
[](auto const& v) { return v.is_currently_selected; });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ModPlatform
|
} // namespace ModPlatform
|
||||||
|
@ -69,13 +69,20 @@ class ResourceAPI {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct VersionSearchArgs {
|
struct VersionSearchArgs {
|
||||||
QString addonId;
|
ModPlatform::IndexedPack& pack;
|
||||||
|
|
||||||
std::optional<std::list<Version> > mcVersions;
|
std::optional<std::list<Version> > mcVersions;
|
||||||
std::optional<ModLoaderTypes> loaders;
|
std::optional<ModLoaderTypes> loaders;
|
||||||
|
|
||||||
|
void operator=(VersionSearchArgs other)
|
||||||
|
{
|
||||||
|
pack = other.pack;
|
||||||
|
mcVersions = other.mcVersions;
|
||||||
|
loaders = other.loaders;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct VersionSearchCallbacks {
|
struct VersionSearchCallbacks {
|
||||||
std::function<void(QJsonDocument&, QString)> on_succeed;
|
std::function<void(QJsonDocument&, ModPlatform::IndexedPack&)> on_succeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProjectInfoArgs {
|
struct ProjectInfoArgs {
|
||||||
|
@ -114,7 +114,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
|||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
|
|
||||||
auto netJob = new NetJob(QString("Flame::GetLatestVersion(%1)").arg(args.addonId), APPLICATION->network());
|
auto netJob = new NetJob(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
|
||||||
auto response = new QByteArray();
|
auto response = new QByteArray();
|
||||||
ModPlatform::IndexedVersion ver;
|
ModPlatform::IndexedVersion ver;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class FlameAPI : public NetworkResourceAPI {
|
|||||||
|
|
||||||
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
|
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
|
||||||
{
|
{
|
||||||
QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.addonId)};
|
QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString())};
|
||||||
|
|
||||||
QStringList get_parameters;
|
QStringList get_parameters;
|
||||||
if (args.mcVersions.has_value())
|
if (args.mcVersions.has_value())
|
||||||
|
@ -129,7 +129,8 @@ void FlameCheckUpdate::executeTask()
|
|||||||
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
|
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
|
||||||
setProgress(i++, m_mods.size());
|
setProgress(i++, m_mods.size());
|
||||||
|
|
||||||
auto latest_ver = api.getLatestVersion({ mod->metadata()->project_id.toString(), m_game_versions, m_loaders });
|
ModPlatform::IndexedPack pack{ mod->metadata()->project_id.toString() };
|
||||||
|
auto latest_ver = api.getLatestVersion({ pack, m_game_versions, m_loaders });
|
||||||
|
|
||||||
// Check if we were aborted while getting the latest version
|
// Check if we were aborted while getting the latest version
|
||||||
if (m_was_aborted) {
|
if (m_was_aborted) {
|
||||||
|
@ -76,10 +76,10 @@ static QString enumToString(int hash_algorithm)
|
|||||||
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||||
QJsonArray& arr,
|
QJsonArray& arr,
|
||||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||||
BaseInstance* inst)
|
const BaseInstance* inst)
|
||||||
{
|
{
|
||||||
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
||||||
auto profile = (dynamic_cast<MinecraftInstance*>(inst))->getPackProfile();
|
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||||
|
|
||||||
for (auto versionIter : arr) {
|
for (auto versionIter : arr) {
|
||||||
|
@ -17,7 +17,7 @@ void loadBody(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
|||||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||||
QJsonArray& arr,
|
QJsonArray& arr,
|
||||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||||
BaseInstance* inst);
|
const BaseInstance* inst);
|
||||||
auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion;
|
auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion;
|
||||||
|
|
||||||
} // namespace FlameMod
|
} // namespace FlameMod
|
||||||
|
@ -79,7 +79,7 @@ NetJob::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Ver
|
|||||||
|
|
||||||
auto versions_url = versions_url_optional.value();
|
auto versions_url = versions_url_optional.value();
|
||||||
|
|
||||||
auto netJob = new NetJob(QString("%1::Versions").arg(args.addonId), APPLICATION->network());
|
auto netJob = new NetJob(QString("%1::Versions").arg(args.pack.name), APPLICATION->network());
|
||||||
auto response = new QByteArray();
|
auto response = new QByteArray();
|
||||||
|
|
||||||
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
||||||
@ -94,7 +94,7 @@ NetJob::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Ver
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks.on_succeed(doc, args.addonId);
|
callbacks.on_succeed(doc, args.pack);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(netJob, &NetJob::finished, [response] {
|
QObject::connect(netJob, &NetJob::finished, [response] {
|
||||||
|
@ -141,7 +141,7 @@ class ModrinthAPI : public NetworkResourceAPI {
|
|||||||
get_arguments.append(QString("loaders=[\"%1\"]").arg(getModLoaderStrings(args.loaders.value()).join("\",\"")));
|
get_arguments.append(QString("loaders=[\"%1\"]").arg(getModLoaderStrings(args.loaders.value()).join("\",\"")));
|
||||||
|
|
||||||
return QString("%1/project/%2/version%3%4")
|
return QString("%1/project/%2/version%3%4")
|
||||||
.arg(BuildConfig.MODRINTH_PROD_URL, args.addonId, get_arguments.isEmpty() ? "" : "?", get_arguments.join('&'));
|
.arg(BuildConfig.MODRINTH_PROD_URL, args.pack.addonId.toString(), get_arguments.isEmpty() ? "" : "?", get_arguments.join('&'));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto getGameVersionsArray(std::list<Version> mcVersions) const -> QString
|
auto getGameVersionsArray(std::list<Version> mcVersions) const -> QString
|
||||||
|
@ -95,10 +95,10 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob
|
|||||||
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||||
QJsonArray& arr,
|
QJsonArray& arr,
|
||||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||||
BaseInstance* inst)
|
const BaseInstance* inst)
|
||||||
{
|
{
|
||||||
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
||||||
QString mcVersion = (static_cast<MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
|
QString mcVersion = (static_cast<const MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
|
||||||
|
|
||||||
for (auto versionIter : arr) {
|
for (auto versionIter : arr) {
|
||||||
auto obj = versionIter.toObject();
|
auto obj = versionIter.toObject();
|
||||||
|
@ -29,7 +29,7 @@ void loadExtraPackData(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
|||||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||||
QJsonArray& arr,
|
QJsonArray& arr,
|
||||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||||
BaseInstance* inst);
|
const BaseInstance* inst);
|
||||||
auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion;
|
auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion;
|
||||||
|
|
||||||
} // namespace Modrinth
|
} // namespace Modrinth
|
||||||
|
@ -141,38 +141,44 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage()
|
|||||||
return m_selectedPage;
|
return m_selectedPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceDownloadDialog::addResource(QString name, ResourceDownloadTask* task)
|
void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed)
|
||||||
{
|
{
|
||||||
removeResource(name);
|
removeResource(pack, ver);
|
||||||
m_selected.insert(name, task);
|
|
||||||
|
ver.is_currently_selected = true;
|
||||||
|
m_selected.insert(pack.name, new ResourceDownloadTask(pack, ver, getBaseModel(), is_indexed));
|
||||||
|
|
||||||
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceDownloadDialog::removeResource(QString name)
|
static ModPlatform::IndexedVersion& getVersionWithID(ModPlatform::IndexedPack& pack, QVariant id)
|
||||||
{
|
{
|
||||||
if (m_selected.contains(name))
|
Q_ASSERT(pack.versionsLoaded);
|
||||||
m_selected.find(name).value()->deleteLater();
|
auto it = std::find_if(pack.versions.begin(), pack.versions.end(), [id](auto const& v) { return v.fileId == id; });
|
||||||
m_selected.remove(name);
|
Q_ASSERT(it != pack.versions.end());
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver)
|
||||||
|
{
|
||||||
|
if (auto selected_task_it = m_selected.find(pack.name); selected_task_it != m_selected.end()) {
|
||||||
|
auto selected_task = *selected_task_it;
|
||||||
|
auto old_version_id = selected_task->getVersionID();
|
||||||
|
|
||||||
|
// If the new and old version IDs don't match, search for the old one and deselect it.
|
||||||
|
if (ver.fileId != old_version_id)
|
||||||
|
getVersionWithID(pack, old_version_id).is_currently_selected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deselect the new version too, since all versions of that pack got removed.
|
||||||
|
ver.is_currently_selected = false;
|
||||||
|
|
||||||
|
m_selected.remove(pack.name);
|
||||||
|
|
||||||
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceDownloadDialog::isSelected(QString name, QString filename) const
|
const QList<ResourceDownloadDialog::DownloadTaskPtr> ResourceDownloadDialog::getTasks()
|
||||||
{
|
|
||||||
auto iter = m_selected.constFind(name);
|
|
||||||
if (iter == m_selected.constEnd())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// FIXME: Is there a way to check for versions without checking the filename
|
|
||||||
// as a heuristic, other than adding such info to ResourceDownloadTask itself?
|
|
||||||
if (!filename.isEmpty())
|
|
||||||
return iter.value()->getFilename() == filename;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QList<ResourceDownloadTask*> ResourceDownloadDialog::getTasks()
|
|
||||||
{
|
{
|
||||||
return m_selected.values();
|
return m_selected.values();
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
|
|
||||||
|
#include "QObjectPtr.h"
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
#include "ui/pages/BasePageProvider.h"
|
#include "ui/pages/BasePageProvider.h"
|
||||||
|
|
||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
@ -41,6 +43,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using DownloadTaskPtr = shared_qobject_ptr<ResourceDownloadTask>;
|
||||||
|
|
||||||
ResourceDownloadDialog(QWidget* parent, const std::shared_ptr<ResourceFolderModel> base_model);
|
ResourceDownloadDialog(QWidget* parent, const std::shared_ptr<ResourceFolderModel> base_model);
|
||||||
|
|
||||||
void initializeContainer();
|
void initializeContainer();
|
||||||
@ -54,11 +58,10 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||||||
bool selectPage(QString pageId);
|
bool selectPage(QString pageId);
|
||||||
ResourcePage* getSelectedPage();
|
ResourcePage* getSelectedPage();
|
||||||
|
|
||||||
void addResource(QString name, ResourceDownloadTask* task);
|
void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, bool is_indexed = false);
|
||||||
void removeResource(QString name);
|
void removeResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
|
||||||
[[nodiscard]] bool isSelected(QString name, QString filename = "") const;
|
|
||||||
|
|
||||||
const QList<ResourceDownloadTask*> getTasks();
|
const QList<DownloadTaskPtr> getTasks();
|
||||||
[[nodiscard]] const std::shared_ptr<ResourceFolderModel> getBaseModel() const { return m_base_model; }
|
[[nodiscard]] const std::shared_ptr<ResourceFolderModel> getBaseModel() const { return m_base_model; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -82,7 +85,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||||||
QDialogButtonBox m_buttons;
|
QDialogButtonBox m_buttons;
|
||||||
QVBoxLayout m_vertical_layout;
|
QVBoxLayout m_vertical_layout;
|
||||||
|
|
||||||
QHash<QString, ResourceDownloadTask*> m_selected;
|
QHash<QString, DownloadTaskPtr> m_selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "ModModel.h"
|
#include "ModModel.h"
|
||||||
|
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "ModPage.h"
|
|
||||||
#include "minecraft/MinecraftInstance.h"
|
#include "minecraft/MinecraftInstance.h"
|
||||||
#include "minecraft/PackProfile.h"
|
#include "minecraft/PackProfile.h"
|
||||||
|
|
||||||
@ -9,15 +9,23 @@
|
|||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
ModModel::ModModel(ModPage* parent, ResourceAPI* api) : ResourceModel(parent, api) {}
|
ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(base_inst, api) {}
|
||||||
|
|
||||||
/******** Make data requests ********/
|
/******** Make data requests ********/
|
||||||
|
|
||||||
ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
||||||
{
|
{
|
||||||
auto profile = static_cast<MinecraftInstance&>(m_associated_page->m_base_instance).getPackProfile();
|
auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
|
||||||
|
|
||||||
|
Q_ASSERT(profile);
|
||||||
|
Q_ASSERT(m_filter);
|
||||||
|
|
||||||
|
std::optional<std::list<Version>> versions {};
|
||||||
|
if (!m_filter->versions.empty())
|
||||||
|
versions = m_filter->versions;
|
||||||
|
|
||||||
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term,
|
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term,
|
||||||
getSorts()[currentSort], profile->getModLoaders(), getMineVersions() };
|
getSorts()[currentSort], profile->getModLoaders(), versions };
|
||||||
}
|
}
|
||||||
ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
|
ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
|
||||||
{
|
{
|
||||||
@ -30,19 +38,24 @@ ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
|
|||||||
|
|
||||||
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
|
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
|
||||||
{
|
{
|
||||||
auto const& pack = m_packs[entry.row()];
|
auto& pack = m_packs[entry.row()];
|
||||||
auto profile = static_cast<MinecraftInstance&>(m_associated_page->m_base_instance).getPackProfile();
|
auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
|
||||||
|
|
||||||
return { pack.addonId.toString(), getMineVersions(), profile->getModLoaders() };
|
Q_ASSERT(profile);
|
||||||
|
Q_ASSERT(m_filter);
|
||||||
|
|
||||||
|
std::optional<std::list<Version>> versions {};
|
||||||
|
if (!m_filter->versions.empty())
|
||||||
|
versions = m_filter->versions;
|
||||||
|
|
||||||
|
return { pack, versions, profile->getModLoaders() };
|
||||||
}
|
}
|
||||||
ResourceAPI::VersionSearchCallbacks ModModel::createVersionsCallbacks(QModelIndex& entry)
|
ResourceAPI::VersionSearchCallbacks ModModel::createVersionsCallbacks(QModelIndex& entry)
|
||||||
{
|
{
|
||||||
auto const& pack = m_packs[entry.row()];
|
return { [this, entry](auto& doc, auto& pack) {
|
||||||
|
|
||||||
return { [this, pack, entry](auto& doc, auto addonId) {
|
|
||||||
if (!s_running_models.constFind(this).value())
|
if (!s_running_models.constFind(this).value())
|
||||||
return;
|
return;
|
||||||
versionRequestSucceeded(doc, addonId, entry);
|
versionRequestSucceeded(doc, pack, entry);
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +100,7 @@ void ModModel::searchRequestFinished(QJsonDocument& doc)
|
|||||||
loadIndexedPack(pack, packObj);
|
loadIndexedPack(pack, packObj);
|
||||||
newList.append(pack);
|
newList.append(pack);
|
||||||
} catch (const JSONValidationError& e) {
|
} catch (const JSONValidationError& e) {
|
||||||
qWarning() << "Error while loading mod from " << m_associated_page->debugName() << ": " << e.cause();
|
qWarning() << "Error while loading mod from " << debugName() << ": " << e.cause();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,48 +140,36 @@ void ModModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack&
|
|||||||
new_pack.setValue(pack);
|
new_pack.setValue(pack);
|
||||||
if (!setData(index, new_pack, Qt::UserRole)) {
|
if (!setData(index, new_pack, Qt::UserRole)) {
|
||||||
qWarning() << "Failed to cache mod info!";
|
qWarning() << "Failed to cache mod info!";
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_associated_page->updateUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModModel::versionRequestSucceeded(QJsonDocument doc, QString addonId, const QModelIndex& index)
|
|
||||||
{
|
|
||||||
auto current = m_associated_page->getCurrentPack();
|
|
||||||
if (addonId != current.addonId) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit projectInfoUpdated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModModel::versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
|
||||||
|
{
|
||||||
auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
|
auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadIndexedPackVersions(current, arr);
|
loadIndexedPackVersions(pack, arr);
|
||||||
} catch (const JSONValidationError& e) {
|
} catch (const JSONValidationError& e) {
|
||||||
qDebug() << doc;
|
qDebug() << doc;
|
||||||
qWarning() << "Error while reading " << debugName() << " mod version: " << e.cause();
|
qWarning() << "Error while reading " << debugName() << " mod version: " << e.cause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the index is still valid for this mod or not
|
||||||
|
if (pack.addonId == data(index, Qt::UserRole).value<ModPlatform::IndexedPack>().addonId) {
|
||||||
// Cache info :^)
|
// Cache info :^)
|
||||||
QVariant new_pack;
|
QVariant new_pack;
|
||||||
new_pack.setValue(current);
|
new_pack.setValue(pack);
|
||||||
if (!setData(index, new_pack, Qt::UserRole)) {
|
if (!setData(index, new_pack, Qt::UserRole)) {
|
||||||
qWarning() << "Failed to cache mod versions!";
|
qWarning() << "Failed to cache mod versions!";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_associated_page->updateVersionList();
|
emit versionListUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/******** Helpers ********/
|
|
||||||
|
|
||||||
#define MOD_PAGE(x) static_cast<ModPage*>(x)
|
|
||||||
|
|
||||||
auto ModModel::getMineVersions() const -> std::optional<std::list<Version>>
|
|
||||||
{
|
|
||||||
auto versions = MOD_PAGE(m_associated_page)->getFilter()->versions;
|
|
||||||
if (!versions.empty())
|
|
||||||
return versions;
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "modplatform/ResourceAPI.h"
|
#include "modplatform/ResourceAPI.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ResourceModel.h"
|
#include "ui/pages/modplatform/ResourceModel.h"
|
||||||
|
#include "ui/widgets/ModFilterWidget.h"
|
||||||
|
|
||||||
class Version;
|
class Version;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ class ModModel : public ResourceModel {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModModel(ModPage* parent, ResourceAPI* api);
|
ModModel(const BaseInstance&, ResourceAPI* api);
|
||||||
|
|
||||||
/* Ask the API for more information */
|
/* Ask the API for more information */
|
||||||
void searchWithTerm(const QString& term, const int sort, const bool filter_changed);
|
void searchWithTerm(const QString& term, const int sort, const bool filter_changed);
|
||||||
@ -26,12 +27,12 @@ class ModModel : public ResourceModel {
|
|||||||
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
|
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
|
||||||
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
|
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
|
||||||
|
|
||||||
|
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void searchRequestFinished(QJsonDocument& doc);
|
void searchRequestFinished(QJsonDocument& doc);
|
||||||
|
|
||||||
void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
|
void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
|
||||||
|
void versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
|
||||||
void versionRequestSucceeded(QJsonDocument doc, QString addonId, const QModelIndex& index);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||||
@ -47,10 +48,10 @@ class ModModel : public ResourceModel {
|
|||||||
virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0;
|
virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0;
|
||||||
virtual auto getSorts() const -> const char** = 0;
|
virtual auto getSorts() const -> const char** = 0;
|
||||||
|
|
||||||
inline auto getMineVersions() const -> std::optional<std::list<Version>>;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int currentSort = 0;
|
int currentSort = 0;
|
||||||
|
|
||||||
|
std::shared_ptr<ModFilterWidget::Filter> m_filter = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -51,8 +51,6 @@
|
|||||||
|
|
||||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ModModel.h"
|
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||||
@ -151,7 +149,7 @@ void ModPage::updateVersionList()
|
|||||||
void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
|
void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
|
||||||
{
|
{
|
||||||
bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||||
m_parent_dialog->addResource(pack.name, new ResourceDownloadTask(pack, version, m_parent_dialog->getBaseModel(), is_indexed));
|
m_parent_dialog->addResource(pack, version, is_indexed);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ResourcePage.h"
|
#include "ui/pages/modplatform/ResourcePage.h"
|
||||||
|
#include "ui/pages/modplatform/ModModel.h"
|
||||||
#include "ui/widgets/ModFilterWidget.h"
|
#include "ui/widgets/ModFilterWidget.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -24,9 +25,14 @@ class ModPage : public ResourcePage {
|
|||||||
static T* create(ModDownloadDialog* dialog, BaseInstance& instance)
|
static T* create(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||||
{
|
{
|
||||||
auto page = new T(dialog, instance);
|
auto page = new T(dialog, instance);
|
||||||
|
auto model = static_cast<ModModel*>(page->getModel());
|
||||||
|
|
||||||
auto filter_widget = ModFilterWidget::create(static_cast<MinecraftInstance&>(instance).getPackProfile()->getComponentVersion("net.minecraft"), page);
|
auto filter_widget = ModFilterWidget::create(static_cast<MinecraftInstance&>(instance).getPackProfile()->getComponentVersion("net.minecraft"), page);
|
||||||
page->setFilterWidget(filter_widget);
|
page->setFilterWidget(filter_widget);
|
||||||
|
model->setFilter(page->getFilter());
|
||||||
|
|
||||||
|
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList);
|
||||||
|
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,13 @@
|
|||||||
|
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ResourcePage.h"
|
|
||||||
#include "ui/widgets/ProjectItem.h"
|
#include "ui/widgets/ProjectItem.h"
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
QHash<ResourceModel*, bool> ResourceModel::s_running_models;
|
QHash<ResourceModel*, bool> ResourceModel::s_running_models;
|
||||||
|
|
||||||
ResourceModel::ResourceModel(ResourcePage* parent, ResourceAPI* api) : QAbstractListModel(), m_api(api), m_associated_page(parent)
|
ResourceModel::ResourceModel(BaseInstance const& base_inst, ResourceAPI* api) : QAbstractListModel(), m_base_instance(base_inst), m_api(api)
|
||||||
{
|
{
|
||||||
s_running_models.insert(this, true);
|
s_running_models.insert(this, true);
|
||||||
}
|
}
|
||||||
@ -72,7 +71,7 @@ auto ResourceModel::data(const QModelIndex& index, int role) const -> QVariant
|
|||||||
case UserDataTypes::DESCRIPTION:
|
case UserDataTypes::DESCRIPTION:
|
||||||
return pack.description;
|
return pack.description;
|
||||||
case UserDataTypes::SELECTED:
|
case UserDataTypes::SELECTED:
|
||||||
return isPackSelected(pack);
|
return pack.isAnyVersionSelected();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -87,13 +86,14 @@ bool ResourceModel::setData(const QModelIndex& index, const QVariant& value, int
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_packs[pos] = value.value<ModPlatform::IndexedPack>();
|
m_packs[pos] = value.value<ModPlatform::IndexedPack>();
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ResourceModel::debugName() const
|
QString ResourceModel::debugName() const
|
||||||
{
|
{
|
||||||
return m_associated_page->debugName() + " (Model)";
|
return "ResourceDownload (Model)";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceModel::fetchMore(const QModelIndex& parent)
|
void ResourceModel::fetchMore(const QModelIndex& parent)
|
||||||
@ -195,7 +195,7 @@ std::optional<QIcon> ResourceModel::getIcon(QModelIndex& index, const QUrl& url)
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto cache_entry = APPLICATION->metacache()->resolveEntry(
|
auto cache_entry = APPLICATION->metacache()->resolveEntry(
|
||||||
m_associated_page->metaEntryBase(),
|
metaEntryBase(),
|
||||||
QString("logos/%1").arg(QString(QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Algorithm::Sha1).toHex())));
|
QString("logos/%1").arg(QString(QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Algorithm::Sha1).toHex())));
|
||||||
auto icon_fetch_action = Net::Download::makeCached(url, cache_entry);
|
auto icon_fetch_action = Net::Download::makeCached(url, cache_entry);
|
||||||
|
|
||||||
@ -222,11 +222,6 @@ std::optional<QIcon> ResourceModel::getIcon(QModelIndex& index, const QUrl& url)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceModel::isPackSelected(const ModPlatform::IndexedPack& pack) const
|
|
||||||
{
|
|
||||||
return m_associated_page->isPackSelected(pack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
|
void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
|
||||||
{
|
{
|
||||||
switch (network_error_code) {
|
switch (network_error_code) {
|
||||||
@ -237,9 +232,7 @@ void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
|
|||||||
case 409:
|
case 409:
|
||||||
// 409 Gone, notify user to update
|
// 409 Gone, notify user to update
|
||||||
QMessageBox::critical(nullptr, tr("Error"),
|
QMessageBox::critical(nullptr, tr("Error"),
|
||||||
//: %1 refers to the launcher itself
|
QString("%1")
|
||||||
QString("%1 %2")
|
|
||||||
.arg(m_associated_page->displayName())
|
|
||||||
.arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
|
.arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
#include "QObjectPtr.h"
|
#include "QObjectPtr.h"
|
||||||
|
#include "BaseInstance.h"
|
||||||
#include "modplatform/ResourceAPI.h"
|
#include "modplatform/ResourceAPI.h"
|
||||||
#include "tasks/ConcurrentTask.h"
|
#include "tasks/ConcurrentTask.h"
|
||||||
|
|
||||||
@ -17,19 +18,18 @@ struct IndexedPack;
|
|||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
class ResourcePage;
|
|
||||||
|
|
||||||
class ResourceModel : public QAbstractListModel {
|
class ResourceModel : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceModel(ResourcePage* parent, ResourceAPI* api);
|
ResourceModel(BaseInstance const&, ResourceAPI* api);
|
||||||
~ResourceModel() override;
|
~ResourceModel() override;
|
||||||
|
|
||||||
[[nodiscard]] auto data(const QModelIndex&, int role) const -> QVariant override;
|
[[nodiscard]] auto data(const QModelIndex&, int role) const -> QVariant override;
|
||||||
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
|
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
|
||||||
|
|
||||||
[[nodiscard]] auto debugName() const -> QString;
|
[[nodiscard]] virtual auto debugName() const -> QString;
|
||||||
|
[[nodiscard]] virtual auto metaEntryBase() const -> QString = 0;
|
||||||
|
|
||||||
[[nodiscard]] inline int rowCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : m_packs.size(); }
|
[[nodiscard]] inline int rowCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : m_packs.size(); }
|
||||||
[[nodiscard]] inline int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : 1; };
|
[[nodiscard]] inline int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : 1; };
|
||||||
@ -38,6 +38,10 @@ class ResourceModel : public QAbstractListModel {
|
|||||||
inline void addActiveJob(Task::Ptr ptr) { m_current_job.addTask(ptr); if (!m_current_job.isRunning()) m_current_job.start(); }
|
inline void addActiveJob(Task::Ptr ptr) { m_current_job.addTask(ptr); if (!m_current_job.isRunning()) m_current_job.start(); }
|
||||||
inline Task const& activeJob() { return m_current_job; }
|
inline Task const& activeJob() { return m_current_job; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void versionListUpdated();
|
||||||
|
void projectInfoUpdated();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void fetchMore(const QModelIndex& parent) override;
|
void fetchMore(const QModelIndex& parent) override;
|
||||||
[[nodiscard]] inline bool canFetchMore(const QModelIndex& parent) const override
|
[[nodiscard]] inline bool canFetchMore(const QModelIndex& parent) const override
|
||||||
@ -72,9 +76,9 @@ class ResourceModel : public QAbstractListModel {
|
|||||||
/** Resets the model's data. */
|
/** Resets the model's data. */
|
||||||
void clearData();
|
void clearData();
|
||||||
|
|
||||||
[[nodiscard]] bool isPackSelected(const ModPlatform::IndexedPack&) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const BaseInstance& m_base_instance;
|
||||||
|
|
||||||
/* Basic search parameters */
|
/* Basic search parameters */
|
||||||
enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None;
|
enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None;
|
||||||
int m_next_search_offset = 0;
|
int m_next_search_offset = 0;
|
||||||
@ -88,8 +92,6 @@ class ResourceModel : public QAbstractListModel {
|
|||||||
QSet<QUrl> m_currently_running_icon_actions;
|
QSet<QUrl> m_currently_running_icon_actions;
|
||||||
QSet<QUrl> m_failed_icon_actions;
|
QSet<QUrl> m_failed_icon_actions;
|
||||||
|
|
||||||
ResourcePage* m_associated_page = nullptr;
|
|
||||||
|
|
||||||
QList<ModPlatform::IndexedPack> m_packs;
|
QList<ModPlatform::IndexedPack> m_packs;
|
||||||
|
|
||||||
// HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
|
// HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
|
||||||
|
@ -103,19 +103,18 @@ void ResourcePage::setSearchTerm(QString term)
|
|||||||
m_ui->searchEdit->setText(term);
|
m_ui->searchEdit->setText(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResourcePage::setCurrentPack(ModPlatform::IndexedPack pack)
|
||||||
|
{
|
||||||
|
QVariant v;
|
||||||
|
v.setValue(pack);
|
||||||
|
return m_model->setData(m_ui->packView->currentIndex(), v, Qt::UserRole);
|
||||||
|
}
|
||||||
|
|
||||||
ModPlatform::IndexedPack ResourcePage::getCurrentPack() const
|
ModPlatform::IndexedPack ResourcePage::getCurrentPack() const
|
||||||
{
|
{
|
||||||
return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack>();
|
return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourcePage::isPackSelected(const ModPlatform::IndexedPack& pack, int version) const
|
|
||||||
{
|
|
||||||
if (version < 0 || !pack.versionsLoaded)
|
|
||||||
return m_parent_dialog->isSelected(pack.name);
|
|
||||||
|
|
||||||
return m_parent_dialog->isSelected(pack.name, pack.versions[version].fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourcePage::updateUi()
|
void ResourcePage::updateUi()
|
||||||
{
|
{
|
||||||
auto current_pack = getCurrentPack();
|
auto current_pack = getCurrentPack();
|
||||||
@ -185,7 +184,7 @@ void ResourcePage::updateSelectionButton()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ui->resourceSelectionButton->setEnabled(true);
|
m_ui->resourceSelectionButton->setEnabled(true);
|
||||||
if (!isPackSelected(getCurrentPack(), m_selected_version_index)) {
|
if (!getCurrentPack().isVersionSelected(m_selected_version_index)) {
|
||||||
m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString()));
|
m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString()));
|
||||||
} else {
|
} else {
|
||||||
m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString()));
|
m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString()));
|
||||||
@ -256,12 +255,12 @@ void ResourcePage::onVersionSelectionChanged(QString data)
|
|||||||
|
|
||||||
void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
|
void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
|
||||||
{
|
{
|
||||||
m_parent_dialog->addResource(pack.name, new ResourceDownloadTask(pack, version, m_parent_dialog->getBaseModel()));
|
m_parent_dialog->addResource(pack, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion&)
|
void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
|
||||||
{
|
{
|
||||||
m_parent_dialog->removeResource(pack.name);
|
m_parent_dialog->removeResource(pack, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourcePage::onResourceSelected()
|
void ResourcePage::onResourceSelected()
|
||||||
@ -270,13 +269,19 @@ void ResourcePage::onResourceSelected()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto current_pack = getCurrentPack();
|
auto current_pack = getCurrentPack();
|
||||||
|
if (!current_pack.versionsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
auto& version = current_pack.versions[m_selected_version_index];
|
auto& version = current_pack.versions[m_selected_version_index];
|
||||||
if (m_parent_dialog->isSelected(current_pack.name, version.fileName))
|
if (version.is_currently_selected)
|
||||||
removeResourceFromDialog(current_pack, version);
|
removeResourceFromDialog(current_pack, version);
|
||||||
else
|
else
|
||||||
addResourceToDialog(current_pack, version);
|
addResourceToDialog(current_pack, version);
|
||||||
|
|
||||||
|
// Save the modified pack (and prevent warning in release build)
|
||||||
|
[[maybe_unused]] bool set = setCurrentPack(current_pack);
|
||||||
|
Q_ASSERT(set);
|
||||||
|
|
||||||
updateSelectionButton();
|
updateSelectionButton();
|
||||||
|
|
||||||
/* Force redraw on the resource list when the selection changes */
|
/* Force redraw on the resource list when the selection changes */
|
||||||
|
@ -50,11 +50,13 @@ class ResourcePage : public QWidget, public BasePage {
|
|||||||
/** Programatically set the term in the search bar. */
|
/** Programatically set the term in the search bar. */
|
||||||
void setSearchTerm(QString);
|
void setSearchTerm(QString);
|
||||||
|
|
||||||
[[nodiscard]] bool isPackSelected(const ModPlatform::IndexedPack&, int version = -1) const;
|
[[nodiscard]] bool setCurrentPack(ModPlatform::IndexedPack);
|
||||||
[[nodiscard]] auto getCurrentPack() const -> ModPlatform::IndexedPack;
|
[[nodiscard]] auto getCurrentPack() const -> ModPlatform::IndexedPack;
|
||||||
|
|
||||||
[[nodiscard]] auto getDialog() const -> const ResourceDownloadDialog* { return m_parent_dialog; }
|
[[nodiscard]] auto getDialog() const -> const ResourceDownloadDialog* { return m_parent_dialog; }
|
||||||
|
|
||||||
|
[[nodiscard]] auto getModel() const -> ResourceModel* { return m_model; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ResourcePage(ResourceDownloadDialog* parent, BaseInstance&);
|
ResourcePage(ResourceDownloadDialog* parent, BaseInstance&);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
|
|
||||||
|
#include "modplatform/flame/FlameAPI.h"
|
||||||
#include "modplatform/flame/FlameModIndex.h"
|
#include "modplatform/flame/FlameModIndex.h"
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
@ -9,7 +10,7 @@ namespace ResourceDownload {
|
|||||||
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
||||||
const char* FlameModModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" };
|
const char* FlameModModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" };
|
||||||
|
|
||||||
FlameModModel::FlameModModel(FlameModPage* parent) : ModModel(parent, new FlameAPI) {}
|
FlameModModel::FlameModModel(BaseInstance const& base) : ModModel(base, new FlameAPI) {}
|
||||||
|
|
||||||
void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||||
{
|
{
|
||||||
@ -24,7 +25,7 @@ void FlameModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject&
|
|||||||
|
|
||||||
void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
||||||
{
|
{
|
||||||
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_associated_page->m_base_instance);
|
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "modplatform/flame/FlameAPI.h"
|
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ModModel.h"
|
#include "ui/pages/modplatform/ModModel.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
|
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
@ -12,10 +9,13 @@ class FlameModModel : public ModModel {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FlameModModel(FlameModPage* parent);
|
FlameModModel(const BaseInstance&);
|
||||||
~FlameModModel() override = default;
|
~FlameModModel() override = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
[[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; }
|
||||||
|
[[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); }
|
||||||
|
|
||||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
||||||
|
@ -45,7 +45,7 @@ namespace ResourceDownload {
|
|||||||
FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||||
: ModPage(dialog, instance)
|
: ModPage(dialog, instance)
|
||||||
{
|
{
|
||||||
m_model = new FlameModModel(this);
|
m_model = new FlameModModel(instance);
|
||||||
m_ui->packView->setModel(m_model);
|
m_ui->packView->setModel(m_model);
|
||||||
|
|
||||||
// index is used to set the sorting with the flame api
|
// index is used to set the sorting with the flame api
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
#include "ModrinthResourceModels.h"
|
#include "ModrinthResourceModels.h"
|
||||||
|
|
||||||
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
|
|
||||||
|
|
||||||
#include "modplatform/modrinth/ModrinthAPI.h"
|
#include "modplatform/modrinth/ModrinthAPI.h"
|
||||||
#include "modplatform/modrinth/ModrinthPackIndex.h"
|
#include "modplatform/modrinth/ModrinthPackIndex.h"
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ namespace ResourceDownload {
|
|||||||
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
||||||
const char* ModrinthModModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" };
|
const char* ModrinthModModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" };
|
||||||
|
|
||||||
ModrinthModModel::ModrinthModModel(ModrinthModPage* parent) : ModModel(parent, new ModrinthAPI){};
|
ModrinthModModel::ModrinthModModel(BaseInstance const& base) : ModModel(base, new ModrinthAPI){};
|
||||||
|
|
||||||
void ModrinthModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
void ModrinthModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||||
{
|
{
|
||||||
@ -42,7 +40,7 @@ void ModrinthModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObjec
|
|||||||
|
|
||||||
void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
||||||
{
|
{
|
||||||
::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_associated_page->m_base_instance);
|
::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/pages/modplatform/ModModel.h"
|
#include "ui/pages/modplatform/ModModel.h"
|
||||||
|
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
@ -28,10 +29,13 @@ class ModrinthModModel : public ModModel {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModrinthModModel(ModrinthModPage* parent);
|
ModrinthModModel(const BaseInstance&);
|
||||||
~ModrinthModModel() override = default;
|
~ModrinthModModel() override = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
[[nodiscard]] QString debugName() const override { return Modrinth::debugName() + " (Model)"; }
|
||||||
|
[[nodiscard]] QString metaEntryBase() const override { return Modrinth::metaEntryBase(); }
|
||||||
|
|
||||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
||||||
|
@ -47,7 +47,7 @@ namespace ResourceDownload {
|
|||||||
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||||
: ModPage(dialog, instance)
|
: ModPage(dialog, instance)
|
||||||
{
|
{
|
||||||
m_model = new ModrinthModModel(this);
|
m_model = new ModrinthModModel(instance);
|
||||||
m_ui->packView->setModel(m_model);
|
m_ui->packView->setModel(m_model);
|
||||||
|
|
||||||
// index is used to set the sorting with the modrinth api
|
// index is used to set the sorting with the modrinth api
|
||||||
|
Loading…
Reference in New Issue
Block a user