mirror of
https://github.com/octopusYan/alist-gui.git
synced 2024-11-10 06:26:43 +08:00
Compare commits
No commits in common. "b1218e9122e290e74822afebdea87fe234e0950b" and "55ea1d8a80da24aa5aef21632f72d8974b1ea264" have entirely different histories.
b1218e9122
...
55ea1d8a80
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,7 +7,6 @@ target/
|
|||||||
!**/src/main/**/target/
|
!**/src/main/**/target/
|
||||||
!**/src/test/**/target/
|
!**/src/test/**/target/
|
||||||
/config/
|
/config/
|
||||||
/bin/
|
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
### IntelliJ IDEA ###
|
||||||
.idea/
|
.idea/
|
||||||
|
68
pom.xml
68
pom.xml
@ -18,21 +18,21 @@
|
|||||||
<description>AList windows gui</description>
|
<description>AList windows gui</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<java.version>21</java.version>
|
<java.version>17</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
<junit.version>5.10.0</junit.version>
|
<junit.version>5.10.0</junit.version>
|
||||||
<javafx.version>21.0.4</javafx.version>
|
<javafx.version>17.0.6</javafx.version>
|
||||||
<slf4j.version>2.0.16</slf4j.version>
|
<slf4j.version>2.0.16</slf4j.version>
|
||||||
<logback.version>1.4.14</logback.version>
|
<logback.version>1.4.14</logback.version>
|
||||||
<hutool.version>5.8.32</hutool.version>
|
<hutool.version>5.8.32</hutool.version>
|
||||||
<common-lang3.version>3.16.0</common-lang3.version>
|
<common-lang3.version>3.16.0</common-lang3.version>
|
||||||
|
<!-- <common-io.version>2.16.1</common-io.version>-->
|
||||||
<common-exec.version>1.4.0</common-exec.version>
|
<common-exec.version>1.4.0</common-exec.version>
|
||||||
<lombok.version>1.18.32</lombok.version>
|
<lombok.version>1.18.32</lombok.version>
|
||||||
<jackson.version>2.15.4</jackson.version>
|
|
||||||
<ikonli.version>12.3.1</ikonli.version>
|
<ikonli.version>12.3.1</ikonli.version>
|
||||||
<gluonhq-emoji.version>1.0.1</gluonhq-emoji.version>
|
<gluonhq-emoji.version>1.0.1</gluonhq-emoji.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -50,21 +50,12 @@
|
|||||||
<version>${javafx.version}</version>
|
<version>${javafx.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mkpaz.github.io/atlantafx/ -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.mkpaz</groupId>
|
<groupId>io.github.mkpaz</groupId>
|
||||||
<artifactId>atlantafx-base</artifactId>
|
<artifactId>atlantafx-base</artifactId>
|
||||||
<version>2.0.1</version>
|
<version>2.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- java 网络代理查找库-->
|
|
||||||
<!-- https://github.com/MarkusBernhardt/proxy-vole -->
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.bidib.com.github.markusbernhardt/proxy-vole -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bidib.com.github.markusbernhardt</groupId>
|
|
||||||
<artifactId>proxy-vole</artifactId>
|
|
||||||
<version>1.1.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- slf4j -->
|
<!-- slf4j -->
|
||||||
<!-- https://slf4j.org/manual.html -->
|
<!-- https://slf4j.org/manual.html -->
|
||||||
@ -128,7 +119,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>2.15.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.kordamp.ikonli/ikonli-javafx -->
|
<!-- https://mvnrepository.com/artifact/org.kordamp.ikonli/ikonli-javafx -->
|
||||||
@ -184,9 +175,8 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.13.0</version>
|
<version>3.13.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>21</source>
|
<source>17</source>
|
||||||
<target>21</target>
|
<target>17</target>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
@ -198,45 +188,11 @@
|
|||||||
<nonFilteredFileExtensions>
|
<nonFilteredFileExtensions>
|
||||||
<nonFilteredFileExtension>exe</nonFilteredFileExtension>
|
<nonFilteredFileExtension>exe</nonFilteredFileExtension>
|
||||||
<nonFilteredFileExtension>dll</nonFilteredFileExtension>
|
<nonFilteredFileExtension>dll</nonFilteredFileExtension>
|
||||||
<filteredFileExtension>scss</filteredFileExtension>
|
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
|
||||||
</nonFilteredFileExtensions>
|
</nonFilteredFileExtensions>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- https://github.com/HebiRobotics/sass-cli-maven-plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>us.hebi.sass</groupId>
|
|
||||||
<artifactId>sass-cli-maven-plugin</artifactId>
|
|
||||||
<version>1.0.3</version>
|
|
||||||
<configuration>
|
|
||||||
<sassVersion>1.78.0</sassVersion>
|
|
||||||
<args> <!-- Any argument that should be forwarded to the sass cli -->
|
|
||||||
<arg>
|
|
||||||
${project.basedir}/src/main/resources/css/root.scss:${project.basedir}/target/classes/css/root.css
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
${project.basedir}/src/main/resources/css/root-view.scss:${project.basedir}/target/classes/css/root-view.css
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
${project.basedir}/src/main/resources/css/main-view.scss:${project.basedir}/target/classes/css/main-view.css
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
${project.basedir}/src/main/resources/css/setup-view.scss:${project.basedir}/target/classes/css/setup-view.css
|
|
||||||
</arg>
|
|
||||||
<arg>--no-source-map</arg>
|
|
||||||
</args>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>sass-exec</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>run</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-maven-plugin</artifactId>
|
<artifactId>javafx-maven-plugin</artifactId>
|
||||||
@ -246,7 +202,8 @@
|
|||||||
<!-- Default configuration for running with: mvn clean javafx:run -->
|
<!-- Default configuration for running with: mvn clean javafx:run -->
|
||||||
<id>default-cli</id>
|
<id>default-cli</id>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>cn.octopusyan.alistgui/cn.octopusyan.alistgui.AppLauncher</mainClass>
|
<mainClass>cn.octopusyan.alistgui/cn.octopusyan.alistgui.AppLuncher
|
||||||
|
</mainClass>
|
||||||
<launcher>launcher</launcher>
|
<launcher>launcher</launcher>
|
||||||
<jlinkZipName>app</jlinkZipName>
|
<jlinkZipName>app</jlinkZipName>
|
||||||
<jlinkImageName>app</jlinkImageName>
|
<jlinkImageName>app</jlinkImageName>
|
||||||
@ -258,14 +215,13 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- https://github.com/fvarrui/JavaPackager -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.github.fvarrui</groupId>
|
<groupId>io.github.fvarrui</groupId>
|
||||||
<artifactId>javapackager</artifactId>
|
<artifactId>javapackager</artifactId>
|
||||||
<version>1.7.7-SNAPSHOT</version>
|
<version>1.7.7-SNAPSHOT</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<bundleJre>true</bundleJre>
|
<bundleJre>true</bundleJre>
|
||||||
<mainClass>cn.octopusyan.alistgui.AppLauncher</mainClass>
|
<mainClass>cn.octopusyan.alistgui.AppLuncher</mainClass>
|
||||||
<generateInstaller>false</generateInstaller>
|
<generateInstaller>false</generateInstaller>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
|
@ -5,7 +5,7 @@ package cn.octopusyan.alistgui;
|
|||||||
*
|
*
|
||||||
* @author octopus_yan@foxmail.com
|
* @author octopus_yan@foxmail.com
|
||||||
*/
|
*/
|
||||||
public class AppLauncher {
|
public class AppLuncher {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Application.launch(Application.class, args);
|
Application.launch(Application.class, args);
|
@ -1,14 +1,14 @@
|
|||||||
package cn.octopusyan.alistgui;
|
package cn.octopusyan.alistgui;
|
||||||
|
|
||||||
import atlantafx.base.theme.PrimerLight;
|
import atlantafx.base.theme.PrimerLight;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
import cn.octopusyan.alistgui.config.AppConstant;
|
||||||
|
import cn.octopusyan.alistgui.config.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
|
||||||
import cn.octopusyan.alistgui.manager.http.HttpConfig;
|
import cn.octopusyan.alistgui.manager.http.HttpConfig;
|
||||||
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
||||||
import cn.octopusyan.alistgui.manager.thread.ThreadPoolManager;
|
import cn.octopusyan.alistgui.manager.thread.ThreadPoolManager;
|
||||||
import cn.octopusyan.alistgui.util.alert.AlertUtil;
|
import cn.octopusyan.alistgui.util.AlertUtil;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class Application extends javafx.application.Application {
|
public class Application extends javafx.application.Application {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
||||||
@ -28,39 +27,18 @@ public class Application extends javafx.application.Application {
|
|||||||
private static Stage primaryStage;
|
private static Stage primaryStage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() throws Exception {
|
||||||
logger.info("application init ...");
|
logger.info("application init ...");
|
||||||
// 初始化客户端配置
|
// 初始化客户端配置
|
||||||
ConfigManager.load();
|
ConfigManager.load();
|
||||||
|
|
||||||
// http请求工具初始化
|
|
||||||
HttpConfig httpConfig = new HttpConfig();
|
|
||||||
// 加载代理设置
|
|
||||||
if (!ProxySetup.NO_PROXY.equals(ConfigManager.proxySetup())) {
|
|
||||||
// 系统代理
|
|
||||||
if (ProxySetup.SYSTEM.equals(ConfigManager.proxySetup())) {
|
|
||||||
httpConfig.setProxySelector(ProxySelector.getDefault());
|
|
||||||
}
|
|
||||||
// 自定义代理
|
|
||||||
if (ProxySetup.MANUAL.equals(ConfigManager.proxySetup()) && ConfigManager.hasProxy()) {
|
|
||||||
InetSocketAddress unresolved = InetSocketAddress.createUnresolved(
|
|
||||||
Objects.requireNonNull(ConfigManager.proxyHost()),
|
|
||||||
ConfigManager.getProxyPort()
|
|
||||||
);
|
|
||||||
httpConfig.setProxySelector(ProxySelector.of(unresolved));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
httpConfig.setConnectTimeout(10);
|
|
||||||
HttpUtil.init(httpConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws IOException {
|
public void start(Stage primaryStage) throws IOException {
|
||||||
|
Application.primaryStage = primaryStage;
|
||||||
|
|
||||||
logger.info("application start ...");
|
logger.info("application start ...");
|
||||||
|
|
||||||
Application.primaryStage = primaryStage;
|
|
||||||
|
|
||||||
// 初始化弹窗工具
|
// 初始化弹窗工具
|
||||||
AlertUtil.initOwner(primaryStage);
|
AlertUtil.initOwner(primaryStage);
|
||||||
|
|
||||||
@ -68,6 +46,24 @@ public class Application extends javafx.application.Application {
|
|||||||
Thread.setDefaultUncaughtExceptionHandler(this::showErrorDialog);
|
Thread.setDefaultUncaughtExceptionHandler(this::showErrorDialog);
|
||||||
Thread.currentThread().setUncaughtExceptionHandler(this::showErrorDialog);
|
Thread.currentThread().setUncaughtExceptionHandler(this::showErrorDialog);
|
||||||
|
|
||||||
|
// http请求工具初始化
|
||||||
|
HttpConfig httpConfig = new HttpConfig();
|
||||||
|
|
||||||
|
if(!ProxySetup.NO_PROXY.equals(ConfigManager.proxySetup())) {
|
||||||
|
// 系统代理
|
||||||
|
if (ProxySetup.SYSTEM.equals(ConfigManager.proxySetup())) {
|
||||||
|
httpConfig.setProxySelector(ProxySelector.getDefault());
|
||||||
|
}
|
||||||
|
// 自定义代理
|
||||||
|
if (ProxySetup.MANUAL.equals(ConfigManager.proxySetup()) && ConfigManager.hasProxy()) {
|
||||||
|
InetSocketAddress unresolved = InetSocketAddress.createUnresolved(ConfigManager.proxyHost(), ConfigManager.getProxyPort());
|
||||||
|
httpConfig.setProxySelector(ProxySelector.of(unresolved));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
httpConfig.setConnectTimeout(10);
|
||||||
|
HttpUtil.init(httpConfig);
|
||||||
|
|
||||||
// i18n
|
// i18n
|
||||||
Context.setLanguage(ConfigManager.language());
|
Context.setLanguage(ConfigManager.language());
|
||||||
|
|
||||||
@ -75,10 +71,10 @@ public class Application extends javafx.application.Application {
|
|||||||
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
Application.setUserAgentStylesheet(new PrimerLight().getUserAgentStylesheet());
|
||||||
|
|
||||||
// 启动主界面
|
// 启动主界面
|
||||||
primaryStage.initStyle(StageStyle.TRANSPARENT);
|
|
||||||
primaryStage.setTitle(String.format("%s v%s", Constants.APP_TITLE, Constants.APP_VERSION));
|
|
||||||
Scene scene = Context.initScene();
|
Scene scene = Context.initScene();
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.initStyle(StageStyle.TRANSPARENT);
|
||||||
|
primaryStage.setTitle(String.format("%s v%s", AppConstant.APP_TITLE, AppConstant.APP_VERSION));
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
|
|
||||||
logger.info("application start over ...");
|
logger.info("application start over ...");
|
||||||
@ -86,11 +82,11 @@ public class Application extends javafx.application.Application {
|
|||||||
|
|
||||||
private void showErrorDialog(Thread t, Throwable e) {
|
private void showErrorDialog(Thread t, Throwable e) {
|
||||||
logger.error("", e);
|
logger.error("", e);
|
||||||
AlertUtil.exception(new Exception(e)).show();
|
AlertUtil.exceptionAlert(new Exception(e)).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() throws Exception {
|
||||||
logger.info("application stop ...");
|
logger.info("application stop ...");
|
||||||
// 保存应用数据
|
// 保存应用数据
|
||||||
ConfigManager.save();
|
ConfigManager.save();
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
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<Void> {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,15 +10,13 @@ import java.nio.file.Paths;
|
|||||||
*
|
*
|
||||||
* @author octopus_yan@foxmail.com
|
* @author octopus_yan@foxmail.com
|
||||||
*/
|
*/
|
||||||
public class Constants {
|
public class AppConstant {
|
||||||
public static final String APP_TITLE = PropertiesUtils.getInstance().getProperty("app.title");
|
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_NAME = PropertiesUtils.getInstance().getProperty("app.name");
|
||||||
public static final String APP_VERSION = PropertiesUtils.getInstance().getProperty("app.version");
|
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 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 TMP_DIR_PATH = System.getProperty("java.io.tmpdir") + APP_NAME;
|
||||||
public static final String CONFIG_DIR_PATH = STR."\{DATA_DIR_PATH}\{File.separator}config";
|
public static final String CONFIG_DIR_PATH = 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 GUI_CONFIG_PATH = CONFIG_DIR_PATH + File.separator + "gui.yaml";
|
||||||
public static final String BAK_FILE_PATH = STR."\{Constants.TMP_DIR_PATH}\{File.separator}bak";
|
public static final String BAK_FILE_PATH = AppConstant.TMP_DIR_PATH + File.separator + "bak";
|
||||||
}
|
}
|
127
src/main/java/cn/octopusyan/alistgui/config/ConfigManager.java
Normal file
127
src/main/java/cn/octopusyan/alistgui/config/ConfigManager.java
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import cn.octopusyan.alistgui.base.BaseController;
|
|||||||
import cn.octopusyan.alistgui.controller.MainController;
|
import cn.octopusyan.alistgui.controller.MainController;
|
||||||
import cn.octopusyan.alistgui.controller.RootController;
|
import cn.octopusyan.alistgui.controller.RootController;
|
||||||
import cn.octopusyan.alistgui.controller.SetupController;
|
import cn.octopusyan.alistgui.controller.SetupController;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
|
||||||
import cn.octopusyan.alistgui.util.FxmlUtil;
|
import cn.octopusyan.alistgui.util.FxmlUtil;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
@ -13,11 +12,13 @@ import javafx.beans.property.ObjectProperty;
|
|||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.effect.DropShadow;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import lombok.Getter;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -34,11 +35,9 @@ public class Context {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(Context.class);
|
private static final Logger log = LoggerFactory.getLogger(Context.class);
|
||||||
private static Scene scene;
|
private static Scene scene;
|
||||||
private static final IntegerProperty currentViewIndexProperty = new SimpleIntegerProperty(0);
|
private static final IntegerProperty currentViewIndexProperty = new SimpleIntegerProperty(0);
|
||||||
// 获取控制器集合
|
|
||||||
/**
|
/**
|
||||||
* 控制器集合
|
* 控制器集合
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private static final Map<String, BaseController<?>> controllers = new HashMap<>();
|
private static final Map<String, BaseController<?>> controllers = new HashMap<>();
|
||||||
/**
|
/**
|
||||||
* 默认语言文件 Base Name
|
* 默认语言文件 Base Name
|
||||||
@ -62,20 +61,22 @@ public class Context {
|
|||||||
throw new IllegalStateException("Utility class");
|
throw new IllegalStateException("Utility class");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取控制器集合
|
||||||
|
public static Map<String, BaseController<?>> getControllers() {
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取控制工厂
|
// 获取控制工厂
|
||||||
public static Callback<Class<?>, Object> getControlFactory() {
|
public static Callback<Class<?>, Object> getControlFactory() {
|
||||||
return type -> {
|
return type -> {
|
||||||
try {
|
if (type.equals(RootController.class)) {
|
||||||
return switch (type.getDeclaredConstructor().newInstance()) {
|
return new RootController();
|
||||||
case RootController root -> root;
|
} else if (type.equals(MainController.class)) {
|
||||||
case MainController main -> main;
|
return new MainController();
|
||||||
case SetupController setup -> setup;
|
} else if (type.equals(SetupController.class)) {
|
||||||
default -> throw new IllegalStateException(STR."Unexpected value: \{type}");
|
return new SetupController();
|
||||||
};
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
throw new IllegalStateException("Unexpected value: " + type);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,13 +134,15 @@ public class Context {
|
|||||||
* 初始化 语言
|
* 初始化 语言
|
||||||
*/
|
*/
|
||||||
private static void initI18n() {
|
private static void initI18n() {
|
||||||
currentLocaleProperty().addListener((_, _, _) -> Platform.runLater(() -> {
|
currentLocaleProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
try {
|
Platform.runLater(() -> {
|
||||||
loadScene();
|
try {
|
||||||
} catch (IOException e) {
|
loadScene();
|
||||||
log.error("", e);
|
} catch (IOException e) {
|
||||||
}
|
log.error("", e);
|
||||||
}));
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,34 +171,39 @@ public class Context {
|
|||||||
private static void loadScene() throws IOException {
|
private static void loadScene() throws IOException {
|
||||||
FXMLLoader loader = FxmlUtil.load("root-view");
|
FXMLLoader loader = FxmlUtil.load("root-view");
|
||||||
loader.setControllerFactory(Context.getControlFactory());
|
loader.setControllerFactory(Context.getControlFactory());
|
||||||
//底层面板
|
Parent root = loader.load();//底层面板
|
||||||
Pane root = loader.load();
|
// bindShadow((Pane) root);
|
||||||
Optional.ofNullable(scene).ifPresentOrElse(
|
Optional.ofNullable(scene).ifPresentOrElse(
|
||||||
s -> s.setRoot(root),
|
s -> s.setRoot(root),
|
||||||
() -> {
|
() -> {
|
||||||
scene = new Scene(root, root.getPrefWidth() + 20, root.getPrefHeight() + 20, Color.TRANSPARENT);
|
scene = new Scene(root);
|
||||||
URL resource = Objects.requireNonNull(Context.class.getResource("/css/root-view.css"));
|
URL resource = Objects.requireNonNull(Context.class.getResource("/css/root.css"));
|
||||||
scene.getStylesheets().addAll(resource.toExternalForm());
|
scene.getStylesheets().addAll(resource.toExternalForm());
|
||||||
scene.setFill(Color.TRANSPARENT);
|
scene.setFill(Color.TRANSPARENT);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 设置当前展示的界面
|
||||||
* 设置当前展示的界面
|
public static void setCurrentViewIndex(Number newValue) {
|
||||||
*
|
currentViewIndexProperty.setValue(newValue);
|
||||||
* @param index 界面Index
|
|
||||||
*/
|
|
||||||
public static void setCurrentViewIndex(Number index) {
|
|
||||||
currentViewIndexProperty.setValue(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 获取当前展示的界面Index
|
||||||
* 获取当前展示的界面Index
|
|
||||||
*
|
|
||||||
* @return 界面Index
|
|
||||||
*/
|
|
||||||
public static Integer getCurrentViewIndex() {
|
public static Integer getCurrentViewIndex() {
|
||||||
return currentViewIndexProperty.get();
|
return currentViewIndexProperty.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void bindShadow(Pane pane) {
|
||||||
|
Pane root = new Pane();
|
||||||
|
root.setPadding(new Insets(20, 20, 20, 20));
|
||||||
|
DropShadow dropshadow = new DropShadow();// 阴影向外
|
||||||
|
dropshadow.setRadius(10);// 颜色蔓延的距离
|
||||||
|
dropshadow.setOffsetX(0);// 水平方向,0则向左右两侧,正则向右,负则向左
|
||||||
|
dropshadow.setOffsetY(0);// 垂直方向,0则向上下两侧,正则向下,负则向上
|
||||||
|
dropshadow.setSpread(0.1);// 颜色变淡的程度
|
||||||
|
dropshadow.setColor(Color.BLACK);// 设置颜色
|
||||||
|
root.setEffect(dropshadow);// 绑定指定窗口控件
|
||||||
|
root.getChildren().addAll(pane);
|
||||||
|
}
|
||||||
}
|
}
|
@ -47,7 +47,6 @@ public class RootController extends BaseController<VBox> {
|
|||||||
public Button github;
|
public Button github;
|
||||||
@FXML
|
@FXML
|
||||||
public Button sponsor;
|
public Button sponsor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取根布局
|
* 获取根布局
|
||||||
*
|
*
|
||||||
@ -72,19 +71,12 @@ public class RootController extends BaseController<VBox> {
|
|||||||
@Override
|
@Override
|
||||||
public void initViewStyle() {
|
public void initViewStyle() {
|
||||||
// 设置图标
|
// 设置图标
|
||||||
EmojiData.emojiFromShortName("book").ifPresent(icon -> {
|
ImageView book = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("book").get(), 25);
|
||||||
ImageView book = EmojiImageUtils.emojiView(icon, 25);
|
document.setGraphic(book);
|
||||||
document.setGraphic(book);
|
ImageView githubIcon = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("cat").get(), 25);
|
||||||
});
|
github.setGraphic(githubIcon);
|
||||||
EmojiData.emojiFromShortName("cat").ifPresent(icon -> {
|
ImageView juice = EmojiImageUtils.emojiView(EmojiData.emojiFromShortName("tropical_drink").get(), 25);
|
||||||
ImageView githubIcon = EmojiImageUtils.emojiView(icon, 25);
|
sponsor.setGraphic(juice);
|
||||||
github.setGraphic(githubIcon);
|
|
||||||
|
|
||||||
});
|
|
||||||
EmojiData.emojiFromShortName("tropical_drink").ifPresent(icon -> {
|
|
||||||
ImageView juice = EmojiImageUtils.emojiView(icon, 25);
|
|
||||||
sponsor.setGraphic(juice);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,9 +84,9 @@ public class RootController extends BaseController<VBox> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initViewAction() {
|
public void initViewAction() {
|
||||||
closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().close());
|
closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> getWindow().close());
|
||||||
minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().setIconified(true));
|
minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> getWindow().setIconified(true));
|
||||||
alwaysOnTopIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> {
|
alwaysOnTopIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
boolean newVal = !getWindow().isAlwaysOnTop();
|
boolean newVal = !getWindow().isAlwaysOnTop();
|
||||||
alwaysOnTopIcon.pseudoClassStateChanged(PseudoClass.getPseudoClass("always-on-top"), newVal);
|
alwaysOnTopIcon.pseudoClassStateChanged(PseudoClass.getPseudoClass("always-on-top"), newVal);
|
||||||
getWindow().setAlwaysOnTop(newVal);
|
getWindow().setAlwaysOnTop(newVal);
|
||||||
@ -109,8 +101,8 @@ public class RootController extends BaseController<VBox> {
|
|||||||
getWindow().setY(event.getScreenY() + yOffset);
|
getWindow().setY(event.getScreenY() + yOffset);
|
||||||
});
|
});
|
||||||
|
|
||||||
tabPane.getSelectionModel()
|
tabPane.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
.selectedIndexProperty()
|
Context.setCurrentViewIndex(newValue);
|
||||||
.addListener((_, _, newValue) -> Context.setCurrentViewIndex(newValue));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package cn.octopusyan.alistgui.controller;
|
package cn.octopusyan.alistgui.controller;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
|
import cn.octopusyan.alistgui.config.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
|
||||||
import cn.octopusyan.alistgui.viewModel.SetupViewModel;
|
import cn.octopusyan.alistgui.viewModel.SetupViewModel;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -22,11 +22,11 @@ import java.util.Locale;
|
|||||||
*
|
*
|
||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public class SetupController extends BaseController<AnchorPane> implements Initializable {
|
public class SetupController extends BaseController<GridPane> implements Initializable {
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public AnchorPane setupView;
|
public GridPane setupView;
|
||||||
@FXML
|
@FXML
|
||||||
public CheckBox autoStartCheckBox;
|
public CheckBox autoStartCheckBox;
|
||||||
@FXML
|
@FXML
|
||||||
@ -35,23 +35,26 @@ public class SetupController extends BaseController<AnchorPane> implements Initi
|
|||||||
public ComboBox<Locale> languageComboBox;
|
public ComboBox<Locale> languageComboBox;
|
||||||
@FXML
|
@FXML
|
||||||
public ComboBox<ProxySetup> proxySetupComboBox;
|
public ComboBox<ProxySetup> proxySetupComboBox;
|
||||||
|
// @FXML
|
||||||
|
// public RadioButton noProxy;
|
||||||
|
// @FXML
|
||||||
|
// public RadioButton systemProxy;
|
||||||
|
// @FXML
|
||||||
|
// public RadioButton manualProxy;
|
||||||
@FXML
|
@FXML
|
||||||
public Pane proxySetupPane;
|
public Pane proxySetupPane;
|
||||||
@FXML
|
@FXML
|
||||||
public Button proxyCheck;
|
|
||||||
@FXML
|
|
||||||
public TextField proxyHost;
|
public TextField proxyHost;
|
||||||
@FXML
|
@FXML
|
||||||
public TextField proxyPort;
|
public TextField proxyPort;
|
||||||
@FXML
|
@FXML
|
||||||
public Label aListVersion;
|
public Label alistVersion;
|
||||||
@FXML
|
|
||||||
public Button checkAppVersion;
|
|
||||||
|
|
||||||
private final SetupViewModel setupViewModel = new SetupViewModel();
|
private final SetupViewModel setupViewModel = new SetupViewModel();
|
||||||
|
private final ToggleGroup proxySetupGroup = new ToggleGroup();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnchorPane getRootPanel() {
|
public GridPane getRootPanel() {
|
||||||
return setupView;
|
return setupView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,13 +63,18 @@ public class SetupController extends BaseController<AnchorPane> implements Initi
|
|||||||
languageComboBox.setItems(FXCollections.observableList(Context.SUPPORT_LANGUAGE_LIST));
|
languageComboBox.setItems(FXCollections.observableList(Context.SUPPORT_LANGUAGE_LIST));
|
||||||
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
||||||
|
|
||||||
|
// noProxy.setToggleGroup(proxySetupGroup);
|
||||||
|
// systemProxy.setToggleGroup(proxySetupGroup);
|
||||||
|
// manualProxy.setToggleGroup(proxySetupGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initViewStyle() {
|
public void initViewStyle() {
|
||||||
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener(observable -> {
|
||||||
|
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(setupViewModel.proxySetupProperty().get()));
|
||||||
|
});
|
||||||
|
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue));
|
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue));
|
||||||
proxyCheck.setVisible(!ProxySetup.NO_PROXY.equals(newValue));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
||||||
@ -77,19 +85,15 @@ public class SetupController extends BaseController<AnchorPane> implements Initi
|
|||||||
public void initViewAction() {
|
public void initViewAction() {
|
||||||
autoStartCheckBox.selectedProperty().bindBidirectional(setupViewModel.autoStartProperty());
|
autoStartCheckBox.selectedProperty().bindBidirectional(setupViewModel.autoStartProperty());
|
||||||
silentStartupCheckBox.selectedProperty().bindBidirectional(setupViewModel.silentStartupProperty());
|
silentStartupCheckBox.selectedProperty().bindBidirectional(setupViewModel.silentStartupProperty());
|
||||||
proxySetupComboBox.getSelectionModel().selectedItemProperty()
|
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
.addListener((_, _, newValue) -> setupViewModel.proxySetupProperty().set(newValue));
|
setupViewModel.proxySetupProperty().set(newValue);
|
||||||
|
});
|
||||||
proxyHost.textProperty().bindBidirectional(setupViewModel.proxyHostProperty());
|
proxyHost.textProperty().bindBidirectional(setupViewModel.proxyHostProperty());
|
||||||
proxyPort.textProperty().bindBidirectional(setupViewModel.proxyPortProperty());
|
proxyPort.textProperty().bindBidirectional(setupViewModel.proxyPortProperty());
|
||||||
languageComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
languageComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
setupViewModel.languageProperty().set(newValue);
|
setupViewModel.languageProperty().set(newValue);
|
||||||
logger.info("language changed to {}", newValue);
|
logger.info("language changed to {}", newValue);
|
||||||
});
|
});
|
||||||
aListVersion.textProperty().bindBidirectional(setupViewModel.aListVersionProperty());
|
alistVersion.textProperty().bindBidirectional(setupViewModel.aListVersionProperty());
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void checkAListUpdate() {
|
|
||||||
setupViewModel.checkAListUpdate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,181 +0,0 @@
|
|||||||
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> T loadConfig(String path, Class<T> 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 <T> void checkFile(File src, Class<T> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,10 @@
|
|||||||
package cn.octopusyan.alistgui.manager.http;
|
package cn.octopusyan.alistgui.manager.http;
|
||||||
|
|
||||||
|
import cn.octopusyan.alistgui.config.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
import cn.octopusyan.alistgui.model.ProxyInfo;
|
import cn.octopusyan.alistgui.model.ProxyInfo;
|
||||||
import cn.octopusyan.alistgui.util.JsonUtil;
|
import cn.octopusyan.alistgui.util.JsonUtil;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.github.markusbernhardt.proxy.ProxySearch;
|
|
||||||
import com.github.markusbernhardt.proxy.selector.misc.BufferedProxySelector;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@ -29,19 +28,6 @@ public class HttpUtil {
|
|||||||
private volatile static HttpUtil util;
|
private volatile static HttpUtil util;
|
||||||
private volatile HttpClient httpClient;
|
private volatile HttpClient httpClient;
|
||||||
private final HttpConfig httpConfig;
|
private final HttpConfig httpConfig;
|
||||||
public static final ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();
|
|
||||||
|
|
||||||
static {
|
|
||||||
proxySearch.addStrategy(ProxySearch.Strategy.WIN);
|
|
||||||
proxySearch.addStrategy(ProxySearch.Strategy.OS_DEFAULT);
|
|
||||||
proxySearch.addStrategy(ProxySearch.Strategy.IE);
|
|
||||||
proxySearch.addStrategy(ProxySearch.Strategy.FIREFOX);
|
|
||||||
proxySearch.addStrategy(ProxySearch.Strategy.JAVA);
|
|
||||||
// PAC 代理查询
|
|
||||||
proxySearch.setPacCacheSettings(20, 1000 * 60 * 10, BufferedProxySelector.CacheScope.CACHE_SCOPE_HOST);
|
|
||||||
// 设置系统默认代理
|
|
||||||
ProxySelector.setDefault(proxySearch.getProxySelector());
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpUtil(HttpConfig httpConfig) {
|
private HttpUtil(HttpConfig httpConfig) {
|
||||||
this.httpConfig = httpConfig;
|
this.httpConfig = httpConfig;
|
||||||
@ -83,7 +69,7 @@ public class HttpUtil {
|
|||||||
case NO_PROXY -> clearProxy();
|
case NO_PROXY -> clearProxy();
|
||||||
case SYSTEM -> httpConfig.setProxySelector(ProxySelector.getDefault());
|
case SYSTEM -> httpConfig.setProxySelector(ProxySelector.getDefault());
|
||||||
case MANUAL -> {
|
case MANUAL -> {
|
||||||
InetSocketAddress unresolved = InetSocketAddress.createUnresolved(proxy.getHost(), Integer.parseInt(proxy.getPort()));
|
InetSocketAddress unresolved = InetSocketAddress.createUnresolved(ConfigManager.proxyHost(), ConfigManager.getProxyPort());
|
||||||
httpConfig.setProxySelector(ProxySelector.of(unresolved));
|
httpConfig.setProxySelector(ProxySelector.of(unresolved));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,71 @@
|
|||||||
package cn.octopusyan.alistgui.model;
|
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 cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
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 lombok.Data;
|
import lombok.Data;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GUI配置信息
|
* GUI配置信息
|
||||||
|
* 通过Jackson 写入yaml
|
||||||
*
|
*
|
||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GuiConfig {
|
public class GuiConfig {
|
||||||
private static final Logger log = LoggerFactory.getLogger(GuiConfig.class);
|
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 autoStart = false;
|
||||||
private Boolean silentStartup = false;
|
private Boolean silentStartup = false;
|
||||||
private ProxyInfo proxyInfo;
|
private ProxyInfo proxyInfo = new ProxyInfo();
|
||||||
private String proxySetup = ProxySetup.NO_PROXY.getName();
|
private String proxySetup = ProxySetup.NO_PROXY.getName();
|
||||||
private String language = ConfigManager.DEFAULT_LANGUAGE.toString();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
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";
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.model.upgrade;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author octopus_yan
|
|
||||||
*/
|
|
||||||
public interface UpgradeApp {
|
|
||||||
String getOwner();
|
|
||||||
|
|
||||||
String getRepo();
|
|
||||||
|
|
||||||
String getReleaseFile();
|
|
||||||
|
|
||||||
String getVersion();
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
228
src/main/java/cn/octopusyan/alistgui/util/AlertUtil.java
Normal file
228
src/main/java/cn/octopusyan/alistgui/util/AlertUtil.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
package cn.octopusyan.alistgui.util;
|
||||||
|
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.Window;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹窗工具
|
||||||
|
*
|
||||||
|
* @author octopus_yan@foxmail.com
|
||||||
|
*/
|
||||||
|
public class AlertUtil {
|
||||||
|
private static Window mOwner;
|
||||||
|
private static Builder builder;
|
||||||
|
|
||||||
|
public static void initOwner(Stage stage) {
|
||||||
|
AlertUtil.mOwner = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder<T extends Dialog> {
|
||||||
|
T alert;
|
||||||
|
|
||||||
|
public Builder(T alert) {
|
||||||
|
this.alert = alert;
|
||||||
|
if (mOwner != null) this.alert.initOwner(mOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> title(String title) {
|
||||||
|
alert.setTitle(title);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> header(String header) {
|
||||||
|
alert.setHeaderText(header);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> content(String content) {
|
||||||
|
alert.setContentText(content);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> icon(String path) {
|
||||||
|
icon(new Image(Objects.requireNonNull(this.getClass().getResource(path)).toString()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> icon(Image image) {
|
||||||
|
getStage().getIcons().add(image);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
if (AlertUtil.builder == null) {
|
||||||
|
AlertUtil.builder = this;
|
||||||
|
} else if (AlertUtil.builder.alert.isShowing()) {
|
||||||
|
if (!Objects.equals(AlertUtil.builder.alert.getContentText(), alert.getContentText()))
|
||||||
|
((Alert) AlertUtil.builder.alert).setOnHidden(event -> {
|
||||||
|
AlertUtil.builder = null;
|
||||||
|
show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlertUtil.confirm
|
||||||
|
*/
|
||||||
|
public void show(OnClickListener listener) {
|
||||||
|
|
||||||
|
Optional<ButtonType> result = alert.showAndWait();
|
||||||
|
|
||||||
|
listener.onClicked(result.get().getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlertUtil.confirm
|
||||||
|
*/
|
||||||
|
public void show(OnChoseListener listener) {
|
||||||
|
Optional<ButtonType> result = alert.showAndWait();
|
||||||
|
if (result.get() == ButtonType.OK) {
|
||||||
|
listener.confirm();
|
||||||
|
} else {
|
||||||
|
listener.cancelOrClose(result.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlertUtil.input
|
||||||
|
* 如果用户点击了取消按钮,将会返回null
|
||||||
|
*/
|
||||||
|
public String getInput() {
|
||||||
|
Optional<String> result = alert.showAndWait();
|
||||||
|
if (result.isPresent()) {
|
||||||
|
return result.get();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlertUtil.choices
|
||||||
|
*/
|
||||||
|
public <R> R getChoice(R... choices) {
|
||||||
|
Optional result = alert.showAndWait();
|
||||||
|
return (R) result.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stage getStage() {
|
||||||
|
return (Stage) alert.getDialogPane().getScene().getWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<Alert> info(String content) {
|
||||||
|
return new Builder<Alert>(new Alert(Alert.AlertType.INFORMATION)).content(content).header(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<Alert> info() {
|
||||||
|
return new Builder<Alert>(new Alert(Alert.AlertType.INFORMATION));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<Alert> error(String message) {
|
||||||
|
return new Builder<Alert>(new Alert(Alert.AlertType.ERROR)).header(null).content(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<Alert> warning() {
|
||||||
|
return new Builder<Alert>(new Alert(Alert.AlertType.WARNING));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<Alert> exception(Exception ex) {
|
||||||
|
return new Builder<Alert>(exceptionAlert(ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Alert exceptionAlert(Exception ex) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Exception Dialog");
|
||||||
|
alert.setHeaderText(ex.getClass().getSimpleName());
|
||||||
|
alert.setContentText(ex.getMessage());
|
||||||
|
|
||||||
|
// 创建可扩展的异常。
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
ex.printStackTrace(pw);
|
||||||
|
String exceptionText = sw.toString();
|
||||||
|
|
||||||
|
Label label = new Label("The exception stacktrace was :");
|
||||||
|
|
||||||
|
TextArea textArea = new TextArea(exceptionText);
|
||||||
|
textArea.setEditable(false);
|
||||||
|
textArea.setWrapText(true);
|
||||||
|
|
||||||
|
textArea.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
textArea.setMaxHeight(Double.MAX_VALUE);
|
||||||
|
GridPane.setVgrow(textArea, Priority.ALWAYS);
|
||||||
|
GridPane.setHgrow(textArea, Priority.ALWAYS);
|
||||||
|
|
||||||
|
GridPane expContent = new GridPane();
|
||||||
|
expContent.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
expContent.add(label, 0, 0);
|
||||||
|
expContent.add(textArea, 0, 1);
|
||||||
|
|
||||||
|
// 将可扩展异常设置到对话框窗格中。
|
||||||
|
alert.getDialogPane().setExpandableContent(expContent);
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认对话框
|
||||||
|
*/
|
||||||
|
public static Builder<Alert> confirm() {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setTitle("确认对话框");
|
||||||
|
return new Builder<Alert>(alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义确认对话框 <p>
|
||||||
|
* <code>"Cancel"</code> OR <code>"取消"</code> 为取消按钮
|
||||||
|
*/
|
||||||
|
public static Builder<Alert> confirm(String... buttons) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
|
||||||
|
List<ButtonType> buttonList = Arrays.stream(buttons).map((type) -> {
|
||||||
|
ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER;
|
||||||
|
if ("Cancel".equals(type) || "取消".equals(type))
|
||||||
|
buttonData = ButtonBar.ButtonData.CANCEL_CLOSE;
|
||||||
|
return new ButtonType(type, buttonData);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
alert.getButtonTypes().setAll(buttonList);
|
||||||
|
|
||||||
|
return new Builder<Alert>(alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder<TextInputDialog> input(String content) {
|
||||||
|
TextInputDialog dialog = new TextInputDialog();
|
||||||
|
dialog.setContentText(content);
|
||||||
|
return new Builder<TextInputDialog>(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <T> Builder<ChoiceDialog<T>> choices(String hintText, T... choices) {
|
||||||
|
ChoiceDialog<T> dialog = new ChoiceDialog<T>(choices[0], choices);
|
||||||
|
dialog.setContentText(hintText);
|
||||||
|
return new Builder<ChoiceDialog<T>>(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface OnChoseListener {
|
||||||
|
void confirm();
|
||||||
|
|
||||||
|
void cancelOrClose(ButtonType buttonType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnClickListener {
|
||||||
|
void onClicked(String result);
|
||||||
|
}
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
|
||||||
|
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.ButtonType;
|
|
||||||
import javafx.stage.Window;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author octopus_yan
|
|
||||||
*/
|
|
||||||
public class AlertBuilder extends BaseBuilder<Alert, ButtonType> {
|
|
||||||
|
|
||||||
public AlertBuilder(Alert alert, Window owner) {
|
|
||||||
super(alert, owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AlertUtil.confirm
|
|
||||||
*/
|
|
||||||
public void show(AlertUtil.OnClickListener listener) {
|
|
||||||
Optional<ButtonType> result = alert.showAndWait();
|
|
||||||
result.ifPresent(r -> listener.onClicked(r.getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AlertUtil.confirm
|
|
||||||
*/
|
|
||||||
public void show(AlertUtil.OnChoseListener listener) {
|
|
||||||
Optional<ButtonType> result = alert.showAndWait();
|
|
||||||
result.ifPresent(r -> {
|
|
||||||
if (r == ButtonType.OK) {
|
|
||||||
listener.confirm();
|
|
||||||
} else {
|
|
||||||
listener.cancelOrClose(r);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
|
||||||
|
|
||||||
import javafx.scene.control.*;
|
|
||||||
import javafx.scene.layout.GridPane;
|
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import javafx.stage.Window;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 弹窗工具
|
|
||||||
*
|
|
||||||
* @author octopus_yan@foxmail.com
|
|
||||||
*/
|
|
||||||
public class AlertUtil {
|
|
||||||
private static Window mOwner;
|
|
||||||
|
|
||||||
public static void initOwner(Stage stage) {
|
|
||||||
AlertUtil.mOwner = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlertBuilder info(String content) {
|
|
||||||
AlertBuilder alertBuilder = new AlertBuilder(new Alert(Alert.AlertType.INFORMATION), mOwner);
|
|
||||||
alertBuilder.content(content).header(null);
|
|
||||||
return alertBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlertBuilder info() {
|
|
||||||
return new AlertBuilder(new Alert(Alert.AlertType.INFORMATION), mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlertBuilder error(String message) {
|
|
||||||
AlertBuilder alertBuilder = new AlertBuilder(new Alert(Alert.AlertType.ERROR), mOwner);
|
|
||||||
alertBuilder.header(null).content(message);
|
|
||||||
return alertBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlertBuilder warning() {
|
|
||||||
return new AlertBuilder(new Alert(Alert.AlertType.WARNING), mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AlertBuilder exception(Exception ex) {
|
|
||||||
return new AlertBuilder(exceptionAlert(ex), mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Alert exceptionAlert(Exception ex) {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
|
||||||
alert.setTitle("Exception Dialog");
|
|
||||||
alert.setHeaderText(ex.getClass().getSimpleName());
|
|
||||||
alert.setContentText(ex.getMessage());
|
|
||||||
|
|
||||||
// 创建可扩展的异常。
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
ex.printStackTrace(pw);
|
|
||||||
String exceptionText = sw.toString();
|
|
||||||
|
|
||||||
Label label = new Label("The exception stacktrace was :");
|
|
||||||
|
|
||||||
TextArea textArea = new TextArea(exceptionText);
|
|
||||||
textArea.setEditable(false);
|
|
||||||
textArea.setWrapText(true);
|
|
||||||
|
|
||||||
textArea.setMaxWidth(Double.MAX_VALUE);
|
|
||||||
textArea.setMaxHeight(Double.MAX_VALUE);
|
|
||||||
GridPane.setVgrow(textArea, Priority.ALWAYS);
|
|
||||||
GridPane.setHgrow(textArea, Priority.ALWAYS);
|
|
||||||
|
|
||||||
GridPane expContent = new GridPane();
|
|
||||||
expContent.setMaxWidth(Double.MAX_VALUE);
|
|
||||||
expContent.add(label, 0, 0);
|
|
||||||
expContent.add(textArea, 0, 1);
|
|
||||||
|
|
||||||
// 将可扩展异常设置到对话框窗格中。
|
|
||||||
alert.getDialogPane().setExpandableContent(expContent);
|
|
||||||
return alert;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确认对话框
|
|
||||||
*/
|
|
||||||
public static AlertBuilder confirm() {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
||||||
alert.setTitle("确认对话框");
|
|
||||||
return new AlertBuilder(alert, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义确认对话框 <p>
|
|
||||||
* <code>"Cancel"</code> OR <code>"取消"</code> 为取消按钮
|
|
||||||
*/
|
|
||||||
public static AlertBuilder confirm(String... buttons) {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
||||||
|
|
||||||
List<ButtonType> buttonList = Arrays.stream(buttons).map((type) -> {
|
|
||||||
ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER;
|
|
||||||
if ("cancel".equals(StringUtils.lowerCase(type)) || "取消".equals(type))
|
|
||||||
buttonData = ButtonBar.ButtonData.CANCEL_CLOSE;
|
|
||||||
return new ButtonType(type, buttonData);
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
|
|
||||||
alert.getButtonTypes().setAll(buttonList);
|
|
||||||
|
|
||||||
return new AlertBuilder(alert, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TextInputBuilder input(String content) {
|
|
||||||
TextInputDialog dialog = new TextInputDialog();
|
|
||||||
dialog.setContentText(content);
|
|
||||||
return new TextInputBuilder(dialog, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SafeVarargs
|
|
||||||
public static <T> ChoiceBuilder<T> choices(String hintText, T... choices) {
|
|
||||||
ChoiceDialog<T> dialog = new ChoiceDialog<>(choices[0], choices);
|
|
||||||
dialog.setContentText(hintText);
|
|
||||||
return new ChoiceBuilder<>(dialog, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface OnChoseListener {
|
|
||||||
void confirm();
|
|
||||||
|
|
||||||
void cancelOrClose(ButtonType buttonType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnClickListener {
|
|
||||||
void onClicked(String result);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
|
||||||
|
|
||||||
import javafx.scene.control.Dialog;
|
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import javafx.stage.Window;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author octopus_yan
|
|
||||||
*/
|
|
||||||
public abstract class BaseBuilder<T extends Dialog<R>, R> {
|
|
||||||
T alert;
|
|
||||||
|
|
||||||
public BaseBuilder(T alert, Window mOwner) {
|
|
||||||
this.alert = alert;
|
|
||||||
if (mOwner != null)
|
|
||||||
this.alert.initOwner(mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseBuilder<T, R> title(String title) {
|
|
||||||
alert.setTitle(title);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseBuilder<T, R> header(String header) {
|
|
||||||
alert.setHeaderText(header);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseBuilder<T, R> content(String content) {
|
|
||||||
alert.setContentText(content);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseBuilder<T, R> icon(String path) {
|
|
||||||
return icon(new Image(Objects.requireNonNull(this.getClass().getResource(path)).toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseBuilder<T, R> icon(Image image) {
|
|
||||||
getStage().getIcons().add(image);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
|
||||||
if (alert.isShowing()) {
|
|
||||||
if (!Objects.equals(alert.getContentText(), alert.getContentText()))
|
|
||||||
alert.setOnHidden(_ -> show());
|
|
||||||
}
|
|
||||||
alert.showAndWait();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stage getStage() {
|
|
||||||
return (Stage) alert.getDialogPane().getScene().getWindow();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
|
||||||
|
|
||||||
import javafx.scene.control.ChoiceDialog;
|
|
||||||
import javafx.stage.Window;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author octopus_yan
|
|
||||||
*/
|
|
||||||
public class ChoiceBuilder<R> extends BaseBuilder<ChoiceDialog<R>, R> {
|
|
||||||
public ChoiceBuilder(ChoiceDialog<R> alert, Window mOwner) {
|
|
||||||
super(alert, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AlertUtil.choices
|
|
||||||
*/
|
|
||||||
public R getChoice(Collection<R> choices) {
|
|
||||||
Optional<R> result = alert.showAndWait();
|
|
||||||
return result.orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
|
||||||
|
|
||||||
import javafx.scene.control.TextInputDialog;
|
|
||||||
import javafx.stage.Window;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author octopus_yan
|
|
||||||
*/
|
|
||||||
public class TextInputBuilder extends BaseBuilder<TextInputDialog, String>{
|
|
||||||
public TextInputBuilder(TextInputDialog alert, Window mOwner) {
|
|
||||||
super(alert, mOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AlertUtil.input
|
|
||||||
* 如果用户点击了取消按钮,将会返回null
|
|
||||||
*/
|
|
||||||
public String getInput() {
|
|
||||||
Optional<String> result = alert.showAndWait();
|
|
||||||
return result.orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,12 @@
|
|||||||
package cn.octopusyan.alistgui.viewModel;
|
package cn.octopusyan.alistgui.viewModel;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseTask;
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import cn.hutool.core.net.url.UrlBuilder;
|
||||||
|
import cn.octopusyan.alistgui.config.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
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 javafx.beans.property.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -20,21 +20,19 @@ public class SetupViewModel {
|
|||||||
private final BooleanProperty silentStartup = new SimpleBooleanProperty(ConfigManager.silentStartup());
|
private final BooleanProperty silentStartup = new SimpleBooleanProperty(ConfigManager.silentStartup());
|
||||||
private final StringProperty proxyHost = new SimpleStringProperty(ConfigManager.proxyHost());
|
private final StringProperty proxyHost = new SimpleStringProperty(ConfigManager.proxyHost());
|
||||||
private final StringProperty proxyPort = new SimpleStringProperty(ConfigManager.proxyPort());
|
private final StringProperty proxyPort = new SimpleStringProperty(ConfigManager.proxyPort());
|
||||||
|
private final BooleanProperty proxyVerify = new SimpleBooleanProperty(false);
|
||||||
private final ObjectProperty<Locale> language = new SimpleObjectProperty<>(ConfigManager.language());
|
private final ObjectProperty<Locale> language = new SimpleObjectProperty<>(ConfigManager.language());
|
||||||
private final ObjectProperty<ProxySetup> proxySetup = new SimpleObjectProperty<>(ConfigManager.proxySetup());
|
private final ObjectProperty<ProxySetup> proxySetup = new SimpleObjectProperty<>(ConfigManager.proxySetup());
|
||||||
private final StringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
|
private final SimpleStringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
|
||||||
private final StringProperty aListNewVersion = new SimpleStringProperty("");
|
|
||||||
private final BooleanProperty aListUpgrade = new SimpleBooleanProperty(false);
|
|
||||||
|
|
||||||
|
|
||||||
public SetupViewModel() {
|
public SetupViewModel() {
|
||||||
aListVersion.addListener((_, _, newValue) -> ConfigManager.aListVersion(newValue));
|
aListVersion.addListener((observable, oldValue, newValue) -> ConfigManager.aListVersion(newValue));
|
||||||
autoStart.addListener((_, _, newValue) -> ConfigManager.autoStart(newValue));
|
autoStart.addListener((observable, oldValue, newValue) -> ConfigManager.autoStart(newValue));
|
||||||
silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
|
silentStartup.addListener((observable, oldValue, newValue) -> ConfigManager.silentStartup(newValue));
|
||||||
proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue));
|
proxySetup.addListener((observable, oldValue, newValue) -> ConfigManager.proxySetup(newValue));
|
||||||
proxyHost.addListener((_, _, newValue) -> ConfigManager.proxyHost(newValue));
|
proxyHost.addListener((observable, oldValue, newValue) -> ConfigManager.proxyHost(newValue));
|
||||||
proxyPort.addListener((_, _, newValue) -> ConfigManager.proxyPort(newValue));
|
proxyPort.addListener((observable, oldValue, newValue) -> ConfigManager.proxyPort(newValue));
|
||||||
language.addListener((_, _, newValue) -> Context.setLanguage(newValue));
|
language.addListener((observable, oldValue, newValue) -> Context.setLanguage(newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty autoStartProperty() {
|
public BooleanProperty autoStartProperty() {
|
||||||
@ -65,35 +63,25 @@ public class SetupViewModel {
|
|||||||
return aListVersion;
|
return aListVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty aListUpgradeProperty() {
|
|
||||||
return aListUpgrade;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty aListNewVersionProperty() {
|
|
||||||
return aListNewVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查alist更新
|
* 验证代理地址
|
||||||
|
*
|
||||||
|
* @param address 新的代理地址
|
||||||
|
* @return UrlBuilder, 验证失败时为null
|
||||||
*/
|
*/
|
||||||
public void checkAListUpdate() {
|
public UrlBuilder validateAddress(String address) {
|
||||||
var task = new UpgradeTask(this, ConfigManager.aList());
|
if (StringUtils.isEmpty(address))
|
||||||
task.onListen(new BaseTask.Listener() {
|
return null;
|
||||||
@Override
|
|
||||||
public void onSucceeded() {
|
|
||||||
AlertUtil.info(STR."""
|
|
||||||
当前版本 : \{aListVersion.get()}
|
|
||||||
最新版本 : \{aListNewVersion.get()}
|
|
||||||
""")
|
|
||||||
.title("AList 更新提示")
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// 验证 URL 的可用性
|
||||||
public void onFailed(Throwable throwable) {
|
UrlBuilder ub = UrlBuilder.of(address);
|
||||||
AlertUtil.exception(new Exception(throwable)).show();
|
boolean isUrlValid = Validator.isUrl(address) && ub.getPort() > 0;
|
||||||
}
|
|
||||||
});
|
// 设置 proxyVerify 和 proxyVerifyMsg
|
||||||
task.execute();
|
proxyVerify.setValue(isUrlValid);
|
||||||
|
|
||||||
|
if (isUrlValid)
|
||||||
|
return ub;
|
||||||
|
else return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,9 @@ module cn.octopusyan.alistgui {
|
|||||||
requires com.fasterxml.jackson.databind;
|
requires com.fasterxml.jackson.databind;
|
||||||
requires com.fasterxml.jackson.dataformat.yaml;
|
requires com.fasterxml.jackson.dataformat.yaml;
|
||||||
requires atlantafx.base;
|
requires atlantafx.base;
|
||||||
requires proxy.vole;
|
|
||||||
|
|
||||||
exports cn.octopusyan.alistgui;
|
exports cn.octopusyan.alistgui;
|
||||||
opens cn.octopusyan.alistgui to javafx.fxml;
|
opens cn.octopusyan.alistgui to javafx.fxml;
|
||||||
opens cn.octopusyan.alistgui.model to com.fasterxml.jackson.databind;
|
opens cn.octopusyan.alistgui.model to com.fasterxml.jackson.databind;
|
||||||
opens cn.octopusyan.alistgui.controller to javafx.fxml;
|
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;
|
|
||||||
}
|
}
|
87
src/main/resources/css/main-view.css
Normal file
87
src/main/resources/css/main-view.css
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/**************************************************
|
||||||
|
* Main View
|
||||||
|
**************************************************/
|
||||||
|
#homeLabel {
|
||||||
|
-fx-font-size: 35;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#statusLabel {
|
||||||
|
-fx-padding: 2 5 2 5;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
-fx-font-size: 15;
|
||||||
|
-fx-background-color: #1bc964;
|
||||||
|
-fx-background-radius: 10;
|
||||||
|
-fx-text-alignment: CENTER;
|
||||||
|
-fx-border-radius: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-menu {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-padding: 10 40 10 40;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-border-width: 2;
|
||||||
|
-fx-opacity: 0.9;
|
||||||
|
}
|
||||||
|
.control-menu:hover {
|
||||||
|
-fx-opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton {
|
||||||
|
-fx-background-color: #fa6057;
|
||||||
|
-fx-border-color: #fa6057;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#passwordButton {
|
||||||
|
-fx-background-color: #1bc964;
|
||||||
|
-fx-border-color: #1bc964;
|
||||||
|
}
|
||||||
|
|
||||||
|
#restartButton {
|
||||||
|
-fx-background-color: linear-gradient(#57b4f2, #9198e5);
|
||||||
|
-fx-border-color: linear-gradient(#57b4f2, #9198e5);
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#moreButton {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-text-fill: #9254d1;
|
||||||
|
-fx-border-color: #9254d1;
|
||||||
|
-fx-border-width: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logArea {
|
||||||
|
-fx-font-family: "Lucida Console";
|
||||||
|
-fx-font-size: 20;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-background-insets: 0;
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
#logArea:focused {
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
#logArea .content {
|
||||||
|
-fx-padding: 0 15 0 15;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
}
|
||||||
|
#logArea .content:focused {
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
#logArea .scroll-pane {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
#logArea .scroll-pane .viewport {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=main-view.css.map */
|
1
src/main/resources/css/main-view.css.map
Normal file
1
src/main/resources/css/main-view.css.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sourceRoot":"","sources":["main-view.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAGA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAEA;EACE","file":"main-view.css"}
|
@ -50,6 +50,7 @@
|
|||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
-fx-text-fill: #9254d1;
|
-fx-text-fill: #9254d1;
|
||||||
-fx-border-color: #9254d1;
|
-fx-border-color: #9254d1;
|
||||||
|
-fx-border-width: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#logArea {
|
#logArea {
|
||||||
|
99
src/main/resources/css/root-view.css
Normal file
99
src/main/resources/css/root-view.css
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
@import "root.css";
|
||||||
|
/**************************************************
|
||||||
|
* Window Header
|
||||||
|
**************************************************/
|
||||||
|
#windowHeader .icon-button {
|
||||||
|
-fx-icon-code: fa-circle;
|
||||||
|
-fx-opacity: 0.5;
|
||||||
|
}
|
||||||
|
#windowHeader .icon-button:hover {
|
||||||
|
-fx-opacity: 1;
|
||||||
|
}
|
||||||
|
#windowHeader #closeIcon {
|
||||||
|
-fx-color: #fa6057;
|
||||||
|
-fx-background-color: #fa6057;
|
||||||
|
-fx-icon-color: #fa6057;
|
||||||
|
}
|
||||||
|
#windowHeader #minimizeIcon {
|
||||||
|
-fx-color: #fbbc2e;
|
||||||
|
-fx-background-color: #fbbc2e;
|
||||||
|
-fx-icon-color: #fbbc2e;
|
||||||
|
}
|
||||||
|
#windowHeader #alwaysOnTopIcon {
|
||||||
|
-fx-color: #27c940;
|
||||||
|
-fx-background-color: #27c940;
|
||||||
|
-fx-icon-color: #27c940;
|
||||||
|
}
|
||||||
|
#windowHeader #alwaysOnTopIcon:always-on-top {
|
||||||
|
-fx-opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Tab label
|
||||||
|
**************************************************/
|
||||||
|
#tabPane .tab-header-area {
|
||||||
|
-fx-background-radius: 0 0 0 0;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
#tabPane .headers-region {
|
||||||
|
-fx-alignment: TOP_CENTER;
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-padding: 5 0 5 0;
|
||||||
|
}
|
||||||
|
#tabPane .tab-header-background {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
#tabPane .tab {
|
||||||
|
-fx-padding: 10 20 10 20;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-border-width: 0;
|
||||||
|
}
|
||||||
|
#tabPane .tab .ikonli-font-icon {
|
||||||
|
-fx-icon-color: black;
|
||||||
|
}
|
||||||
|
#tabPane .tab .tab-label {
|
||||||
|
-fx-text-alignment: CENTER;
|
||||||
|
-fx-alignment: CENTER;
|
||||||
|
}
|
||||||
|
#tabPane .tab:selected {
|
||||||
|
-fx-background-color: #2c69e0;
|
||||||
|
}
|
||||||
|
#tabPane .tab:selected .ikonli-font-icon {
|
||||||
|
-fx-icon-color: white;
|
||||||
|
}
|
||||||
|
#tabPane .tab:selected .tab-label {
|
||||||
|
-fx-text-fill: white;
|
||||||
|
}
|
||||||
|
#tabPane .tab:selected .focus-indicator {
|
||||||
|
-fx-border-width: 0;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-border-insets: 0;
|
||||||
|
}
|
||||||
|
#tabPane .tab-label {
|
||||||
|
-fx-font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Window Footer
|
||||||
|
**************************************************/
|
||||||
|
#windowFooter .button {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-text-alignment: CENTER;
|
||||||
|
}
|
||||||
|
#windowFooter #document {
|
||||||
|
-fx-text-fill: #1bc964;
|
||||||
|
}
|
||||||
|
#windowFooter #github {
|
||||||
|
-fx-text-fill: #1f4ca6;
|
||||||
|
}
|
||||||
|
#windowFooter #sponsor {
|
||||||
|
-fx-text-fill: #f22760;
|
||||||
|
}
|
||||||
|
#windowFooter .ikonli-font-icon {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=root-view.css.map */
|
1
src/main/resources/css/root-view.css.map
Normal file
1
src/main/resources/css/root-view.css.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sourceRoot":"","sources":["root-view.scss"],"names":[],"mappings":"AAAQ;AACR;AAAA;AAAA;AAIE;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;;AAMN;AAAA;AAAA;AAME;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAKN;EACE;;;AAIJ;AAAA;AAAA;AAKE;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE","file":"root-view.css"}
|
14
src/main/resources/css/root.css
Normal file
14
src/main/resources/css/root.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**************************************************
|
||||||
|
* Root
|
||||||
|
**************************************************/
|
||||||
|
.root {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
-fx-font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root-pane {
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=root.css.map */
|
1
src/main/resources/css/root.css.map
Normal file
1
src/main/resources/css/root.css.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sourceRoot":"","sources":["root.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAIA;EACE;EACA;;;AAGF;EACE;EACA","file":"root.css"}
|
@ -2,17 +2,13 @@
|
|||||||
* Root
|
* Root
|
||||||
**************************************************/
|
**************************************************/
|
||||||
|
|
||||||
.root-pane {
|
.root {
|
||||||
-fx-font-size: 15;
|
-fx-font-size: 15;
|
||||||
-fx-font-weight: normal;
|
-fx-font-weight: normal;
|
||||||
|
}
|
||||||
-fx-background-radius: 15;
|
|
||||||
-fx-border-radius: 15;
|
.root-pane {
|
||||||
|
-fx-background-radius: 15;
|
||||||
// 窗口阴影
|
-fx-border-radius: 15;
|
||||||
-fx-background-color: rgba(255, 255, 255, 1);
|
|
||||||
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.3), 15, 0, 0, 0);
|
|
||||||
-fx-background-insets: 20;
|
|
||||||
-fx-padding: 20;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/main/resources/css/setup-view.css
Normal file
34
src/main/resources/css/setup-view.css
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**************************************************
|
||||||
|
* Setup View
|
||||||
|
**************************************************/
|
||||||
|
#setupView .check-box {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
}
|
||||||
|
#setupView .proxy-panel {
|
||||||
|
-fx-background-color: #e9e9e9;
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-border-width: 5;
|
||||||
|
}
|
||||||
|
#setupView .proxy-panel .radio-button {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
#setupView .proxy-label {
|
||||||
|
-fx-font-size: 15;
|
||||||
|
-fx-text-fill: #2c69e0;
|
||||||
|
-fx-text-alignment: CENTER;
|
||||||
|
}
|
||||||
|
#setupView .shield .label {
|
||||||
|
-fx-text-fill: white;
|
||||||
|
-fx-label-padding: 3 5 3 5;
|
||||||
|
}
|
||||||
|
#setupView .shield .shield-name {
|
||||||
|
-fx-background-color: #555555;
|
||||||
|
-fx-background-radius: 5 0 0 5;
|
||||||
|
}
|
||||||
|
#setupView .shield .shield-version {
|
||||||
|
-fx-background-color: #6969AA;
|
||||||
|
-fx-background-radius: 0 5 5 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=setup-view.css.map */
|
1
src/main/resources/css/setup-view.css.map
Normal file
1
src/main/resources/css/setup-view.css.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sourceRoot":"","sources":["setup-view.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAKE;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAKA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA","file":"setup-view.css"}
|
@ -3,48 +3,59 @@
|
|||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<AnchorPane fx:id="setupView" prefHeight="700" prefWidth="720" stylesheets="@../css/setup-view.css"
|
<GridPane fx:id="setupView" prefHeight="700" prefWidth="720" stylesheets="@../css/setup-view.css"
|
||||||
xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
|
xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
|
||||||
fx:controller="cn.octopusyan.alistgui.controller.SetupController">
|
fx:controller="cn.octopusyan.alistgui.controller.SetupController">
|
||||||
<padding>
|
<padding>
|
||||||
<Insets left="10.0" right="10.0" top="20.0"/>
|
<Insets left="10.0" right="10.0" top="20.0"/>
|
||||||
</padding>
|
</padding>
|
||||||
<VBox spacing="20" AnchorPane.topAnchor="0" AnchorPane.leftAnchor="0">
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" percentWidth="100"/>
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints vgrow="SOMETIMES"/>
|
||||||
|
</rowConstraints>
|
||||||
|
<VBox spacing="20">
|
||||||
<CheckBox fx:id="autoStartCheckBox" text="%setup.auto-start.label"/>
|
<CheckBox fx:id="autoStartCheckBox" text="%setup.auto-start.label"/>
|
||||||
<CheckBox fx:id="silentStartupCheckBox" text="%setup.silent-startup.label"/>
|
<CheckBox fx:id="silentStartupCheckBox" text="%setup.silent-startup.label"/>
|
||||||
<HBox alignment="CENTER_LEFT" spacing="10">
|
<HBox alignment="CENTER_LEFT" spacing="10">
|
||||||
<Label text="%setup.language"/>
|
<Label text="%setup.language"/>
|
||||||
<ComboBox fx:id="languageComboBox"/>
|
<ComboBox fx:id="languageComboBox"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox alignment="CENTER_LEFT" spacing="20">
|
|
||||||
<Label styleClass="proxy-label" text="%setup.proxy"/>
|
|
||||||
<ComboBox fx:id="proxySetupComboBox"/>
|
|
||||||
<Button fx:id="proxyCheck" text="%setup.proxy.test"/>
|
|
||||||
</HBox>
|
|
||||||
<VBox fx:id="proxySetupPane" spacing="10">
|
|
||||||
<HBox alignment="CENTER_LEFT" spacing="20">
|
<HBox alignment="CENTER_LEFT" spacing="20">
|
||||||
<Label text="%setup.proxy.host"/>
|
<Label text="%setup.proxyInfo" styleClass="proxyInfo-label"/>
|
||||||
<TextField fx:id="proxyHost" promptText="127.0.0.1"/>
|
<ComboBox fx:id="proxySetupComboBox"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox alignment="CENTER_LEFT" spacing="20">
|
<!-- <HBox spacing="10" visible="false">-->
|
||||||
<Label text="%setup.proxy.port"/>
|
<!-- <RadioButton fx:id="noProxy" text="%proxyInfo.setup.label.no_proxy"/>-->
|
||||||
<TextField fx:id="proxyPort" promptText="8080"/>
|
<!-- <RadioButton fx:id="systemProxy" text="%proxyInfo.setup.label.system"/>-->
|
||||||
</HBox>
|
<!-- <RadioButton fx:id="manualProxy" text="%proxyInfo.setup.label.manual"/>-->
|
||||||
</VBox>
|
<!-- </HBox>-->
|
||||||
|
<VBox fx:id="proxySetupPane" spacing="10">
|
||||||
|
<HBox spacing="20" alignment="CENTER_LEFT">
|
||||||
|
<Label text="%setup.proxyInfo.host"/>
|
||||||
|
<TextField fx:id="proxyHost" promptText="127.0.0.1"/>
|
||||||
|
</HBox>
|
||||||
|
<HBox spacing="20" alignment="CENTER_LEFT">
|
||||||
|
<Label text="%setup.proxyInfo.port"/>
|
||||||
|
<TextField fx:id="proxyPort" promptText="8080"/>
|
||||||
|
</HBox>
|
||||||
|
</VBox>
|
||||||
</VBox>
|
</VBox>
|
||||||
<AnchorPane AnchorPane.rightAnchor="0" AnchorPane.bottomAnchor="0">
|
<AnchorPane GridPane.rowIndex="1">
|
||||||
<VBox alignment="CENTER" spacing="10" AnchorPane.bottomAnchor="50" AnchorPane.rightAnchor="0"
|
<VBox alignment="CENTER" spacing="10"
|
||||||
AnchorPane.topAnchor="0">
|
AnchorPane.bottomAnchor="50" AnchorPane.rightAnchor="0" AnchorPane.topAnchor="0">
|
||||||
<HBox alignment="CENTER" styleClass="shield">
|
<HBox alignment="CENTER" styleClass="shield">
|
||||||
<Label styleClass="shield-name" text="%alist.version"/>
|
<Label text="%alist.version" styleClass="shield-name"/>
|
||||||
<Label fx:id="aListVersion" styleClass="shield-version"/>
|
<Label fx:id="alistVersion" styleClass="shield-version"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox alignment="CENTER" styleClass="shield">
|
<HBox alignment="CENTER" styleClass="shield">
|
||||||
<Label styleClass="shield-name" text="%app.version"/>
|
<Label text="%app.version" styleClass="shield-name"/>
|
||||||
<Label styleClass="shield-version" text="v${project.version}"/>
|
<Label text="${project.version}" styleClass="shield-version"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<Button fx:id="checkAppVersion" text="%app.update"/>
|
<Button text="%app.update"/>
|
||||||
<Button fx:id="checkAListVersion" onAction="#checkAListUpdate" text="%alist.update"/>
|
<Button text="%alist.update"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
</AnchorPane>
|
</GridPane>
|
||||||
|
@ -11,7 +11,7 @@ main.status.label-running=\u8FD0\u884C\u4E2D
|
|||||||
main.status.label-stop=\u5DF2\u505C\u6B62
|
main.status.label-stop=\u5DF2\u505C\u6B62
|
||||||
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
|
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
|
||||||
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
|
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
|
||||||
setup.proxy=HTTP\u4EE3\u7406
|
setup.proxyInfo=HTTP\u4EE3\u7406
|
||||||
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
|
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
|
||||||
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
|
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
|
||||||
setup.language=\u8BED\u8A00
|
setup.language=\u8BED\u8A00
|
||||||
@ -19,10 +19,9 @@ alist.version=AList \u7248\u672C
|
|||||||
app.version=GUI \u7248\u672C
|
app.version=GUI \u7248\u672C
|
||||||
alist.update=\u68C0\u67E5 AList \u7248\u672C
|
alist.update=\u68C0\u67E5 AList \u7248\u672C
|
||||||
app.update=\u68C0\u67E5 GUI \u7248\u672C
|
app.update=\u68C0\u67E5 GUI \u7248\u672C
|
||||||
setup.proxy.host=\u4E3B\u673A
|
setup.proxyInfo.host=\u4E3B\u673A
|
||||||
setup.proxy.port=\u7AEF\u53E3
|
setup.proxyInfo.port=\u7AEF\u53E3
|
||||||
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
|
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
|
||||||
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
|
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
|
||||||
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
|
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
|
||||||
setup.proxy.test=\u6D4B\u8BD5
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ main.status.label-running=Running
|
|||||||
main.status.label-stop=Stoped
|
main.status.label-stop=Stoped
|
||||||
main.more.browser=Open in browser
|
main.more.browser=Open in browser
|
||||||
main.more.open-log=Open the log folder
|
main.more.open-log=Open the log folder
|
||||||
setup.proxy=HTTP PROXY
|
setup.proxyInfo=HTTP PROXY
|
||||||
setup.auto-start.label=Auto start with PC
|
setup.auto-start.label=Auto start with PC
|
||||||
setup.silent-startup.label=Silent startup
|
setup.silent-startup.label=Silent startup
|
||||||
setup.language=language
|
setup.language=language
|
||||||
@ -19,10 +19,9 @@ alist.version=AList Version
|
|||||||
app.version=GUI Version
|
app.version=GUI Version
|
||||||
alist.update=Check AList Version
|
alist.update=Check AList Version
|
||||||
app.update=Check GUI Version
|
app.update=Check GUI Version
|
||||||
setup.proxy.host=Host
|
setup.proxyInfo.host=Host
|
||||||
setup.proxy.port=Port
|
setup.proxyInfo.port=Port
|
||||||
proxy.setup.label.no_proxy=No Proxy
|
proxy.setup.label.no_proxy=No Proxy
|
||||||
proxy.setup.label.system=System Proxy
|
proxy.setup.label.system=System Proxy
|
||||||
proxy.setup.label.manual=Manual Config
|
proxy.setup.label.manual=Manual Config
|
||||||
setup.proxy.test=Check connection
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ main.status.label-running=\u8FD0\u884C\u4E2D
|
|||||||
main.status.label-stop=\u5DF2\u505C\u6B62
|
main.status.label-stop=\u5DF2\u505C\u6B62
|
||||||
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
|
main.more.browser=\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00
|
||||||
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
|
main.more.open-log=\u6253\u5F00\u65E5\u5FD7\u6587\u4EF6\u5939
|
||||||
setup.proxy=HTTP\u4EE3\u7406
|
setup.proxyInfo=HTTP\u4EE3\u7406
|
||||||
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
|
setup.auto-start.label=\u5F00\u673A\u81EA\u542F
|
||||||
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
|
setup.silent-startup.label=\u9759\u9ED8\u542F\u52A8
|
||||||
setup.language=\u8BED\u8A00
|
setup.language=\u8BED\u8A00
|
||||||
@ -19,10 +19,9 @@ alist.version=AList \u7248\u672C
|
|||||||
app.version=GUI \u7248\u672C
|
app.version=GUI \u7248\u672C
|
||||||
alist.update=\u68C0\u67E5 AList \u7248\u672C
|
alist.update=\u68C0\u67E5 AList \u7248\u672C
|
||||||
app.update=\u68C0\u67E5 GUI \u7248\u672C
|
app.update=\u68C0\u67E5 GUI \u7248\u672C
|
||||||
setup.proxy.host=\u4E3B\u673A
|
setup.proxyInfo.host=\u4E3B\u673A
|
||||||
setup.proxy.port=\u7AEF\u53E3
|
setup.proxyInfo.port=\u7AEF\u53E3
|
||||||
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
|
proxy.setup.label.no_proxy=\u4E0D\u4EE3\u7406
|
||||||
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
|
proxy.setup.label.system=\u7CFB\u7EDF\u4EE3\u7406
|
||||||
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
|
proxy.setup.label.manual=\u624B\u52A8\u8BBE\u7F6E
|
||||||
setup.proxy.test=\u6D4B\u8BD5
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user