mirror of
https://github.com/octopusYan/alist-gui.git
synced 2024-11-22 03:56:42 +08:00
feat: alist 检查更次
This commit is contained in:
parent
80bda287cc
commit
cfd7075c8f
@ -9,9 +9,11 @@ import javafx.concurrent.Task;
|
|||||||
*/
|
*/
|
||||||
public abstract class BaseTask extends Task<Void> {
|
public abstract class BaseTask extends Task<Void> {
|
||||||
private final ThreadPoolManager Executor = ThreadPoolManager.getInstance();
|
private final ThreadPoolManager Executor = ThreadPoolManager.getInstance();
|
||||||
|
protected Listener listener;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void call() throws Exception {
|
protected Void call() throws Exception {
|
||||||
|
if (listener != null) listener.onStart();
|
||||||
task();
|
task();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -23,7 +25,8 @@ public abstract class BaseTask extends Task<Void> {
|
|||||||
protected abstract void task() throws Exception;
|
protected abstract void task() throws Exception;
|
||||||
|
|
||||||
public void onListen(Listener listener) {
|
public void onListen(Listener listener) {
|
||||||
if (listener == null) return;
|
this.listener = listener;
|
||||||
|
if (this.listener == null) return;
|
||||||
|
|
||||||
setOnRunning(_ -> listener.onRunning());
|
setOnRunning(_ -> listener.onRunning());
|
||||||
setOnCancelled(_ -> listener.onCancelled());
|
setOnCancelled(_ -> listener.onCancelled());
|
||||||
@ -36,6 +39,9 @@ public abstract class BaseTask extends Task<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
|
default void onStart() {
|
||||||
|
}
|
||||||
|
|
||||||
default void onRunning() {
|
default void onRunning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.octopusyan.alistgui.config;
|
package cn.octopusyan.alistgui.config;
|
||||||
|
|
||||||
|
import atlantafx.base.theme.Theme;
|
||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
import cn.octopusyan.alistgui.controller.AboutController;
|
import cn.octopusyan.alistgui.controller.AboutController;
|
||||||
import cn.octopusyan.alistgui.controller.MainController;
|
import cn.octopusyan.alistgui.controller.MainController;
|
||||||
@ -36,6 +37,7 @@ 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);
|
||||||
|
private static final ObjectProperty<Theme> theme = new SimpleObjectProperty<>(ConfigManager.theme());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器集合
|
* 控制器集合
|
||||||
@ -82,6 +84,10 @@ public class Context {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ObjectProperty<Theme> themeProperty() {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取当前所选时区属性
|
// 获取当前所选时区属性
|
||||||
public static ObjectProperty<Locale> currentLocaleProperty() {
|
public static ObjectProperty<Locale> currentLocaleProperty() {
|
||||||
return currentLocale;
|
return currentLocale;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
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.manager.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
@ -49,6 +50,6 @@ public class AboutController extends BaseController<VBox> {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void checkAListUpdate() {
|
public void checkAListUpdate() {
|
||||||
viewModule.checkAListUpdate();
|
viewModule.checkUpdate(ConfigManager.aList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.octopusyan.alistgui.controller;
|
package cn.octopusyan.alistgui.controller;
|
||||||
|
|
||||||
|
import atlantafx.base.theme.Theme;
|
||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
@ -14,6 +15,7 @@ import javafx.scene.control.ComboBox;
|
|||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -37,7 +39,7 @@ public class SetupController extends BaseController<VBox> implements Initializab
|
|||||||
@FXML
|
@FXML
|
||||||
public ComboBox<Locale> languageComboBox;
|
public ComboBox<Locale> languageComboBox;
|
||||||
@FXML
|
@FXML
|
||||||
public ComboBox<String> themeComboBox;
|
public ComboBox<Theme> themeComboBox;
|
||||||
@FXML
|
@FXML
|
||||||
public ComboBox<ProxySetup> proxySetupComboBox;
|
public ComboBox<ProxySetup> proxySetupComboBox;
|
||||||
@FXML
|
@FXML
|
||||||
@ -59,8 +61,20 @@ public class SetupController extends BaseController<VBox> implements Initializab
|
|||||||
@Override
|
@Override
|
||||||
public void initData() {
|
public void initData() {
|
||||||
languageComboBox.setItems(FXCollections.observableList(Context.SUPPORT_LANGUAGE_LIST));
|
languageComboBox.setItems(FXCollections.observableList(Context.SUPPORT_LANGUAGE_LIST));
|
||||||
themeComboBox.setItems(FXCollections.observableList(ConfigManager.THEME_NAME_LIST));
|
themeComboBox.setItems(FXCollections.observableList(ConfigManager.THEME_LIST));
|
||||||
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
||||||
|
|
||||||
|
themeComboBox.setConverter(new StringConverter<>() {
|
||||||
|
@Override
|
||||||
|
public String toString(Theme object) {
|
||||||
|
return object.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Theme fromString(String string) {
|
||||||
|
return ConfigManager.THEME_MAP.get(string);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,7 +85,7 @@ public class SetupController extends BaseController<VBox> implements Initializab
|
|||||||
});
|
});
|
||||||
|
|
||||||
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
||||||
themeComboBox.getSelectionModel().select(ConfigManager.themeName());
|
themeComboBox.getSelectionModel().select(ConfigManager.theme());
|
||||||
proxySetupComboBox.getSelectionModel().select(ConfigManager.proxySetup());
|
proxySetupComboBox.getSelectionModel().select(ConfigManager.proxySetup());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package cn.octopusyan.alistgui.manager;
|
|||||||
import atlantafx.base.theme.*;
|
import atlantafx.base.theme.*;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.lang.PatternPool;
|
import cn.hutool.core.lang.PatternPool;
|
||||||
|
import cn.hutool.core.net.NetUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.octopusyan.alistgui.Application;
|
import cn.octopusyan.alistgui.Application;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
@ -12,6 +13,7 @@ import cn.octopusyan.alistgui.model.GuiConfig;
|
|||||||
import cn.octopusyan.alistgui.model.ProxyInfo;
|
import cn.octopusyan.alistgui.model.ProxyInfo;
|
||||||
import cn.octopusyan.alistgui.model.UpgradeConfig;
|
import cn.octopusyan.alistgui.model.UpgradeConfig;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.AList;
|
import cn.octopusyan.alistgui.model.upgrade.AList;
|
||||||
|
import cn.octopusyan.alistgui.model.upgrade.Gui;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
@ -22,11 +24,14 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端设置
|
* 客户端设置
|
||||||
@ -37,22 +42,17 @@ public class ConfigManager {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
||||||
public static ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
public static ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
|
||||||
public static final Locale DEFAULT_LANGUAGE = Locale.SIMPLIFIED_CHINESE;
|
public static final Locale DEFAULT_LANGUAGE = Locale.SIMPLIFIED_CHINESE;
|
||||||
private static GuiConfig guiConfig;
|
public static final String DEFAULT_THEME = new PrimerLight().getName();
|
||||||
private static UpgradeConfig upgradeConfig;
|
public static List<Theme> THEME_LIST = List.of(
|
||||||
|
|
||||||
public static final String DEFAULT_THEME = "Primer Light";
|
|
||||||
public static List<Theme> THEME_LIST = Arrays.asList(
|
|
||||||
new PrimerLight(), new PrimerDark(),
|
new PrimerLight(), new PrimerDark(),
|
||||||
new NordLight(), new NordDark(),
|
new NordLight(), new NordDark(),
|
||||||
new CupertinoLight(), new CupertinoDark(),
|
new CupertinoLight(), new CupertinoDark(),
|
||||||
new Dracula()
|
new Dracula()
|
||||||
);
|
);
|
||||||
public static List<String> THEME_NAME_LIST = Arrays.asList(
|
public static Map<String, Theme> THEME_MAP = THEME_LIST.stream()
|
||||||
"Primer Light", "Primer Dark",
|
.collect(Collectors.toMap(Theme::getName, Function.identity()));
|
||||||
"Nord Light", "Nord Dark",
|
|
||||||
"Cupertino Light", "Cupertino Dark",
|
private static GuiConfig guiConfig;
|
||||||
"Dracula"
|
|
||||||
);
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
@ -61,7 +61,6 @@ public class ConfigManager {
|
|||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
guiConfig = loadConfig(Constants.GUI_CONFIG_PATH, GuiConfig.class);
|
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) {
|
private static <T> T loadConfig(String path, Class<T> clazz) {
|
||||||
@ -77,6 +76,24 @@ public class ConfigManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("save config error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------{ 主题 }------------------------------------------
|
// --------------------------------{ 主题 }------------------------------------------
|
||||||
|
|
||||||
public static String themeName() {
|
public static String themeName() {
|
||||||
@ -84,82 +101,15 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Theme theme() {
|
public static Theme theme() {
|
||||||
return THEME_LIST.get(THEME_NAME_LIST.indexOf(themeName()));
|
return THEME_MAP.get(themeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void themeName(String themeName) {
|
public static void theme(Theme theme) {
|
||||||
int themeIndex = THEME_NAME_LIST.indexOf(themeName);
|
Application.setUserAgentStylesheet(theme.getUserAgentStylesheet());
|
||||||
if (themeIndex < 0) return;
|
guiConfig.setTheme(theme.getName());
|
||||||
|
|
||||||
guiConfig.setTheme(themeName);
|
|
||||||
Application.setUserAgentStylesheet(theme().getUserAgentStylesheet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public 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() {
|
public static ProxySetup proxySetup() {
|
||||||
return ProxySetup.valueOf(StringUtils.upperCase(guiConfig.getProxySetup()));
|
return ProxySetup.valueOf(StringUtils.upperCase(guiConfig.getProxySetup()));
|
||||||
@ -186,6 +136,94 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProxyInfo getProxyInfo() {
|
||||||
|
ProxyInfo proxyInfo = guiConfig.getProxyInfo();
|
||||||
|
|
||||||
|
if (proxyInfo == null)
|
||||||
|
setProxyInfo(new ProxyInfo());
|
||||||
|
|
||||||
|
return guiConfig.getProxyInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setProxyInfo(ProxyInfo info) {
|
||||||
|
guiConfig.setProxyInfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String proxyHost() {
|
||||||
|
return getProxyInfo().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void proxyHost(String host) {
|
||||||
|
final Matcher matcher = PatternPool.IPV4.matcher(host);
|
||||||
|
if (!matcher.matches()) return;
|
||||||
|
|
||||||
|
getProxyInfo().setHost(host);
|
||||||
|
|
||||||
|
checkProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String proxyPort() {
|
||||||
|
return getProxyInfo().getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getProxyPort() {
|
||||||
|
return Integer.parseInt(proxyPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void proxyPort(String port) {
|
||||||
|
if (!NumberUtil.isNumber(port)) return;
|
||||||
|
|
||||||
|
getProxyInfo().setPort(port);
|
||||||
|
|
||||||
|
checkProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkProxy() {
|
||||||
|
if (!hasProxy()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
InetSocketAddress address = NetUtil.createAddress(proxyHost(), getProxyPort());
|
||||||
|
if (NetUtil.isOpen(address, 2000)) {
|
||||||
|
HttpUtil.getInstance().proxy(proxySetup(), ConfigManager.getProxyInfo());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(STR."host=\{proxyHost()},port=\{proxyPort()}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------{ 语言 }------------------------------------------
|
||||||
|
|
||||||
|
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 boolean silentStartup() {
|
public static boolean silentStartup() {
|
||||||
return guiConfig.getSilentStartup();
|
return guiConfig.getSilentStartup();
|
||||||
}
|
}
|
||||||
@ -194,35 +232,33 @@ public class ConfigManager {
|
|||||||
guiConfig.setSilentStartup(startup);
|
guiConfig.setSilentStartup(startup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------{ 版本检查 }------------------------------------------
|
||||||
|
|
||||||
|
public static UpgradeConfig upgradeConfig() {
|
||||||
|
return guiConfig.getUpgradeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public static AList aList() {
|
public static AList aList() {
|
||||||
return upgradeConfig.getAList();
|
return upgradeConfig().getAList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String aListVersion() {
|
public static String aListVersion() {
|
||||||
return upgradeConfig.getAList().getVersion();
|
return aList().getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void aListVersion(String version) {
|
public static void aListVersion(String version) {
|
||||||
upgradeConfig.getAList().setVersion(version);
|
aList().setVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Gui gui() {
|
||||||
private static <T> void checkFile(File src, Class<T> clazz) throws Exception {
|
return upgradeConfig().getGui();
|
||||||
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() {
|
public static String guiVersion() {
|
||||||
try {
|
return gui().getVersion();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void guiVersion(String version) {
|
||||||
|
gui().setVersion(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
package cn.octopusyan.alistgui.manager;
|
package cn.octopusyan.alistgui.manager;
|
||||||
|
|
||||||
import atlantafx.base.util.BBCodeParser;
|
import atlantafx.base.util.BBCodeParser;
|
||||||
|
import cn.hutool.core.util.ReUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模拟控制台输出
|
* 模拟控制台输出
|
||||||
@ -19,18 +26,14 @@ import java.util.Date;
|
|||||||
public class ConsoleLog {
|
public class ConsoleLog {
|
||||||
public static final String format = "yyyy/MM/dd hh:mm:ss";
|
public static final String format = "yyyy/MM/dd hh:mm:ss";
|
||||||
private volatile static ConsoleLog log;
|
private volatile static ConsoleLog log;
|
||||||
private final ScrollPane logAreaSp;
|
|
||||||
private final VBox textArea;
|
private final VBox textArea;
|
||||||
|
private final static String CONSOLE_COLOR_PREFIX = "^\033\\[(\\d+)m(.*)\033\\[0m(.*)$";
|
||||||
|
private final static String CONSOLE_COLOR_SUFFIX = "\033[0m";
|
||||||
|
|
||||||
private ConsoleLog(ScrollPane logAreaSp, VBox textArea) {
|
private ConsoleLog(ScrollPane logAreaSp, VBox textArea) {
|
||||||
this.textArea = textArea;
|
this.textArea = textArea;
|
||||||
this.logAreaSp = logAreaSp;
|
|
||||||
|
|
||||||
textArea.maxWidthProperty().bind(logAreaSp.prefWidthProperty());
|
textArea.heightProperty().subscribe(() -> logAreaSp.vvalueProperty().setValue(1));
|
||||||
|
|
||||||
textArea.heightProperty().subscribe(() -> {
|
|
||||||
logAreaSp.vvalueProperty().setValue(1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConsoleLog getInstance() {
|
public static ConsoleLog getInstance() {
|
||||||
@ -63,41 +66,120 @@ public class ConsoleLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String tag, String message, Object... param) {
|
public static void info(String tag, String message, Object... param) {
|
||||||
printLog(tag, "INFO", message, param);
|
printLog(tag, Level.INFO, message, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warning(String tag, String message, Object... param) {
|
public static void warning(String tag, String message, Object... param) {
|
||||||
printLog(tag, "[color=-color-chart-2]WARN[/color]", message, param);
|
printLog(tag, Level.WARN, message, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void error(String tag, String message, Object... param) {
|
public static void error(String tag, String message, Object... param) {
|
||||||
printLog(tag, "[color=-color-chart-3]ERROR[/color]", message, param);
|
printLog(tag, Level.ERROR, message, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void msg(String message, Object... param) {
|
public static void msg(String message, Object... param) {
|
||||||
Node text = BBCodeParser.createFormattedText(STR."\{StrUtil.format(message, param)}\n\n");
|
if (message.contains("\033[")) {
|
||||||
|
message = resetConsoleColor(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node text = BBCodeParser.createFormattedText(STR."\{StrUtil.format(message, param)}");
|
||||||
Platform.runLater(() -> log.textArea.getChildren().add(text));
|
Platform.runLater(() -> log.textArea.getChildren().add(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printLog(String tag, String level, String message, Object... param) {
|
public static void printLog(String tag, Level level, String message, Object... param) {
|
||||||
|
|
||||||
String time = DateFormatUtils.format(new Date(), format);
|
String time = DateFormatUtils.format(new Date(), format);
|
||||||
time = STR."[color=-color-accent-emphasis]\{time}[/color]";
|
time = STR."[color=-color-accent-emphasis]\{time}[/color]";
|
||||||
|
|
||||||
String levelStr = StringUtils.substringBetween(level, "]", "[");
|
String levelStr = resetLevelColor(level);
|
||||||
if (levelStr == null) levelStr = level;
|
|
||||||
level = StringUtils.replace(level, levelStr, StringUtils.center(levelStr, 5));
|
|
||||||
|
|
||||||
tag = StringUtils.isEmpty(tag) ? "" : STR."\{tag}: ";
|
tag = StringUtils.isEmpty(tag) ? "" : STR."\{tag}: ";
|
||||||
|
|
||||||
String msg = STR."[color=-color-fg-muted]\{StrUtil.format(message, param)}[/color]";
|
message = STR."[color=-color-fg-muted]\{StrUtil.format(message, param)}[/color]";
|
||||||
|
|
||||||
Node text;
|
Node text;
|
||||||
if (msg.contains("\n")) {
|
String input = STR."\{time} \{levelStr} \{tag}\{message}";
|
||||||
text = BBCodeParser.createLayout(STR."\{time} \{level} \{tag}\{msg}");
|
|
||||||
|
if (input.contains("\n")) {
|
||||||
|
text = BBCodeParser.createLayout(input);
|
||||||
} else {
|
} else {
|
||||||
text = BBCodeParser.createFormattedText(STR."\{time} \{level} \{tag}\{msg}");
|
text = BBCodeParser.createFormattedText(input);
|
||||||
}
|
}
|
||||||
Platform.runLater(() -> log.textArea.getChildren().add(text));
|
Platform.runLater(() -> log.textArea.getChildren().add(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================{ 私有方法 }================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 控制台输出颜色
|
||||||
|
*
|
||||||
|
* @param msg alist 输出消息
|
||||||
|
* @return bbcode 颜色文本
|
||||||
|
*/
|
||||||
|
private static String resetConsoleColor(String msg) {
|
||||||
|
try {
|
||||||
|
String colorCode = ReUtil.get(CONSOLE_COLOR_PREFIX, msg, 1);
|
||||||
|
String color = StringUtils.lowerCase(Color.valueOf(Integer.parseInt(colorCode)).getColor());
|
||||||
|
String colorMsg = ReUtil.get(CONSOLE_COLOR_PREFIX, msg, 2);
|
||||||
|
msg = ReUtil.get(CONSOLE_COLOR_PREFIX, msg, 3);
|
||||||
|
return color(color, colorMsg) + msg;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param level 级别
|
||||||
|
* @return bbcode 颜色
|
||||||
|
*/
|
||||||
|
private static String resetLevelColor(Level level) {
|
||||||
|
return color(level.getColor(), level.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String color(String color, String msg) {
|
||||||
|
String PREFIX = STR."\{StringUtils.isEmpty(color) ? "" : STR."[color=\{color}]"}";
|
||||||
|
String SUFFIX = STR."\{StringUtils.isEmpty(color) ? "" : "[/color]"}";
|
||||||
|
return STR."\{PREFIX}\{msg}\{SUFFIX}";
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================{ 枚举 }================================
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum Level {
|
||||||
|
INFO("INFO", null),
|
||||||
|
WARN("WARN", "color=-color-chart-2"),
|
||||||
|
ERROR("ERROR", "color=-color-chart-3"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
|
enum Color {
|
||||||
|
BLACK(30, "-color-fg-default"),
|
||||||
|
RED(31, "-color-danger-fg"),
|
||||||
|
GREEN(32, "-color-success-fg"),
|
||||||
|
YELLOW(33, "-color-warning-emphasis"),
|
||||||
|
BLUE(34, "-color-accent-fg"),
|
||||||
|
PINKISH_RED(35, "-color-danger-4"),
|
||||||
|
CYAN(36, "-color-accent-emphasis"),
|
||||||
|
WHITE(37, "-color-bg-default");
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
private final String color;
|
||||||
|
|
||||||
|
public static final Map<String, Color> NAME_CODE = Arrays.stream(Color.values())
|
||||||
|
.collect(Collectors.toMap(Color::name, Function.identity()));
|
||||||
|
|
||||||
|
public static final Map<Integer, Color> CODE_NAME = Arrays.stream(Color.values())
|
||||||
|
.collect(Collectors.toMap(Color::getCode, Function.identity()));
|
||||||
|
|
||||||
|
public static Color valueOf(int code) {
|
||||||
|
return CODE_NAME.get(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ 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 lombok.Getter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@ -25,6 +26,7 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public class HttpUtil {
|
public class HttpUtil {
|
||||||
private volatile static HttpUtil util;
|
private volatile static HttpUtil util;
|
||||||
|
@Getter
|
||||||
private volatile HttpClient httpClient;
|
private volatile HttpClient httpClient;
|
||||||
private final HttpConfig httpConfig;
|
private final HttpConfig httpConfig;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package cn.octopusyan.alistgui.model;
|
|||||||
|
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -17,9 +18,13 @@ public class GuiConfig {
|
|||||||
|
|
||||||
private Boolean autoStart = false;
|
private Boolean autoStart = false;
|
||||||
private Boolean silentStartup = false;
|
private Boolean silentStartup = false;
|
||||||
|
@JsonProperty("proxy")
|
||||||
private ProxyInfo proxyInfo;
|
private ProxyInfo proxyInfo;
|
||||||
|
@JsonProperty("proxy.testUrl")
|
||||||
|
private String proxyTestUrl = "http://";
|
||||||
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();
|
||||||
private String theme = ConfigManager.DEFAULT_THEME;
|
private String theme = ConfigManager.DEFAULT_THEME;
|
||||||
private String proxyTestUrl = "http://";
|
@JsonProperty("upgrade")
|
||||||
|
private UpgradeConfig upgradeConfig = new UpgradeConfig();
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class UpgradeConfig {
|
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 AList aList = new AList();
|
||||||
private Gui gui = new Gui();
|
private Gui gui = new Gui();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
package cn.octopusyan.alistgui.model.upgrade;
|
package cn.octopusyan.alistgui.model.upgrade;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public interface UpgradeApp {
|
public interface UpgradeApp {
|
||||||
|
@JsonIgnore
|
||||||
|
default String getReleaseApi() {
|
||||||
|
return STR."https://api.github.com/repos/\{getOwner()}/\{getRepo()}/releases/latest";
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
default String getDownloadUrl(String version) {
|
||||||
|
return STR."https://github.com/\{getOwner()}/\{getRepo()}/releases/download/\{version}/\{getReleaseFile()}";
|
||||||
|
}
|
||||||
|
|
||||||
String getOwner();
|
String getOwner();
|
||||||
|
|
||||||
String getRepo();
|
String getRepo();
|
||||||
|
158
src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java
Normal file
158
src/main/java/cn/octopusyan/alistgui/task/DownloadTask.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package cn.octopusyan.alistgui.task;
|
||||||
|
|
||||||
|
import cn.octopusyan.alistgui.base.BaseTask;
|
||||||
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
|
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.file.OpenOption;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletionStage;
|
||||||
|
import java.util.concurrent.Flow;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO 下载任务
|
||||||
|
*
|
||||||
|
* @author octopus_yan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class DownloadTask extends BaseTask {
|
||||||
|
private final String downloadUrl;
|
||||||
|
|
||||||
|
public DownloadTask(String downloadUrl) {
|
||||||
|
this.downloadUrl = downloadUrl;
|
||||||
|
log.info(STR."downlaod url : \{downloadUrl}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void task() throws Exception {
|
||||||
|
HttpClient client = HttpUtil.getInstance().getHttpClient();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(downloadUrl)).build();
|
||||||
|
|
||||||
|
// 检查bin目录
|
||||||
|
File binDir = new File(Constants.BIN_DIR_PATH);
|
||||||
|
if (!binDir.exists()) {
|
||||||
|
log.debug(STR."dir [\{Constants.BIN_DIR_PATH}] not exists");
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
binDir.mkdirs();
|
||||||
|
log.debug(STR."created dir [\{Constants.BIN_DIR_PATH}]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载处理器
|
||||||
|
var handler = BodyHandler.create(
|
||||||
|
Path.of(Constants.BIN_DIR_PATH),
|
||||||
|
StandardOpenOption.CREATE, StandardOpenOption.WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
// 下载监听
|
||||||
|
handler.listener((total, progress) -> {
|
||||||
|
// 输出进度
|
||||||
|
if (listener != null && listener instanceof Listener lis)
|
||||||
|
lis.onProgress(total, progress);
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info("download start");
|
||||||
|
HttpResponse<Path> response = client.send(request, handler);
|
||||||
|
log.info("download success");
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Listener extends BaseTask.Listener {
|
||||||
|
void onProgress(Long total, Long progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义下载返回处理
|
||||||
|
*/
|
||||||
|
private static class BodyHandler implements HttpResponse.BodyHandler<Path> {
|
||||||
|
private final HttpResponse.BodyHandler<Path> handler;
|
||||||
|
private BiConsumer<Long, Long> consumer;
|
||||||
|
|
||||||
|
private BodyHandler(HttpResponse.BodyHandler<Path> handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BodyHandler create(Path directory, OpenOption... openOptions) {
|
||||||
|
return new BodyHandler(HttpResponse.BodyHandlers.ofFileDownload(directory, openOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpResponse.BodySubscriber<Path> apply(HttpResponse.ResponseInfo responseInfo) {
|
||||||
|
AtomicLong length = new AtomicLong(-1);
|
||||||
|
// 获取文件大小
|
||||||
|
Optional<String> string = responseInfo.headers().firstValue("content-length");
|
||||||
|
string.ifPresentOrElse(s -> {
|
||||||
|
length.set(Long.parseLong(s));
|
||||||
|
log.debug(STR."========={content-length = \{s}}=========");
|
||||||
|
}, () -> {
|
||||||
|
String msg = "response not has header [content-length]";
|
||||||
|
log.error(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
BodySubscriber subscriber = new BodySubscriber(handler.apply(responseInfo));
|
||||||
|
subscriber.setConsumer(progress -> consumer.accept(length.get(), progress));
|
||||||
|
|
||||||
|
return subscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void listener(BiConsumer<Long, Long> consumer) {
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BodySubscriber implements HttpResponse.BodySubscriber<Path> {
|
||||||
|
private final HttpResponse.BodySubscriber<Path> subscriber;
|
||||||
|
private final AtomicLong progress = new AtomicLong(0);
|
||||||
|
@Setter
|
||||||
|
private Consumer<Long> consumer;
|
||||||
|
|
||||||
|
public BodySubscriber(HttpResponse.BodySubscriber<Path> subscriber) {
|
||||||
|
this.subscriber = subscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletionStage<Path> getBody() {
|
||||||
|
return subscriber.getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Flow.Subscription subscription) {
|
||||||
|
subscriber.onSubscribe(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(List<ByteBuffer> item) {
|
||||||
|
subscriber.onNext(item);
|
||||||
|
|
||||||
|
// 记录进度
|
||||||
|
for (ByteBuffer byteBuffer : item) {
|
||||||
|
progress.addAndGet(byteBuffer.limit());
|
||||||
|
}
|
||||||
|
consumer.accept(progress.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
subscriber.onError(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
subscriber.onComplete();
|
||||||
|
|
||||||
|
consumer.accept(progress.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
package cn.octopusyan.alistgui.task;
|
package cn.octopusyan.alistgui.task;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.octopusyan.alistgui.base.BaseTask;
|
import cn.octopusyan.alistgui.base.BaseTask;
|
||||||
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
||||||
import cn.octopusyan.alistgui.model.UpgradeConfig;
|
import cn.octopusyan.alistgui.model.upgrade.AList;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
||||||
import cn.octopusyan.alistgui.util.JsonUtil;
|
import cn.octopusyan.alistgui.util.JsonUtil;
|
||||||
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
||||||
@ -16,31 +15,30 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public class UpgradeTask extends BaseTask {
|
public class UpgradeTask extends BaseTask {
|
||||||
private final AboutViewModule vm;
|
private final AboutViewModule viewModule;
|
||||||
private final UpgradeApp app;
|
private final UpgradeApp app;
|
||||||
|
|
||||||
public UpgradeTask(AboutViewModule viewModel, UpgradeApp app) {
|
public UpgradeTask(AboutViewModule viewModel, UpgradeApp app) {
|
||||||
this.vm = viewModel;
|
this.viewModule = viewModel;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void task() throws Exception {
|
protected void task() throws Exception {
|
||||||
String releaseApi = StrUtil.format(UpgradeConfig.RELEASE_API, app.getOwner(), app.getRepo());
|
String responseStr = HttpUtil.getInstance().get(app.getReleaseApi(), null, null);
|
||||||
String responseStr = HttpUtil.getInstance().get(releaseApi, null, null);
|
|
||||||
JsonNode response = JsonUtil.parseJsonObject(responseStr);
|
JsonNode response = JsonUtil.parseJsonObject(responseStr);
|
||||||
|
|
||||||
|
// TODO 校验返回内容
|
||||||
String newVersion = response.get("tag_name").asText();
|
String newVersion = response.get("tag_name").asText();
|
||||||
String downloadUrl = StrUtil.format(UpgradeConfig.DOWNLOAD_API,
|
|
||||||
app.getOwner(),
|
|
||||||
app.getRepo(),
|
|
||||||
newVersion,
|
|
||||||
app.getReleaseFile()
|
|
||||||
);
|
|
||||||
|
|
||||||
runLater(() -> {
|
runLater(() -> {
|
||||||
vm.aListUpgradeProperty().setValue(StringUtils.equals(app.getVersion(), newVersion));
|
if (app instanceof AList) {
|
||||||
vm.aListNewVersionProperty().setValue(newVersion);
|
viewModule.aListUpgradeProperty().setValue(!StringUtils.equals(app.getVersion(), newVersion));
|
||||||
|
viewModule.aListNewVersionProperty().setValue(newVersion);
|
||||||
|
} else {
|
||||||
|
viewModule.guiUpgradeProperty().setValue(!StringUtils.equals(app.getVersion(), newVersion));
|
||||||
|
viewModule.guiNewVersionProperty().setValue(newVersion);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,11 @@ public class AlertBuilder extends BaseBuilder<AlertBuilder, Alert> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AlertBuilder buttons(ButtonType... buttons) {
|
||||||
|
dialog.getButtonTypes().addAll(buttons);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public AlertBuilder exception(Exception ex) {
|
public AlertBuilder exception(Exception ex) {
|
||||||
dialog.setTitle("Exception Dialog");
|
dialog.setTitle("Exception Dialog");
|
||||||
dialog.setHeaderText(ex.getClass().getSimpleName());
|
dialog.setHeaderText(ex.getClass().getSimpleName());
|
||||||
@ -71,8 +76,9 @@ public class AlertBuilder extends BaseBuilder<AlertBuilder, Alert> {
|
|||||||
|
|
||||||
return Arrays.stream(buttons).map((type) -> {
|
return Arrays.stream(buttons).map((type) -> {
|
||||||
ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER;
|
ButtonBar.ButtonData buttonData = ButtonBar.ButtonData.OTHER;
|
||||||
if ("cancel".equals(StringUtils.lowerCase(type)) || "取消".equals(type))
|
if ("cancel".equals(StringUtils.lowerCase(type)) || "取消".equals(type)) {
|
||||||
buttonData = ButtonBar.ButtonData.CANCEL_CLOSE;
|
return ButtonType.CANCEL;
|
||||||
|
}
|
||||||
return new ButtonType(type, buttonData);
|
return new ButtonType(type, buttonData);
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,10 @@ public class AlertUtil {
|
|||||||
return confirm().buttons(buttons);
|
return confirm().buttons(buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AlertBuilder confirm(ButtonType... buttons) {
|
||||||
|
return confirm().buttons(buttons);
|
||||||
|
}
|
||||||
|
|
||||||
public static AlertBuilder alert(Alert.AlertType type) {
|
public static AlertBuilder alert(Alert.AlertType type) {
|
||||||
return new AlertBuilder(mOwner, type);
|
return new AlertBuilder(mOwner, type);
|
||||||
}
|
}
|
||||||
@ -77,7 +81,8 @@ public class AlertUtil {
|
|||||||
public interface OnChoseListener {
|
public interface OnChoseListener {
|
||||||
void confirm();
|
void confirm();
|
||||||
|
|
||||||
void cancelOrClose(ButtonType buttonType);
|
default void cancelOrClose(ButtonType buttonType) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnClickListener {
|
public interface OnClickListener {
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
package cn.octopusyan.alistgui.util.alert;
|
package cn.octopusyan.alistgui.util.alert;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.scene.control.Dialog;
|
import javafx.scene.control.Dialog;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import javafx.stage.Window;
|
import javafx.stage.Window;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
@ -17,7 +11,6 @@ public abstract class BaseBuilder<T extends BaseBuilder<T, ?>, D extends Dialog<
|
|||||||
|
|
||||||
public BaseBuilder(D dialog, Window mOwner) {
|
public BaseBuilder(D dialog, Window mOwner) {
|
||||||
this.dialog = dialog;
|
this.dialog = dialog;
|
||||||
icon("/assets/logo.png");
|
|
||||||
if (mOwner != null)
|
if (mOwner != null)
|
||||||
this.dialog.initOwner(mOwner);
|
this.dialog.initOwner(mOwner);
|
||||||
}
|
}
|
||||||
@ -37,18 +30,6 @@ public abstract class BaseBuilder<T extends BaseBuilder<T, ?>, D extends Dialog<
|
|||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T icon(String path) {
|
|
||||||
return icon(new Image(Objects.requireNonNull(this.getClass().getResource(path)).toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public T icon(Image image) {
|
|
||||||
ObservableList<Image> icons = getStage().getIcons();
|
|
||||||
if (icons.isEmpty()) {
|
|
||||||
Platform.runLater(() -> icons.add(image));
|
|
||||||
}
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public D getDialog() {
|
public D getDialog() {
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
@ -58,11 +39,7 @@ public abstract class BaseBuilder<T extends BaseBuilder<T, ?>, D extends Dialog<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
if(dialog.isShowing())
|
if (dialog.isShowing())
|
||||||
dialog.close();
|
dialog.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stage getStage() {
|
|
||||||
return (Stage) dialog.getDialogPane().getScene().getWindow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class ProgressBuilder extends BaseBuilder<ProgressBuilder, Dialog<Void>>
|
|||||||
HBox hBox = new HBox();
|
HBox hBox = new HBox();
|
||||||
hBox.setPrefWidth(350);
|
hBox.setPrefWidth(350);
|
||||||
hBox.setAlignment(Pos.CENTER);
|
hBox.setAlignment(Pos.CENTER);
|
||||||
hBox.setPadding(new Insets(0, 0, 0, 0));
|
hBox.setPadding(new Insets(10, 0, 10, 0));
|
||||||
|
|
||||||
// 取消按钮
|
// 取消按钮
|
||||||
Button cancel = new Button(Context.getLanguageBinding("label.cancel").get());
|
Button cancel = new Button(Context.getLanguageBinding("label.cancel").get());
|
||||||
|
@ -1,14 +1,28 @@
|
|||||||
package cn.octopusyan.alistgui.viewModel;
|
package cn.octopusyan.alistgui.viewModel;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.core.util.ZipUtil;
|
||||||
import cn.octopusyan.alistgui.base.BaseTask;
|
import cn.octopusyan.alistgui.base.BaseTask;
|
||||||
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
|
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
||||||
|
import cn.octopusyan.alistgui.model.upgrade.AList;
|
||||||
|
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
||||||
|
import cn.octopusyan.alistgui.task.DownloadTask;
|
||||||
import cn.octopusyan.alistgui.task.UpgradeTask;
|
import cn.octopusyan.alistgui.task.UpgradeTask;
|
||||||
|
import cn.octopusyan.alistgui.util.alert.AlertBuilder;
|
||||||
import cn.octopusyan.alistgui.util.alert.AlertUtil;
|
import cn.octopusyan.alistgui.util.alert.AlertUtil;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.scene.control.ButtonType;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关于
|
* 关于
|
||||||
*
|
*
|
||||||
@ -19,6 +33,9 @@ public class AboutViewModule {
|
|||||||
private final StringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
|
private final StringProperty aListVersion = new SimpleStringProperty(ConfigManager.aListVersion());
|
||||||
private final StringProperty aListNewVersion = new SimpleStringProperty("");
|
private final StringProperty aListNewVersion = new SimpleStringProperty("");
|
||||||
private final BooleanProperty aListUpgrade = new SimpleBooleanProperty(false);
|
private final BooleanProperty aListUpgrade = new SimpleBooleanProperty(false);
|
||||||
|
private final StringProperty guiVersion = new SimpleStringProperty(ConfigManager.guiVersion());
|
||||||
|
private final StringProperty guiNewVersion = new SimpleStringProperty("");
|
||||||
|
private final BooleanProperty guiUpgrade = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
public AboutViewModule() {
|
public AboutViewModule() {
|
||||||
aListVersion.addListener((_, _, newValue) -> ConfigManager.aListVersion(newValue));
|
aListVersion.addListener((_, _, newValue) -> ConfigManager.aListVersion(newValue));
|
||||||
@ -36,38 +53,173 @@ public class AboutViewModule {
|
|||||||
return aListNewVersion;
|
return aListNewVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringProperty guiVersionProperty() {
|
||||||
|
return guiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty guiNewVersionProperty() {
|
||||||
|
return guiNewVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty guiUpgradeProperty() {
|
||||||
|
return guiUpgrade;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查alist更新
|
* 检查更新
|
||||||
*/
|
*/
|
||||||
public void checkAListUpdate() {
|
public void checkUpdate(UpgradeApp app) {
|
||||||
var task = new UpgradeTask(this, ConfigManager.aList());
|
|
||||||
task.onListen(new BaseTask.Listener() {
|
// 检查任务
|
||||||
@Override
|
startUpgrade(app, () -> {
|
||||||
public void onSucceeded() {
|
// 判断 检查的应用
|
||||||
AlertUtil.confirm()
|
boolean tag = app instanceof AList;
|
||||||
|
|
||||||
|
boolean upgrade = tag ? aListUpgrade.get() : guiUpgrade.get();
|
||||||
|
String version = tag ? aListVersion.get() : guiVersion.get();
|
||||||
|
String newVersion = tag ? aListNewVersion.get() : guiNewVersion.get();
|
||||||
|
String title = Context.getLanguageBinding(STR."about.\{tag ? "alist" : "app"}.update").getValue();
|
||||||
|
String currentLabel = Context.getLanguageBinding("update.current").get();
|
||||||
|
String newLabel = Context.getLanguageBinding("update.remote").get();
|
||||||
|
String header = Context.getLanguageBinding(STR."update.upgrade.\{upgrade ? "new" : "not"}").get();
|
||||||
|
|
||||||
|
String msg = STR."\{app.getRepo()}\{upgrade ? "" : STR." \{version}"} \{header} \{upgrade ? newVersion : ""}";
|
||||||
|
log.info(msg);
|
||||||
|
ConsoleLog.info(msg);
|
||||||
|
|
||||||
|
AlertBuilder builder = upgrade ? AlertUtil.confirm() : AlertUtil.info();
|
||||||
|
builder.title(title)
|
||||||
|
.header(header)
|
||||||
.content(STR."""
|
.content(STR."""
|
||||||
当前版本 : \{aListVersion.get()}
|
\{currentLabel} : \{version}
|
||||||
最新版本 : \{aListNewVersion.get()}
|
\{newLabel} : \{newVersion}
|
||||||
""")
|
""")
|
||||||
.title(Context.getLanguageBinding("about.alist.update").getValue())
|
.show(() -> {
|
||||||
.show(new AlertUtil.OnChoseListener() {
|
if (upgrade) startDownload(app, newVersion);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startUpgrade(UpgradeApp app, Runnable runnable) {
|
||||||
|
// 检查更新的任务
|
||||||
|
var task = new UpgradeTask(this, app);
|
||||||
|
|
||||||
|
// 加载弹窗
|
||||||
|
final var progress = AlertUtil.progress();
|
||||||
|
progress.title(Context.getLanguageBinding("proxy.test.title").get());
|
||||||
|
progress.onCancel(task::cancel);
|
||||||
|
|
||||||
|
// 任务监听
|
||||||
|
task.onListen(new BaseTask.Listener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void confirm() {
|
public void onStart() {
|
||||||
log.info("========confirm==========");
|
String msg = STR."start update \{app.getRepo()}...";
|
||||||
|
log.info(msg);
|
||||||
|
ConsoleLog.info(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelOrClose(ButtonType buttonType) {
|
public void onRunning() {
|
||||||
log.info("========cancelOrClose==========");
|
progress.show();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
@Override
|
||||||
|
public void onSucceeded() {
|
||||||
|
progress.close();
|
||||||
|
if (runnable != null) runnable.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailed(Throwable throwable) {
|
public void onFailed(Throwable throwable) {
|
||||||
|
String msg = STR."\{app.getRepo()} check version error";
|
||||||
|
log.error(msg, throwable);
|
||||||
|
ConsoleLog.error(STR."\{msg} : \{throwable.getMessage()}");
|
||||||
AlertUtil.exception(new Exception(throwable)).show();
|
AlertUtil.exception(new Exception(throwable)).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 执行任务
|
||||||
task.execute();
|
task.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param app 应用
|
||||||
|
* @param version 下载版本
|
||||||
|
*/
|
||||||
|
private void startDownload(UpgradeApp app, String version) {
|
||||||
|
DownloadTask downloadTask = new DownloadTask(app.getDownloadUrl(version));
|
||||||
|
downloadTask.onListen(new DownloadTask.Listener() {
|
||||||
|
|
||||||
|
private volatile int lastProgress = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
String msg = STR."download \{app.getRepo()} start";
|
||||||
|
log.info(msg);
|
||||||
|
ConsoleLog.info(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgress(Long total, Long progress) {
|
||||||
|
int a = (int) (((double) progress / total) * 100);
|
||||||
|
if (a % 10 == 0) {
|
||||||
|
if (a != lastProgress) {
|
||||||
|
lastProgress = a;
|
||||||
|
String msg = STR."\{app.getRepo()} \{a} %";
|
||||||
|
log.info(STR."download \{msg}");
|
||||||
|
ConsoleLog.info(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSucceeded() {
|
||||||
|
String msg = STR."download \{app.getRepo()} success";
|
||||||
|
log.info(msg);
|
||||||
|
ConsoleLog.info(msg);
|
||||||
|
|
||||||
|
// 解压并删除文件
|
||||||
|
unzip(app);
|
||||||
|
|
||||||
|
Platform.runLater(() -> aListVersion.setValue(aListNewVersion.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed(Throwable throwable) {
|
||||||
|
log.error("下载失败", throwable);
|
||||||
|
ConsoleLog.error(STR."下载失败 => \{throwable.getMessage()}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadTask.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unzip(UpgradeApp app) {
|
||||||
|
File file = new File(Constants.BIN_DIR_PATH + File.separator + app.getReleaseFile());
|
||||||
|
ZipFile zipFile = ZipUtil.toZipFile(file, CharsetUtil.defaultCharset());
|
||||||
|
ZipUtil.read(zipFile, zipEntry -> {
|
||||||
|
String path = zipEntry.getName();
|
||||||
|
if (FileUtil.isWindows()) {
|
||||||
|
// Win系统下
|
||||||
|
path = StrUtil.replace(path, "*", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
final File outItemFile = FileUtil.file(Constants.BIN_DIR_PATH, path);
|
||||||
|
if (zipEntry.isDirectory()) {
|
||||||
|
// 目录
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
outItemFile.mkdirs();
|
||||||
|
} else {
|
||||||
|
InputStream in = ZipUtil.getStream(zipFile, zipEntry);
|
||||||
|
// 文件
|
||||||
|
FileUtil.writeFromStream(in, outItemFile, false);
|
||||||
|
|
||||||
|
log.info(STR."unzip ==> \{outItemFile.getAbsoluteFile()}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解压完成后删除
|
||||||
|
FileUtil.del(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.octopusyan.alistgui.viewModel;
|
package cn.octopusyan.alistgui.viewModel;
|
||||||
|
|
||||||
|
import atlantafx.base.theme.Theme;
|
||||||
import cn.octopusyan.alistgui.base.BaseTask;
|
import cn.octopusyan.alistgui.base.BaseTask;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.enums.ProxySetup;
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
@ -22,7 +23,7 @@ import java.util.Locale;
|
|||||||
public class SetupViewModel {
|
public class SetupViewModel {
|
||||||
private final BooleanProperty autoStart = new SimpleBooleanProperty(ConfigManager.autoStart());
|
private final BooleanProperty autoStart = new SimpleBooleanProperty(ConfigManager.autoStart());
|
||||||
private final BooleanProperty silentStartup = new SimpleBooleanProperty(ConfigManager.silentStartup());
|
private final BooleanProperty silentStartup = new SimpleBooleanProperty(ConfigManager.silentStartup());
|
||||||
private final StringProperty theme = new SimpleStringProperty(ConfigManager.themeName());
|
private final ObjectProperty<Theme> theme = new SimpleObjectProperty<>(ConfigManager.theme());
|
||||||
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 ObjectProperty<Locale> language = new SimpleObjectProperty<>(ConfigManager.language());
|
private final ObjectProperty<Locale> language = new SimpleObjectProperty<>(ConfigManager.language());
|
||||||
@ -31,7 +32,8 @@ public class SetupViewModel {
|
|||||||
|
|
||||||
|
|
||||||
public SetupViewModel() {
|
public SetupViewModel() {
|
||||||
theme.addListener((_, _, newValue) -> ConfigManager.themeName(newValue));
|
theme.bindBidirectional(Context.themeProperty());
|
||||||
|
theme.addListener((_, _, newValue) -> ConfigManager.theme(newValue));
|
||||||
autoStart.addListener((_, _, newValue) -> ConfigManager.autoStart(newValue));
|
autoStart.addListener((_, _, newValue) -> ConfigManager.autoStart(newValue));
|
||||||
silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
|
silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
|
||||||
proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue));
|
proxySetup.addListener((_, _, newValue) -> ConfigManager.proxySetup(newValue));
|
||||||
@ -41,7 +43,7 @@ public class SetupViewModel {
|
|||||||
language.addListener((_, _, newValue) -> Context.setLanguage(newValue));
|
language.addListener((_, _, newValue) -> Context.setLanguage(newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty themeProperty() {
|
public ObjectProperty<Theme> themeProperty() {
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,6 @@
|
|||||||
<Label styleClass="shield-name" text="%about.app.version"/>
|
<Label styleClass="shield-name" text="%about.app.version"/>
|
||||||
<Label styleClass="shield-version" text="v${project.version}"/>
|
<Label styleClass="shield-version" text="v${project.version}"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<Button fx:id="checkAppVersion" text="%about.app.update"/>
|
<Button fx:id="checkAppVersion" styleClass="flat" text="%about.app.update"/>
|
||||||
<Button fx:id="checkAListVersion" onAction="#checkAListUpdate" text="%about.alist.update"/>
|
<Button fx:id="checkAListVersion" styleClass="flat" onAction="#checkAListUpdate" text="%about.alist.update"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
@ -32,5 +32,10 @@ about.app.version=GUI \u7248\u672C
|
|||||||
about.alist.update=\u68C0\u67E5 AList \u7248\u672C
|
about.alist.update=\u68C0\u67E5 AList \u7248\u672C
|
||||||
about.app.update=\u68C0\u67E5 GUI \u7248\u672C
|
about.app.update=\u68C0\u67E5 GUI \u7248\u672C
|
||||||
setup.theme=\u4E3B\u9898
|
setup.theme=\u4E3B\u9898
|
||||||
|
update.current=\u5F53\u524D
|
||||||
|
update.remote=\u6700\u65B0
|
||||||
|
update.upgrade.not=\u5DF2\u662F\u6700\u65B0\u7248\u672C
|
||||||
|
update.upgrade.new=\u68C0\u67E5\u5230\u65B0\u7248\u672C
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,5 +32,9 @@ about.app.version=GUI Version
|
|||||||
about.alist.update=Check AList Version
|
about.alist.update=Check AList Version
|
||||||
about.app.update=Check GUI Version
|
about.app.update=Check GUI Version
|
||||||
setup.theme=Theme
|
setup.theme=Theme
|
||||||
|
update.current=Current
|
||||||
|
update.remote=Latest
|
||||||
|
update.upgrade.not=It is already the latest version
|
||||||
|
update.upgrade.new=Detected a new version
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,5 +32,9 @@ about.app.version=GUI \u7248\u672C
|
|||||||
about.alist.update=\u68C0\u67E5 AList \u7248\u672C
|
about.alist.update=\u68C0\u67E5 AList \u7248\u672C
|
||||||
about.app.update=\u68C0\u67E5 GUI \u7248\u672C
|
about.app.update=\u68C0\u67E5 GUI \u7248\u672C
|
||||||
setup.theme=\u4E3B\u9898
|
setup.theme=\u4E3B\u9898
|
||||||
|
update.current=\u5F53\u524D
|
||||||
|
update.remote=\u6700\u65B0
|
||||||
|
update.upgrade.not=\u5DF2\u662F\u6700\u65B0\u7248\u672C
|
||||||
|
update.upgrade.new=\u68C0\u67E5\u5230\u65B0\u7248\u672C
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user