diff --git a/src/curseforge/curseforgeapi.cpp b/src/curseforge/curseforgeapi.cpp index 2bbc808..67cb260 100644 --- a/src/curseforge/curseforgeapi.cpp +++ b/src/curseforge/curseforgeapi.cpp @@ -153,10 +153,17 @@ Reply CurseforgeAPI::getFileInfo(int id, int FileID) } }; } -Reply > CurseforgeAPI::getFiles(int id) +Reply, int> CurseforgeAPI::getFiles(int id, int index) { //TODO: page QUrl url = PREFIX + "/v1/mods/" + QString::number(id) + "/files"; + //url query + QUrlQuery urlQuery; + //index + urlQuery.addQueryItem("index", QString::number(index)); + //page size + urlQuery.addQueryItem("pageSize", QString::number(Config().getSearchResultCount())); + url.setQuery(urlQuery); QNetworkRequest request(url); request.setRawHeader("x-api-key",XAPIKEY); @@ -168,15 +175,16 @@ Reply > CurseforgeAPI::getFiles(int id) QJsonDocument jsonDocument = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { qDebug("%s", error.errorString().toUtf8().constData()); - return QList{}; + return std::make_pair(QList{}, 0); } - auto resultList = value(jsonDocument.toVariant(),"data").toList(); + auto resultList = value(jsonDocument.toVariant(), "data").toList(); + auto totalCount = value(jsonDocument.toVariant(), "pagination", "totalCount").toInt(); QList fileInfoList; for(const auto &result : qAsConst(resultList)) fileInfoList << CurseforgeFileInfo::fromVariant(result); - return fileInfoList; + return std::make_pair(fileInfoList, totalCount); } }; } diff --git a/src/curseforge/curseforgeapi.h b/src/curseforge/curseforgeapi.h index 0e85964..6288227 100644 --- a/src/curseforge/curseforgeapi.h +++ b/src/curseforge/curseforgeapi.h @@ -28,7 +28,7 @@ class CurseforgeAPI : public QObject Reply getChangelog(int id, int FileID); Reply getDownloadUrl(int id, int FileID); Reply getFileInfo(int id, int FileID); - Reply > getFiles(int id); + Reply, int> getFiles(int id, int index); Reply getInfo(int id); Reply getTimestamp(); Reply > getMinecraftVersionList(); diff --git a/src/curseforge/curseforgemod.cpp b/src/curseforge/curseforgemod.cpp index cdf94c0..c004e8a 100644 --- a/src/curseforge/curseforgemod.cpp +++ b/src/curseforge/curseforgemod.cpp @@ -91,16 +91,16 @@ void CurseforgeMod::acquireDescription() }); } -std::shared_ptr>> CurseforgeMod::acquireAllFileList() +std::shared_ptr, int>> CurseforgeMod::acquireMoreFileList() { if(allFileListGetter_ && allFileListGetter_->isRunning()) return allFileListGetter_; - qDebug()<getFiles(modInfo_.id()).asUnique(); - allFileListGetter_->setOnFinished(this, [=](const QList &fileList){ - modInfo_.allFileList_ = fileList; - emit allFileListReady(fileList); + allFileListGetter_ = api_->getFiles(modInfo_.id(), modInfo().allFileList().size()).asUnique(); + allFileListGetter_->setOnFinished(this, [=](const QList &fileList, int count){ + modInfo_.allFileList_ << fileList; + modInfo_.totalFileCount_ = count; + emit moreFileListReady(fileList); }, [=](auto){ - emit allFileListReady({}); + emit moreFileListReady({}); }); return allFileListGetter_; } diff --git a/src/curseforge/curseforgemod.h b/src/curseforge/curseforgemod.h index c43fcb1..08625ef 100644 --- a/src/curseforge/curseforgemod.h +++ b/src/curseforge/curseforgemod.h @@ -26,7 +26,7 @@ class CurseforgeMod : public QObject, public Tagable void acquireBasicInfo(); void acquireIcon(); void acquireDescription(); - std::shared_ptr>> acquireAllFileList(); + std::shared_ptr, int>> acquireMoreFileList(); const CurseforgeModInfo &modInfo() const; void download(const CurseforgeFileInfo &fileInfo, LocalModPath *downloadPath = nullptr); @@ -38,7 +38,7 @@ class CurseforgeMod : public QObject, public Tagable void basicInfoReady(); void iconReady(); void descriptionReady(); - void allFileListReady(QList fileInfos); + void moreFileListReady(QList fileInfos); void downloadStarted(); @@ -50,7 +50,7 @@ class CurseforgeMod : public QObject, public Tagable std::shared_ptr> basicInfoGetter_; bool gettingIcon_ = false; std::shared_ptr> descriptionGetter_; - std::shared_ptr>> allFileListGetter_; + std::shared_ptr, int>> allFileListGetter_; }; #endif // CURSEFORGEMOD_H diff --git a/src/curseforge/curseforgemodinfo.cpp b/src/curseforge/curseforgemodinfo.cpp index 39137ee..35b1ee4 100644 --- a/src/curseforge/curseforgemodinfo.cpp +++ b/src/curseforge/curseforgemodinfo.cpp @@ -144,6 +144,21 @@ bool CurseforgeModInfo::hasBasicInfo() const return basicInfo_; } +bool CurseforgeModInfo::fileCompleted() const +{ + return allFileList_.size() != 0 && allFileList_.size() == totalFileCount_; +} + +int CurseforgeModInfo::totalFileCount() const +{ + return totalFileCount_; +} + +void CurseforgeModInfo::setTotalFileCount(int newTotalFileCount) +{ + totalFileCount_ = newTotalFileCount; +} + const QList &CurseforgeModInfo::categories() const { return categories_; diff --git a/src/curseforge/curseforgemodinfo.h b/src/curseforge/curseforgemodinfo.h index c0536fd..910dd74 100644 --- a/src/curseforge/curseforgemodinfo.h +++ b/src/curseforge/curseforgemodinfo.h @@ -55,6 +55,10 @@ class CurseforgeModInfo : public CurseforgeModCacheInfo, Tagable void setLatestFiles(const QList &newLatestFiles); bool hasBasicInfo() const; + bool fileCompleted() const; + int totalFileCount() const; + void setTotalFileCount(int newTotalFileCount); + private: QUrl websiteUrl_; QList images_; @@ -64,6 +68,7 @@ class CurseforgeModInfo : public CurseforgeModCacheInfo, Tagable QList loaderTypes_; QList latestFileList_; QList allFileList_; + int totalFileCount_ = 0; QList categories_; QDateTime dateModified_; QDateTime dateCreated_; diff --git a/src/local/localmod.cpp b/src/local/localmod.cpp index 2497e53..6e254f9 100644 --- a/src/local/localmod.cpp +++ b/src/local/localmod.cpp @@ -98,7 +98,7 @@ void LocalMod::setCurseforgeMod(CurseforgeMod *newCurseforgeMod) removeSubTagable(modrinthMod_); curseforgeMod_ = newCurseforgeMod; if(curseforgeMod_){ - connect(curseforgeMod_, &CurseforgeMod::allFileListReady, this, &LocalMod::setCurseforgeFileInfos); + connect(curseforgeMod_, &CurseforgeMod::moreFileListReady, this, &LocalMod::setCurseforgeFileInfos); addSubTagable(curseforgeMod_); curseforgeMod_->setParent(this); curseforgeMod_->acquireBasicInfo(); @@ -114,7 +114,7 @@ void LocalMod::setCurseforgeId(int id, bool cache) if(id != 0){ curseforgeMod_ = new CurseforgeMod(this, id); addSubTagable(curseforgeMod_); - connect(curseforgeMod_, &CurseforgeMod::allFileListReady, this, &LocalMod::setCurseforgeFileInfos); + connect(curseforgeMod_, &CurseforgeMod::moreFileListReady, this, &LocalMod::setCurseforgeFileInfos); emit curseforgeReady(true); emit modInfoChanged(); emit modCacheUpdated(); @@ -162,8 +162,9 @@ void LocalMod::checkCurseforgeUpdate(bool force) emit checkCurseforgeUpdateStarted(); //update file list if(force || curseforgeMod_->modInfo().allFileList().isEmpty()){ - curseforgeFileListGetter_ = curseforgeMod_->acquireAllFileList(); - curseforgeFileListGetter_->setOnFinished(this, [=](const QList &){ + //TODO + curseforgeFileListGetter_ = curseforgeMod_->acquireMoreFileList(); + curseforgeFileListGetter_->setOnFinished(this, [=](const QList &, int count){ curseforgeUpdater_.findUpdate(modFile_->linker()->curseforgeFileInfo()); emit curseforgeUpdateReady(true); }, [=](auto){ diff --git a/src/local/localmod.h b/src/local/localmod.h index 6c48300..ff4a84d 100644 --- a/src/local/localmod.h +++ b/src/local/localmod.h @@ -180,7 +180,7 @@ public slots: Updater modrinthUpdater_; CheckSheet *updateChecker_; - std::shared_ptr > > curseforgeFileListGetter_; + std::shared_ptr, int> > curseforgeFileListGetter_; std::shared_ptr > > modrinthFileListGetter_; //dependencies diff --git a/src/ui/curseforge/curseforgefilelistwidget.cpp b/src/ui/curseforge/curseforgefilelistwidget.cpp index 6237303..15d0e80 100644 --- a/src/ui/curseforge/curseforgefilelistwidget.cpp +++ b/src/ui/curseforge/curseforgefilelistwidget.cpp @@ -21,6 +21,7 @@ CurseforgeFileListWidget::CurseforgeFileListWidget(CurseforgeModBrowser *parent) ui->fileListView->setVerticalScrollBar(new SmoothScrollBar(this)); ui->fileListView->setProperty("class", "ModList"); connect(ui->fileListView->verticalScrollBar(), &QAbstractSlider::valueChanged, this , &CurseforgeFileListWidget::updateIndexWidget); + connect(ui->fileListView->verticalScrollBar(), &QSlider::valueChanged, this, &CurseforgeFileListWidget::onListSliderChanged); ui->downloadPathSelect->hide(); downloadPathSelectMenu_ = parent->downloadPathSelectMenu(); } @@ -33,7 +34,8 @@ CurseforgeFileListWidget::CurseforgeFileListWidget(QWidget *parent, LocalMod *lo ui->fileListView->setModel(&model_); ui->fileListView->setVerticalScrollBar(new SmoothScrollBar(this)); ui->fileListView->setProperty("class", "ModList"); - connect(ui->fileListView->verticalScrollBar(), &QAbstractSlider::valueChanged, this , &CurseforgeFileListWidget::updateIndexWidget); + connect(ui->fileListView->verticalScrollBar(), &QAbstractSlider::valueChanged, this, &CurseforgeFileListWidget::updateIndexWidget); + connect(ui->fileListView->verticalScrollBar(), &QSlider::valueChanged, this, &CurseforgeFileListWidget::onListSliderChanged); ui->downloadPathSelect->hide(); downloadPathSelectMenu_ = new DownloadPathSelectMenu(this); ui->downloadPathSelect->setDefaultAction(downloadPathSelectMenu_->menuAction()); @@ -53,13 +55,13 @@ void CurseforgeFileListWidget::setMod(CurseforgeMod *mod) ui->fileListView->setVisible(mod_); if(!mod_) return; connect(this, &CurseforgeFileListWidget::modChanged, disconnecter( - connect(mod_, &CurseforgeMod::allFileListReady, this, &CurseforgeFileListWidget::updateFileList), + connect(mod_, &CurseforgeMod::moreFileListReady, this, &CurseforgeFileListWidget::updateFileList), connect(mod_, &QObject::destroyed, this, [=]{ setMod(nullptr); }))); updateFileList(); - if(mod_->modInfo().allFileList().isEmpty()){ + if(!mod_->modInfo().fileCompleted()){ ui->fileListView->setCursor(Qt::BusyCursor); - mod->acquireAllFileList(); + mod_->acquireMoreFileList(); } } @@ -130,3 +132,13 @@ void CurseforgeFileListWidget::updateIndexWidget() item->setSizeHint(QSize(0, itemWidget->height())); } } + +void CurseforgeFileListWidget::onListSliderChanged(int i) +{ + if(i >= ui->fileListView->verticalScrollBar()->maximum() - 1000){ + if(!mod_->modInfo().fileCompleted()){ + ui->fileListView->setCursor(Qt::BusyCursor); + mod_->acquireMoreFileList(); + } + } +} diff --git a/src/ui/curseforge/curseforgefilelistwidget.h b/src/ui/curseforge/curseforgefilelistwidget.h index a43fe2d..0b6d64e 100644 --- a/src/ui/curseforge/curseforgefilelistwidget.h +++ b/src/ui/curseforge/curseforgefilelistwidget.h @@ -37,6 +37,7 @@ public slots: private slots: void updateFileList(); void updateIndexWidget(); + void onListSliderChanged(int i); protected: void paintEvent(QPaintEvent *event) override; diff --git a/src/ui/tagsflowwidget.cpp b/src/ui/tagsflowwidget.cpp index f9bb430..30a2f47 100644 --- a/src/ui/tagsflowwidget.cpp +++ b/src/ui/tagsflowwidget.cpp @@ -17,36 +17,9 @@ TagsFlowWidget::TagsFlowWidget(QWidget *parent) : setContextMenuPolicy(Qt::CustomContextMenu); } -void TagsFlowWidget::setTagable(const Tagable &tagable) -{ - //tags - for(auto widget : qAsConst(tagWidgets_)){ - layout()->removeWidget(widget); - widget->deleteLater(); - } - tagWidgets_.clear(); - for(auto &&tag : tagable.tags(Config().getShowTagCategories())){ - auto label = new QLabel(this); - if(!tag.iconName().isEmpty()) - label->setText(QString(R"( %2)").arg(tag.iconName(), tag.name())); - else - label->setText(tag.name()); - label->setToolTip(tr("%1: %2").arg(tag.category().name(), tag.name())); - label->setStyleSheet(QString("color: #fff; background-color: %1; border-radius:10px; padding:2px 4px;").arg(tag.category().color().name())); - layout()->addWidget(label); - tagWidgets_ << label; - } -} - void TagsFlowWidget::updateUi() { - //tags - for(auto widget : qAsConst(tagWidgets_)){ - layout()->removeWidget(widget); - widget->deleteLater(); - } - tagWidgets_.clear(); - if(!tagableObject_) return; + if(!tagableObject_) return; for(auto &&tag : tagableObject_->tags(Config().getShowTagCategories())){ auto label = new QLabel(this); if(!tag.iconName().isEmpty()) diff --git a/src/ui/tagsflowwidget.h b/src/ui/tagsflowwidget.h index e4ba5f4..91d769c 100644 --- a/src/ui/tagsflowwidget.h +++ b/src/ui/tagsflowwidget.h @@ -13,8 +13,6 @@ class TagsFlowWidget : public QWidget public: explicit TagsFlowWidget(QWidget *parent = nullptr); - void setTagable(const Tagable &tagable); - template void setTagableObject(T* tagableObject) {