mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-12 21:36:21 -04:00
feat: (modpack download): category & sort.
This commit is contained in:
parent
af7cf393dc
commit
37fb9a0d65
@ -42,7 +42,6 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||
import org.jackhuang.hmcl.ui.construct.PromptDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorController;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider;
|
||||
import org.jackhuang.hmcl.ui.main.RootPage;
|
||||
import org.jackhuang.hmcl.ui.versions.GameListPage;
|
||||
@ -84,12 +83,13 @@ public final class Controllers {
|
||||
private static AuthlibInjectorServersPage serversPage = null;
|
||||
private static Lazy<RootPage> rootPage = new Lazy<>(RootPage::new);
|
||||
private static DecoratorController decorator;
|
||||
private static Lazy<ModDownloadListPage> modDownloadListPage = new Lazy<>(() ->
|
||||
new ModDownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl) {
|
||||
{
|
||||
state.set(State.fromTitle(i18n("modpack.download")));
|
||||
}
|
||||
});
|
||||
private static Lazy<ModDownloadListPage> modDownloadListPage = new Lazy<>(() -> {
|
||||
return new ModDownloadListPage(CurseModManager.SECTION_MODPACK, Versions::downloadModpackImpl) {
|
||||
{
|
||||
state.set(State.fromTitle(i18n("modpack.download")));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
private Controllers() {
|
||||
}
|
||||
|
@ -17,9 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.versions;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import com.jfoenix.controls.*;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
@ -44,6 +42,7 @@ import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@ -174,13 +173,37 @@ public class ModDownloadListPage extends Control implements DecoratorPage {
|
||||
}
|
||||
});
|
||||
|
||||
JFXTextField categoryField = new JFXTextField();
|
||||
categoryField.setPromptText(i18n("mods.category"));
|
||||
searchPane.add(categoryField, 0, 1);
|
||||
StackPane categoryStackPane = new StackPane();
|
||||
JFXComboBox<CategoryIndented> categoryComboBox = new JFXComboBox<>();
|
||||
categoryStackPane.getChildren().setAll(categoryComboBox);
|
||||
categoryComboBox.prefWidthProperty().bind(categoryStackPane.widthProperty());
|
||||
categoryComboBox.getStyleClass().add("fit-width");
|
||||
categoryComboBox.setPromptText(i18n("mods.category"));
|
||||
Task.supplyAsync(() -> CurseModManager.getCategories(getSkinnable().section))
|
||||
.thenAcceptAsync(Schedulers.javafx(), categories -> {
|
||||
List<CategoryIndented> result = new ArrayList<>();
|
||||
for (CurseModManager.Category category : categories) {
|
||||
resolveCategory(category, 0, result);
|
||||
}
|
||||
categoryComboBox.getItems().setAll(result);
|
||||
}).start();
|
||||
searchPane.add(categoryStackPane, 0, 1);
|
||||
|
||||
JFXTextField sortField = new JFXTextField();
|
||||
sortField.setPromptText(i18n("search.sort"));
|
||||
searchPane.add(sortField, 1, 1);
|
||||
StackPane sortStackPane = new StackPane();
|
||||
JFXComboBox<String> sortComboBox = new JFXComboBox<>();
|
||||
sortStackPane.getChildren().setAll(sortComboBox);
|
||||
sortComboBox.prefWidthProperty().bind(sortStackPane.widthProperty());
|
||||
sortComboBox.getStyleClass().add("fit-width");
|
||||
sortComboBox.setPromptText(i18n("search.sort"));
|
||||
sortComboBox.getItems().setAll(
|
||||
i18n("curse.sort.date_created"),
|
||||
i18n("curse.sort.popularity"),
|
||||
i18n("curse.sort.last_updated"),
|
||||
i18n("curse.sort.name"),
|
||||
i18n("curse.sort.author"),
|
||||
i18n("curse.sort.total_downloads"));
|
||||
sortComboBox.getSelectionModel().select(0);
|
||||
searchPane.add(sortStackPane, 1, 1);
|
||||
|
||||
VBox vbox = new VBox();
|
||||
vbox.setAlignment(Pos.CENTER_RIGHT);
|
||||
@ -189,7 +212,14 @@ public class ModDownloadListPage extends Control implements DecoratorPage {
|
||||
JFXButton searchButton = new JFXButton();
|
||||
searchButton.setText(i18n("search"));
|
||||
searchButton.setOnAction(e -> {
|
||||
getSkinnable().search(gameVersionField.getText(), 0, 0, nameField.getText(), 0);
|
||||
getSkinnable().search(gameVersionField.getText(),
|
||||
Optional.ofNullable(categoryComboBox.getSelectionModel().getSelectedItem())
|
||||
.map(CategoryIndented::getCategory)
|
||||
.map(CurseModManager.Category::getId)
|
||||
.orElse(0),
|
||||
0,
|
||||
nameField.getText(),
|
||||
sortComboBox.getSelectionModel().getSelectedIndex());
|
||||
});
|
||||
searchPane.add(searchButton, 0, 2);
|
||||
vbox.getChildren().setAll(searchButton);
|
||||
@ -256,5 +286,35 @@ public class ModDownloadListPage extends Control implements DecoratorPage {
|
||||
|
||||
getChildren().setAll(pane);
|
||||
}
|
||||
|
||||
private static class CategoryIndented {
|
||||
private final int indent;
|
||||
private final CurseModManager.Category category;
|
||||
|
||||
public CategoryIndented(int indent, CurseModManager.Category category) {
|
||||
this.indent = indent;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return indent;
|
||||
}
|
||||
|
||||
public CurseModManager.Category getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.repeats(' ', indent) + i18n("curse.category." + category.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private static void resolveCategory(CurseModManager.Category category, int indent, List<CategoryIndented> result) {
|
||||
result.add(new CategoryIndented(indent, category));
|
||||
for (CurseModManager.Category subcategory : category.getSubcategories()) {
|
||||
resolveCategory(subcategory, indent + 1, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ import java.nio.file.Path;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.download.LocalModpackPage.MODPACK_FILE;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class Versions {
|
||||
|
@ -156,6 +156,13 @@ curse.category.4558=Redstone
|
||||
curse.category.4843=Automation
|
||||
curse.category.4906=MCreator
|
||||
|
||||
curse.sort.author=Author
|
||||
curse.sort.date_created=Date Created
|
||||
curse.sort.last_updated=Last Updated
|
||||
curse.sort.name=Name
|
||||
curse.sort.popularity=Popularity
|
||||
curse.sort.total_downloads=Total Downloads
|
||||
|
||||
download=Download
|
||||
download.code.404=File not found on the remote server: %s
|
||||
download.failed=Failed to download %1$s, response code: %2$d
|
||||
|
@ -157,6 +157,13 @@ curse.category.4558=红石
|
||||
curse.category.4843=自动化
|
||||
curse.category.4906=MCreator
|
||||
|
||||
curse.sort.author=作者
|
||||
curse.sort.date_created=创建日期
|
||||
curse.sort.last_updated=最近更新
|
||||
curse.sort.name=名称
|
||||
curse.sort.popularity=热度
|
||||
curse.sort.total_downloads=下载量
|
||||
|
||||
download=下载
|
||||
download.code.404=远程服务器不包含需要下载的文件: %s
|
||||
download.failed=下载失败: %1$s,错误码:%2$d
|
||||
|
@ -11,7 +11,9 @@ import java.util.*;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
|
||||
public class CurseModManager {
|
||||
public final class CurseModManager {
|
||||
private CurseModManager() {
|
||||
}
|
||||
|
||||
public static List<CurseAddon> searchPaginated(String gameVersion, int category, int section, int pageOffset, String searchFilter, int sort) throws IOException {
|
||||
String response = NetworkUtils.doGet(new URL(NetworkUtils.withQuery("https://addons-ecs.forgesvc.net/api/v2/addon/search", mapOf(
|
||||
|
@ -235,4 +235,12 @@ public final class StringUtils {
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String repeats(char ch, int repeat) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
result.append(ch);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user