Fix #3644: 修复下载 - 模组界面无法正常翻页、Category 会在切换下载源时出错的问题 (#3768)

This commit is contained in:
Burning_TNT 2025-04-09 11:35:56 +08:00 committed by GitHub
parent a3cb871928
commit c33ef5170b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 15 deletions

View File

@ -60,10 +60,7 @@ import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.BindingMapping;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber; import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent; import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent;
@ -156,7 +153,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
FXUtils.runInFX(() -> selectedVersion.set(versionID)); FXUtils.runInFX(() -> selectedVersion.set(versionID));
} }
public void search(String userGameVersion, RemoteModRepository.Category category, int pageOffset, String searchFilter, RemoteModRepository.SortType sort) { private void search(String userGameVersion, RemoteModRepository.Category category, int pageOffset, String searchFilter, RemoteModRepository.SortType sort) {
retrySearch = null; retrySearch = null;
setLoading(true); setLoading(true);
setFailed(false); setFailed(false);
@ -171,7 +168,9 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
? version.getProfile().getRepository().getGameVersion(version.getVersion()).orElse("") ? version.getProfile().getRepository().getGameVersion(version.getVersion()).orElse("")
: ""; : "";
} }
}).thenApplyAsync(gameVersion -> repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC)).whenComplete(Schedulers.javafx(), (result, exception) -> { }).thenApplyAsync(
gameVersion -> repository.search(gameVersion, category, pageOffset, 50, searchFilter, sort, RemoteModRepository.SortOrder.DESC)
).whenComplete(Schedulers.javafx(), (result, exception) -> {
if (searchID != currentSearchID) { if (searchID != currentSearchID) {
return; return;
} }
@ -312,7 +311,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
StackPane categoryStackPane = new StackPane(); StackPane categoryStackPane = new StackPane();
JFXComboBox<CategoryIndented> categoryComboBox = new JFXComboBox<>(); JFXComboBox<CategoryIndented> categoryComboBox = new JFXComboBox<>();
categoryComboBox.getItems().setAll(new CategoryIndented(0, null)); categoryComboBox.getItems().setAll(CategoryIndented.ALL);
categoryStackPane.getChildren().setAll(categoryComboBox); categoryStackPane.getChildren().setAll(categoryComboBox);
categoryComboBox.prefWidthProperty().bind(categoryStackPane.widthProperty()); categoryComboBox.prefWidthProperty().bind(categoryStackPane.widthProperty());
categoryComboBox.getStyleClass().add("fit-width"); categoryComboBox.getStyleClass().add("fit-width");
@ -320,14 +319,22 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
categoryComboBox.getSelectionModel().select(0); categoryComboBox.getSelectionModel().select(0);
categoryComboBox.setConverter(stringConverter(getSkinnable()::getLocalizedCategoryIndent)); categoryComboBox.setConverter(stringConverter(getSkinnable()::getLocalizedCategoryIndent));
FXUtils.onChangeAndOperate(getSkinnable().downloadSource, downloadSource -> { FXUtils.onChangeAndOperate(getSkinnable().downloadSource, downloadSource -> {
categoryComboBox.getItems().setAll(CategoryIndented.ALL);
categoryComboBox.getSelectionModel().select(0);
Task.supplyAsync(() -> getSkinnable().repository.getCategories()) Task.supplyAsync(() -> getSkinnable().repository.getCategories())
.thenAcceptAsync(Schedulers.javafx(), categories -> { .thenAcceptAsync(Schedulers.javafx(), categories -> {
if (!Objects.equals(getSkinnable().downloadSource.get(), downloadSource)) {
return;
}
List<CategoryIndented> result = new ArrayList<>(); List<CategoryIndented> result = new ArrayList<>();
result.add(new CategoryIndented(0, null)); result.add(CategoryIndented.ALL);
for (RemoteModRepository.Category category : Lang.toIterable(categories)) { for (RemoteModRepository.Category category : Lang.toIterable(categories)) {
resolveCategory(category, 0, result); resolveCategory(category, 0, result);
} }
categoryComboBox.getItems().setAll(result); categoryComboBox.getItems().setAll(result);
categoryComboBox.getSelectionModel().select(0);
}).start(); }).start();
}); });
@ -344,7 +351,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
IntegerProperty filterID = new SimpleIntegerProperty(this, "Filter ID", 0); IntegerProperty filterID = new SimpleIntegerProperty(this, "Filter ID", 0);
IntegerProperty currentFilterID = new SimpleIntegerProperty(this, "Current Filter ID", -1); IntegerProperty currentFilterID = new SimpleIntegerProperty(this, "Current Filter ID", -1);
EventHandler<ActionEvent> searchAction = e -> { EventHandler<ActionEvent> searchAction = e -> {
if (currentFilterID.get() != filterID.get()) { if (currentFilterID.get() != -1 && currentFilterID.get() != filterID.get()) {
control.pageOffset.set(0); control.pageOffset.set(0);
} }
currentFilterID.set(filterID.get()); currentFilterID.set(filterID.get());
@ -379,8 +386,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
JFXButton firstPageButton = FXUtils.newBorderButton(i18n("search.first_page")); JFXButton firstPageButton = FXUtils.newBorderButton(i18n("search.first_page"));
firstPageButton.setOnAction(event -> { firstPageButton.setOnAction(event -> {
control.pageOffset.set(0); control.pageOffset.set(0);
changeButton.value.run();
searchAction.handle(event); searchAction.handle(event);
changeButton.value.run();
}); });
JFXButton previousPageButton = FXUtils.newBorderButton(i18n("search.previous_page")); JFXButton previousPageButton = FXUtils.newBorderButton(i18n("search.previous_page"));
@ -388,8 +395,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
int pageOffset = control.pageOffset.get(); int pageOffset = control.pageOffset.get();
if (pageOffset > 0) { if (pageOffset > 0) {
control.pageOffset.set(pageOffset - 1); control.pageOffset.set(pageOffset - 1);
changeButton.value.run();
searchAction.handle(event); searchAction.handle(event);
changeButton.value.run();
} }
}); });
@ -404,16 +411,16 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
int nv = control.pageOffset.get() + 1; int nv = control.pageOffset.get() + 1;
if (nv < control.pageCount.get()) { if (nv < control.pageCount.get()) {
control.pageOffset.set(nv); control.pageOffset.set(nv);
changeButton.value.run();
searchAction.handle(event); searchAction.handle(event);
changeButton.value.run();
} }
}); });
JFXButton lastPageButton = FXUtils.newBorderButton(i18n("search.last_page")); JFXButton lastPageButton = FXUtils.newBorderButton(i18n("search.last_page"));
lastPageButton.setOnAction(event -> { lastPageButton.setOnAction(event -> {
control.pageOffset.set(control.pageCount.get() - 1); control.pageOffset.set(control.pageCount.get() - 1);
changeButton.value.run();
searchAction.handle(event); searchAction.handle(event);
changeButton.value.run();
}); });
firstPageButton.setDisable(true); firstPageButton.setDisable(true);
@ -529,6 +536,8 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
} }
private static class CategoryIndented { private static class CategoryIndented {
private static final CategoryIndented ALL = new CategoryIndented(0, null);
private final int indent; private final int indent;
private final RemoteModRepository.Category category; private final RemoteModRepository.Category category;

View File

@ -110,7 +110,7 @@ public final class HMCLLocalizedDownloadListPage extends DownloadListPage {
try { try {
return I18n.getResourceBundle().getString(key); return I18n.getResourceBundle().getString(key);
} catch (MissingResourceException e) { } catch (MissingResourceException e) {
LOG.warning("Cannot find key " + key + " in resource bundle", e); LOG.warning("Cannot find key " + key + " in resource bundle");
return category; return category;
} }
} }

View File

@ -102,7 +102,9 @@ public final class CurseForgeRemoteModRepository implements RemoteModRepository
@Override @Override
public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder) throws IOException { public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Category category, int pageOffset, int pageSize, String searchFilter, SortType sortType, SortOrder sortOrder) throws IOException {
int categoryId = 0; int categoryId = 0;
if (category != null) categoryId = ((CurseAddon.Category) category.getSelf()).getId(); if (category != null && category.getSelf() instanceof CurseAddon.Category) {
categoryId = ((CurseAddon.Category) category.getSelf()).getId();
}
Response<List<CurseAddon>> response = HttpRequest.GET(PREFIX + "/v1/mods/search", Response<List<CurseAddon>> response = HttpRequest.GET(PREFIX + "/v1/mods/search",
pair("gameId", "432"), pair("gameId", "432"),
pair("classId", Integer.toString(section)), pair("classId", Integer.toString(section)),