mirror of
https://github.com/octopusYan/alist-gui.git
synced 2025-12-08 17:21:56 +08:00
Compare commits
14 Commits
alpha/v1.0
...
4988cdc31e
| Author | SHA1 | Date | |
|---|---|---|---|
| 4988cdc31e | |||
| 4e1af001c2 | |||
| ef7f4461c2 | |||
| 6670dc7210 | |||
| 98c4ec2cd8 | |||
| 7e0ec8b598 | |||
| 47b001cdf8 | |||
| b9e842a80c | |||
| 899f286682 | |||
| 229662bd15 | |||
| 6294fdbf42 | |||
| fbdf6b3ba7 | |||
| 828a2fdb62 | |||
| 4702396bbc |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -118,7 +118,7 @@ jobs:
|
|||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: |
|
run: |
|
||||||
mvn clean package -f pom.xml
|
mvn clean package -f pom.xml
|
||||||
mkdir zipball && cp target/*-windows.zip zipball
|
mkdir zipball && cp target/*.zip zipball
|
||||||
|
|
||||||
- name: Upload AListGUI to Github
|
- name: Upload AListGUI to Github
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
34
README.md
34
README.md
@ -18,6 +18,40 @@
|
|||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
|
|
||||||
|
### 截图
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> 主界面 </summary>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/909ac6ad-0021-47d7-a75c-7fb6505e8c15">
|
||||||
|
<img alt="main" src="https://github.com/user-attachments/assets/4984f7fb-acaa-4dbc-a322-8b6b89557cbf">
|
||||||
|
</picture>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> 管理员信息 </summary>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/840dca69-e67d-4083-88f8-8e67c3e47141">
|
||||||
|
<img alt="main" src="https://github.com/user-attachments/assets/a93d5967-65b5-4185-8bfb-77e55d811532">
|
||||||
|
</picture>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> 设置 </summary>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/8fc8c489-b9cd-4e34-ad32-4899ccc275e9">
|
||||||
|
<img alt="main" src="https://github.com/user-attachments/assets/f4cc78df-0718-4bac-9985-3761611f8f57">
|
||||||
|
</picture>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary> 关于 </summary>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/dbef2d66-4ca4-4e89-8292-dbdce3566f93">
|
||||||
|
<img alt="about" src="https://github.com/user-attachments/assets/0e474a5d-78f3-4475-a8a9-fca15c3ed515">
|
||||||
|
</picture>
|
||||||
|
</details>
|
||||||
|
|
||||||
#### 本地运行
|
#### 本地运行
|
||||||
|
|
||||||
1. 克隆代码
|
1. 克隆代码
|
||||||
|
|||||||
23
pom.xml
23
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>cn.octopusyan</groupId>
|
<groupId>cn.octopusyan</groupId>
|
||||||
<artifactId>alist-gui</artifactId>
|
<artifactId>alist-gui</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
<name>alist-gui</name>
|
<name>alist-gui</name>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
@ -258,18 +258,18 @@
|
|||||||
<vmArgs>
|
<vmArgs>
|
||||||
<arg>--enable-preview</arg>
|
<arg>--enable-preview</arg>
|
||||||
<arg>-Xmx100m</arg>
|
<arg>-Xmx100m</arg>
|
||||||
<!-- <arg>-Djava.awt.headless=false</arg>-->
|
|
||||||
</vmArgs>
|
</vmArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>bundling-for-windows</id>
|
<id>windows</id>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>package</goal>
|
<goal>package</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<platform>windows</platform>
|
<platform>windows</platform>
|
||||||
|
<zipballName>${project.name}-windows</zipballName>
|
||||||
<createZipball>true</createZipball>
|
<createZipball>true</createZipball>
|
||||||
<winConfig>
|
<winConfig>
|
||||||
<headerType>gui</headerType>
|
<headerType>gui</headerType>
|
||||||
@ -277,6 +277,23 @@
|
|||||||
</winConfig>
|
</winConfig>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>windows-nojre</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>package</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<zipballName>${project.name}-windows-nojre</zipballName>
|
||||||
|
<platform>windows</platform>
|
||||||
|
<createZipball>true</createZipball>
|
||||||
|
<bundleJre>false</bundleJre>
|
||||||
|
<winConfig>
|
||||||
|
<headerType>gui</headerType>
|
||||||
|
<generateMsi>false</generateMsi>
|
||||||
|
</winConfig>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|||||||
@ -18,11 +18,12 @@ import lombok.Getter;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.*;
|
||||||
import java.net.ProxySelector;
|
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
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);
|
||||||
@ -32,6 +33,10 @@ public class Application extends javafx.application.Application {
|
|||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
logger.info("application init ...");
|
logger.info("application init ...");
|
||||||
|
|
||||||
|
// 单例模式检查
|
||||||
|
makeSingle();
|
||||||
|
|
||||||
// 初始化客户端配置
|
// 初始化客户端配置
|
||||||
ConfigManager.load();
|
ConfigManager.load();
|
||||||
|
|
||||||
@ -83,6 +88,7 @@ public class Application extends javafx.application.Application {
|
|||||||
primaryStage.setTitle(String.format("%s v%s", Constants.APP_TITLE, Constants.APP_VERSION));
|
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.show();
|
primaryStage.show();
|
||||||
|
|
||||||
// 静默启动
|
// 静默启动
|
||||||
@ -113,4 +119,84 @@ public class Application extends javafx.application.Application {
|
|||||||
Platform.exit();
|
Platform.exit();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int SINGLE_INSTANCE_LISTENER_PORT = 9009;
|
||||||
|
private static final String SINGLE_INSTANCE_FOCUS_MESSAGE = "focus";
|
||||||
|
|
||||||
|
private static final String instanceId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我们在聚焦现有实例之前定义一个暂停
|
||||||
|
* 因为有时启动实例的命令行或窗口
|
||||||
|
* 可能会在第二个实例执行完成后重新获得焦点
|
||||||
|
* 所以我们在聚焦原始窗口之前引入了一个短暂的延迟
|
||||||
|
* 以便原始窗口可以保留焦点。
|
||||||
|
*/
|
||||||
|
private static final int FOCUS_REQUEST_PAUSE_MILLIS = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单实例检测
|
||||||
|
*
|
||||||
|
* @see <a href='https://www.cnblogs.com/shihaiming/p/13553278.html'>JavaFX单实例运行应用程序</url>
|
||||||
|
*/
|
||||||
|
public static void makeSingle() {
|
||||||
|
CountDownLatch instanceCheckLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
Thread instanceListener = new Thread(() -> {
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(SINGLE_INSTANCE_LISTENER_PORT, 10)) {
|
||||||
|
instanceCheckLatch.countDown();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try (
|
||||||
|
Socket clientSocket = serverSocket.accept();
|
||||||
|
BufferedReader in = new BufferedReader(
|
||||||
|
new InputStreamReader(clientSocket.getInputStream()))
|
||||||
|
) {
|
||||||
|
String input = in.readLine();
|
||||||
|
logger.info(STR."Received single instance listener message: \{input}");
|
||||||
|
if (input.startsWith(SINGLE_INSTANCE_FOCUS_MESSAGE) && primaryStage != null) {
|
||||||
|
//noinspection BusyWait
|
||||||
|
Thread.sleep(FOCUS_REQUEST_PAUSE_MILLIS);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
logger.info(STR."To front \{instanceId}");
|
||||||
|
primaryStage.setIconified(false);
|
||||||
|
primaryStage.show();
|
||||||
|
primaryStage.toFront();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Single instance listener unable to process focus message from client");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (java.net.BindException b) {
|
||||||
|
logger.error("SingleInstanceApp already running");
|
||||||
|
|
||||||
|
try (
|
||||||
|
Socket clientSocket = new Socket(InetAddress.getLocalHost(), SINGLE_INSTANCE_LISTENER_PORT);
|
||||||
|
PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()))
|
||||||
|
) {
|
||||||
|
logger.info("Requesting existing app to focus");
|
||||||
|
out.println(STR."\{SINGLE_INSTANCE_FOCUS_MESSAGE} requested by \{instanceId}");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(STR."Aborting execution for instance \{instanceId}");
|
||||||
|
Platform.exit();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("", e);
|
||||||
|
} finally {
|
||||||
|
instanceCheckLatch.countDown();
|
||||||
|
}
|
||||||
|
}, "instance-listener");
|
||||||
|
instanceListener.setDaemon(true);
|
||||||
|
instanceListener.start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
instanceCheckLatch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
Thread.interrupted();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ import cn.octopusyan.alistgui.Application;
|
|||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.config.I18n;
|
import cn.octopusyan.alistgui.config.I18n;
|
||||||
import cn.octopusyan.alistgui.util.FxmlUtil;
|
import cn.octopusyan.alistgui.util.FxmlUtil;
|
||||||
import cn.octopusyan.alistgui.util.WindowsUtil;
|
import cn.octopusyan.alistgui.util.ViewUtil;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.Labeled;
|
import javafx.scene.control.Labeled;
|
||||||
@ -83,7 +83,7 @@ public abstract class BaseController<VM extends BaseViewModel> implements Initia
|
|||||||
// 全局窗口拖拽
|
// 全局窗口拖拽
|
||||||
if (dragWindow() && getRootPanel() != null) {
|
if (dragWindow() && getRootPanel() != null) {
|
||||||
// 窗口拖拽
|
// 窗口拖拽
|
||||||
WindowsUtil.bindDragged(getRootPanel());
|
ViewUtil.bindDragged(getRootPanel());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 国际化绑定
|
// 国际化绑定
|
||||||
|
|||||||
@ -2,10 +2,7 @@ package cn.octopusyan.alistgui.config;
|
|||||||
|
|
||||||
import cn.octopusyan.alistgui.Application;
|
import cn.octopusyan.alistgui.Application;
|
||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
import cn.octopusyan.alistgui.controller.AboutController;
|
import cn.octopusyan.alistgui.controller.*;
|
||||||
import cn.octopusyan.alistgui.controller.MainController;
|
|
||||||
import cn.octopusyan.alistgui.controller.RootController;
|
|
||||||
import cn.octopusyan.alistgui.controller.SetupController;
|
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
||||||
import cn.octopusyan.alistgui.util.FxmlUtil;
|
import cn.octopusyan.alistgui.util.FxmlUtil;
|
||||||
@ -76,6 +73,7 @@ public class Context {
|
|||||||
case MainController main -> main;
|
case MainController main -> main;
|
||||||
case SetupController setup -> setup;
|
case SetupController setup -> setup;
|
||||||
case AboutController about -> about;
|
case AboutController about -> about;
|
||||||
|
case PasswordController passwod -> passwod;
|
||||||
default -> throw new IllegalStateException(STR."Unexpected value: \{type}");
|
default -> throw new IllegalStateException(STR."Unexpected value: \{type}");
|
||||||
};
|
};
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package cn.octopusyan.alistgui.controller;
|
|||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
import cn.octopusyan.alistgui.config.I18n;
|
import cn.octopusyan.alistgui.config.I18n;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.view.alert.AlertUtil;
|
|
||||||
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
import cn.octopusyan.alistgui.viewModel.AboutViewModule;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@ -60,8 +59,7 @@ public class AboutController extends BaseController<AboutViewModule> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkGuiUpdate() {
|
public void checkGuiUpdate() {
|
||||||
// TODO 检查 gui 版本
|
viewModel.checkUpdate(ConfigManager.gui());
|
||||||
AlertUtil.info("待开发。。。").show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import cn.octopusyan.alistgui.config.Context;
|
|||||||
import cn.octopusyan.alistgui.config.I18n;
|
import cn.octopusyan.alistgui.config.I18n;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.manager.SystemTrayManager;
|
import cn.octopusyan.alistgui.manager.SystemTrayManager;
|
||||||
import cn.octopusyan.alistgui.util.WindowsUtil;
|
import cn.octopusyan.alistgui.util.ViewUtil;
|
||||||
import cn.octopusyan.alistgui.viewModel.RootViewModel;
|
import cn.octopusyan.alistgui.viewModel.RootViewModel;
|
||||||
import com.gluonhq.emoji.EmojiData;
|
import com.gluonhq.emoji.EmojiData;
|
||||||
import com.gluonhq.emoji.util.EmojiImageUtils;
|
import com.gluonhq.emoji.util.EmojiImageUtils;
|
||||||
@ -114,12 +114,13 @@ public class RootController extends BaseController<RootViewModel> {
|
|||||||
@Override
|
@Override
|
||||||
public void initViewAction() {
|
public void initViewAction() {
|
||||||
closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> {
|
closeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> {
|
||||||
|
Platform.setImplicitExit(!ConfigManager.closeToTray());
|
||||||
if (ConfigManager.closeToTray()) {
|
if (ConfigManager.closeToTray()) {
|
||||||
SystemTrayManager.show();
|
SystemTrayManager.show();
|
||||||
} else {
|
} else {
|
||||||
SystemTrayManager.hide();
|
SystemTrayManager.hide();
|
||||||
|
Platform.exit();
|
||||||
}
|
}
|
||||||
Platform.setImplicitExit(!ConfigManager.closeToTray());
|
|
||||||
getWindow().close();
|
getWindow().close();
|
||||||
});
|
});
|
||||||
minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().setIconified(true));
|
minimizeIcon.addEventHandler(MouseEvent.MOUSE_CLICKED, _ -> getWindow().setIconified(true));
|
||||||
@ -129,7 +130,7 @@ public class RootController extends BaseController<RootViewModel> {
|
|||||||
getWindow().setAlwaysOnTop(newVal);
|
getWindow().setAlwaysOnTop(newVal);
|
||||||
});
|
});
|
||||||
|
|
||||||
WindowsUtil.bindDragged(windowHeader);
|
ViewUtil.bindDragged(windowHeader);
|
||||||
|
|
||||||
viewModel.currentViewIndexProperty().bind(tabPane.getSelectionModel().selectedIndexProperty());
|
viewModel.currentViewIndexProperty().bind(tabPane.getSelectionModel().selectedIndexProperty());
|
||||||
}
|
}
|
||||||
@ -143,6 +144,11 @@ public class RootController extends BaseController<RootViewModel> {
|
|||||||
Context.openUrl("https://github.com/alist-org/alist");
|
Context.openUrl("https://github.com/alist-org/alist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showTab(int index) {
|
||||||
|
if (index < 0 || index > 2) return;
|
||||||
|
tabPane.getSelectionModel().select(index);
|
||||||
|
}
|
||||||
|
|
||||||
public void showModal(Node node, boolean persistent) {
|
public void showModal(Node node, boolean persistent) {
|
||||||
modalPane.show(node);
|
modalPane.show(node);
|
||||||
modalPane.setPersistent(persistent);
|
modalPane.setPersistent(persistent);
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import cn.octopusyan.alistgui.config.Context;
|
|||||||
import cn.octopusyan.alistgui.config.I18n;
|
import cn.octopusyan.alistgui.config.I18n;
|
||||||
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 cn.octopusyan.alistgui.view.ProxySetupCell;
|
||||||
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;
|
||||||
@ -60,6 +61,9 @@ public class SetupController extends BaseController<SetupViewModel> implements I
|
|||||||
themeComboBox.setItems(FXCollections.observableList(ConfigManager.THEME_LIST));
|
themeComboBox.setItems(FXCollections.observableList(ConfigManager.THEME_LIST));
|
||||||
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
proxySetupComboBox.setItems(FXCollections.observableList(List.of(ProxySetup.values())));
|
||||||
|
|
||||||
|
proxySetupComboBox.setCellFactory(_ -> new ProxySetupCell());
|
||||||
|
proxySetupComboBox.setButtonCell(new ProxySetupCell());
|
||||||
|
|
||||||
themeComboBox.setConverter(new StringConverter<>() {
|
themeComboBox.setConverter(new StringConverter<>() {
|
||||||
@Override
|
@Override
|
||||||
public String toString(Theme object) {
|
public String toString(Theme object) {
|
||||||
@ -78,6 +82,14 @@ public class SetupController extends BaseController<SetupViewModel> implements I
|
|||||||
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
proxySetupComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newValue) -> {
|
||||||
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue));
|
proxySetupPane.setVisible(ProxySetup.MANUAL.equals(newValue));
|
||||||
proxyCheck.setVisible(!ProxySetup.NO_PROXY.equals(newValue));
|
proxyCheck.setVisible(!ProxySetup.NO_PROXY.equals(newValue));
|
||||||
|
|
||||||
|
// proxySetupComboBox.promptTextProperty().bind(
|
||||||
|
//// Bindings.createStringBinding(
|
||||||
|
//// () -> Context.getLanguageBinding(STR."proxy.setup.label.\{newValue.getName()}").get(),
|
||||||
|
//// Context.currentLocaleProperty()
|
||||||
|
//// )
|
||||||
|
// Context.getLanguageBinding(STR."proxy.setup.label.\{newValue.getName()}")
|
||||||
|
// );
|
||||||
});
|
});
|
||||||
|
|
||||||
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
languageComboBox.getSelectionModel().select(ConfigManager.language());
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.octopusyan.alistgui.enums;
|
package cn.octopusyan.alistgui.enums;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
|
import javafx.beans.binding.StringBinding;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@ -20,6 +21,10 @@ public enum ProxySetup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Context.getLanguageBinding("proxy.setup.label." + getName()).getValue();
|
return getBinding().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBinding getBinding() {
|
||||||
|
return Context.getLanguageBinding(STR."proxy.setup.label.\{getName()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,7 +205,7 @@ public class AListManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var task = new CheckUpdateTask(ConfigManager.aList());
|
var task = new CheckUpdateTask(ConfigManager.aList());
|
||||||
task.onListen(new TaskListener.UpgradeUpgradeListener(task) {
|
task.onListen(new TaskListener.UpgradeListener(task) {
|
||||||
@Override
|
@Override
|
||||||
public void onChecked(boolean hasUpgrade, String version) {
|
public void onChecked(boolean hasUpgrade, String version) {
|
||||||
Platform.runLater(() -> showDownload(version));
|
Platform.runLater(() -> showDownload(version));
|
||||||
|
|||||||
@ -278,6 +278,10 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String guiVersion() {
|
public static String guiVersion() {
|
||||||
|
// 覆盖配置文件读取的版本号
|
||||||
|
if (!Constants.APP_VERSION.equals(gui().getVersion())) {
|
||||||
|
guiVersion(Constants.APP_VERSION);
|
||||||
|
}
|
||||||
return gui().getVersion();
|
return gui().getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package cn.octopusyan.alistgui.manager;
|
|||||||
import cn.octopusyan.alistgui.Application;
|
import cn.octopusyan.alistgui.Application;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.util.WindowsUtil;
|
import cn.octopusyan.alistgui.util.ViewUtil;
|
||||||
import cn.octopusyan.alistgui.view.PopupMenu;
|
import cn.octopusyan.alistgui.view.PopupMenu;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
@ -48,7 +48,7 @@ public class SystemTrayManager {
|
|||||||
|
|
||||||
public static void icon(String path) {
|
public static void icon(String path) {
|
||||||
if (trayIcon == null) return;
|
if (trayIcon == null) return;
|
||||||
icon(WindowsUtil.class.getResource(path));
|
icon(ViewUtil.class.getResource(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void icon(URL url) {
|
public static void icon(URL url) {
|
||||||
@ -100,7 +100,7 @@ public class SystemTrayManager {
|
|||||||
if (trayIcon != null) return;
|
if (trayIcon != null) return;
|
||||||
|
|
||||||
// 系统托盘图标
|
// 系统托盘图标
|
||||||
URL resource = WindowsUtil.class.getResource(STR."/assets/logo\{running ? "" : "-disabled"}.png");
|
URL resource = ViewUtil.class.getResource(STR."/assets/logo\{running ? "" : "-disabled"}.png");
|
||||||
Image image = Toolkit.getDefaultToolkit().getImage(resource);
|
Image image = Toolkit.getDefaultToolkit().getImage(resource);
|
||||||
trayIcon = new TrayIcon(image);
|
trayIcon = new TrayIcon(image);
|
||||||
|
|
||||||
@ -187,6 +187,6 @@ public class SystemTrayManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Stage stage() {
|
private static Stage stage() {
|
||||||
return WindowsUtil.getStage();
|
return ViewUtil.getStage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ public class GuiConfig {
|
|||||||
|
|
||||||
private Boolean autoStart = false;
|
private Boolean autoStart = false;
|
||||||
private Boolean silentStartup = false;
|
private Boolean silentStartup = false;
|
||||||
private Boolean closeToTray = true;
|
private Boolean closeToTray = false;
|
||||||
@JsonProperty("proxy")
|
@JsonProperty("proxy")
|
||||||
private ProxyInfo proxyInfo;
|
private ProxyInfo proxyInfo;
|
||||||
@JsonProperty("proxy.testUrl")
|
@JsonProperty("proxy.testUrl")
|
||||||
|
|||||||
@ -10,18 +10,12 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class Gui implements UpgradeApp {
|
public class Gui implements UpgradeApp {
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private final String owner = "alist-org";
|
private final String owner = "octopusYan";
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private final String repo = "alist";
|
private final String repo = "alist-gui";
|
||||||
|
|
||||||
|
private String releaseFile = "alist-gui-windows-nojre.zip";
|
||||||
|
|
||||||
private String releaseFile = "alist-gui-{version}-windows.zip";
|
|
||||||
private String version = PropertiesUtils.getInstance().getProperty("app.version");
|
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,7 +1,6 @@
|
|||||||
package cn.octopusyan.alistgui.task;
|
package cn.octopusyan.alistgui.task;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseTask;
|
import cn.octopusyan.alistgui.base.BaseTask;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
|
||||||
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
import cn.octopusyan.alistgui.manager.http.HttpUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@ -13,10 +12,12 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class DownloadTask extends BaseTask {
|
public class DownloadTask extends BaseTask {
|
||||||
private final String downloadUrl;
|
private final String downloadUrl;
|
||||||
|
private final String savePath;
|
||||||
|
|
||||||
public DownloadTask(String downloadUrl) {
|
public DownloadTask(String downloadUrl, String savePath) {
|
||||||
super(STR."Download \{downloadUrl}");
|
super(STR."Download \{downloadUrl}");
|
||||||
this.downloadUrl = downloadUrl;
|
this.downloadUrl = downloadUrl;
|
||||||
|
this.savePath = savePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onListen(DownloadListener listener) {
|
public void onListen(DownloadListener listener) {
|
||||||
@ -27,7 +28,7 @@ public class DownloadTask extends BaseTask {
|
|||||||
protected void task() throws Exception {
|
protected void task() throws Exception {
|
||||||
HttpUtil.getInstance().download(
|
HttpUtil.getInstance().download(
|
||||||
downloadUrl,
|
downloadUrl,
|
||||||
Constants.BIN_DIR_PATH,
|
savePath,
|
||||||
listener instanceof DownloadListener ? ((DownloadListener) listener)::onProgress : null
|
listener instanceof DownloadListener ? ((DownloadListener) listener)::onProgress : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,8 +89,8 @@ public abstract class TaskListener implements BaseTask.Listener {
|
|||||||
/**
|
/**
|
||||||
* 检查更新监听默认实现
|
* 检查更新监听默认实现
|
||||||
*/
|
*/
|
||||||
public static abstract class UpgradeUpgradeListener extends TaskListener implements CheckUpdateTask.UpgradeListener {
|
public static abstract class UpgradeListener extends TaskListener implements CheckUpdateTask.UpgradeListener {
|
||||||
public UpgradeUpgradeListener(BaseTask task) {
|
public UpgradeListener(BaseTask task) {
|
||||||
super(task);
|
super(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,11 @@ import cn.hutool.core.util.CharsetUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.ZipUtil;
|
import cn.hutool.core.util.ZipUtil;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
|
import cn.octopusyan.alistgui.controller.RootController;
|
||||||
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.AList;
|
import cn.octopusyan.alistgui.model.upgrade.AList;
|
||||||
|
import cn.octopusyan.alistgui.model.upgrade.Gui;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
||||||
import cn.octopusyan.alistgui.task.DownloadTask;
|
import cn.octopusyan.alistgui.task.DownloadTask;
|
||||||
import cn.octopusyan.alistgui.task.listener.TaskListener;
|
import cn.octopusyan.alistgui.task.listener.TaskListener;
|
||||||
@ -24,7 +27,6 @@ import java.util.zip.ZipFile;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class DownloadUtil {
|
public class DownloadUtil {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件
|
* 下载文件
|
||||||
*
|
*
|
||||||
@ -32,12 +34,19 @@ public class DownloadUtil {
|
|||||||
* @param version 下载版本
|
* @param version 下载版本
|
||||||
*/
|
*/
|
||||||
public static DownloadTask startDownload(UpgradeApp app, String version, Runnable runnable) {
|
public static DownloadTask startDownload(UpgradeApp app, String version, Runnable runnable) {
|
||||||
var task = new DownloadTask(app.getDownloadUrl(version));
|
var parentPath = switch (app) {
|
||||||
|
case AList _ -> Constants.BIN_DIR_PATH;
|
||||||
|
case Gui _ -> Constants.DATA_DIR_PATH;
|
||||||
|
default -> throw new IllegalStateException(STR."Unexpected value: \{app}");
|
||||||
|
};
|
||||||
|
var task = new DownloadTask(app.getDownloadUrl(version), parentPath);
|
||||||
task.onListen(new TaskListener.DownloadListener(task) {
|
task.onListen(new TaskListener.DownloadListener(task) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRunning() {
|
public void onRunning() {
|
||||||
// 不展示进度条
|
// 不展示进度条
|
||||||
|
RootController root = (RootController) Context.getControllers().get(RootController.class.getSimpleName());
|
||||||
|
root.showTab(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,6 +73,11 @@ public class DownloadUtil {
|
|||||||
path = StrUtil.replace(path, "*", "_");
|
path = StrUtil.replace(path, "*", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打包后文件都在alist-gui文件夹下,解压时去掉
|
||||||
|
if (app instanceof Gui) {
|
||||||
|
path = path.replaceFirst(Constants.APP_NAME, "");
|
||||||
|
}
|
||||||
|
|
||||||
final File outItemFile = FileUtil.file(parentPath, path);
|
final File outItemFile = FileUtil.file(parentPath, path);
|
||||||
if (zipEntry.isDirectory()) {
|
if (zipEntry.isDirectory()) {
|
||||||
// 目录
|
// 目录
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import java.util.Map;
|
|||||||
*
|
*
|
||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public class WindowsUtil {
|
public class ViewUtil {
|
||||||
// 获取系统缩放比
|
// 获取系统缩放比
|
||||||
public static final double scaleX = Screen.getPrimary().getOutputScaleX();
|
public static final double scaleX = Screen.getPrimary().getOutputScaleX();
|
||||||
public static final double scaleY = Screen.getPrimary().getOutputScaleY();
|
public static final double scaleY = Screen.getPrimary().getOutputScaleY();
|
||||||
@ -2,7 +2,7 @@ package cn.octopusyan.alistgui.view;
|
|||||||
|
|
||||||
import atlantafx.base.controls.CaptionMenuItem;
|
import atlantafx.base.controls.CaptionMenuItem;
|
||||||
import cn.octopusyan.alistgui.config.Constants;
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
import cn.octopusyan.alistgui.util.WindowsUtil;
|
import cn.octopusyan.alistgui.util.ViewUtil;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
@ -115,8 +115,8 @@ public class PopupMenu {
|
|||||||
root.hide();
|
root.hide();
|
||||||
|
|
||||||
root.show(utilityStage,
|
root.show(utilityStage,
|
||||||
event.getX() / WindowsUtil.scaleX,
|
event.getX() / ViewUtil.scaleX,
|
||||||
event.getY() / WindowsUtil.scaleY
|
event.getY() / ViewUtil.scaleY
|
||||||
);
|
);
|
||||||
// 获取焦点 (失去焦点隐藏自身)
|
// 获取焦点 (失去焦点隐藏自身)
|
||||||
root.requestFocus();
|
root.requestFocus();
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.octopusyan.alistgui.view;
|
||||||
|
|
||||||
|
import cn.octopusyan.alistgui.enums.ProxySetup;
|
||||||
|
import javafx.scene.control.ListCell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProxySetup I18n Cell
|
||||||
|
*
|
||||||
|
* @author octopus_yan
|
||||||
|
*/
|
||||||
|
public class ProxySetupCell extends ListCell<ProxySetup> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(ProxySetup item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
textProperty().unbind();
|
||||||
|
if (empty || item == null) {
|
||||||
|
setText("");
|
||||||
|
} else {
|
||||||
|
textProperty().bind(item.getBinding());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ package cn.octopusyan.alistgui.view.alert.builder;
|
|||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseBuilder;
|
import cn.octopusyan.alistgui.base.BaseBuilder;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
import cn.octopusyan.alistgui.util.WindowsUtil;
|
import cn.octopusyan.alistgui.util.ViewUtil;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.ButtonBar;
|
import javafx.scene.control.ButtonBar;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
@ -26,9 +26,9 @@ public class DefaultBuilder extends BaseBuilder<DefaultBuilder, Dialog<?>> {
|
|||||||
|
|
||||||
DialogPane dialogPane = dialog.getDialogPane();
|
DialogPane dialogPane = dialog.getDialogPane();
|
||||||
dialogPane.getScene().setFill(Color.TRANSPARENT);
|
dialogPane.getScene().setFill(Color.TRANSPARENT);
|
||||||
WindowsUtil.bindDragged(dialogPane);
|
ViewUtil.bindDragged(dialogPane);
|
||||||
WindowsUtil.bindShadow(dialogPane);
|
ViewUtil.bindShadow(dialogPane);
|
||||||
WindowsUtil.getStage(dialogPane).initStyle(StageStyle.TRANSPARENT);
|
ViewUtil.getStage(dialogPane).initStyle(StageStyle.TRANSPARENT);
|
||||||
|
|
||||||
dialogPane.getButtonTypes().add(new ButtonType(
|
dialogPane.getButtonTypes().add(new ButtonType(
|
||||||
Context.getLanguageBinding("label.cancel").get(),
|
Context.getLanguageBinding("label.cancel").get(),
|
||||||
|
|||||||
@ -1,14 +1,19 @@
|
|||||||
package cn.octopusyan.alistgui.viewModel;
|
package cn.octopusyan.alistgui.viewModel;
|
||||||
|
|
||||||
|
import cn.octopusyan.alistgui.Application;
|
||||||
import cn.octopusyan.alistgui.base.BaseViewModel;
|
import cn.octopusyan.alistgui.base.BaseViewModel;
|
||||||
|
import cn.octopusyan.alistgui.config.Constants;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
import cn.octopusyan.alistgui.config.Context;
|
||||||
|
import cn.octopusyan.alistgui.manager.AListManager;
|
||||||
import cn.octopusyan.alistgui.manager.ConfigManager;
|
import cn.octopusyan.alistgui.manager.ConfigManager;
|
||||||
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.AList;
|
import cn.octopusyan.alistgui.model.upgrade.AList;
|
||||||
|
import cn.octopusyan.alistgui.model.upgrade.Gui;
|
||||||
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
import cn.octopusyan.alistgui.model.upgrade.UpgradeApp;
|
||||||
import cn.octopusyan.alistgui.task.CheckUpdateTask;
|
import cn.octopusyan.alistgui.task.CheckUpdateTask;
|
||||||
import cn.octopusyan.alistgui.task.listener.TaskListener;
|
import cn.octopusyan.alistgui.task.listener.TaskListener;
|
||||||
import cn.octopusyan.alistgui.util.DownloadUtil;
|
import cn.octopusyan.alistgui.util.DownloadUtil;
|
||||||
|
import cn.octopusyan.alistgui.util.ProcessesUtil;
|
||||||
import cn.octopusyan.alistgui.view.alert.AlertUtil;
|
import cn.octopusyan.alistgui.view.alert.AlertUtil;
|
||||||
import cn.octopusyan.alistgui.view.alert.builder.AlertBuilder;
|
import cn.octopusyan.alistgui.view.alert.builder.AlertBuilder;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@ -61,52 +66,22 @@ public class AboutViewModule extends BaseViewModel {
|
|||||||
* 检查更新
|
* 检查更新
|
||||||
*/
|
*/
|
||||||
public void checkUpdate(UpgradeApp app) {
|
public void checkUpdate(UpgradeApp app) {
|
||||||
|
|
||||||
// 检查任务
|
// 检查任务
|
||||||
startUpgrade(app, () -> {
|
startUpgrade(app, () -> onChecked(app));
|
||||||
// 判断 检查的应用
|
|
||||||
boolean tag = app instanceof AList;
|
|
||||||
|
|
||||||
boolean upgrade = tag ? aListUpgrade.get() : guiUpgrade.get();
|
|
||||||
String version = tag ? aListVersion.get() : guiVersion.get();
|
|
||||||
String newVersion = tag ? aListNewVersion.get() : guiNewVersion.get();
|
|
||||||
String title = Context.getLanguageBinding(STR."about.\{tag ? "alist" : "app"}.update").getValue();
|
|
||||||
String currentLabel = Context.getLanguageBinding("update.current").get();
|
|
||||||
String newLabel = Context.getLanguageBinding("update.remote").get();
|
|
||||||
String header = Context.getLanguageBinding(STR."update.upgrade.\{upgrade ? "new" : "not"}").get();
|
|
||||||
|
|
||||||
// 版本检查消息
|
|
||||||
String msg = STR."\{app.getRepo()}\{upgrade ? "" : STR." \{version}"} \{header} \{upgrade ? newVersion : ""}";
|
|
||||||
log.info(msg);
|
|
||||||
ConsoleLog.info(msg);
|
|
||||||
|
|
||||||
// 弹窗
|
|
||||||
AlertBuilder builder = upgrade ? AlertUtil.confirm() : AlertUtil.info();
|
|
||||||
builder.title(title)
|
|
||||||
.header(header)
|
|
||||||
.content(STR."""
|
|
||||||
\{currentLabel} : \{version}
|
|
||||||
\{newLabel} : \{newVersion}
|
|
||||||
""")
|
|
||||||
.show(() -> {
|
|
||||||
// 可升级,且点击了确定后,开始下载任务
|
|
||||||
if (upgrade)
|
|
||||||
DownloadUtil.startDownload(app, newVersion, () -> {
|
|
||||||
// 下载完成后,解压并删除文件
|
|
||||||
DownloadUtil.unzip(app);
|
|
||||||
// 设置应用版本
|
|
||||||
Platform.runLater(() -> aListVersion.setValue(aListNewVersion.getValue()));
|
|
||||||
}).execute();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始检查更新
|
||||||
|
*
|
||||||
|
* @param app 更新的应用
|
||||||
|
* @param runnable 检查后执行的任务
|
||||||
|
*/
|
||||||
private void startUpgrade(UpgradeApp app, Runnable runnable) {
|
private void startUpgrade(UpgradeApp app, Runnable runnable) {
|
||||||
// 检查更新的任务
|
// 检查更新的任务
|
||||||
var task = new CheckUpdateTask(app);
|
var task = new CheckUpdateTask(app);
|
||||||
|
|
||||||
// 任务监听
|
// 任务监听
|
||||||
task.onListen(new TaskListener.UpgradeUpgradeListener(task) {
|
task.onListen(new TaskListener.UpgradeListener(task) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSucceed() {
|
protected void onSucceed() {
|
||||||
@ -135,4 +110,62 @@ public class AboutViewModule extends BaseViewModel {
|
|||||||
// 执行任务
|
// 执行任务
|
||||||
task.execute();
|
task.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void onChecked(UpgradeApp app) {
|
||||||
|
// 判断 检查的应用
|
||||||
|
boolean tag = app instanceof AList;
|
||||||
|
|
||||||
|
boolean upgrade = tag ? aListUpgrade.get() : guiUpgrade.get();
|
||||||
|
String version = tag ? aListVersion.get() : guiVersion.get();
|
||||||
|
String newVersion = tag ? aListNewVersion.get() : guiNewVersion.get();
|
||||||
|
String title = Context.getLanguageBinding(STR."about.\{tag ? "alist" : "app"}.update").getValue();
|
||||||
|
String currentLabel = Context.getLanguageBinding("update.current").get();
|
||||||
|
String newLabel = Context.getLanguageBinding("update.remote").get();
|
||||||
|
String header = Context.getLanguageBinding(STR."update.upgrade.\{upgrade ? "new" : "not"}").get();
|
||||||
|
|
||||||
|
// 版本检查消息
|
||||||
|
String msg = STR."\{app.getRepo()}\{upgrade ? "" : STR." \{version}"} \{header} \{upgrade ? newVersion : ""}";
|
||||||
|
log.info(msg);
|
||||||
|
ConsoleLog.info(msg);
|
||||||
|
|
||||||
|
// 弹窗
|
||||||
|
AlertBuilder builder = upgrade ? AlertUtil.confirm() : AlertUtil.info();
|
||||||
|
builder.title(title)
|
||||||
|
.header(header)
|
||||||
|
.content(STR."""
|
||||||
|
\{currentLabel} : \{version}
|
||||||
|
\{newLabel} : \{newVersion}
|
||||||
|
""")
|
||||||
|
.show(() -> {
|
||||||
|
// 可升级,且点击了确定后,开始下载任务
|
||||||
|
if (upgrade)
|
||||||
|
DownloadUtil.startDownload(app, newVersion, () -> {
|
||||||
|
|
||||||
|
// 下载完成后,解压并删除文件
|
||||||
|
DownloadUtil.unzip(app);
|
||||||
|
|
||||||
|
// 解压后
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
switch (app) {
|
||||||
|
case AList _ -> {
|
||||||
|
// 设置应用版本
|
||||||
|
aListVersion.setValue(aListNewVersion.getValue());
|
||||||
|
AListManager.restart();
|
||||||
|
}
|
||||||
|
case Gui _ -> {
|
||||||
|
log.info(STR."guiNewVersion => \{guiNewVersion.get()}");
|
||||||
|
// 重启
|
||||||
|
Platform.setImplicitExit(true);
|
||||||
|
Application.getPrimaryStage().close();
|
||||||
|
|
||||||
|
ProcessesUtil.init(Constants.DATA_DIR_PATH).exec(STR."\{Constants.APP_NAME}.exe");
|
||||||
|
}
|
||||||
|
default -> throw new IllegalStateException(STR."Unexpected value: \{app}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}).execute();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
app.name=${project.name}
|
app.name=${project.name}
|
||||||
app.title=AList GUI
|
app.title=AList GUI
|
||||||
app.version=${project.version}
|
app.version=v${project.version}
|
||||||
Reference in New Issue
Block a user