From 1b5522958a1da70e22e4c2da544f99cb3a19b708 Mon Sep 17 00:00:00 2001 From: Glavo Date: Sat, 7 Jan 2023 21:32:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20FeedbackPage=20(#1913)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update FeedbackPage * Update logo * close #1259 --- .../org/jackhuang/hmcl/ui/main/AboutPage.java | 28 +- .../jackhuang/hmcl/ui/main/FeedbackPage.java | 484 ++---------------- .../resources/assets/lang/I18N.properties | 47 +- .../resources/assets/lang/I18N_es.properties | 42 +- .../resources/assets/lang/I18N_ja.properties | 38 +- .../resources/assets/lang/I18N_ru.properties | 38 +- .../resources/assets/lang/I18N_zh.properties | 45 +- .../assets/lang/I18N_zh_CN.properties | 43 +- 8 files changed, 103 insertions(+), 662 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java index 068ad6dce..5de8004cf 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/AboutPage.java @@ -98,36 +98,13 @@ public class AboutPage extends StackPane { contributors.setSubtitle(i18n("about.thanks_to.contributors.statement")); contributors.setExternalLink("https://github.com/huanghongxun/HMCL/graphs/contributors"); - thanks.getContent().setAll(yushijinhun, bangbang93, glavo, mcbbs, mcmod, gamerteam, redLnn, contributors); - } - - ComponentList community = new ComponentList(); - { IconedTwoLineListItem users = new IconedTwoLineListItem(); users.setImage(new Image("/assets/img/craft_table.png", 32, 32, false, true)); users.setTitle(i18n("about.thanks_to.users")); users.setSubtitle(i18n("about.thanks_to.users.statement")); users.setExternalLink("https://hmcl.huangyuhui.net/api/redirect/sponsor"); - IconedTwoLineListItem qq = new IconedTwoLineListItem(); - qq.setImage(new Image("/assets/img/icon.png", 32, 32, false, true)); - qq.setTitle(i18n("about.community.qqchannel")); - qq.setSubtitle(i18n("about.community.qqchannel.statement")); - qq.setExternalLink("https://pd.qq.com/s/qor74cm6"); - - IconedTwoLineListItem discord = new IconedTwoLineListItem(); - discord.setImage(new Image("/assets/img/discord.png", 32, 32, false, true)); - discord.setTitle(i18n("about.community.discord")); - discord.setSubtitle(i18n("about.community.discord.statement")); - discord.setExternalLink("https://discord.gg/jVvC7HfM6U"); - - IconedTwoLineListItem kookapp = new IconedTwoLineListItem(); - kookapp.setImage(new Image("/assets/img/kookapp.png", 32, 32, false, true)); - kookapp.setTitle(i18n("about.community.kookapp")); - kookapp.setSubtitle(i18n("about.community.kookapp.statement")); - kookapp.setExternalLink("https://kook.top/Kx7n3t"); - - community.getContent().setAll(users, qq, discord, kookapp); + thanks.getContent().setAll(yushijinhun, bangbang93, glavo, mcbbs, mcmod, gamerteam, redLnn, contributors, users); } ComponentList dep = new ComponentList(); @@ -209,9 +186,6 @@ public class AboutPage extends StackPane { ComponentList.createComponentListTitle(i18n("about.thanks_to")), thanks, - ComponentList.createComponentListTitle(i18n("about.community")), - community, - ComponentList.createComponentListTitle(i18n("about.dependency")), dep, diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java index bca7f749c..10e84fde2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java @@ -17,454 +17,70 @@ */ package org.jackhuang.hmcl.ui.main; -import com.google.gson.JsonParseException; -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import com.jfoenix.controls.*; -import javafx.beans.binding.Bindings; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; +import com.jfoenix.controls.JFXScrollPane; import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.Label; -import javafx.scene.layout.*; -import org.apache.commons.lang3.mutable.MutableObject; -import org.jackhuang.hmcl.Metadata; -import org.jackhuang.hmcl.game.OAuthServer; -import org.jackhuang.hmcl.setting.Accounts; -import org.jackhuang.hmcl.setting.HMCLAccounts; -import org.jackhuang.hmcl.setting.Theme; -import org.jackhuang.hmcl.task.Schedulers; -import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.ui.Controllers; -import org.jackhuang.hmcl.ui.FXUtils; -import org.jackhuang.hmcl.ui.SVG; -import org.jackhuang.hmcl.ui.construct.*; -import org.jackhuang.hmcl.util.StringUtils; -import org.jackhuang.hmcl.util.io.HttpRequest; -import org.jackhuang.hmcl.util.io.NetworkUtils; -import org.jackhuang.hmcl.util.io.ResponseCodeException; -import org.jackhuang.hmcl.util.javafx.BindingMapping; +import javafx.scene.control.ScrollPane; +import javafx.scene.image.Image; +import javafx.scene.layout.VBox; +import org.jackhuang.hmcl.ui.construct.ComponentList; +import org.jackhuang.hmcl.ui.construct.IconedTwoLineListItem; +import org.jackhuang.hmcl.ui.construct.SpinnerPane; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed; -import static org.jackhuang.hmcl.ui.FXUtils.stringConverter; -import static org.jackhuang.hmcl.util.Lang.mapOf; -import static org.jackhuang.hmcl.util.Pair.pair; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -public class FeedbackPage extends VBox implements PageAware { - private final ObservableList feedbacks = FXCollections.observableArrayList(); - private final SpinnerPane spinnerPane = new SpinnerPane(); +public class FeedbackPage extends SpinnerPane { public FeedbackPage() { - setSpacing(10); - setPadding(new Insets(10)); + VBox content = new VBox(); + content.setPadding(new Insets(10)); + content.setSpacing(10); + content.setFillWidth(true); + ScrollPane scrollPane = new ScrollPane(content); + scrollPane.setFitToWidth(true); + JFXScrollPane.smoothScrolling(scrollPane); + setContent(scrollPane); + ComponentList community = new ComponentList(); { - HBox loginPane = new HBox(16); - loginPane.setAlignment(Pos.CENTER_LEFT); - loginPane.getStyleClass().add("card"); + IconedTwoLineListItem users = new IconedTwoLineListItem(); + users.setImage(new Image("/assets/img/craft_table.png", 32, 32, false, true)); + users.setTitle(i18n("feedback.qq_group")); + users.setSubtitle(i18n("feedback.qq_group.statement")); + users.setExternalLink("https://hmcl.huangyuhui.net/api/redirect/sponsor"); - TwoLineListItem accountInfo = new TwoLineListItem(); - HBox.setHgrow(accountInfo, Priority.ALWAYS); - accountInfo.titleProperty().bind(BindingMapping.of(HMCLAccounts.accountProperty()) - .map(account -> account == null ? i18n("account.not_logged_in") : account.getNickname())); - accountInfo.subtitleProperty().bind(BindingMapping.of(HMCLAccounts.accountProperty()) - .map(account -> account == null ? i18n("account.not_logged_in") : account.getEmail())); + IconedTwoLineListItem github = new IconedTwoLineListItem(); + github.setImage(new Image("/assets/img/github.png", 32, 32, false, true)); + github.setTitle(i18n("feedback.github")); + github.setSubtitle(i18n("feedback.github.statement")); + github.setExternalLink("https://github.com/huanghongxun/HMCL/issues/new/choose"); - JFXButton logButton = new JFXButton(); - logButton.textProperty().bind(BindingMapping.of(HMCLAccounts.accountProperty()) - .map(account -> account == null ? i18n("account.login") : i18n("account.logout"))); - logButton.setOnAction(e -> log()); + IconedTwoLineListItem qq = new IconedTwoLineListItem(); + qq.setImage(new Image("/assets/img/icon@2x.png", 32, 32, false, true)); + qq.setTitle(i18n("feedback.qq_channel")); + qq.setSubtitle(i18n("feedback.qq_channel.statement")); + qq.setExternalLink("https://pd.qq.com/s/qor74cm6"); - loginPane.getChildren().setAll(accountInfo, logButton); - getChildren().add(loginPane); + IconedTwoLineListItem discord = new IconedTwoLineListItem(); + discord.setImage(new Image("/assets/img/discord.png", 32, 32, false, true)); + discord.setTitle(i18n("feedback.discord")); + discord.setSubtitle(i18n("feedback.discord.statement")); + discord.setExternalLink("https://discord.gg/jVvC7HfM6U"); + + IconedTwoLineListItem kookapp = new IconedTwoLineListItem(); + kookapp.setImage(new Image("/assets/img/kookapp.png", 32, 32, false, true)); + kookapp.setTitle(i18n("feedback.kookapp")); + kookapp.setSubtitle(i18n("feedback.kookapp.statement")); + kookapp.setExternalLink("https://kook.top/Kx7n3t"); + + community.getContent().setAll(users, github, qq, discord, kookapp); } - { - HBox searchPane = new HBox(8); - searchPane.getStyleClass().add("card"); - getChildren().add(searchPane); + content.getChildren().addAll( + ComponentList.createComponentListTitle(i18n("feedback.channel")), + community + ); - JFXTextField searchField = new JFXTextField(); - searchField.setOnAction(e -> search(searchField.getText(), "time", true)); - HBox.setHgrow(searchField, Priority.ALWAYS); - searchField.setPromptText(i18n("search")); - - JFXButton searchButton = new JFXButton(); - searchButton.getStyleClass().add("toggle-icon4"); - searchButton.setGraphic(SVG.magnify(Theme.blackFillBinding(), -1, -1)); - searchButton.setOnAction(e -> search(searchField.getText(), "time", true)); - - JFXButton addButton = new JFXButton(); - addButton.getStyleClass().add("toggle-icon4"); - addButton.setGraphic(SVG.plus(Theme.blackFillBinding(), -1, -1)); - addButton.setOnAction(e -> addFeedback()); - - searchPane.getChildren().setAll(searchField, searchButton, addButton); - } - - { - spinnerPane.getStyleClass().add("card"); - VBox.setVgrow(spinnerPane, Priority.ALWAYS); - JFXListView listView = new JFXListView<>(); - spinnerPane.setContent(listView); - Bindings.bindContent(listView.getItems(), feedbacks); - MutableObject lastCell = new MutableObject<>(); - listView.setCellFactory(x -> new MDListCell(listView, lastCell) { - private final TwoLineListItem content = new TwoLineListItem(); - private final JFXButton likeButton = new JFXButton(); - private final JFXButton unlikeButton = new JFXButton(); - private final HBox container; - - { - container = new HBox(8); - container.setPickOnBounds(false); - container.setAlignment(Pos.CENTER_LEFT); - HBox.setHgrow(content, Priority.ALWAYS); - content.setMouseTransparent(false); - setSelectable(); - - likeButton.getStyleClass().add("toggle-icon4"); - likeButton.setGraphic(FXUtils.limitingSize(SVG.thumbUpOutline(Theme.blackFillBinding(), 24, 24), 24, 24)); - - unlikeButton.getStyleClass().add("toggle-icon4"); - unlikeButton.setGraphic(FXUtils.limitingSize(SVG.thumbDownOutline(Theme.blackFillBinding(), 24, 24), 24, 24)); - - container.getChildren().setAll(content, likeButton, unlikeButton); - - StackPane.setMargin(container, new Insets(10, 16, 10, 16)); - getContainer().getChildren().setAll(container); - } - - @Override - protected void updateControl(FeedbackResponse feedback, boolean empty) { - if (empty) return; - content.setTitle(feedback.getTitle()); - content.setSubtitle(feedback.getAuthor()); - content.getTags().setAll( - "#" + feedback.getId(), - i18n("feedback.state." + feedback.getState().name().toLowerCase(Locale.US)), - i18n("feedback.type." + feedback.getType().name().toLowerCase(Locale.US))); - content.setOnMouseClicked(e -> { - getFeedback(feedback.getId()) - .thenAcceptAsync(Schedulers.javafx(), f -> { - Controllers.dialog(new ViewFeedbackDialog(f)); - }) - .start(); - }); - } - }); - - getChildren().add(spinnerPane); - } + this.setContent(content); } - @Override - public void onPageShown() { - search("", "time", false); - } - - private void search(String keyword, String order, boolean showAll) { - HMCLAccounts.HMCLAccount account = HMCLAccounts.getAccount(); - Task.supplyAsync(() -> { - Map query = mapOf( - pair("keyword", keyword), - pair("order", order) - ); - if (showAll) { - query.put("showAll", "1"); - } - HttpRequest req = HttpRequest.GET(NetworkUtils.withQuery("https://hmcl.huangyuhui.net/api/feedback", query)); - if (account != null) { - req.authorization("Bearer", HMCLAccounts.getAccount().getIdToken()) - .header("Authorization-Provider", HMCLAccounts.getAccount().getProvider()); - } - return req.>getJson(new TypeToken>(){}.getType()); - }).whenComplete(Schedulers.javafx(), (result, exception) -> { - spinnerPane.hideSpinner(); - if (exception != null) { - if (exception instanceof ResponseCodeException) { - int responseCode = ((ResponseCodeException) exception).getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { - spinnerPane.setFailedReason(i18n("feedback.failed.permission")); - return; - } else if (responseCode == 429) { - spinnerPane.setFailedReason(i18n("feedback.failed.too_frequently")); - return; - } - } - spinnerPane.setFailedReason(i18n("feedback.failed")); - } else { - feedbacks.setAll(result); - } - }).start(); - } - - private Task getFeedback(int id) { - return Task.supplyAsync(() -> HttpRequest.GET("https://hmcl.huangyuhui.net/api/feedback/" + id).getJson(FeedbackResponse.class)); - } - - private void log() { - if (HMCLAccounts.getAccount() == null) { - // login - Controllers.dialog(new LoginDialog()); - } else { - // logout - HMCLAccounts.setAccount(null); - } - } - - private void addFeedback() { - if (HMCLAccounts.getAccount() == null) { - Controllers.dialog(i18n("feedback.add.login")); - return; - } - - Controllers.dialog(new AddFeedbackDialog()); - } - - private static final class LoginDialog extends JFXDialogLayout { - private final SpinnerPane spinnerPane = new SpinnerPane(); - private final Label errorLabel = new Label(); - private final BooleanProperty logging = new SimpleBooleanProperty(); - - public LoginDialog() { - setHeading(new Label(i18n("feedback.login"))); - - VBox vbox = new VBox(8); - setBody(vbox); - HintPane hintPane = new HintPane(MessageDialogPane.MessageType.INFO); - hintPane.textProperty().bind(BindingMapping.of(logging).map(logging -> i18n("account.hmcl.hint"))); - hintPane.setOnMouseClicked(e -> { - if (logging.get() && OAuthServer.lastlyOpenedURL != null) { - FXUtils.copyText(OAuthServer.lastlyOpenedURL); - } - }); - vbox.getChildren().setAll(hintPane); - - JFXButton loginButton = new JFXButton(); - spinnerPane.setContent(loginButton); - loginButton.setText(i18n("account.login")); - loginButton.setOnAction(e -> login()); - - JFXButton cancelButton = new JFXButton(); - cancelButton.setText(i18n("button.cancel")); - cancelButton.setOnAction(e -> fireEvent(new DialogCloseEvent())); - onEscPressed(this, cancelButton::fire); - - setActions(errorLabel, spinnerPane, cancelButton); - } - - private void login() { - spinnerPane.showSpinner(); - errorLabel.setText(""); - logging.set(true); - - HMCLAccounts.login().whenComplete(Schedulers.javafx(), (result, exception) -> { - logging.set(false); - if (exception != null) { - if (exception instanceof IOException) { - errorLabel.setText(i18n("account.failed.connect_authentication_server")); - } else if (exception instanceof JsonParseException) { - errorLabel.setText(i18n("account.failed.server_response_malformed")); - } else { - errorLabel.setText(Accounts.localizeErrorMessage(exception)); - } - } else { - fireEvent(new DialogCloseEvent()); - } - }).start(); - } - } - - private static class AddFeedbackDialog extends DialogPane { - - JFXTextField titleField = new JFXTextField(); - JFXComboBox comboBox = new JFXComboBox<>(); - JFXTextArea contentArea = new JFXTextArea(); - - public AddFeedbackDialog() { - setTitle(i18n("feedback.add")); - - GridPane body = new GridPane(); - body.setVgap(8); - body.setHgap(8); - - HintPane searchHintPane = new HintPane(MessageDialogPane.MessageType.WARNING); - GridPane.setColumnSpan(searchHintPane, 2); - searchHintPane.setText(i18n("feedback.add.hint.search_before_add")); - body.addRow(0, searchHintPane); - - HintPane titleHintPane = new HintPane(MessageDialogPane.MessageType.INFO); - GridPane.setColumnSpan(titleHintPane, 2); - titleHintPane.setText(i18n("feedback.add.hint.title")); - body.addRow(1, titleHintPane); - - titleField.setValidators(new RequiredValidator()); - body.addRow(2, new Label(i18n("feedback.title")), titleField); - - comboBox.setMaxWidth(-1); - comboBox.getItems().setAll(FeedbackType.values()); - comboBox.getSelectionModel().select(0); - comboBox.setConverter(stringConverter(e -> i18n("feedback.type." + e.name().toLowerCase()))); - body.addRow(3, new Label(i18n("feedback.type")), comboBox); - - Label contentLabel = new Label(i18n("feedback.content")); - GridPane.setColumnSpan(contentLabel, 2); - body.addRow(4, contentLabel); - - contentArea.setValidators(new RequiredValidator()); - contentArea.setPromptText(i18n("feedback.add.hint.content")); - GridPane.setColumnSpan(contentArea, 2); - body.addRow(5, contentArea); - - validProperty().bind(Bindings.createBooleanBinding(() -> { - return titleField.validate() && contentArea.validate(); - }, titleField.textProperty(), contentArea.textProperty())); - - setBody(body); - } - - @Override - protected void onAccept() { - setLoading(); - - addFeedback(titleField.getText(), comboBox.getValue(), contentArea.getText()) - .whenComplete(Schedulers.javafx(), exception -> { - if (exception != null) { - onFailure(exception.getLocalizedMessage()); - } else { - onSuccess(); - } - }) - .start(); - } - - private Task addFeedback(String title, FeedbackType feedbackType, String content) { - return Task.runAsync(() -> { - HttpRequest.POST("https://hmcl.huangyuhui.net/api/feedback") - .json(mapOf( - pair("title", title), - pair("content", content), - pair("type", feedbackType.name().toLowerCase(Locale.ROOT)), - pair("launcher_version", Metadata.VERSION) - )) - .authorization("Bearer", HMCLAccounts.getAccount().getIdToken()) - .header("Authorization-Provider", HMCLAccounts.getAccount().getProvider()) - .getString(); - }); - } - } - - private static class ViewFeedbackDialog extends JFXDialogLayout { - - public ViewFeedbackDialog(FeedbackResponse feedback) { - BorderPane heading = new BorderPane(); - TwoLineListItem left = new TwoLineListItem(); - heading.setLeft(left); - left.setTitle(feedback.getTitle()); - left.setSubtitle(feedback.getAuthor()); - left.getTags().add("#" + feedback.getId()); - left.getTags().add(i18n("feedback.state." + feedback.getState().name().toLowerCase(Locale.US))); - left.getTags().add(feedback.getLauncherVersion()); - left.getTags().add(i18n("feedback.type." + feedback.getType().name().toLowerCase())); - - setHeading(heading); - - Label content = new Label(feedback.getContent()); - content.setWrapText(true); - - TwoLineListItem response = new TwoLineListItem(); - response.getStyleClass().setAll("two-line-item-second-large"); - response.setTitle(i18n("feedback.response")); - response.setSubtitle(StringUtils.isBlank(feedback.getReason()) - ? i18n("feedback.response.empty") - : feedback.getReason()); - - VBox body = new VBox(content, response); - body.setSpacing(8); - setBody(body); - - JFXButton okButton = new JFXButton(); - okButton.setText(i18n("button.ok")); - okButton.setOnAction(e -> fireEvent(new DialogCloseEvent())); - - setActions(okButton); - } - } - - private static class FeedbackResponse { - private final int id; - private final String title; - private final String content; - private final String author; - @SerializedName("launcher_version") - private final String launcherVersion; - private final FeedbackType type; - private final FeedbackState state; - private final String reason; - - public FeedbackResponse(int id, String title, String content, String author, String launcherVersion, FeedbackType type, FeedbackState state, String reason) { - this.id = id; - this.title = title; - this.content = content; - this.author = author; - this.launcherVersion = launcherVersion; - this.type = type; - this.state = state; - this.reason = reason; - } - - public int getId() { - return id; - } - - public String getTitle() { - return title; - } - - public String getContent() { - return content; - } - - public String getAuthor() { - return author; - } - - public String getLauncherVersion() { - return launcherVersion; - } - - public FeedbackType getType() { - return type; - } - - public FeedbackState getState() { - return state; - } - - public String getReason() { - return reason; - } - } - - private enum FeedbackType { - FEATURE, - BUG - } - - private enum FeedbackState { - OPEN, - REJECTED, - ACCEPTED - } } diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 35cf6f723..49d19154d 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -26,13 +26,6 @@ about.author=Author about.author.statement=@huanghongxun on bilibili about.claim=EULA about.claim.statement=Click on this link for full text. -about.community=Community -about.community.qqchannel=QQ Channel -about.community.qqchannel.statement=Join our QQ Channel community ! -about.community.discord=Discord -about.community.discord.statement=Join our Discord community ! -about.community.kookapp=KOOK -about.community.kookapp.statement=Join our KOOK community ! about.dependency=Third-party Libraries about.legal=Legal Acknowledgement about.thanks_to=Thanks to @@ -387,35 +380,17 @@ fatal.unsupported_platform.osx_arm64=HMCL has provided support for Apple Silicon fatal.unsupported_platform.windows_arm64=HMCL has provided native support for the Windows on ARM platform. If you encounter problems when playing game, please try to start the game with Java based on x86 architecture.\n\nIf you are using the Qualcomm platform, you may need to install the OpenGL Compatibility Pack before playing games.\nClick the link to go to the Microsoft Store and install the compatibility pack. feedback=Feedback -feedback.add=Add a Feedback -feedback.add.hint.search_before_add=Before submitting feedback, you should search the keyword to see if there are duplicated entries. If so, you can upvote it to promote its priority.\n\ -\n\ -Please provide valuable feedback. Any content that is considered spam, a violation of People's Republic of China's regulations, or unrelated posts other than the launcher itself will lead to an account ban. -feedback.add.hint.title=The feedback title should summarize your issue concisely. Issues like "I have a problem", "I have an idea", "Game won't open", etc. will be closed automatically. -feedback.add.hint.content=The feedback content should describe your encountered issue or feature you wanted to add. If it's the former, you need to tell us the exact steps to reproduce the issue, e.g. what issue occurred when which buttons are clicked in what specific order. \n\ -\n\ -If it's the latter, you need to convince us on why it is needed, or what issue it could solve. -feedback.add.login=You must log in/register an HMCL account first to provide feedback. -feedback.add.permission=You must contribute to our project first before adding feedback\! -feedback.author=Author -feedback.content=Content -feedback.empty=No feedback to display -feedback.failed=Failed to load -feedback.failed.permission=This feature is limited to registered HMCL users with feedback permission only. -feedback.failed.too_frequently=Whoa\! Slow your searches down\! -feedback.like=Like -feedback.login=Log in to your HMCL account -feedback.response=Reply -feedback.response.empty=Not Viewed Yet -feedback.state.accepted=Accepted -feedback.state.open=Open -feedback.state.rejected=Rejected -feedback.title=Title -feedback.type=Type -feedback.type.bug=Bug Report -feedback.type.feature=Feature Request -feedback.unlike=Dislike -feedback.version=Launcher Version +feedback.channel=Feedback channel +feedback.discord=Discord +feedback.discord.statement=Join our Discord community. +feedback.github=GitHub Issue +feedback.github.statement=Creating an issue on GitHub. +feedback.kookapp=KOOK +feedback.kookapp.statement=Join our KOOK community. +feedback.qq_channel=QQ Channel +feedback.qq_channel.statement=Join our QQ Channel community. +feedback.qq_group=HMCL User Group +feedback.qq_group.statement=Join HMCL user QQ group through donation. file=File diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index c6f2b6572..67e285396 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -26,13 +26,6 @@ about.author=Autor about.author.statement=@huanghongxun en bilibili about.claim=EULA about.claim.statement=Haz clic en este enlace para ver el texto completo. -about.community=Comunidad -about.community.qqchannel=QQ Canal -about.community.qqchannel.statement=¡Únete a nuestra comunidad de QQ Canal! -about.community.discord=Discord -about.community.discord.statement=¡Únete a nuestra comunidad de Discord! -about.community.kaiheila=KaiHeiLa -about.community.kaiheila.statement=¡Únete a nuestra comunidad de KaiHeiLa! about.dependency=Bibliotecas de terceros about.legal=Reconocimiento legal about.thanks_to=Gracias a @@ -361,35 +354,12 @@ fatal.illegal_char=Su ruta de usuario contiene un carácter ilegal '\=', por lo Por ejemplo, no podrá utilizar authlib-injector o cambiar el skin de su cuenta offline. feedback=Comentarios -feedback.add=Añadir un comentario -feedback.add.hint.search_before_add=Antes de enviar un comentario, debes buscar la palabra clave para ver si hay entradas duplicadas. Si es así, puedes votar a favor para promover su prioridad. -\n\ -Por favor, proporciona comentarios valiosos. Cualquier contenido que se considere spam, una violación de las regulaciones de la República Popular de China, o mensajes no relacionados con el launcher en sí, dará lugar a una prohibición de la cuenta. -feedback.add.hint.title=El título del comentario debe resumir tu problema de forma concisa. Los temas como "Tengo un problema", "Tengo una idea", "El juego no se abre", etc. se cerrarán automáticamente. -feedback.add.hint.content=El contenido del comentario debe describir el problema encontrado o la función que quieres añadir. Si se trata de lo primero, tienes que decirnos los pasos exactos para reproducir el problema, por ejemplo, qué problema se produce cuando se hace clic en qué botones y en qué orden específico. \n\ -\n\ -Si es lo segundo, necesitas convencernos de por qué es necesario, o qué problema podría resolver. -feedback.add.login=Debe iniciar sesión/registrar una cuenta HMCL primero para proporcionar comentarios. -feedback.add.permission=¡Debe contribuir primero a nuestro proyecto antes de añadir comentarios! -feedback.author=Autor -feedback.content=Contenido -feedback.empty=No hay comentarios para mostrar -feedback.failed=No se ha podido cargar -feedback.failed.permission=Esta función está limitada a los usuarios registrados de HMCL con permiso de comentarios. -feedback.failed.too_frequently=¡Qué! ¡Reduce la velocidad de tus búsquedas! -feedback.like=Me gusta -feedback.login=Acceder a tu cuenta HMCL -feedback.response=Responder -feedback.response.empty=No visto todavía -feedback.state.accepted=Aceptado -feedback.state.open=Abierto -feedback.state.rejected=Rechazado -feedback.title=Título -feedback.type=Tipo -feedback.type.bug=Informe de error -feedback.type.feature=Solicitud de característica -feedback.unlike=No me gusta -feedback.version=Versión del launcher +feedback.discord=Discord +feedback.discord.statement=¡Únete a nuestra comunidad de Discord! +feedback.kookapp=KaiHeiLa +feedback.kookapp.statement=¡Únete a nuestra comunidad de KaiHeiLa! +feedback.qq_channel=QQ Canal +feedback.qq_channel.statement=¡Únete a nuestra comunidad de QQ Canal! file=Archivo diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index e8091088e..4a27fccc5 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -24,13 +24,6 @@ about.author=Author about.author.statement=bilibili : @huanghongxun about.claim=EULA about.claim.statement=テキスト全体のリンクをクリックします。 -about.community=コミュニティ -about.community.qqchannel=QQ チャネル -about.community.qqchannel.statement=チャットに参加しよう! -about.community.discord=Discord -about.community.discord.statement=チャットに参加しよう! -about.community.kookapp=KOOK -about.community.kookapp.statement=チャットに参加しよう! about.dependency=Dependencies about.legal=法的承認 about.thanks_to=Thanks to @@ -325,31 +318,12 @@ fatal.samba=If you are trying to run HMCL in a shared folder by Samba, HMCL may fatal.illegal_char=ユーザーフォルダーのパスに不正な文字'='が含まれています, ログインアカウントやオフラインログインではスキンの変更ができなくなり。 feedback=フィードバック -Feedback.add=フィードバックを追加 -Feedback.add.hint.search_before_add=新しいフィードバックを追加する前に、キーワードを検索して、報告する内容がすでに報告されているかどうかを確認する必要があります。持っている場合は、それを賛成して優先順位を上げることができます -Feedback.add.hint.title=フィードバックのタイトルは、ニーズを簡潔に要約できる必要があります。 「問題がある」、「アイデアがある」、「ゲームが開かない」など、一般的な問題を一目で確認できないタイトルは使用できません。 -Feedback.add.hint.content=フィードバックコンテンツは、ニーズを完全かつ簡潔に表現する必要があります。問題が発生した場合は、ランチャーを開いた後にクリックされたボタンや、操作が実行された後にトリガーされる問題など、繰り返しパスを詳細に説明する必要があります。新しい機能を追加する場合は、プレーヤーがその機能を必要とする理由、その機能で解決できる問題、およびその機能の実装方法について詳しく説明する必要があります。 -Feedback.add.login=フィードバックの許可を得るには、HMCLアカウントにログイン/登録する必要があります。 -Feedback.add.permission=新しいフィードバックを追加するには、フィードバック権限を取得する必要があります。 -feedback.author=作成者 -feedback.content=コンテンツ -Feedback.empty=条件を満たすアイテムはありません。 -Feedback.failed=ロードに失敗しました -Feedback.failed.permission=フィードバックを送信する権限を持つアカウントにログインしている場合にのみ、キーワードで検索できます。 -Feedback.failed.too_frequently=頻繁すぎる。あとでもう一度試してみてください。 -Feedback.like=Like -Feedback.login=HMCLアカウントにログインします -feedback.response=応答 -Feedback.response.empty=応答なし -feedback.state.accepted=承認済み -Feedback.state.open=保留中 -Feedback.state.rejected=拒否されました -feedback.title=タイトル -feedback.type=タイプ -Feedback.type.bug=バグレポート -Feedback.type.feature=機能リクエスト -Feedback.unlike=Unlike -Feedback.version=ランチャーバージョン +feedback.discord=Discord +feedback.discord.statement=チャットに参加しよう! +feedback.kookapp=KOOK +feedback.kookapp.statement=チャットに参加しよう! +feedback.qq_channel=QQ チャネル +feedback.qq_channel.statement=チャットに参加しよう! file=ファイル diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 96ce12ee0..d07be94fc 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -24,13 +24,6 @@ about.author=Автор about.author.statement=bilibili: @huanghongxun about.claim=EULA about.claim.statement=Кликните на ссылку, чтобы увидеть весь текст. -about.community=Сообщество -about.community.qqchannel=QQ канал -about.community.qqchannel.statement=Присоединиться! -about.community.discord=Discord -about.community.discord.statement=Присоединиться! -about.community.kookapp=KOOK -about.community.kookapp.statement=Присоединиться! about.dependency=Зависимости about.legal=Юридическое подтверждение about.thanks_to=Отдельная благодарность @@ -328,31 +321,12 @@ fatal.samba=Если вы пытаетесь запустить лаунчер fatal.illegal_char=Недопустимый символ '=' в пути к папке пользователя. Лаунчер может работать, но некоторые функции не будут работать.\nВы не сможете использовать аккаунт authlib-injector или изменить офлайн скин. feedback=Обратная связь -feedback.add=Добавить отзыв (на английском или китайском) -feedback.add.hint.search_before_add=Прежде чем добавлять новый отзыв, следует провести поиск по ключевому слову, чтобы выяснить, сообщалось ли уже о том, о чем вы хотите сообщить, или нет. Если есть, вы можете проголосовать за него, чтобы повысить его приоритет. -feedback.add.hint.title=Заголовок отзыва должен кратко выражать ваши потребности. Такие заголовки, как "У меня проблема", "У меня есть идея", "Игра не открывается" и т.д. которые не позволяют другим увидеть общую проблему с первого взгляда, неприемлемы. -feedback.add.hint.content=Содержание отзыва должно полностью и кратко выражать ваши потребности. Если вы столкнулись с проблемой, необходимо подробно описать путь повторения, например, какая кнопка нажимается после открытия программы запуска, и какая проблема возникает после выполнения какой операции. Если вы хотите добавить новые функции, вам нужно всё продумать: почему игрокам нужна эта функция, какие проблемы она может решить и как её можно реализовать. -feedback.add.login=Чтобы получить разрешение на обратную связь, необходимо войти/зарегистрировать аккаунт HMCL. -feedback.add.permission=Чтобы добавлять отзывы, необходимо получить разрешение. -feedback.author=Автор -feedback.content=Контент -feedback.empty=Нет элементов, удовлетворяющих условиям. -feedback.failed=Не удалось загрузить -feedback.failed.permission=Поиск по ключевым словам возможен только при входе в аккаунт с разрешением отправки отзывов. -feedback.failed.too_frequently=Слишком часто. Повторите попытку позже. -feedback.like=Нравится -feedback.login=Войти в аккаунт HMCL -feedback.response=Ответ -feedback.response.empty=Не ответили -feedback.state.accepted=Принято -feedback.state.open=В ожидании -feedback.state.rejected=Отклонено -feedback.title=Заголовок -feedback.type=Тип -feedback.type.bug=Сообщить об ошибке -feedback.type.feature=Запрос функции -feedback.unlike=Не нравится -feedback.version=Версия лаунчера +feedback.discord=Discord +feedback.discord.statement=Присоединиться! +feedback.kookapp=KOOK +feedback.kookapp.statement=Присоединиться! +feedback.qq_channel=QQ канал +feedback.qq_channel.statement=Присоединиться! file=Файл diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 82b2de8f2..cdc76a16a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -24,13 +24,6 @@ about.author=作者 about.author.statement=bilibili: @huanghongxun about.claim=用戶協議 about.claim.statement=點擊連結以查看全文 -about.community=社區 -about.community.qqchannel=QQ 頻道 -about.community.qqchannel.statement=歡迎加入 QQ 頻道 討論區,加入後請遵守討論區規定。 -about.community.discord=Discord -about.community.discord.statement=歡迎加入 Discord 討論區,加入後請遵守討論區規定。 -about.community.kookapp=KOOK -about.community.kookapp.statement=歡迎加入 KOOK 討論區,加入後請遵守討論區規定。 about.dependency=相依元件 about.legal=法律聲明 about.thanks_to=鳴謝 @@ -351,32 +344,18 @@ fatal.unsupported_platform=Minecraft 尚未你您的平臺提供完善支持, fatal.unsupported_platform.osx_arm64=HMCL 已為 Apple Silicon 平臺提供支援,使用 ARM 原生 Java 啟動遊戲以獲得更流暢的遊戲體驗。\n如果你在遊戲中遭遇問題,使用 x86-64 架構的 Java 啟動遊戲可能有更好的相容性。 fatal.unsupported_platform.windows_arm64=HMCL 已為 Windows on Arm 平臺提供原生支持。如果你在遊戲中遭遇問題,請嘗試使用 x86 架構的 Java 啟動遊戲。\n\n如果你正在使用高通平臺,你可能需要安裝 OpenGL 相容包後才能進行遊戲。點擊連結前往 Microsoft Store 安裝相容包。 -feedback=回饋 -feedback.add=新增回饋 -feedback.add.hint.search_before_add=添加回饋前,請先搜尋已有回饋中是否已經有人提出過相關內容,如果有,你可以透過給對應回饋按讚來提升對應回饋的優先度。\n請你發布有意義的回饋。如果您發布了違反國家法律法規、灌水等不良訊息,或求助遊戲內容玩法等問題,你的帳號將被封禁。 -feedback.add.hint.title=回饋標題需能簡練概括你的需求。"我有問題"、"我有一個想法"、"遊戲打不開" 等無法讓其他人一眼看出大致問題的標題是不被接受的。 -feedback.add.hint.content=回饋內容需完整且簡練地表達你的需求。如果你遇到了問題,你需要詳細描述復現路徑,比如在打開啟動器後通過點擊什麼按鈕,做了什麼操作後觸發了什麼問題。如果你希望添加新功能,你需要闡述:為什麼玩家需要該功能,該功能能解決什麼問題,該功能可以怎麼實現。 -feedback.add.login=你需要先登入/註冊 HMCL 回饋帳號並獲得回饋權限才能添加回饋。 -feedback.add.permission=你需要獲得回饋權限才能添加回饋。 -feedback.author=發布者 -feedback.content=正文 -feedback.empty=沒有滿足條件的回饋 -feedback.failed=載入失敗 -feedback.failed.permission=登錄帳戶並取得回饋權限後才能根據關鍵字搜索回饋 -feedback.failed.too_frequently=搜索次數太頻繁啦 -feedback.like=贊成 -feedback.login=登入 HMCL 帳號 -feedback.response=回復 -feedback.response.empty=尚未查看 -feedback.state.accepted=接受 -feedback.state.open=開放 -feedback.state.rejected=拒絕 -feedback.title=標題 -feedback.type=類型 -feedback.type.bug=問題回饋 -feedback.type.feature=新功能請求 -feedback.unlike=反對 -feedback.version=啟動器版本 +feedback=反饋 +feedback.channel=反饋渠道 +feedback.discord=Discord +feedback.discord.statement=歡迎加入 Discord 討論區,加入後請遵守討論區規定。 +feedback.github=GitHub Issue +feedback.github.statement=打開一個 GitHub Issue。 +feedback.kookapp=KOOK +feedback.kookapp.statement=歡迎加入 KOOK 討論區,加入後請遵守討論區規定。 +feedback.qq_channel=QQ 頻道 +feedback.qq_channel.statement=歡迎加入 QQ 頻道討論區,加入後請遵守討論區規定。 +feedback.qq_group=HMCL 用戶群 +feedback.qq_group.statement=通過捐贈支持加入 HMCL 用戶 QQ 群。 file=檔案 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index cd0dab535..2b6e79c65 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -24,13 +24,6 @@ about.author=作者 about.author.statement=bilibili ID: @huanghongxun about.claim=用户协议 about.claim.statement=点击链接以查看全文 -about.community=社区 -about.community.qqchannel=QQ 频道 -about.community.qqchannel.statement=欢迎加入 QQ 频道 讨论区,加入后请遵守讨论区规定。 -about.community.discord=Discord -about.community.discord.statement=欢迎加入 Discord 讨论区,加入后请遵守讨论区规定。 -about.community.kookapp=KOOK -about.community.kookapp.statement=欢迎加入 KOOK 讨论区,加入后请遵守讨论区规定。 about.dependency=依赖 about.legal=法律声明 about.thanks_to=鸣谢 @@ -352,31 +345,17 @@ fatal.unsupported_platform.osx_arm64=HMCL 已为 Apple Silicon 平台提供支 fatal.unsupported_platform.windows_arm64=HMCL 已为 Windows on Arm 平台提供原生支持。如果你在游戏中遭遇问题,请尝试使用 x86 架构的 Java 启动游戏。\n\n如果你正在使用高通平台,你可能需要安装 OpenGL 兼容包后才能进行游戏。点击链接前往 Microsoft Store 安装兼容包。 feedback=反馈 -feedback.add=新增反馈 -feedback.add.hint.search_before_add=添加反馈前,请先搜索已有反馈中是否已经有人提出过相关内容,如果有,你可以通过给对应反馈点赞来提升对应反馈的优先级。\n请你发布有意义的反馈。如果您发布了违反国家法律法规、灌水等不良信息,或求助游戏内容玩法等问题,你的账号将被封禁。 -feedback.add.hint.title=反馈标题需能简练概括你的需求。带有 "我有问题"、"我有一个想法"、"游戏打不开" 等无法让其他人一眼看出大致问题的标题的反馈将会被直接关闭。 -feedback.add.hint.content=反馈内容需完整且简练地表达你的需求。如果你遇到了问题,你需要详细描述复现路径,比如在打开启动器后通过点击什么按钮,做了什么操作后触发了什么问题。如果你希望添加新功能,你需要阐述:为什么玩家需要该功能,该功能能解决什么问题,该功能可以怎么实现。 -feedback.add.login=你需要先登录/注册 HMCL 反馈帐户并获得反馈权限才能添加反馈! -feedback.add.permission=你需要赞助等方式获得反馈权限才能添加反馈! -feedback.author=发布者 -feedback.content=正文 -feedback.empty=没有满足条件的反馈 -feedback.failed=加载失败 -feedback.failed.permission=登录账户并取得反馈权限后才能根据关键字搜索反馈! -feedback.failed.too_frequently=搜索次数太频繁啦! -feedback.like=赞成 -feedback.login=登录 HMCL 帐户 -feedback.response=回复 -feedback.response.empty=尚未查看 -feedback.state.accepted=接受 -feedback.state.open=开放 -feedback.state.rejected=拒绝 -feedback.title=标题 -feedback.type=类型 -feedback.type.bug=问题反馈 -feedback.type.feature=新功能请求 -feedback.unlike=反对 -feedback.version=启动器版本 +feedback.channel=反馈渠道 +feedback.discord=Discord +feedback.discord.statement=欢迎加入 Discord 讨论区,加入后请遵守讨论区规定。 +feedback.github=GitHub Issue +feedback.github.statement=打开一个 GitHub Issue。 +feedback.kookapp=KOOK +feedback.kookapp.statement=欢迎加入 KOOK 讨论区,加入后请遵守讨论区规定。 +feedback.qq_channel=QQ 频道 +feedback.qq_channel.statement=欢迎加入 QQ 频道讨论区,加入后请遵守讨论区规定。 +feedback.qq_group=HMCL 用户群 +feedback.qq_group.statement=通过捐赠支持加入 HMCL 用户 QQ 群。 file=文件