优化更新日志展示功能 (#4703)

1. 如果检测到是降级更新,则不展示更新日志;
2. 如果检测到最新更新日志和最新版本不匹配,则不显示更新日志;
3. 展示当前版本与 `nowchange`/`nowpreview` 之间的所有更新日志,而不只展示一个版本的日志。
This commit is contained in:
Glavo
2025-10-20 20:21:13 +08:00
committed by GitHub
parent 2516fb5d69
commit 27e1e021d7

View File

@@ -22,17 +22,24 @@ import com.jfoenix.controls.JFXDialogLayout;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.ScrollPane;
import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
import org.jackhuang.hmcl.upgrade.RemoteVersion;
import org.jackhuang.hmcl.util.versioning.VersionNumber;
import org.jetbrains.annotations.Nullable;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import java.io.IOException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.jackhuang.hmcl.Metadata.CHANGELOG_URL;
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
@@ -40,6 +47,26 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public final class UpgradeDialog extends JFXDialogLayout {
private static final Pattern CHANGELOG_TITLE_PATTERN = Pattern.compile("HMCL (?<version>\\d(?:\\.\\d+)+)");
private static @Nullable VersionNumber extractVersionNumber(Node node) {
String text;
if (node instanceof Element element) {
text = element.text();
} else if (node instanceof TextNode textNode) {
text = textNode.text();
} else {
return null;
}
Matcher matcher = CHANGELOG_TITLE_PATTERN.matcher(text);
if (matcher.find())
return VersionNumber.asVersion(matcher.group("version"));
else
return null;
}
public UpgradeDialog(RemoteVersion remoteVersion, Runnable updateRunnable) {
maxWidthProperty().bind(Controllers.getScene().widthProperty().multiply(0.7));
maxHeightProperty().bind(Controllers.getScene().heightProperty().multiply(0.7));
@@ -49,7 +76,14 @@ public final class UpgradeDialog extends JFXDialogLayout {
String url = CHANGELOG_URL + remoteVersion.getChannel().channelName + ".html";
boolean isPreview = remoteVersion.isPreview();
Task.supplyAsync(Schedulers.io(), () -> {
VersionNumber targetVersion = VersionNumber.asVersion(remoteVersion.getVersion());
VersionNumber currentVersion = VersionNumber.asVersion(Metadata.VERSION);
if (targetVersion.compareTo(currentVersion) <= 0) {
return null;
}
Document document = Jsoup.parse(new URL(url), 30 * 1000);
String id = null;
Node node = null;
@@ -65,15 +99,27 @@ public final class UpgradeDialog extends JFXDialogLayout {
if (node == null || !"h1".equals(node.nodeName()))
throw new IOException("Cannot find current changelog in document");
VersionNumber changelogVersion = extractVersionNumber(node);
if (changelogVersion == null)
throw new IOException("Cannot find current changelog in document. The node: " + node);
if (!targetVersion.equals(changelogVersion)) {
LOG.warning("The changelog has not been updated yet. Expected: " + targetVersion + ", Actual: " + changelogVersion);
return null;
}
HTMLRenderer renderer = new HTMLRenderer(uri -> {
LOG.info("Open link: " + uri);
FXUtils.openLink(uri.toString());
});
do {
if ("h1".equals(node.nodeName()) && !id.equals(node.attr("id"))) {
if ("h1".equals(node.nodeName())) {
changelogVersion = extractVersionNumber(node);
if (changelogVersion == null || changelogVersion.compareTo(currentVersion) <= 0) {
break;
}
}
renderer.appendNode(node);
node = node.nextSibling();
} while (node != null);
@@ -82,10 +128,14 @@ public final class UpgradeDialog extends JFXDialogLayout {
return renderer.render();
}).whenComplete(Schedulers.javafx(), (result, exception) -> {
if (exception == null) {
if (result != null) {
ScrollPane scrollPane = new ScrollPane(result);
scrollPane.setFitToWidth(true);
FXUtils.smoothScrolling(scrollPane);
setBody(scrollPane);
} else {
setBody();
}
} else {
LOG.warning("Failed to load update log, trying to open it in browser");
FXUtils.openLink(url);