diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java index b67007ee2..5c1399733 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/LeftPaneController.java @@ -19,9 +19,7 @@ package org.jackhuang.hmcl.ui; import com.jfoenix.concurrency.JFXUtilities; import javafx.application.Platform; -import javafx.beans.binding.When; import javafx.scene.layout.Region; -import javafx.scene.paint.Color; import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.RefreshedVersionsEvent; import org.jackhuang.hmcl.game.HMCLGameRepository; @@ -63,16 +61,7 @@ public final class LeftPaneController extends AdvancedListBox { profileListItem.profileProperty().bind(Profiles.selectedProfileProperty()); IconedItem launcherSettingsItem = new IconedItem(SVG.gear(Theme.blackFillBinding(), 20, 20), "iconed-item"); - - launcherSettingsItem.getLabel().textProperty().bind( - new When(UpdateChecker.outdatedProperty()) - .then(i18n("update.found")) - .otherwise(i18n("settings.launcher"))); - - launcherSettingsItem.getLabel().textFillProperty().bind( - new When(UpdateChecker.outdatedProperty()) - .then(Color.RED) - .otherwise(Color.BLACK)); + launcherSettingsItem.getLabel().setText(i18n("settings.launcher")); launcherSettingsItem.setOnMouseClicked(e -> Controllers.navigate(Controllers.getSettingsPage())); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java index 1993664e6..27226a603 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java @@ -20,6 +20,12 @@ package org.jackhuang.hmcl.ui; import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXPopup; +import javafx.animation.Interpolator; +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.Timeline; +import javafx.beans.InvalidationListener; +import javafx.beans.WeakInvalidationListener; import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.fxml.FXML; @@ -29,6 +35,7 @@ import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.shape.Rectangle; +import javafx.util.Duration; import org.jackhuang.hmcl.event.EventBus; import org.jackhuang.hmcl.event.RefreshedVersionsEvent; import org.jackhuang.hmcl.game.HMCLGameRepository; @@ -37,9 +44,13 @@ import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.construct.PopupMenu; import org.jackhuang.hmcl.ui.construct.RipplerContainer; +import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.ui.versions.GameItem; import org.jackhuang.hmcl.ui.versions.Versions; +import org.jackhuang.hmcl.upgrade.RemoteVersion; +import org.jackhuang.hmcl.upgrade.UpdateChecker; +import org.jackhuang.hmcl.upgrade.UpdateHandler; import org.jackhuang.hmcl.util.versioning.VersionNumber; import java.util.List; @@ -52,16 +63,23 @@ public final class MainPage extends StackPane implements DecoratorPage { private final PopupMenu menu = new PopupMenu(); private final JFXPopup popup = new JFXPopup(menu); + private InvalidationListener updateListener; @FXML private StackPane main; @FXML + private StackPane updatePane; + @FXML private JFXButton btnLaunch; @FXML private JFXButton btnMenu; @FXML + private JFXButton closeButton; + @FXML private Label lblCurrentGame; @FXML + private TwoLineListItem lblLatestVersion; + @FXML private Rectangle separator; private Profile profile; @@ -72,6 +90,32 @@ public final class MainPage extends StackPane implements DecoratorPage { btnMenu.setClip(new Rectangle(211, -100, 100, 200)); menu.setMaxHeight(400); + updatePane.visibleProperty().bind(UpdateChecker.outdatedProperty()); + closeButton.setGraphic(SVG.close(Theme.whiteFillBinding(), 10, 10)); + closeButton.setOnMouseClicked(event -> { + Duration duration = Duration.millis(320); + Timeline nowAnimation = new Timeline(); + nowAnimation.getKeyFrames().addAll( + new KeyFrame(Duration.ZERO, + new KeyValue(updatePane.translateXProperty(), 0, Interpolator.EASE_IN)), + new KeyFrame(duration, + new KeyValue(updatePane.translateXProperty(), 260, Interpolator.EASE_IN)), + new KeyFrame(duration, e -> { + updatePane.visibleProperty().unbind(); + updatePane.setVisible(false); + })); + nowAnimation.play(); + }); + updateListener = any -> { + if (UpdateChecker.isOutdated()) { + lblLatestVersion.setTitle(i18n("update.bubble.title", UpdateChecker.getLatestVersion().getVersion())); + } + }; + UpdateChecker.latestVersionProperty().addListener(new WeakInvalidationListener(updateListener)); + UpdateChecker.outdatedProperty().addListener(new WeakInvalidationListener(updateListener)); + UpdateChecker.checkingUpdateProperty().addListener(new WeakInvalidationListener(updateListener)); + updateListener.invalidated(null); + StackPane graphic = new StackPane(); Node svg = SVG.triangle(Theme.whiteFillBinding(), 10, 10); StackPane.setAlignment(svg, Pos.CENTER_RIGHT); @@ -137,6 +181,15 @@ public final class MainPage extends StackPane implements DecoratorPage { popup.show(btnMenu, JFXPopup.PopupVPosition.BOTTOM, JFXPopup.PopupHPosition.RIGHT, 0, -btnMenu.getHeight()); } + @FXML + private void onUpgrade() { + RemoteVersion target = UpdateChecker.getLatestVersion(); + if (target == null) { + return; + } + UpdateHandler.updateFrom(target); + } + public String getTitle() { return title.get(); } diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 6d66c04e0..b06683d03 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -89,6 +89,15 @@ -fx-padding: 4 0 4 0; } +.bubble { + -fx-background-color: gray; + -fx-background-radius: 2px; +} + +.bubble .label { + -fx-text-fill: white; +} + /******************************************************************************* * * * JFX Tab Pane * diff --git a/HMCL/src/main/resources/assets/fxml/main.fxml b/HMCL/src/main/resources/assets/fxml/main.fxml index d4c105133..42d86a676 100644 --- a/HMCL/src/main/resources/assets/fxml/main.fxml +++ b/HMCL/src/main/resources/assets/fxml/main.fxml @@ -5,16 +5,33 @@ + + + + + + + + + + + + + + + + diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 5fe05ee53..1b151e31b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -350,6 +350,8 @@ update.checking=Checking for updates update.failed=Failed to perform upgrade update.found=Update Available! update.newest_version=Latest version: %s +update.bubble.title=Update Available: %s +update.bubble.subtitle=Click here for details update.note=Development version contains more functionality and bug fixes as well as more possible bugs. update.latest=This is latest Version. update.no_browser=Cannot open any browser. The link has been copied to the clipboard. Paste it to a browser address bar to update. diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 98287626a..89f4198e0 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -350,6 +350,8 @@ update.checking=正在檢查更新 update.failed=更新失敗 update.found=發現到更新 update.newest_version=最新版本為:%s +update.bubble.title=發現更新:%s +update.bubble.subtitle=點擊此處查看詳情 update.note=開發版包含更多的功能以及錯誤修復,但也可能會包含其他的問題。 update.latest=目前版本為最新版本 update.no_browser=無法打開瀏覽器,網址已經複製到剪貼簿了,您可以手動複製網址打開頁面 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 a6036fef8..c316416d3 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -350,6 +350,8 @@ update.checking=正在检查更新 update.failed=更新失败 update.found=发现更新 update.newest_version=最新版本为:%s +update.bubble.title=发现更新:%s +update.bubble.subtitle=点击此处查看详情 update.note=开发版包含更多的功能以及错误修复,但也可能会包含其他的问题。 update.latest=当前版本为最新版本 update.no_browser=无法打开浏览器,网址已经复制到剪贴板了,您可以手动粘贴网址打开页面