diff --git a/pom.xml b/pom.xml
index 2728439..01ca524 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,21 +18,21 @@
AList windows gui
- 17
- 17
- 17
+ 21
+ 21
+ 21
UTF-8
UTF-8
5.10.0
- 17.0.6
+ 21.0.4
2.0.16
1.4.14
5.8.32
3.16.0
-
1.4.0
1.18.32
+ 2.15.4
12.3.1
1.0.1
@@ -50,6 +50,7 @@
${javafx.version}
+
io.github.mkpaz
atlantafx-base
@@ -127,7 +128,7 @@
com.fasterxml.jackson.dataformat
jackson-dataformat-yaml
- 2.15.4
+ ${jackson.version}
@@ -183,8 +184,9 @@
maven-compiler-plugin
3.13.0
-
- 17
+
+ 21
+ --enable-preview
@@ -196,11 +198,45 @@
exe
dll
- ttf
+ scss
+
+
+ us.hebi.sass
+ sass-cli-maven-plugin
+ 1.0.3
+
+ 1.78.0
+
+
+ ${project.basedir}/src/main/resources/css/root.scss:${project.basedir}/target/classes/css/root.css
+
+
+ ${project.basedir}/src/main/resources/css/root-view.scss:${project.basedir}/target/classes/css/root-view.css
+
+
+ ${project.basedir}/src/main/resources/css/main-view.scss:${project.basedir}/target/classes/css/main-view.css
+
+
+ ${project.basedir}/src/main/resources/css/setup-view.scss:${project.basedir}/target/classes/css/setup-view.css
+
+ --no-source-map
+
+
+
+
+ sass-exec
+ generate-resources
+
+ run
+
+
+
+
+
org.openjfx
javafx-maven-plugin
@@ -210,8 +246,7 @@
default-cli
- cn.octopusyan.alistgui/cn.octopusyan.alistgui.AppLuncher
-
+ cn.octopusyan.alistgui/cn.octopusyan.alistgui.AppLauncher
launcher
app
app
@@ -223,13 +258,14 @@
+
io.github.fvarrui
javapackager
1.7.7-SNAPSHOT
true
- cn.octopusyan.alistgui.AppLuncher
+ cn.octopusyan.alistgui.AppLauncher
false
diff --git a/src/main/java/cn/octopusyan/alistgui/base/BaseTask.java b/src/main/java/cn/octopusyan/alistgui/base/BaseTask.java
new file mode 100644
index 0000000..13e87e4
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/base/BaseTask.java
@@ -0,0 +1,50 @@
+package cn.octopusyan.alistgui.base;
+
+import cn.octopusyan.alistgui.manager.thread.ThreadPoolManager;
+import javafx.application.Platform;
+import javafx.concurrent.Task;
+
+/**
+ * @author octopus_yan
+ */
+public abstract class BaseTask extends Task {
+ private final ThreadPoolManager Executor = ThreadPoolManager.getInstance();
+
+ @Override
+ protected Void call() throws Exception {
+ task();
+ return null;
+ }
+
+ protected void runLater(Runnable runnable) {
+ Platform.runLater(runnable);
+ }
+
+ protected abstract void task() throws Exception;
+
+ public void onListen(Listener listener) {
+ if (listener == null) return;
+
+ setOnRunning(_ -> listener.onRunning());
+ setOnCancelled(_ -> listener.onCancelled());
+ setOnFailed(_ -> listener.onFailed(getException()));
+ setOnSucceeded(_ -> listener.onSucceeded());
+ }
+
+ public void execute() {
+ Executor.execute(this);
+ }
+
+ public interface Listener {
+ default void onRunning() {
+ }
+
+ default void onCancelled() {
+ }
+
+ default void onFailed(Throwable throwable) {
+ }
+
+ void onSucceeded();
+ }
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/config/ConfigManager.java b/src/main/java/cn/octopusyan/alistgui/config/ConfigManager.java
deleted file mode 100644
index 4c155a6..0000000
--- a/src/main/java/cn/octopusyan/alistgui/config/ConfigManager.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package cn.octopusyan.alistgui.config;
-
-import cn.hutool.core.lang.PatternPool;
-import cn.hutool.core.util.NumberUtil;
-import cn.octopusyan.alistgui.enums.ProxySetup;
-import cn.octopusyan.alistgui.manager.http.HttpUtil;
-import cn.octopusyan.alistgui.model.GuiConfig;
-import cn.octopusyan.alistgui.model.ProxyInfo;
-import org.apache.commons.lang3.LocaleUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.regex.Matcher;
-
-/**
- * 客户端设置
- *
- * @author octopus_yan@foxmail.com
- */
-public class ConfigManager {
- private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
- public static final Locale DEFAULT_LANGUAGE = Locale.CHINESE;
- private static GuiConfig guiConfig;
-
- public static void load() {
- try {
- guiConfig = GuiConfig.getInstance();
- } catch (IOException e) {
- logger.error("load config error", e);
- }
- }
-
- public static boolean hasProxy() {
- if (guiConfig == null)
- return false;
- ProxyInfo proxyInfo = guiConfig.getProxyInfo();
- return proxyInfo != null
- && StringUtils.isNoneEmpty(proxyInfo.getHost())
- && StringUtils.isNoneEmpty(proxyInfo.getPort())
- && Integer.parseInt(proxyInfo.getPort()) > 0;
- }
-
- public static ProxyInfo getProxyInfo() {
- return guiConfig.getProxyInfo();
- }
-
- public static String proxyHost() {
- return guiConfig.getProxyInfo().getHost();
- }
-
- public static void proxyHost(String host) {
- final Matcher matcher = PatternPool.IPV4.matcher(host);
- if (matcher.matches()) {
- guiConfig.getProxyInfo().setHost(host);
- }
- }
-
- public static String proxyPort() {
- return guiConfig.getProxyInfo().getPort();
- }
-
- public static int getProxyPort() {
- return Integer.parseInt(guiConfig.getProxyInfo().getPort());
- }
-
- public static void proxyPort(String port) {
- if (NumberUtil.isNumber(port))
- guiConfig.getProxyInfo().setPort(port);
- }
-
- public static Locale language() {
- String language = guiConfig.getLanguage();
- return LocaleUtils.toLocale(Optional.ofNullable(language).orElse(DEFAULT_LANGUAGE.toString()));
- }
-
- public static void language(Locale locale) {
- guiConfig.setLanguage(locale.toString());
- }
-
- public static boolean autoStart() {
- return guiConfig.getAutoStart();
- }
-
- public static void autoStart(Boolean autoStart) {
- guiConfig.setAutoStart(autoStart);
- }
-
- public static ProxySetup proxySetup() {
- return ProxySetup.valueOf(StringUtils.upperCase(guiConfig.getProxySetup()));
- }
-
- public static void proxySetup(ProxySetup setup) {
- guiConfig.setProxySetup(setup.getName());
-
- if (!ProxySetup.NO_PROXY.equals(setup) && hasProxy()) {
- HttpUtil.getInstance().proxy(setup, ConfigManager.getProxyInfo());
- }
- }
-
- public static boolean silentStartup() {
- return guiConfig.getSilentStartup();
- }
-
- public static void silentStartup(Boolean startup) {
- guiConfig.setSilentStartup(startup);
- }
-
- public static String aListVersion() {
- return guiConfig.getAListVersion();
- }
-
- public static void aListVersion(String version) {
- guiConfig.setAListVersion(version);
- }
-
- public static void save() {
- try {
- guiConfig.save();
- } catch (IOException e) {
- logger.error("save config error", e);
- }
- }
-}
diff --git a/src/main/java/cn/octopusyan/alistgui/config/AppConstant.java b/src/main/java/cn/octopusyan/alistgui/config/Constants.java
similarity index 57%
rename from src/main/java/cn/octopusyan/alistgui/config/AppConstant.java
rename to src/main/java/cn/octopusyan/alistgui/config/Constants.java
index 95ab185..245eb4c 100644
--- a/src/main/java/cn/octopusyan/alistgui/config/AppConstant.java
+++ b/src/main/java/cn/octopusyan/alistgui/config/Constants.java
@@ -10,13 +10,15 @@ import java.nio.file.Paths;
*
* @author octopus_yan@foxmail.com
*/
-public class AppConstant {
+public class Constants {
public static final String APP_TITLE = PropertiesUtils.getInstance().getProperty("app.title");
public static final String APP_NAME = PropertiesUtils.getInstance().getProperty("app.name");
public static final String APP_VERSION = PropertiesUtils.getInstance().getProperty("app.version");
public static final String DATA_DIR_PATH = Paths.get(".").toFile().getAbsolutePath();
+ public static final String BIN_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}bin";
+ public static final String UPGRADE_PATH = STR."\{BIN_DIR_PATH}\{File.separator}upgrade.yaml";
public static final String TMP_DIR_PATH = System.getProperty("java.io.tmpdir") + APP_NAME;
- public static final String CONFIG_DIR_PATH = DATA_DIR_PATH + File.separator + "config";
- public static final String GUI_CONFIG_PATH = CONFIG_DIR_PATH + File.separator + "gui.yaml";
- public static final String BAK_FILE_PATH = AppConstant.TMP_DIR_PATH + File.separator + "bak";
+ public static final String CONFIG_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}config";
+ public static final String GUI_CONFIG_PATH = STR."\{CONFIG_DIR_PATH}\{File.separator}gui.yaml";
+ public static final String BAK_FILE_PATH = STR."\{Constants.TMP_DIR_PATH}\{File.separator}bak";
}
diff --git a/src/main/java/cn/octopusyan/alistgui/config/Context.java b/src/main/java/cn/octopusyan/alistgui/config/Context.java
index cf14ca4..dca5cee 100644
--- a/src/main/java/cn/octopusyan/alistgui/config/Context.java
+++ b/src/main/java/cn/octopusyan/alistgui/config/Context.java
@@ -65,14 +65,17 @@ public class Context {
// 获取控制工厂
public static Callback, Object> getControlFactory() {
return type -> {
- if (type.equals(RootController.class)) {
- return new RootController();
- } else if (type.equals(MainController.class)) {
- return new MainController();
- } else if (type.equals(SetupController.class)) {
- return new SetupController();
+ try {
+ return switch (type.getDeclaredConstructor().newInstance()) {
+ case RootController root -> root;
+ case MainController main -> main;
+ case SetupController setup -> setup;
+ default -> throw new IllegalStateException(STR."Unexpected value: \{type}");
+ };
+ } catch (Exception e) {
+ log.error("", e);
+ return null;
}
- throw new IllegalStateException("Unexpected value: " + type);
};
}
@@ -130,15 +133,13 @@ public class Context {
* 初始化 语言
*/
private static void initI18n() {
- currentLocaleProperty().addListener((observable, oldValue, newValue) -> {
- Platform.runLater(() -> {
- try {
- loadScene();
- } catch (IOException e) {
- log.error("", e);
- }
- });
- });
+ currentLocaleProperty().addListener((_, _, _) -> Platform.runLater(() -> {
+ try {
+ loadScene();
+ } catch (IOException e) {
+ log.error("", e);
+ }
+ }));
}
/**
diff --git a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java
index ae4ff99..408b5d7 100644
--- a/src/main/java/cn/octopusyan/alistgui/controller/RootController.java
+++ b/src/main/java/cn/octopusyan/alistgui/controller/RootController.java
@@ -47,6 +47,7 @@ public class RootController extends BaseController {
public Button github;
@FXML
public Button sponsor;
+
/**
* 获取根布局
*
@@ -71,12 +72,19 @@ public class RootController extends BaseController {
@Override
public void initViewStyle() {
// 设置图标
- ImageView book = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("book").get(), 25);
- document.setGraphic(book);
- ImageView githubIcon = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("cat").get(), 25);
- github.setGraphic(githubIcon);
- ImageView juice = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("tropical_drink").get(), 25);
- sponsor.setGraphic(juice);
+ EmojiData.emojiFromShortName("book").ifPresent(icon -> {
+ ImageView book = EmojiImageUtils.emojiView(icon, 25);
+ document.setGraphic(book);
+ });
+ EmojiData.emojiFromShortName("cat").ifPresent(icon -> {
+ ImageView githubIcon = EmojiImageUtils.emojiView(icon, 25);
+ github.setGraphic(githubIcon);
+
+ });
+ EmojiData.emojiFromShortName("tropical_drink").ifPresent(icon -> {
+ ImageView juice = EmojiImageUtils.emojiView(icon, 25);
+ sponsor.setGraphic(juice);
+ });
}
/**
@@ -84,9 +92,9 @@ public class RootController extends BaseController {
*/
@Override
public void initViewAction() {
- closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> getWindow().close());
- minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> getWindow().setIconified(true));
- alwaysOnTopIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
+ closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().close());
+ minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().setIconified(true));
+ alwaysOnTopIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> {
boolean newVal = !getWindow().isAlwaysOnTop();
alwaysOnTopIcon.pseudoClassStateChanged(PseudoClass.getPseudoClass("always-on-top"), newVal);
getWindow().setAlwaysOnTop(newVal);
@@ -101,8 +109,8 @@ public class RootController extends BaseController {
getWindow().setY(event.getScreenY() + yOffset);
});
- tabPane.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
- Context.setCurrentViewIndex(newValue);
- });
+ tabPane.getSelectionModel()
+ .selectedIndexProperty()
+ .addListener((_, _, newValue) -> Context.setCurrentViewIndex(newValue));
}
}
diff --git a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java
index a8687a8..4fded3a 100644
--- a/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java
+++ b/src/main/java/cn/octopusyan/alistgui/controller/SetupController.java
@@ -1,15 +1,15 @@
package cn.octopusyan.alistgui.controller;
import cn.octopusyan.alistgui.base.BaseController;
-import cn.octopusyan.alistgui.config.ConfigManager;
import cn.octopusyan.alistgui.config.Context;
import cn.octopusyan.alistgui.enums.ProxySetup;
+import cn.octopusyan.alistgui.manager.ConfigManager;
import cn.octopusyan.alistgui.viewModel.SetupViewModel;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,11 +22,11 @@ import java.util.Locale;
*
* @author octopus_yan
*/
-public class SetupController extends BaseController implements Initializable {
+public class SetupController extends BaseController implements Initializable {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@FXML
- public GridPane setupView;
+ public AnchorPane setupView;
@FXML
public CheckBox autoStartCheckBox;
@FXML
@@ -35,26 +35,23 @@ public class SetupController extends BaseController implements Initial
public ComboBox languageComboBox;
@FXML
public ComboBox proxySetupComboBox;
-// @FXML
-// public RadioButton noProxy;
-// @FXML
-// public RadioButton systemProxy;
-// @FXML
-// public RadioButton manualProxy;
@FXML
public Pane proxySetupPane;
@FXML
+ public Button proxyCheck;
+ @FXML
public TextField proxyHost;
@FXML
public TextField proxyPort;
@FXML
- public Label alistVersion;
+ public Label aListVersion;
+ @FXML
+ public Button checkAppVersion;
private final SetupViewModel setupViewModel = new SetupViewModel();
- private final ToggleGroup proxySetupGroup = new ToggleGroup();
@Override
- public GridPane getRootPanel() {
+ public AnchorPane getRootPanel() {
return setupView;
}
@@ -63,18 +60,13 @@ public class SetupController extends BaseController implements Initial
languageComboBox.setItems(FXCollections.observableList(Context.SUPPORT_LANGUAGE_LIST));
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
-// noProxy.setToggleGroup(proxySetupGroup);
-// systemProxy.setToggleGroup(proxySetupGroup);
-// manualProxy.setToggleGroup(proxySetupGroup);
}
@Override
public void initViewStyle() {
- proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> {
- proxySetupPane.setVisible(ProxySetup.MANUAL.equals(setupViewModel.proxySetupProperty().get()));
- });
- proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue));
+ proxyCheck.setVisible(!ProxySetup.NO_PROXY.equals(newValue));
});
languageComboBox.getSelectionModel().select(ConfigManager.language());
@@ -85,15 +77,19 @@ public class SetupController extends BaseController implements Initial
public void initViewAction() {
autoStartCheckBox.selectedProperty().bindBidirectional(setupViewModel.autoStartProperty());
silentStartupCheckBox.selectedProperty().bindBidirectional(setupViewModel.silentStartupProperty());
- proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
- setupViewModel.proxySetupProperty().set(newValue);
- });
+ proxySetupComboBox.getSelectionModel().selectedItemProperty()
+ .addListener((_, _, newValue) -> setupViewModel.proxySetupProperty().set(newValue));
proxyHost.textProperty().bindBidirectional(setupViewModel.proxyHostProperty());
proxyPort.textProperty().bindBidirectional(setupViewModel.proxyPortProperty());
- languageComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ languageComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
setupViewModel.languageProperty().set(newValue);
logger.info("language changed to {}", newValue);
});
- alistVersion.textProperty().bindBidirectional(setupViewModel.aListVersionProperty());
+ aListVersion.textProperty().bindBidirectional(setupViewModel.aListVersionProperty());
+ }
+
+ @FXML
+ public void checkAListUpdate() {
+ setupViewModel.checkAListUpdate();
}
}
diff --git a/src/main/java/cn/octopusyan/alistgui/manager/ConfigManager.java b/src/main/java/cn/octopusyan/alistgui/manager/ConfigManager.java
new file mode 100644
index 0000000..90a3269
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/manager/ConfigManager.java
@@ -0,0 +1,181 @@
+package cn.octopusyan.alistgui.manager;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.PatternPool;
+import cn.hutool.core.util.NumberUtil;
+import cn.octopusyan.alistgui.config.Constants;
+import cn.octopusyan.alistgui.enums.ProxySetup;
+import cn.octopusyan.alistgui.manager.http.HttpUtil;
+import cn.octopusyan.alistgui.model.GuiConfig;
+import cn.octopusyan.alistgui.model.ProxyInfo;
+import cn.octopusyan.alistgui.model.UpgradeConfig;
+import cn.octopusyan.alistgui.model.upgrade.AList;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import org.apache.commons.lang3.LocaleUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Optional;
+import java.util.regex.Matcher;
+
+/**
+ * 客户端设置
+ *
+ * @author octopus_yan@foxmail.com
+ */
+public class ConfigManager {
+ private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
+ public static ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
+ public static final Locale DEFAULT_LANGUAGE = Locale.CHINESE;
+ private static GuiConfig guiConfig;
+ private static UpgradeConfig upgradeConfig;
+
+ static {
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ }
+
+ public static void load() {
+ guiConfig = loadConfig(Constants.GUI_CONFIG_PATH, GuiConfig.class);
+ upgradeConfig = loadConfig(Constants.UPGRADE_PATH, UpgradeConfig.class);
+ }
+
+ private static T loadConfig(String path, Class clazz) {
+ File src = new File(path);
+ try {
+ if (!src.exists()) {
+ checkFile(src, clazz);
+ }
+ return objectMapper.readValue(src, clazz);
+ } catch (Exception e) {
+ logger.error(String.format("load %s error", clazz.getSimpleName()), e);
+ }
+ return null;
+ }
+
+ public static boolean hasProxy() {
+ if (guiConfig == null)
+ return false;
+ ProxyInfo proxyInfo = getProxyInfo();
+ return proxyInfo != null
+ && StringUtils.isNoneEmpty(proxyInfo.getHost())
+ && StringUtils.isNoneEmpty(proxyInfo.getPort())
+ && Integer.parseInt(proxyInfo.getPort()) > 0;
+ }
+
+ private static ProxyInfo getProxyInfo() {
+ return guiConfig.getProxyInfo();
+ }
+
+ private static void setProxyInfo(ProxyInfo info) {
+ guiConfig.setProxyInfo(info);
+ }
+
+ public static String proxyHost() {
+ if (getProxyInfo() == null) return null;
+ return getProxyInfo().getHost();
+ }
+
+ public static void proxyHost(String host) {
+ final Matcher matcher = PatternPool.IPV4.matcher(host);
+ if (matcher.matches()) {
+ if (getProxyInfo() == null)
+ setProxyInfo(new ProxyInfo());
+ getProxyInfo().setHost(host);
+ }
+ }
+
+ public static String proxyPort() {
+ if (getProxyInfo() == null) return null;
+ return getProxyInfo().getPort();
+ }
+
+ public static int getProxyPort() {
+ return Integer.parseInt(getProxyInfo().getPort());
+ }
+
+ public static void proxyPort(String port) {
+ if (NumberUtil.isNumber(port)) {
+ if (getProxyInfo() == null)
+ setProxyInfo(new ProxyInfo());
+ getProxyInfo().setPort(port);
+ }
+ }
+
+ public static Locale language() {
+ String language = guiConfig.getLanguage();
+ return LocaleUtils.toLocale(Optional.ofNullable(language).orElse(DEFAULT_LANGUAGE.toString()));
+ }
+
+ public static void language(Locale locale) {
+ guiConfig.setLanguage(locale.toString());
+ }
+
+ public static boolean autoStart() {
+ return guiConfig.getAutoStart();
+ }
+
+ public static void autoStart(Boolean autoStart) {
+ guiConfig.setAutoStart(autoStart);
+ }
+
+ public static ProxySetup proxySetup() {
+ return ProxySetup.valueOf(StringUtils.upperCase(guiConfig.getProxySetup()));
+ }
+
+ public static void proxySetup(ProxySetup setup) {
+ guiConfig.setProxySetup(setup.getName());
+
+ if (ProxySetup.NO_PROXY.equals(setup)) {
+ HttpUtil.getInstance().clearProxy();
+ } else if (hasProxy()) {
+ HttpUtil.getInstance().proxy(setup, ConfigManager.getProxyInfo());
+ }
+ }
+
+ public static boolean silentStartup() {
+ return guiConfig.getSilentStartup();
+ }
+
+ public static void silentStartup(Boolean startup) {
+ guiConfig.setSilentStartup(startup);
+ }
+
+ public static AList aList() {
+ return upgradeConfig.getAList();
+ }
+
+ public static String aListVersion() {
+ return upgradeConfig.getAList().getVersion();
+ }
+
+ public static void aListVersion(String version) {
+ upgradeConfig.getAList().setVersion(version);
+ }
+
+
+ private static void checkFile(File src, Class clazz) throws Exception {
+ File parent = FileUtil.getParent(src, 1);
+ if (!parent.exists()) {
+ boolean wasSuccessful = parent.mkdirs();
+ objectMapper.writeValue(src, clazz.getDeclaredConstructor().newInstance());
+ if (!wasSuccessful)
+ logger.error("{} 创建失败", src.getAbsolutePath());
+ }
+ }
+
+ public static void save() {
+ try {
+ objectMapper.writeValue(new File(Constants.GUI_CONFIG_PATH), guiConfig);
+ objectMapper.writeValue(new File(Constants.UPGRADE_PATH), upgradeConfig);
+ } catch (IOException e) {
+ logger.error("save config error", e);
+ }
+ }
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java b/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java
index ac8fa1d..2fc31c3 100644
--- a/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java
+++ b/src/main/java/cn/octopusyan/alistgui/model/GuiConfig.java
@@ -1,71 +1,23 @@
package cn.octopusyan.alistgui.model;
-import cn.hutool.core.io.FileUtil;
-import cn.octopusyan.alistgui.config.AppConstant;
-import cn.octopusyan.alistgui.config.ConfigManager;
import cn.octopusyan.alistgui.enums.ProxySetup;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import cn.octopusyan.alistgui.manager.ConfigManager;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.IOException;
-
/**
* GUI配置信息
- * 通过Jackson 写入yaml
*
* @author octopus_yan
*/
@Data
public class GuiConfig {
private static final Logger log = LoggerFactory.getLogger(GuiConfig.class);
- public static GuiConfig INSTANCE;
- public static ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
private Boolean autoStart = false;
private Boolean silentStartup = false;
- private ProxyInfo proxyInfo = new ProxyInfo();
+ private ProxyInfo proxyInfo;
private String proxySetup = ProxySetup.NO_PROXY.getName();
private String language = ConfigManager.DEFAULT_LANGUAGE.toString();
- @JsonProperty("aListVersion")
- private String aListVersion = "unknown";
-
- static {
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
- }
-
- private GuiConfig() {
-
- }
-
- public static GuiConfig getInstance() throws IOException {
- File src = new File(AppConstant.GUI_CONFIG_PATH);
- if (INSTANCE == null) {
- if (!src.exists()) {
- checkFile(src);
- }
- INSTANCE = objectMapper.readValue(src, GuiConfig.class);
- }
- return INSTANCE;
- }
-
- private static void checkFile(File src) throws IOException {
- File parent = FileUtil.getParent(src, 1);
- if (!parent.exists()) {
- boolean wasSuccessful = parent.mkdirs();
- objectMapper.writeValue(src, new GuiConfig());
- if (!wasSuccessful)
- log.error("{} 创建失败", src.getAbsolutePath());
- }
- }
-
- public void save() throws IOException {
- objectMapper.writeValue(new File(AppConstant.GUI_CONFIG_PATH), INSTANCE);
- }
}
diff --git a/src/main/java/cn/octopusyan/alistgui/model/UpgradeConfig.java b/src/main/java/cn/octopusyan/alistgui/model/UpgradeConfig.java
new file mode 100644
index 0000000..146692b
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/model/UpgradeConfig.java
@@ -0,0 +1,18 @@
+package cn.octopusyan.alistgui.model;
+
+import cn.octopusyan.alistgui.model.upgrade.AList;
+import cn.octopusyan.alistgui.model.upgrade.Gui;
+import lombok.Data;
+
+/**
+ * 更新配置
+ *
+ * @author octopus_yan
+ */
+@Data
+public class UpgradeConfig {
+ public static final String RELEASE_API = "https://api.github.com/repos/{}/{}/releases/latest";
+ public static final String DOWNLOAD_API = "https://github.com/{}/{}/releases/download/{}/{}";
+ private AList aList = new AList();
+ private Gui gui = new Gui();
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/model/upgrade/AList.java b/src/main/java/cn/octopusyan/alistgui/model/upgrade/AList.java
new file mode 100644
index 0000000..9fa79b5
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/model/upgrade/AList.java
@@ -0,0 +1,18 @@
+package cn.octopusyan.alistgui.model.upgrade;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+/**
+ * @author octopus_yan
+ */
+@Data
+public class AList implements UpgradeApp {
+ @JsonIgnore
+ private final String owner = "alist-org";
+ @JsonIgnore
+ private final String repo = "alist";
+
+ private String releaseFile = "alist-windows-amd64.zip";
+ private String version = "unknown";
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java b/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java
new file mode 100644
index 0000000..0dac232
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/model/upgrade/Gui.java
@@ -0,0 +1,27 @@
+package cn.octopusyan.alistgui.model.upgrade;
+
+import cn.octopusyan.alistgui.util.PropertiesUtils;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+/**
+ * @author octopus_yan
+ */
+@Data
+public class Gui implements UpgradeApp {
+ @JsonIgnore
+ private final String owner = "alist-org";
+ @JsonIgnore
+ private final String repo = "alist";
+
+ 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/model/upgrade/UpgradeApp.java b/src/main/java/cn/octopusyan/alistgui/model/upgrade/UpgradeApp.java
new file mode 100644
index 0000000..ad09c3d
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/model/upgrade/UpgradeApp.java
@@ -0,0 +1,14 @@
+package cn.octopusyan.alistgui.model.upgrade;
+
+/**
+ * @author octopus_yan
+ */
+public interface UpgradeApp {
+ String getOwner();
+
+ String getRepo();
+
+ String getReleaseFile();
+
+ String getVersion();
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/task/UpgradeTask.java b/src/main/java/cn/octopusyan/alistgui/task/UpgradeTask.java
new file mode 100644
index 0000000..bc97ef2
--- /dev/null
+++ b/src/main/java/cn/octopusyan/alistgui/task/UpgradeTask.java
@@ -0,0 +1,46 @@
+package cn.octopusyan.alistgui.task;
+
+import cn.hutool.core.util.StrUtil;
+import cn.octopusyan.alistgui.base.BaseTask;
+import cn.octopusyan.alistgui.manager.http.HttpUtil;
+import cn.octopusyan.alistgui.model.UpgradeConfig;
+import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
+import cn.octopusyan.alistgui.util.JsonUtil;
+import cn.octopusyan.alistgui.viewModel.SetupViewModel;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 检查更新任务
+ *
+ * @author octopus_yan
+ */
+public class UpgradeTask extends BaseTask {
+ private final SetupViewModel vm;
+ private final UpgradeApp app;
+
+ public UpgradeTask(SetupViewModel viewModel, UpgradeApp app) {
+ this.vm = viewModel;
+ this.app = app;
+ }
+
+ @Override
+ protected void task() throws Exception {
+ String releaseApi = StrUtil.format(UpgradeConfig.RELEASE_API, app.getOwner(), app.getRepo());
+ String responseStr = HttpUtil.getInstance().get(releaseApi, null, null);
+ JsonNode response = JsonUtil.parseJsonObject(responseStr);
+
+ String newVersion = response.get("tag_name").asText();
+ String downloadUrl = StrUtil.format(UpgradeConfig.DOWNLOAD_API,
+ app.getOwner(),
+ app.getRepo(),
+ newVersion,
+ app.getReleaseFile()
+ );
+
+ runLater(() -> {
+ vm.aListUpgradeProperty().setValue(StringUtils.equals(app.getVersion(), newVersion));
+ vm.aListNewVersionProperty().setValue(newVersion);
+ });
+ }
+}
diff --git a/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java b/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java
index b931ae9..6435772 100644
--- a/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java
+++ b/src/main/java/cn/octopusyan/alistgui/viewModel/SetupViewModel.java
@@ -1,12 +1,12 @@
package cn.octopusyan.alistgui.viewModel;
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.net.url.UrlBuilder;
-import cn.octopusyan.alistgui.config.ConfigManager;
+import cn.octopusyan.alistgui.base.BaseTask;
import cn.octopusyan.alistgui.config.Context;
import cn.octopusyan.alistgui.enums.ProxySetup;
+import cn.octopusyan.alistgui.manager.ConfigManager;
+import cn.octopusyan.alistgui.task.UpgradeTask;
+import cn.octopusyan.alistgui.util.alert.AlertUtil;
import javafx.beans.property.*;
-import org.apache.commons.lang3.StringUtils;
import java.util.Locale;
@@ -20,19 +20,21 @@ public class SetupViewModel {
private final BooleanProperty silentStartup = new SimpleBooleanProperty(ConfigManager.silentStartup());
private final StringProperty proxyHost = new SimpleStringProperty(ConfigManager.proxyHost());
private final StringProperty proxyPort = new SimpleStringProperty(ConfigManager.proxyPort());
- private final BooleanProperty proxyVerify = new SimpleBooleanProperty(false);
private final ObjectProperty language = new SimpleObjectProperty<>(ConfigManager.language());
private final ObjectProperty proxySetup = new SimpleObjectProperty<>(ConfigManager.proxySetup());
- private final SimpleStringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
+ private final StringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
+ private final StringProperty aListNewVersion = new SimpleStringProperty("");
+ private final BooleanProperty aListUpgrade = new SimpleBooleanProperty(false);
+
public SetupViewModel() {
- aListVersion.addListener((observable, oldValue, newValue) -> ConfigManager.aListVersion(newValue));
- autoStart.addListener((observable, oldValue, newValue) -> ConfigManager.autoStart(newValue));
- silentStartup.addListener((observable, oldValue, newValue) -> ConfigManager.silentStartup(newValue));
- proxySetup.addListener((observable, oldValue, newValue) -> ConfigManager.proxySetup(newValue));
- proxyHost.addListener((observable, oldValue, newValue) -> ConfigManager.proxyHost(newValue));
- proxyPort.addListener((observable, oldValue, newValue) -> ConfigManager.proxyPort(newValue));
- language.addListener((observable, oldValue, newValue) -> Context.setLanguage(newValue));
+ aListVersion.addListener((_, _, newValue) -> ConfigManager.aListVersion(newValue));
+ autoStart.addListener((_, _, newValue) -> ConfigManager.autoStart(newValue));
+ silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
+ proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue));
+ proxyHost.addListener((_, _, newValue) -> ConfigManager.proxyHost(newValue));
+ proxyPort.addListener((_, _, newValue) -> ConfigManager.proxyPort(newValue));
+ language.addListener((_, _, newValue) -> Context.setLanguage(newValue));
}
public BooleanProperty autoStartProperty() {
@@ -63,25 +65,35 @@ public class SetupViewModel {
return aListVersion;
}
+ public BooleanProperty aListUpgradeProperty() {
+ return aListUpgrade;
+ }
+
+ public StringProperty aListNewVersionProperty() {
+ return aListNewVersion;
+ }
+
/**
- * 验证代理地址
- *
- * @param address 新的代理地址
- * @return UrlBuilder, 验证失败时为null
+ * 检查alist更新
*/
- public UrlBuilder validateAddress(String address) {
- if (StringUtils.isEmpty(address))
- return null;
+ public void checkAListUpdate() {
+ var task = new UpgradeTask(this, ConfigManager.aList());
+ task.onListen(new BaseTask.Listener() {
+ @Override
+ public void onSucceeded() {
+ AlertUtil.info(STR."""
+ 当前版本 : \{aListVersion.get()}
+ 最新版本 : \{aListNewVersion.get()}
+ """)
+ .title("AList 更新提示")
+ .show();
+ }
- // 验证 URL 的可用性
- UrlBuilder ub = UrlBuilder.of(address);
- boolean isUrlValid = Validator.isUrl(address) && ub.getPort() > 0;
-
- // 设置 proxyVerify 和 proxyVerifyMsg
- proxyVerify.setValue(isUrlValid);
-
- if (isUrlValid)
- return ub;
- else return null;
+ @Override
+ public void onFailed(Throwable throwable) {
+ AlertUtil.exception(new Exception(throwable)).show();
+ }
+ });
+ task.execute();
}
}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index e2051d9..29e5401 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -21,4 +21,6 @@ module cn.octopusyan.alistgui {
opens cn.octopusyan.alistgui to javafx.fxml;
opens cn.octopusyan.alistgui.model to com.fasterxml.jackson.databind;
opens cn.octopusyan.alistgui.controller to javafx.fxml;
+ opens cn.octopusyan.alistgui.base to com.fasterxml.jackson.databind;
+ opens cn.octopusyan.alistgui.model.upgrade to com.fasterxml.jackson.databind;
}
\ No newline at end of file
diff --git a/src/main/resources/css/main-view.scss b/src/main/resources/css/main-view.scss
index 6b1db7d..8bea96d 100644
--- a/src/main/resources/css/main-view.scss
+++ b/src/main/resources/css/main-view.scss
@@ -50,7 +50,6 @@
-fx-background-color: transparent;
-fx-text-fill: #9254d1;
-fx-border-color: #9254d1;
- -fx-border-width: 2;
}
#logArea {
diff --git a/src/main/resources/fxml/setup-view.fxml b/src/main/resources/fxml/setup-view.fxml
index 809822d..1d02484 100644
--- a/src/main/resources/fxml/setup-view.fxml
+++ b/src/main/resources/fxml/setup-view.fxml
@@ -3,59 +3,48 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
diff --git a/src/main/resources/language/language.properties b/src/main/resources/language/language.properties
index 08ea9ad..95c9f55 100644
--- a/src/main/resources/language/language.properties
+++ b/src/main/resources/language/language.properties
@@ -11,7 +11,7 @@ main.status.label-running=\u8FD0\u884C\u4E2D
main.status.label-stop=\u5DF2\u505C\u6B62
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
-setup.proxyInfo=HTTP\u4EE3\u7406
+setup.proxy=HTTP\u4EE3\u7406
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
setup.language=\u8BED\u8A00
@@ -19,9 +19,10 @@ alist.version=AList \u7248\u672C
app.version=GUI \u7248\u672C
alist.update=\u68C0\u67E5 AList \u7248\u672C
app.update=\u68C0\u67E5 GUI \u7248\u672C
-setup.proxyInfo.host=\u4E3B\u673A
-setup.proxyInfo.port=\u7AEF\u53E3
+setup.proxy.host=\u4E3B\u673A
+setup.proxy.port=\u7AEF\u53E3
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
+setup.proxy.test=\u6D4B\u8BD5
diff --git a/src/main/resources/language/language_en.properties b/src/main/resources/language/language_en.properties
index 54f2d1f..7630da2 100644
--- a/src/main/resources/language/language_en.properties
+++ b/src/main/resources/language/language_en.properties
@@ -11,7 +11,7 @@ main.status.label-running=Running
main.status.label-stop=Stoped
main.more.browser=Open in browser
main.more.open-log=Open the log folder
-setup.proxyInfo=HTTP PROXY
+setup.proxy=HTTP PROXY
setup.auto-start.label=Auto start with PC
setup.silent-startup.label=Silent startup
setup.language=language
@@ -19,9 +19,10 @@ alist.version=AList Version
app.version=GUI Version
alist.update=Check AList Version
app.update=Check GUI Version
-setup.proxyInfo.host=Host
-setup.proxyInfo.port=Port
+setup.proxy.host=Host
+setup.proxy.port=Port
proxy.setup.label.no_proxy=No Proxy
proxy.setup.label.system=System Proxy
proxy.setup.label.manual=Manual Config
+setup.proxy.test=Check connection
diff --git a/src/main/resources/language/language_zh.properties b/src/main/resources/language/language_zh.properties
index 08ea9ad..95c9f55 100644
--- a/src/main/resources/language/language_zh.properties
+++ b/src/main/resources/language/language_zh.properties
@@ -11,7 +11,7 @@ main.status.label-running=\u8FD0\u884C\u4E2D
main.status.label-stop=\u5DF2\u505C\u6B62
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
-setup.proxyInfo=HTTP\u4EE3\u7406
+setup.proxy=HTTP\u4EE3\u7406
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
setup.language=\u8BED\u8A00
@@ -19,9 +19,10 @@ alist.version=AList \u7248\u672C
app.version=GUI \u7248\u672C
alist.update=\u68C0\u67E5 AList \u7248\u672C
app.update=\u68C0\u67E5 GUI \u7248\u672C
-setup.proxyInfo.host=\u4E3B\u673A
-setup.proxyInfo.port=\u7AEF\u53E3
+setup.proxy.host=\u4E3B\u673A
+setup.proxy.port=\u7AEF\u53E3
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
+setup.proxy.test=\u6D4B\u8BD5