diff --git a/.github/workflows/auto-alpha-tag.yml b/.github/workflows/auto-alpha-tag.yml index 31dea2e..5f04b02 100644 --- a/.github/workflows/auto-alpha-tag.yml +++ b/.github/workflows/auto-alpha-tag.yml @@ -4,6 +4,11 @@ on: push: branches: - "dev" + paths: + - ".github/workflows/*.yml" + - "src/**" + - "pom.xml" + - "!**/*.md" pull_request: branches: - "dev" diff --git a/README.md b/README.md index 52986e4..6dbae43 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,40 @@ ### TODO +### 截图 + +
+ 主界面 + + + main + +
+ +
+ 管理员信息 + + + main + +
+ +
+ 设置 + + + main + +
+ +
+ 关于 + + + about + +
+ #### 本地运行 1. 克隆代码 diff --git a/pom.xml b/pom.xml index 51bbb7b..3df4e31 100644 --- a/pom.xml +++ b/pom.xml @@ -258,7 +258,6 @@ --enable-preview -Xmx100m - @@ -270,6 +269,7 @@ windows + ${project.name}-windows true gui @@ -277,6 +277,23 @@ + + bundling-for-windows-nojre + package + + package + + + ${project.name}-windows-nojre + windows + true + false + + gui + false + + + diff --git a/src/main/java/cn/octopusyan/alistgui/base/BaseController.java b/src/main/java/cn/octopusyan/alistgui/base/BaseController.java index c1e48e7..87ec59d 100644 --- a/src/main/java/cn/octopusyan/alistgui/base/BaseController.java +++ b/src/main/java/cn/octopusyan/alistgui/base/BaseController.java @@ -2,19 +2,28 @@ package cn.octopusyan.alistgui.base; import cn.octopusyan.alistgui.Application; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.util.FxmlUtil; -import cn.octopusyan.alistgui.util.WindowsUtil; +import cn.octopusyan.alistgui.util.ViewUtil; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Labeled; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Tab; import javafx.scene.layout.Pane; import javafx.stage.Stage; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.ResourceBundle; /** @@ -43,6 +52,29 @@ public abstract class BaseController implements Initia } } viewModel = vm; + + } + + /** + * 国际化绑定 + */ + private void bindI18n() { + // i18n 绑定 + try { + for (Field field : getAllField(this.getClass())) { + I18n i18n = field.getAnnotation(I18n.class); + if (i18n != null && StringUtils.isNoneEmpty(i18n.key())) { + switch (field.get(this)) { + case Labeled labeled -> labeled.textProperty().bind(Context.getLanguageBinding(i18n.key())); + case Tab tab -> tab.textProperty().bind(Context.getLanguageBinding(i18n.key())); + case MenuItem mi -> mi.textProperty().bind(Context.getLanguageBinding(i18n.key())); + default -> {} + } + } + } + } catch (IllegalAccessException e) { + logger.error("获取属性失败", e); + } } @FXML @@ -51,9 +83,12 @@ public abstract class BaseController implements Initia // 全局窗口拖拽 if (dragWindow() && getRootPanel() != null) { // 窗口拖拽 - WindowsUtil.bindDragged(getRootPanel()); + ViewUtil.bindDragged(getRootPanel()); } + // 国际化绑定 + bindI18n(); + // 初始化数据 initData(); @@ -109,4 +144,16 @@ public abstract class BaseController implements Initia * 视图事件 */ public abstract void initViewAction(); + + + private static List getAllField(Class class1) { + List list = new ArrayList<>(); + while (class1 != Object.class) { + list.addAll(Arrays.stream(class1.getDeclaredFields()).toList()); + //获取父类 + class1 = class1.getSuperclass(); + } + return list; + } + } diff --git a/src/main/java/cn/octopusyan/alistgui/config/Context.java b/src/main/java/cn/octopusyan/alistgui/config/Context.java index 0db021e..4430bee 100644 --- a/src/main/java/cn/octopusyan/alistgui/config/Context.java +++ b/src/main/java/cn/octopusyan/alistgui/config/Context.java @@ -1,17 +1,12 @@ package cn.octopusyan.alistgui.config; -import atlantafx.base.theme.Theme; import cn.octopusyan.alistgui.Application; import cn.octopusyan.alistgui.base.BaseController; -import cn.octopusyan.alistgui.controller.AboutController; -import cn.octopusyan.alistgui.controller.MainController; -import cn.octopusyan.alistgui.controller.RootController; -import cn.octopusyan.alistgui.controller.SetupController; +import cn.octopusyan.alistgui.controller.*; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.util.FxmlUtil; import cn.octopusyan.alistgui.util.ProcessesUtil; -import javafx.application.Platform; import javafx.beans.binding.StringBinding; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; @@ -41,7 +36,6 @@ public class Context { private static final Logger log = LoggerFactory.getLogger(Context.class); private static Scene scene; private static final IntegerProperty currentViewIndex = new SimpleIntegerProperty(0); - private static final ObjectProperty theme = new SimpleObjectProperty<>(ConfigManager.theme()); /** * 控制器集合 @@ -79,6 +73,7 @@ public class Context { case MainController main -> main; case SetupController setup -> setup; case AboutController about -> about; + case PasswordController passwod -> passwod; default -> throw new IllegalStateException(STR."Unexpected value: \{type}"); }; } catch (Exception e) { @@ -92,10 +87,6 @@ public class Context { Context.application = application; } - public static ObjectProperty themeProperty() { - return theme; - } - // 获取当前所选时区属性 public static ObjectProperty currentLocaleProperty() { return currentLocale; @@ -150,12 +141,6 @@ public class Context { return LANGUAGE_RESOURCE_FACTORY.getResourceBundleProperty(); } - /** - * 初始化 语言 - */ - private static void initI18n() { - } - /** * 有此类所在路径决定相对路径 * @@ -173,17 +158,8 @@ public class Context { * @return Scene */ public static Scene initScene() { - // locale监听; 切换后,重新加载界面 - currentLocaleProperty().addListener((_, _, locale) -> Platform.runLater(Context::loadScene)); - // 加载 - loadScene(); - return scene; - } - - private static void loadScene() { try { FXMLLoader loader = FxmlUtil.load("root-view"); - loader.setControllerFactory(Context.getControlFactory()); //底层面板 Pane root = loader.load(); Optional.ofNullable(scene).ifPresentOrElse( @@ -198,6 +174,7 @@ public class Context { } catch (Throwable e) { log.error("loadScene error", e); } + return scene; } public static int currentViewIndex() { diff --git a/src/main/java/cn/octopusyan/alistgui/config/I18n.java b/src/main/java/cn/octopusyan/alistgui/config/I18n.java new file mode 100644 index 0000000..8a3161e --- /dev/null +++ b/src/main/java/cn/octopusyan/alistgui/config/I18n.java @@ -0,0 +1,15 @@ +package cn.octopusyan.alistgui.config; + +import java.lang.annotation.*; + +/** + * 显示文本绑定 + * + * @author octopus_yan + */ +@Documented +@Target({ElementType.FIELD})//用此注解用在属性上。 +@Retention(RetentionPolicy.RUNTIME) +public @interface I18n { + String key() default ""; +} diff --git a/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java b/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java index 9b45a26..4e57f1c 100644 --- a/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java +++ b/src/main/java/cn/octopusyan/alistgui/config/ObservableResourceBundleFactory.java @@ -1,5 +1,6 @@ package cn.octopusyan.alistgui.config; +import javafx.beans.binding.Bindings; import javafx.beans.binding.StringBinding; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; @@ -26,15 +27,6 @@ public class ObservableResourceBundleFactory { } public StringBinding getStringBinding(String key) { - return new StringBinding() { - { - bind(resourceBundleProperty); - } - - @Override - protected String computeValue() { - return getResourceBundle().getString(key); - } - }; + return Bindings.createStringBinding(() -> getResourceBundle().getString(key), resourceBundleProperty); } } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java b/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java index 17c45f5..c2caeb3 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/AboutController.java @@ -1,10 +1,10 @@ package cn.octopusyan.alistgui.controller; import cn.octopusyan.alistgui.base.BaseController; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.ConfigManager; -import cn.octopusyan.alistgui.view.alert.AlertUtil; import cn.octopusyan.alistgui.viewModel.AboutViewModule; -import javafx.fxml.FXML; +import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import org.slf4j.Logger; @@ -18,12 +18,22 @@ import org.slf4j.LoggerFactory; public class AboutController extends BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - @FXML public VBox aboutView; - @FXML public Label aListVersion; + @I18n(key = "about.alist.version") + public Label aListVersionLabel; + + @I18n(key = "about.app.version") + public Label appVersionLabel; + + @I18n(key = "about.app.update") + public Button checkAppVersion; + + @I18n(key = "about.alist.update") + public Button checkAListVersion; + @Override public VBox getRootPanel() { return aboutView; @@ -44,15 +54,12 @@ public class AboutController extends BaseController { aListVersion.textProperty().bindBidirectional(viewModel.aListVersionProperty()); } - @FXML public void checkAListUpdate() { viewModel.checkUpdate(ConfigManager.aList()); } - @FXML public void checkGuiUpdate() { - // TODO 检查 gui 版本 - AlertUtil.info("待开发。。。").show(); + viewModel.checkUpdate(ConfigManager.gui()); } } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/MainController.java b/src/main/java/cn/octopusyan/alistgui/controller/MainController.java index a345d1d..7e14417 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/MainController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/MainController.java @@ -2,13 +2,16 @@ package cn.octopusyan.alistgui.controller; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.AListManager; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.util.FxmlUtil; import cn.octopusyan.alistgui.viewModel.MainViewModel; -import javafx.fxml.FXML; +import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.fxml.FXMLLoader; import javafx.scene.control.Button; +import javafx.scene.control.MenuButton; import javafx.scene.control.MenuItem; import javafx.scene.control.ScrollPane; import javafx.scene.layout.VBox; @@ -25,19 +28,34 @@ import java.io.IOException; public class MainController extends BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - @FXML public VBox mainView; - @FXML public VBox logArea; - @FXML public ScrollPane logAreaSp; - @FXML + + @I18n(key = "main.status.label-stop") public Button statusLabel; - @FXML + + @I18n(key = "main.control.start") public Button startButton; - @FXML + + @I18n(key = "main.control.password") + public Button passwordButton; + + @I18n(key = "main.control.restart") + public Button restartButton; + + @I18n(key = "main.control.more") + public MenuButton moreButton; + + @I18n(key = "main.more.browser") public MenuItem browserButton; + @I18n(key = "main.more.open-config") + public MenuItem configButton; + + @I18n(key = "main.more.open-log") + public MenuItem logButton; + private PasswordController controller; @Override @@ -52,19 +70,18 @@ public class MainController extends BaseController { @Override public void initViewStyle() { + // 运行状态监听 + viewModel.runningProperty().addListener((_, _, running) -> { + resetStatus(running); + browserButton.disableProperty().set(!running); + }); } @Override public void initViewAction() { - viewModel.startBtnStyleCssProperty().bindContentBidirectional(startButton.getStyleClass()); - viewModel.statusLabelStyleCssProperty().bindContentBidirectional(statusLabel.getStyleClass()); - viewModel.startBtnTextProperty().bindBidirectional(startButton.textProperty()); - viewModel.statusLabelTextProperty().bindBidirectional(statusLabel.textProperty()); - viewModel.browserButtonDisableProperty().bindBidirectional(browserButton.disableProperty()); } // start button - @FXML public void start() { if (AListManager.isRunning()) { AListManager.stop(); @@ -74,7 +91,6 @@ public class MainController extends BaseController { } // password button - @FXML public void adminPassword() throws IOException { if (controller == null) { FXMLLoader load = FxmlUtil.load("admin-panel"); @@ -85,29 +101,43 @@ public class MainController extends BaseController { } // restart button - @FXML public void restart() { AListManager.restart(); } // more button - @FXML public void openInBrowser() { AListManager.openScheme(); } - @FXML public void openLogFolder() { AListManager.openLogFolder(); } - @FXML public void openConfig() { AListManager.openConfig(); } - private String getText(String key) { - return Context.getLanguageBinding(key).get(); + /** + * 根据运行状态改变按钮样式 + * + * @param running 运行状态 + */ + private void resetStatus(boolean running) { + String removeStyle = running ? "success" : "danger"; + String addStyle = running ? "danger" : "success"; + StringBinding button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}"); + StringBinding status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}"); + + Platform.runLater(() -> { + startButton.getStyleClass().remove(removeStyle); + startButton.getStyleClass().add(addStyle); + startButton.textProperty().bind(button); + + statusLabel.getStyleClass().remove(addStyle); + statusLabel.getStyleClass().add(removeStyle); + statusLabel.textProperty().bind(status); + }); } } diff --git a/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java b/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java index 64134b9..ccb5546 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/PasswordController.java @@ -4,12 +4,14 @@ import atlantafx.base.controls.Popover; import cn.hutool.core.swing.clipboard.ClipboardUtil; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.AListManager; import cn.octopusyan.alistgui.viewModel.AdminPanelViewModel; import javafx.beans.value.ChangeListener; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; @@ -23,20 +25,20 @@ import org.apache.commons.lang3.StringUtils; * @author octopus_yan */ public class PasswordController extends BaseController { - @FXML - private AnchorPane adminPanel; + public AnchorPane adminPanel; - @FXML + @I18n(key = "admin.pwd.toptip") + public Label toptip; + @I18n(key = "admin.pwd.user-field") + public Label usernameLabel; public TextField usernameField; @FXML public Button copyUsername; - @FXML + @I18n(key = "admin.pwd.pwd-field") + public Label passwordLabel; public PasswordField passwordField; - @FXML public Button refreshPassword; - @FXML public Button savePassword; - @FXML public Button copyPassword; private RootController root; diff --git a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java index 4f27e78..99c85e5 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java @@ -3,18 +3,19 @@ package cn.octopusyan.alistgui.controller; import atlantafx.base.controls.ModalPane; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.manager.SystemTrayManager; -import cn.octopusyan.alistgui.util.WindowsUtil; +import cn.octopusyan.alistgui.util.ViewUtil; import cn.octopusyan.alistgui.viewModel.RootViewModel; import com.gluonhq.emoji.EmojiData; import com.gluonhq.emoji.util.EmojiImageUtils; import javafx.application.Platform; import javafx.css.PseudoClass; -import javafx.fxml.FXML; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Button; +import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; @@ -31,27 +32,28 @@ import java.util.Locale; */ public class RootController extends BaseController { // 布局 - @FXML - private StackPane rootPane; - @FXML - private HBox windowHeader; - @FXML - private FontIcon alwaysOnTopIcon; - @FXML - private FontIcon minimizeIcon; - @FXML - private FontIcon closeIcon; + public StackPane rootPane; + public HBox windowHeader; + public FontIcon alwaysOnTopIcon; + public FontIcon minimizeIcon; + public FontIcon closeIcon; // 界面 - @FXML - private TabPane tabPane; + public TabPane tabPane; + + @I18n(key = "root.tab.main") + public Tab mainTab; + @I18n(key = "root.tab.setup") + public Tab setupTab; + @I18n(key = "root.tab.about") + public Tab aboutTab; // footer - @FXML + @I18n(key = "root.foot.doc") public Button document; - @FXML + @I18n(key = "root.foot.github") public Button github; - @FXML + @I18n(key = "root.foot.sponsor") public Button sponsor; private final ModalPane modalPane = new ModalPane(); @@ -94,6 +96,7 @@ public class RootController extends BaseController { sponsor.setGraphic(juice); }); + // 遮罩 getRootPanel().getChildren().add(modalPane); modalPane.setId("modalPane"); // reset side and transition to reuse a single modal pane between different examples @@ -126,22 +129,25 @@ public class RootController extends BaseController { getWindow().setAlwaysOnTop(newVal); }); - WindowsUtil.bindDragged(windowHeader); + ViewUtil.bindDragged(windowHeader); viewModel.currentViewIndexProperty().bind(tabPane.getSelectionModel().selectedIndexProperty()); } - @FXML public void openDocument() { String locale = Context.getCurrentLocale().equals(Locale.ENGLISH) ? "" : "zh/"; Context.openUrl(STR."https://alist.nn.ci/\{locale}"); } - @FXML public void openGithub() { Context.openUrl("https://github.com/alist-org/alist"); } + public void showTab(int index) { + if (index < 0 || index > 2) return; + tabPane.getSelectionModel().select(index); + } + public void showModal(Node node, boolean persistent) { modalPane.show(node); modalPane.setPersistent(persistent); diff --git a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java index 7f3e299..5e2f529 100644 --- a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java +++ b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java @@ -3,16 +3,15 @@ package cn.octopusyan.alistgui.controller; import atlantafx.base.theme.Theme; import cn.octopusyan.alistgui.base.BaseController; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.config.I18n; import cn.octopusyan.alistgui.enums.ProxySetup; import cn.octopusyan.alistgui.manager.ConfigManager; +import cn.octopusyan.alistgui.view.ProxySetupCell; import cn.octopusyan.alistgui.viewModel.SetupViewModel; import javafx.collections.FXCollections; import javafx.fxml.FXML; import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ComboBox; -import javafx.scene.control.TextField; +import javafx.scene.control.*; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.util.StringConverter; @@ -32,26 +31,24 @@ public class SetupController extends BaseController implements I @FXML public VBox setupView; - @FXML + @I18n(key = "setup.auto-start.label") public CheckBox autoStartCheckBox; - @FXML + @I18n(key = "setup.silent-startup.label") public CheckBox silentStartupCheckBox; - @FXML + @I18n(key = "setup.close-to-tray.label") public CheckBox closeToTrayCheckBox; - @FXML public ComboBox languageComboBox; - @FXML public ComboBox themeComboBox; - @FXML public ComboBox proxySetupComboBox; - @FXML public Pane proxySetupPane; - @FXML + @I18n(key = "setup.proxy.test") public Button proxyCheck; - @FXML public TextField proxyHost; - @FXML public TextField proxyPort; + @I18n(key = "setup.proxy.host") + public Label hostLabel; + @I18n(key = "setup.proxy.port") + public Label portLabel; @Override public VBox getRootPanel() { @@ -64,6 +61,9 @@ public class SetupController extends BaseController implements I themeComboBox.setItems(FXCollections.observableList(ConfigManager.THEME_LIST)); proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values()))); + proxySetupComboBox.setCellFactory(_ -> new ProxySetupCell()); + proxySetupComboBox.setButtonCell(new ProxySetupCell()); + themeComboBox.setConverter(new StringConverter<>() { @Override public String toString(Theme object) { @@ -82,6 +82,14 @@ public class SetupController extends BaseController implements I proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> { proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue)); proxyCheck.setVisible(!ProxySetup.NO_PROXY.equals(newValue)); + +// proxySetupComboBox.promptTextProperty().bind( +//// Bindings.createStringBinding( +//// () -> Context.getLanguageBinding(STR."proxy.setup.label.\{newValue.getName()}").get(), +//// Context.currentLocaleProperty() +//// ) +// Context.getLanguageBinding(STR."proxy.setup.label.\{newValue.getName()}") +// ); }); languageComboBox.getSelectionModel().select(ConfigManager.language()); @@ -103,7 +111,6 @@ public class SetupController extends BaseController implements I viewModel.proxySetupProperty().bind(proxySetupComboBox.getSelectionModel().selectedItemProperty()); } - @FXML public void proxyTest() { viewModel.proxyTest(); } diff --git a/src/main/java/cn/octopusyan/alistgui/enums/ProxySetup.java b/src/main/java/cn/octopusyan/alistgui/enums/ProxySetup.java index d0e119a..5ec896b 100644 --- a/src/main/java/cn/octopusyan/alistgui/enums/ProxySetup.java +++ b/src/main/java/cn/octopusyan/alistgui/enums/ProxySetup.java @@ -1,6 +1,7 @@ package cn.octopusyan.alistgui.enums; import cn.octopusyan.alistgui.config.Context; +import javafx.beans.binding.StringBinding; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -20,6 +21,10 @@ public enum ProxySetup { @Override public String toString() { - return Context.getLanguageBinding("proxy.setup.label." + getName()).getValue(); + return getBinding().get(); + } + + public StringBinding getBinding() { + return Context.getLanguageBinding(STR."proxy.setup.label.\{getName()}"); } } diff --git a/src/main/java/cn/octopusyan/alistgui/manager/AListManager.java b/src/main/java/cn/octopusyan/alistgui/manager/AListManager.java index 5312a06..9307628 100644 --- a/src/main/java/cn/octopusyan/alistgui/manager/AListManager.java +++ b/src/main/java/cn/octopusyan/alistgui/manager/AListManager.java @@ -205,7 +205,7 @@ public class AListManager { } var task = new CheckUpdateTask(ConfigManager.aList()); - task.onListen(new TaskListener.UpgradeUpgradeListener(task) { + task.onListen(new TaskListener.UpgradeListener(task) { @Override public void onChecked(boolean hasUpgrade, String version) { Platform.runLater(() -> showDownload(version)); diff --git a/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java b/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java index 966279f..8a1c939 100644 --- a/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java +++ b/src/main/java/cn/octopusyan/alistgui/manager/SystemTrayManager.java @@ -3,9 +3,10 @@ package cn.octopusyan.alistgui.manager; import cn.octopusyan.alistgui.Application; import cn.octopusyan.alistgui.config.Constants; import cn.octopusyan.alistgui.config.Context; -import cn.octopusyan.alistgui.util.WindowsUtil; +import cn.octopusyan.alistgui.util.ViewUtil; import cn.octopusyan.alistgui.view.PopupMenu; import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.scene.control.MenuItem; import javafx.stage.Stage; import lombok.extern.slf4j.Slf4j; @@ -47,7 +48,7 @@ public class SystemTrayManager { public static void icon(String path) { if (trayIcon == null) return; - icon(WindowsUtil.class.getResource(path)); + icon(ViewUtil.class.getResource(path)); } public static void icon(URL url) { @@ -76,7 +77,7 @@ public class SystemTrayManager { return; } - initTrayIcon(); + initTrayIcon(AListManager.isRunning()); try { if (!isShowing()) @@ -95,11 +96,12 @@ public class SystemTrayManager { //========================================={ private }=========================================== - private static void initTrayIcon() { + private static void initTrayIcon(boolean running) { if (trayIcon != null) return; // 系统托盘图标 - Image image = Toolkit.getDefaultToolkit().getImage(WindowsUtil.class.getResource("/assets/logo-disabled.png")); + URL resource = ViewUtil.class.getResource(STR."/assets/logo\{running ? "" : "-disabled"}.png"); + Image image = Toolkit.getDefaultToolkit().getImage(resource); trayIcon = new TrayIcon(image); // 设置图标尺寸自动适应 @@ -129,7 +131,7 @@ public class SystemTrayManager { if (event.isPopupTrigger()) { // 弹出菜单 Platform.runLater(() -> { - initPopupMenu(); + initPopupMenu(running); popupMenu.show(event); }); } else if (event.getButton() == MouseEvent.BUTTON1) { @@ -143,15 +145,19 @@ public class SystemTrayManager { /** * 构建托盘菜单 */ - private static void initPopupMenu() { + private static void initPopupMenu(boolean running) { if (popupMenu != null) return; - MenuItem start = PopupMenu.menuItem(getString("main.control.start"), _ -> AListManager.openScheme()); - MenuItem browser = PopupMenu.menuItem(getString("main.more.browser"), _ -> AListManager.openScheme()); - browser.setDisable(true); + MenuItem start = PopupMenu.menuItem( + getStringBinding(STR."main.control.\{running ? "stop" : "start"}"), + _ -> AListManager.openScheme() + ); + MenuItem browser = PopupMenu.menuItem(getStringBinding("main.more.browser"), _ -> AListManager.openScheme()); + browser.setDisable(!running); AListManager.runningProperty().addListener((_, _, newValue) -> { - start.setText(getString(STR."main.control.\{newValue ? "stop" : "start"}")); + start.textProperty().unbind(); + start.textProperty().bind(getStringBinding(STR."main.control.\{newValue ? "stop" : "start"}")); browser.disableProperty().set(!newValue); toolTip(STR."AList \{newValue ? "running" : "stopped"}"); icon(STR."/assets/logo\{newValue ? "" : "-disabled"}.png"); @@ -168,19 +174,19 @@ public class SystemTrayManager { AListManager.start(); } }) - .addItem(getString("main.control.restart"), _ -> AListManager.restart()) - .addMenu(getString("main.control.more"), browser, - PopupMenu.menuItem(getString("main.more.open-config"), _ -> AListManager.openConfig()), - PopupMenu.menuItem(getString("main.more.open-log"), _ -> AListManager.openLogFolder())) + .addItem(getStringBinding("main.control.restart"), _ -> AListManager.restart()) + .addMenu(getStringBinding("main.control.more"), browser, + PopupMenu.menuItem(getStringBinding("main.more.open-config"), _ -> AListManager.openConfig()), + PopupMenu.menuItem(getStringBinding("main.more.open-log"), _ -> AListManager.openLogFolder())) .addSeparator() .addExitItem(); } - private static String getString(String key) { - return Context.getLanguageBinding(key).get(); + private static StringBinding getStringBinding(String key) { + return Context.getLanguageBinding(key); } private static Stage stage() { - return WindowsUtil.getStage(); + return ViewUtil.getStage(); } -} +} \ No newline at end of file diff --git a/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java b/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java index a9bf845..b6e96d7 100644 --- a/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java +++ b/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java @@ -18,7 +18,7 @@ public class GuiConfig { private Boolean autoStart = false; private Boolean silentStartup = false; - private Boolean closeToTray = true; + private Boolean closeToTray = false; @JsonProperty("proxy") private ProxyInfo proxyInfo; @JsonProperty("proxy.testUrl") diff --git a/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java b/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java index 0dac232..49a332a 100644 --- a/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java +++ b/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java @@ -10,18 +10,12 @@ import lombok.Data; @Data public class Gui implements UpgradeApp { @JsonIgnore - private final String owner = "alist-org"; + private final String owner = "octopusYan"; + @JsonIgnore - private final String repo = "alist"; + private final String repo = "alist-gui"; + + private String releaseFile = "alist-gui-windows-nojre.zip"; - private String releaseFile = "alist-gui-{version}-windows.zip"; private String version = PropertiesUtils.getInstance().getProperty("app.version"); - - public String getReleaseFile() { - return getReleaseFile(version); - } - - public String getReleaseFile(String version) { - return releaseFile.replace("{version}", version); - } } diff --git a/src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java b/src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java index 6a8104e..b15734a 100644 --- a/src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java +++ b/src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java @@ -1,7 +1,6 @@ package cn.octopusyan.alistgui.task; import cn.octopusyan.alistgui.base.BaseTask; -import cn.octopusyan.alistgui.config.Constants; import cn.octopusyan.alistgui.manager.http.HttpUtil; import lombok.extern.slf4j.Slf4j; @@ -13,10 +12,12 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class DownloadTask extends BaseTask { private final String downloadUrl; + private final String savePath; - public DownloadTask(String downloadUrl) { + public DownloadTask(String downloadUrl, String savePath) { super(STR."Download \{downloadUrl}"); this.downloadUrl = downloadUrl; + this.savePath = savePath; } public void onListen(DownloadListener listener) { @@ -27,7 +28,7 @@ public class DownloadTask extends BaseTask { protected void task() throws Exception { HttpUtil.getInstance().download( downloadUrl, - Constants.BIN_DIR_PATH, + savePath, listener instanceof DownloadListener ? ((DownloadListener) listener)::onProgress : null ); } diff --git a/src/main/java/cn/octopusyan/alistgui/task/listener/TaskListener.java b/src/main/java/cn/octopusyan/alistgui/task/listener/TaskListener.java index 03088e4..508574a 100644 --- a/src/main/java/cn/octopusyan/alistgui/task/listener/TaskListener.java +++ b/src/main/java/cn/octopusyan/alistgui/task/listener/TaskListener.java @@ -89,8 +89,8 @@ public abstract class TaskListener implements BaseTask.Listener { /** * 检查更新监听默认实现 */ - public static abstract class UpgradeUpgradeListener extends TaskListener implements CheckUpdateTask.UpgradeListener { - public UpgradeUpgradeListener(BaseTask task) { + public static abstract class UpgradeListener extends TaskListener implements CheckUpdateTask.UpgradeListener { + public UpgradeListener(BaseTask task) { super(task); } diff --git a/src/main/java/cn/octopusyan/alistgui/util/DownloadUtil.java b/src/main/java/cn/octopusyan/alistgui/util/DownloadUtil.java index 406c67e..d74543d 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/DownloadUtil.java +++ b/src/main/java/cn/octopusyan/alistgui/util/DownloadUtil.java @@ -5,8 +5,11 @@ import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.ZipUtil; import cn.octopusyan.alistgui.config.Constants; +import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.controller.RootController; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.model.upgrade.AList; +import cn.octopusyan.alistgui.model.upgrade.Gui; import cn.octopusyan.alistgui.model.upgrade.UpgradeApp; import cn.octopusyan.alistgui.task.DownloadTask; import cn.octopusyan.alistgui.task.listener.TaskListener; @@ -24,7 +27,6 @@ import java.util.zip.ZipFile; @Slf4j public class DownloadUtil { - /** * 下载文件 * @@ -32,12 +34,19 @@ public class DownloadUtil { * @param version 下载版本 */ public static DownloadTask startDownload(UpgradeApp app, String version, Runnable runnable) { - var task = new DownloadTask(app.getDownloadUrl(version)); + var parentPath = switch (app) { + case AList _ -> Constants.BIN_DIR_PATH; + case Gui _ -> Constants.DATA_DIR_PATH; + default -> throw new IllegalStateException(STR."Unexpected value: \{app}"); + }; + var task = new DownloadTask(app.getDownloadUrl(version), parentPath); task.onListen(new TaskListener.DownloadListener(task) { @Override public void onRunning() { // 不展示进度条 + RootController root = (RootController) Context.getControllers().get(RootController.class.getSimpleName()); + root.showTab(0); } @Override @@ -64,6 +73,11 @@ public class DownloadUtil { path = StrUtil.replace(path, "*", "_"); } + // 打包后文件都在alist-gui文件夹下,解压时去掉 + if (app instanceof Gui) { + path = path.replaceFirst(Constants.APP_NAME, ""); + } + final File outItemFile = FileUtil.file(parentPath, path); if (zipEntry.isDirectory()) { // 目录 diff --git a/src/main/java/cn/octopusyan/alistgui/util/FxmlUtil.java b/src/main/java/cn/octopusyan/alistgui/util/FxmlUtil.java index de5c07d..084dc3b 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/FxmlUtil.java +++ b/src/main/java/cn/octopusyan/alistgui/util/FxmlUtil.java @@ -25,7 +25,7 @@ public class FxmlUtil { FxmlUtil.class.getResource(prefix + name + suffix), bundle, new JavaFXBuilderFactory(), - null, + Context.getControlFactory(), StandardCharsets.UTF_8 ); } diff --git a/src/main/java/cn/octopusyan/alistgui/util/Registry.java b/src/main/java/cn/octopusyan/alistgui/util/Registry.java index 33135ba..f370e9d 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/Registry.java +++ b/src/main/java/cn/octopusyan/alistgui/util/Registry.java @@ -43,7 +43,6 @@ public class Registry { RESTORE, SAVE, UNLOAD, - ; } public enum Root { @@ -75,6 +74,5 @@ public class Registry { REG_LINK, REG_FULL_RESOURCE_DESCRIPTOR, REG_EXPAND_SZ, - ; } } diff --git a/src/main/java/cn/octopusyan/alistgui/util/WindowsUtil.java b/src/main/java/cn/octopusyan/alistgui/util/ViewUtil.java similarity index 98% rename from src/main/java/cn/octopusyan/alistgui/util/WindowsUtil.java rename to src/main/java/cn/octopusyan/alistgui/util/ViewUtil.java index 33c5479..18f9d92 100644 --- a/src/main/java/cn/octopusyan/alistgui/util/WindowsUtil.java +++ b/src/main/java/cn/octopusyan/alistgui/util/ViewUtil.java @@ -13,7 +13,7 @@ import java.util.Map; * * @author octopus_yan */ -public class WindowsUtil { +public class ViewUtil { // 获取系统缩放比 public static final double scaleX = Screen.getPrimary().getOutputScaleX(); public static final double scaleY = Screen.getPrimary().getOutputScaleY(); diff --git a/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java b/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java index bf15bd9..9945079 100644 --- a/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java +++ b/src/main/java/cn/octopusyan/alistgui/view/PopupMenu.java @@ -2,8 +2,9 @@ package cn.octopusyan.alistgui.view; import atlantafx.base.controls.CaptionMenuItem; import cn.octopusyan.alistgui.config.Constants; -import cn.octopusyan.alistgui.util.WindowsUtil; +import cn.octopusyan.alistgui.util.ViewUtil; import javafx.application.Platform; +import javafx.beans.binding.StringBinding; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; @@ -47,6 +48,12 @@ public class PopupMenu { return addItem(new MenuItem(label), handler); } + public PopupMenu addItem(StringBinding bind, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(bind); + return addItem(menuItem, handler); + } + public PopupMenu addItem(MenuItem node, EventHandler handler) { node.setOnAction(handler); return addItem(node); @@ -68,6 +75,12 @@ public class PopupMenu { return addMenu(new Menu(label), items); } + public PopupMenu addMenu(StringBinding label, MenuItem... items) { + Menu menu = new Menu(); + menu.textProperty().bind(label); + return addMenu(menu, items); + } + public PopupMenu addMenu(Menu menu, MenuItem... items) { menu.getItems().addAll(items); return addItem(menu); @@ -102,8 +115,8 @@ public class PopupMenu { root.hide(); root.show(utilityStage, - event.getX() / WindowsUtil.scaleX, - event.getY() / WindowsUtil.scaleY + event.getX() / ViewUtil.scaleX, + event.getY() / ViewUtil.scaleY ); // 获取焦点 (失去焦点隐藏自身) root.requestFocus(); @@ -114,4 +127,11 @@ public class PopupMenu { menuItem.setOnAction(handler); return menuItem; } + + public static MenuItem menuItem(StringBinding stringBinding, EventHandler handler) { + MenuItem menuItem = new MenuItem(); + menuItem.textProperty().bind(stringBinding); + menuItem.setOnAction(handler); + return menuItem; + } } diff --git a/src/main/java/cn/octopusyan/alistgui/view/ProxySetupCell.java b/src/main/java/cn/octopusyan/alistgui/view/ProxySetupCell.java new file mode 100644 index 0000000..b15c26f --- /dev/null +++ b/src/main/java/cn/octopusyan/alistgui/view/ProxySetupCell.java @@ -0,0 +1,23 @@ +package cn.octopusyan.alistgui.view; + +import cn.octopusyan.alistgui.enums.ProxySetup; +import javafx.scene.control.ListCell; + +/** + * ProxySetup I18n Cell + * + * @author octopus_yan + */ +public class ProxySetupCell extends ListCell { + + @Override + protected void updateItem(ProxySetup item, boolean empty) { + super.updateItem(item, empty); + textProperty().unbind(); + if (empty || item == null) { + setText(""); + } else { + textProperty().bind(item.getBinding()); + } + } +} diff --git a/src/main/java/cn/octopusyan/alistgui/view/alert/builder/DefaultBuilder.java b/src/main/java/cn/octopusyan/alistgui/view/alert/builder/DefaultBuilder.java index fcf4317..e1dacc0 100644 --- a/src/main/java/cn/octopusyan/alistgui/view/alert/builder/DefaultBuilder.java +++ b/src/main/java/cn/octopusyan/alistgui/view/alert/builder/DefaultBuilder.java @@ -2,7 +2,7 @@ package cn.octopusyan.alistgui.view.alert.builder; import cn.octopusyan.alistgui.base.BaseBuilder; import cn.octopusyan.alistgui.config.Context; -import cn.octopusyan.alistgui.util.WindowsUtil; +import cn.octopusyan.alistgui.util.ViewUtil; import javafx.scene.Node; import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; @@ -26,9 +26,9 @@ public class DefaultBuilder extends BaseBuilder> { DialogPane dialogPane = dialog.getDialogPane(); dialogPane.getScene().setFill(Color.TRANSPARENT); - WindowsUtil.bindDragged(dialogPane); - WindowsUtil.bindShadow(dialogPane); - WindowsUtil.getStage(dialogPane).initStyle(StageStyle.TRANSPARENT); + ViewUtil.bindDragged(dialogPane); + ViewUtil.bindShadow(dialogPane); + ViewUtil.getStage(dialogPane).initStyle(StageStyle.TRANSPARENT); dialogPane.getButtonTypes().add(new ButtonType( Context.getLanguageBinding("label.cancel").get(), diff --git a/src/main/java/cn/octopusyan/alistgui/viewModel/AboutViewModule.java b/src/main/java/cn/octopusyan/alistgui/viewModel/AboutViewModule.java index c5dbdef..c36fda3 100644 --- a/src/main/java/cn/octopusyan/alistgui/viewModel/AboutViewModule.java +++ b/src/main/java/cn/octopusyan/alistgui/viewModel/AboutViewModule.java @@ -1,14 +1,19 @@ package cn.octopusyan.alistgui.viewModel; +import cn.octopusyan.alistgui.Application; import cn.octopusyan.alistgui.base.BaseViewModel; +import cn.octopusyan.alistgui.config.Constants; import cn.octopusyan.alistgui.config.Context; +import cn.octopusyan.alistgui.manager.AListManager; import cn.octopusyan.alistgui.manager.ConfigManager; import cn.octopusyan.alistgui.manager.ConsoleLog; import cn.octopusyan.alistgui.model.upgrade.AList; +import cn.octopusyan.alistgui.model.upgrade.Gui; import cn.octopusyan.alistgui.model.upgrade.UpgradeApp; import cn.octopusyan.alistgui.task.CheckUpdateTask; import cn.octopusyan.alistgui.task.listener.TaskListener; import cn.octopusyan.alistgui.util.DownloadUtil; +import cn.octopusyan.alistgui.util.ProcessesUtil; import cn.octopusyan.alistgui.view.alert.AlertUtil; import cn.octopusyan.alistgui.view.alert.builder.AlertBuilder; import javafx.application.Platform; @@ -61,52 +66,22 @@ public class AboutViewModule extends BaseViewModel { * 检查更新 */ public void checkUpdate(UpgradeApp app) { - // 检查任务 - startUpgrade(app, () -> { - // 判断 检查的应用 - boolean tag = app instanceof AList; - - boolean upgrade = tag ? aListUpgrade.get() : guiUpgrade.get(); - String version = tag ? aListVersion.get() : guiVersion.get(); - String newVersion = tag ? aListNewVersion.get() : guiNewVersion.get(); - String title = Context.getLanguageBinding(STR."about.\{tag ? "alist" : "app"}.update").getValue(); - String currentLabel = Context.getLanguageBinding("update.current").get(); - String newLabel = Context.getLanguageBinding("update.remote").get(); - String header = Context.getLanguageBinding(STR."update.upgrade.\{upgrade ? "new" : "not"}").get(); - - // 版本检查消息 - String msg = STR."\{app.getRepo()}\{upgrade ? "" : STR." \{version}"} \{header} \{upgrade ? newVersion : ""}"; - log.info(msg); - ConsoleLog.info(msg); - - // 弹窗 - AlertBuilder builder = upgrade ? AlertUtil.confirm() : AlertUtil.info(); - builder.title(title) - .header(header) - .content(STR.""" - \{currentLabel} : \{version} - \{newLabel} : \{newVersion} - """) - .show(() -> { - // 可升级,且点击了确定后,开始下载任务 - if (upgrade) - DownloadUtil.startDownload(app, newVersion, () -> { - // 下载完成后,解压并删除文件 - DownloadUtil.unzip(app); - // 设置应用版本 - Platform.runLater(() -> aListVersion.setValue(aListNewVersion.getValue())); - }).execute(); - }); - }); + startUpgrade(app, () -> onChecked(app)); } + /** + * 开始检查更新 + * + * @param app 更新的应用 + * @param runnable 检查后执行的任务 + */ private void startUpgrade(UpgradeApp app, Runnable runnable) { // 检查更新的任务 var task = new CheckUpdateTask(app); // 任务监听 - task.onListen(new TaskListener.UpgradeUpgradeListener(task) { + task.onListen(new TaskListener.UpgradeListener(task) { @Override protected void onSucceed() { @@ -135,4 +110,62 @@ public class AboutViewModule extends BaseViewModel { // 执行任务 task.execute(); } + + + private void onChecked(UpgradeApp app) { + // 判断 检查的应用 + boolean tag = app instanceof AList; + + boolean upgrade = tag ? aListUpgrade.get() : guiUpgrade.get(); + String version = tag ? aListVersion.get() : guiVersion.get(); + String newVersion = tag ? aListNewVersion.get() : guiNewVersion.get(); + String title = Context.getLanguageBinding(STR."about.\{tag ? "alist" : "app"}.update").getValue(); + String currentLabel = Context.getLanguageBinding("update.current").get(); + String newLabel = Context.getLanguageBinding("update.remote").get(); + String header = Context.getLanguageBinding(STR."update.upgrade.\{upgrade ? "new" : "not"}").get(); + + // 版本检查消息 + String msg = STR."\{app.getRepo()}\{upgrade ? "" : STR." \{version}"} \{header} \{upgrade ? newVersion : ""}"; + log.info(msg); + ConsoleLog.info(msg); + + // 弹窗 + AlertBuilder builder = upgrade ? AlertUtil.confirm() : AlertUtil.info(); + builder.title(title) + .header(header) + .content(STR.""" + \{currentLabel} : \{version} + \{newLabel} : \{newVersion} + """) + .show(() -> { + // 可升级,且点击了确定后,开始下载任务 + if (upgrade) + DownloadUtil.startDownload(app, newVersion, () -> { + + // 下载完成后,解压并删除文件 + DownloadUtil.unzip(app); + + // 解压后 + Platform.runLater(() -> { + switch (app) { + case AList _ -> { + // 设置应用版本 + aListVersion.setValue(aListNewVersion.getValue()); + AListManager.restart(); + } + case Gui _ -> { + log.info(STR."guiNewVersion => \{guiNewVersion.get()}"); + // 重启 + Platform.setImplicitExit(true); + Application.getPrimaryStage().close(); + + ProcessesUtil.init(Constants.DATA_DIR_PATH).exec(STR."\{Constants.APP_NAME}.exe"); + } + default -> throw new IllegalStateException(STR."Unexpected value: \{app}"); + } + }); + + }).execute(); + }); + } } diff --git a/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java b/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java index 17fcf9e..1236429 100644 --- a/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java +++ b/src/main/java/cn/octopusyan/alistgui/viewModel/MainViewModel.java @@ -1,11 +1,9 @@ package cn.octopusyan.alistgui.viewModel; import cn.octopusyan.alistgui.base.BaseViewModel; -import cn.octopusyan.alistgui.config.Context; import cn.octopusyan.alistgui.manager.AListManager; -import javafx.application.Platform; -import javafx.beans.property.*; -import javafx.collections.FXCollections; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; /** * 主界面VM @@ -13,56 +11,14 @@ import javafx.collections.FXCollections; * @author octopus_yan */ public class MainViewModel extends BaseViewModel { - private final ListProperty startBtnStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final StringProperty startBtnText = new SimpleStringProperty(); - private final ListProperty statusLabelStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList()); - private final StringProperty statusLabelText = new SimpleStringProperty(); - private final BooleanProperty browserButtonDisable = new SimpleBooleanProperty(); private final BooleanProperty running = new SimpleBooleanProperty(); public MainViewModel() { - running.addListener((_, _, running) -> { - resetStatus(running); - browserButtonDisable.set(!running); - }); // 先添加监听再绑定,解决切换locale后,界面状态显示错误的问题 running.bind(AListManager.runningProperty()); } - public ListProperty startBtnStyleCssProperty() { - return startBtnStyleCss; - } - - public StringProperty startBtnTextProperty() { - return startBtnText; - } - - public ListProperty statusLabelStyleCssProperty() { - return statusLabelStyleCss; - } - - public StringProperty statusLabelTextProperty() { - return statusLabelText; - } - - public BooleanProperty browserButtonDisableProperty() { - return browserButtonDisable; - } - - public void resetStatus(boolean running) { - String removeStyle = running ? "success" : "danger"; - String addStyle = running ? "danger" : "success"; - String button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}").get(); - String status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}").get(); - - Platform.runLater(() -> { - startBtnStyleCss.remove(removeStyle); - startBtnStyleCss.add(addStyle); - startBtnText.set(button); - - statusLabelStyleCss.remove(addStyle); - statusLabelStyleCss.add(removeStyle); - statusLabelText.set(status); - }); + public BooleanProperty runningProperty() { + return running; } } diff --git a/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java b/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java index bb5f582..c910fcc 100644 --- a/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java +++ b/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java @@ -36,7 +36,6 @@ public class SetupViewModel extends BaseViewModel { public SetupViewModel() { - theme.bindBidirectional(Context.themeProperty()); theme.addListener((_, _, newValue) -> ConfigManager.theme(newValue)); silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue)); autoStart.addListener((_, _, newValue) -> { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a63aa58..cc5a405 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,3 @@ app.name=${project.name} app.title=AList GUI -app.version=${project.version} \ No newline at end of file +app.version=v${project.version} \ No newline at end of file diff --git a/src/main/resources/fxml/about-view.fxml b/src/main/resources/fxml/about-view.fxml index be018a1..0b9c817 100644 --- a/src/main/resources/fxml/about-view.fxml +++ b/src/main/resources/fxml/about-view.fxml @@ -22,11 +22,11 @@ - -