mirror of
https://github.com/octopusYan/alist-gui.git
synced 2024-11-22 03:56:42 +08:00
Release v1.0.1
Release v1.0.1
This commit is contained in:
commit
47b001cdf8
5
.github/workflows/auto-alpha-tag.yml
vendored
5
.github/workflows/auto-alpha-tag.yml
vendored
@ -4,6 +4,11 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "dev"
|
- "dev"
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/*.yml"
|
||||||
|
- "src/**"
|
||||||
|
- "pom.xml"
|
||||||
|
- "!**/*.md"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- "dev"
|
- "dev"
|
||||||
|
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. 克隆代码
|
||||||
|
19
pom.xml
19
pom.xml
@ -258,7 +258,6 @@
|
|||||||
<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>
|
||||||
@ -270,6 +269,7 @@
|
|||||||
</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>bundling-for-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>
|
||||||
|
@ -2,19 +2,28 @@ package cn.octopusyan.alistgui.base;
|
|||||||
|
|
||||||
import cn.octopusyan.alistgui.Application;
|
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.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.MenuItem;
|
||||||
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,6 +52,29 @@ public abstract class BaseController<VM extends BaseViewModel> implements Initia
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModel = vm;
|
viewModel = vm;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际化绑定
|
||||||
|
*/
|
||||||
|
private void bindI18n() {
|
||||||
|
// i18n 绑定
|
||||||
|
try {
|
||||||
|
for (Field field : getAllField(this.getClass())) {
|
||||||
|
I18n i18n = field.getAnnotation(I18n.class);
|
||||||
|
if (i18n != null && StringUtils.isNoneEmpty(i18n.key())) {
|
||||||
|
switch (field.get(this)) {
|
||||||
|
case Labeled labeled -> labeled.textProperty().bind(Context.getLanguageBinding(i18n.key()));
|
||||||
|
case Tab tab -> tab.textProperty().bind(Context.getLanguageBinding(i18n.key()));
|
||||||
|
case MenuItem mi -> mi.textProperty().bind(Context.getLanguageBinding(i18n.key()));
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.error("获取属性失败", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -51,9 +83,12 @@ public abstract class BaseController<VM extends BaseViewModel> implements Initia
|
|||||||
// 全局窗口拖拽
|
// 全局窗口拖拽
|
||||||
if (dragWindow() && getRootPanel() != null) {
|
if (dragWindow() && getRootPanel() != null) {
|
||||||
// 窗口拖拽
|
// 窗口拖拽
|
||||||
WindowsUtil.bindDragged(getRootPanel());
|
ViewUtil.bindDragged(getRootPanel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 国际化绑定
|
||||||
|
bindI18n();
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
initData();
|
initData();
|
||||||
|
|
||||||
@ -109,4 +144,16 @@ public abstract class BaseController<VM extends BaseViewModel> implements Initia
|
|||||||
* 视图事件
|
* 视图事件
|
||||||
*/
|
*/
|
||||||
public abstract void initViewAction();
|
public abstract void initViewAction();
|
||||||
|
|
||||||
|
|
||||||
|
private static List<Field> getAllField(Class<?> class1) {
|
||||||
|
List<Field> list = new ArrayList<>();
|
||||||
|
while (class1 != Object.class) {
|
||||||
|
list.addAll(Arrays.stream(class1.getDeclaredFields()).toList());
|
||||||
|
//获取父类
|
||||||
|
class1 = class1.getSuperclass();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
package cn.octopusyan.alistgui.config;
|
package cn.octopusyan.alistgui.config;
|
||||||
|
|
||||||
import atlantafx.base.theme.Theme;
|
|
||||||
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;
|
||||||
import cn.octopusyan.alistgui.util.ProcessesUtil;
|
import cn.octopusyan.alistgui.util.ProcessesUtil;
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
@ -41,7 +36,6 @@ 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 currentViewIndex = new SimpleIntegerProperty(0);
|
private static final IntegerProperty currentViewIndex = new SimpleIntegerProperty(0);
|
||||||
private static final ObjectProperty<Theme> theme = new SimpleObjectProperty<>(ConfigManager.theme());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 控制器集合
|
* 控制器集合
|
||||||
@ -79,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) {
|
||||||
@ -92,10 +87,6 @@ public class Context {
|
|||||||
Context.application = application;
|
Context.application = application;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectProperty<Theme> themeProperty() {
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前所选时区属性
|
// 获取当前所选时区属性
|
||||||
public static ObjectProperty<Locale> currentLocaleProperty() {
|
public static ObjectProperty<Locale> currentLocaleProperty() {
|
||||||
return currentLocale;
|
return currentLocale;
|
||||||
@ -150,12 +141,6 @@ public class Context {
|
|||||||
return LANGUAGE_RESOURCE_FACTORY.getResourceBundleProperty();
|
return LANGUAGE_RESOURCE_FACTORY.getResourceBundleProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化 语言
|
|
||||||
*/
|
|
||||||
private static void initI18n() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 有此类所在路径决定相对路径
|
* 有此类所在路径决定相对路径
|
||||||
*
|
*
|
||||||
@ -173,17 +158,8 @@ public class Context {
|
|||||||
* @return Scene
|
* @return Scene
|
||||||
*/
|
*/
|
||||||
public static Scene initScene() {
|
public static Scene initScene() {
|
||||||
// locale监听; 切换后,重新加载界面
|
|
||||||
currentLocaleProperty().addListener((_, _, locale) -> Platform.runLater(Context::loadScene));
|
|
||||||
// 加载
|
|
||||||
loadScene();
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadScene() {
|
|
||||||
try {
|
try {
|
||||||
FXMLLoader loader = FxmlUtil.load("root-view");
|
FXMLLoader loader = FxmlUtil.load("root-view");
|
||||||
loader.setControllerFactory(Context.getControlFactory());
|
|
||||||
//底层面板
|
//底层面板
|
||||||
Pane root = loader.load();
|
Pane root = loader.load();
|
||||||
Optional.ofNullable(scene).ifPresentOrElse(
|
Optional.ofNullable(scene).ifPresentOrElse(
|
||||||
@ -198,6 +174,7 @@ public class Context {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("loadScene error", e);
|
log.error("loadScene error", e);
|
||||||
}
|
}
|
||||||
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int currentViewIndex() {
|
public static int currentViewIndex() {
|
||||||
|
15
src/main/java/cn/octopusyan/alistgui/config/I18n.java
Normal file
15
src/main/java/cn/octopusyan/alistgui/config/I18n.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package cn.octopusyan.alistgui.config;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示文本绑定
|
||||||
|
*
|
||||||
|
* @author octopus_yan
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Target({ElementType.FIELD})//用此注解用在属性上。
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface I18n {
|
||||||
|
String key() default "";
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package cn.octopusyan.alistgui.config;
|
package cn.octopusyan.alistgui.config;
|
||||||
|
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
@ -26,15 +27,6 @@ public class ObservableResourceBundleFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StringBinding getStringBinding(String key) {
|
public StringBinding getStringBinding(String key) {
|
||||||
return new StringBinding() {
|
return Bindings.createStringBinding(() -> getResourceBundle().getString(key), resourceBundleProperty);
|
||||||
{
|
|
||||||
bind(resourceBundleProperty);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String computeValue() {
|
|
||||||
return getResourceBundle().getString(key);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package cn.octopusyan.alistgui.controller;
|
package cn.octopusyan.alistgui.controller;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseController;
|
import cn.octopusyan.alistgui.base.BaseController;
|
||||||
|
import cn.octopusyan.alistgui.config.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.fxml.FXML;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -18,12 +18,22 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class AboutController extends BaseController<AboutViewModule> {
|
public class AboutController extends BaseController<AboutViewModule> {
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@FXML
|
|
||||||
public VBox aboutView;
|
public VBox aboutView;
|
||||||
|
|
||||||
@FXML
|
|
||||||
public Label aListVersion;
|
public Label aListVersion;
|
||||||
|
|
||||||
|
@I18n(key = "about.alist.version")
|
||||||
|
public Label aListVersionLabel;
|
||||||
|
|
||||||
|
@I18n(key = "about.app.version")
|
||||||
|
public Label appVersionLabel;
|
||||||
|
|
||||||
|
@I18n(key = "about.app.update")
|
||||||
|
public Button checkAppVersion;
|
||||||
|
|
||||||
|
@I18n(key = "about.alist.update")
|
||||||
|
public Button checkAListVersion;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VBox getRootPanel() {
|
public VBox getRootPanel() {
|
||||||
return aboutView;
|
return aboutView;
|
||||||
@ -44,15 +54,12 @@ public class AboutController extends BaseController<AboutViewModule> {
|
|||||||
aListVersion.textProperty().bindBidirectional(viewModel.aListVersionProperty());
|
aListVersion.textProperty().bindBidirectional(viewModel.aListVersionProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void checkAListUpdate() {
|
public void checkAListUpdate() {
|
||||||
viewModel.checkUpdate(ConfigManager.aList());
|
viewModel.checkUpdate(ConfigManager.aList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void checkGuiUpdate() {
|
public void checkGuiUpdate() {
|
||||||
// TODO 检查 gui 版本
|
viewModel.checkUpdate(ConfigManager.gui());
|
||||||
AlertUtil.info("待开发。。。").show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,16 @@ package cn.octopusyan.alistgui.controller;
|
|||||||
|
|
||||||
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.config.I18n;
|
||||||
import cn.octopusyan.alistgui.manager.AListManager;
|
import cn.octopusyan.alistgui.manager.AListManager;
|
||||||
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
import cn.octopusyan.alistgui.manager.ConsoleLog;
|
||||||
import cn.octopusyan.alistgui.util.FxmlUtil;
|
import cn.octopusyan.alistgui.util.FxmlUtil;
|
||||||
import cn.octopusyan.alistgui.viewModel.MainViewModel;
|
import cn.octopusyan.alistgui.viewModel.MainViewModel;
|
||||||
import javafx.fxml.FXML;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.MenuButton;
|
||||||
import javafx.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
@ -25,19 +28,34 @@ import java.io.IOException;
|
|||||||
public class MainController extends BaseController<MainViewModel> {
|
public class MainController extends BaseController<MainViewModel> {
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@FXML
|
|
||||||
public VBox mainView;
|
public VBox mainView;
|
||||||
@FXML
|
|
||||||
public VBox logArea;
|
public VBox logArea;
|
||||||
@FXML
|
|
||||||
public ScrollPane logAreaSp;
|
public ScrollPane logAreaSp;
|
||||||
@FXML
|
|
||||||
|
@I18n(key = "main.status.label-stop")
|
||||||
public Button statusLabel;
|
public Button statusLabel;
|
||||||
@FXML
|
|
||||||
|
@I18n(key = "main.control.start")
|
||||||
public Button startButton;
|
public Button startButton;
|
||||||
@FXML
|
|
||||||
|
@I18n(key = "main.control.password")
|
||||||
|
public Button passwordButton;
|
||||||
|
|
||||||
|
@I18n(key = "main.control.restart")
|
||||||
|
public Button restartButton;
|
||||||
|
|
||||||
|
@I18n(key = "main.control.more")
|
||||||
|
public MenuButton moreButton;
|
||||||
|
|
||||||
|
@I18n(key = "main.more.browser")
|
||||||
public MenuItem browserButton;
|
public MenuItem browserButton;
|
||||||
|
|
||||||
|
@I18n(key = "main.more.open-config")
|
||||||
|
public MenuItem configButton;
|
||||||
|
|
||||||
|
@I18n(key = "main.more.open-log")
|
||||||
|
public MenuItem logButton;
|
||||||
|
|
||||||
private PasswordController controller;
|
private PasswordController controller;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,19 +70,18 @@ public class MainController extends BaseController<MainViewModel> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initViewStyle() {
|
public void initViewStyle() {
|
||||||
|
// 运行状态监听
|
||||||
|
viewModel.runningProperty().addListener((_, _, running) -> {
|
||||||
|
resetStatus(running);
|
||||||
|
browserButton.disableProperty().set(!running);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initViewAction() {
|
public void initViewAction() {
|
||||||
viewModel.startBtnStyleCssProperty().bindContentBidirectional(startButton.getStyleClass());
|
|
||||||
viewModel.statusLabelStyleCssProperty().bindContentBidirectional(statusLabel.getStyleClass());
|
|
||||||
viewModel.startBtnTextProperty().bindBidirectional(startButton.textProperty());
|
|
||||||
viewModel.statusLabelTextProperty().bindBidirectional(statusLabel.textProperty());
|
|
||||||
viewModel.browserButtonDisableProperty().bindBidirectional(browserButton.disableProperty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start button
|
// start button
|
||||||
@FXML
|
|
||||||
public void start() {
|
public void start() {
|
||||||
if (AListManager.isRunning()) {
|
if (AListManager.isRunning()) {
|
||||||
AListManager.stop();
|
AListManager.stop();
|
||||||
@ -74,7 +91,6 @@ public class MainController extends BaseController<MainViewModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// password button
|
// password button
|
||||||
@FXML
|
|
||||||
public void adminPassword() throws IOException {
|
public void adminPassword() throws IOException {
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
FXMLLoader load = FxmlUtil.load("admin-panel");
|
FXMLLoader load = FxmlUtil.load("admin-panel");
|
||||||
@ -85,29 +101,43 @@ public class MainController extends BaseController<MainViewModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// restart button
|
// restart button
|
||||||
@FXML
|
|
||||||
public void restart() {
|
public void restart() {
|
||||||
AListManager.restart();
|
AListManager.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// more button
|
// more button
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void openInBrowser() {
|
public void openInBrowser() {
|
||||||
AListManager.openScheme();
|
AListManager.openScheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void openLogFolder() {
|
public void openLogFolder() {
|
||||||
AListManager.openLogFolder();
|
AListManager.openLogFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void openConfig() {
|
public void openConfig() {
|
||||||
AListManager.openConfig();
|
AListManager.openConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getText(String key) {
|
/**
|
||||||
return Context.getLanguageBinding(key).get();
|
* 根据运行状态改变按钮样式
|
||||||
|
*
|
||||||
|
* @param running 运行状态
|
||||||
|
*/
|
||||||
|
private void resetStatus(boolean running) {
|
||||||
|
String removeStyle = running ? "success" : "danger";
|
||||||
|
String addStyle = running ? "danger" : "success";
|
||||||
|
StringBinding button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}");
|
||||||
|
StringBinding status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}");
|
||||||
|
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
startButton.getStyleClass().remove(removeStyle);
|
||||||
|
startButton.getStyleClass().add(addStyle);
|
||||||
|
startButton.textProperty().bind(button);
|
||||||
|
|
||||||
|
statusLabel.getStyleClass().remove(addStyle);
|
||||||
|
statusLabel.getStyleClass().add(removeStyle);
|
||||||
|
statusLabel.textProperty().bind(status);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@ import atlantafx.base.controls.Popover;
|
|||||||
import cn.hutool.core.swing.clipboard.ClipboardUtil;
|
import cn.hutool.core.swing.clipboard.ClipboardUtil;
|
||||||
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.config.I18n;
|
||||||
import cn.octopusyan.alistgui.manager.AListManager;
|
import cn.octopusyan.alistgui.manager.AListManager;
|
||||||
import cn.octopusyan.alistgui.viewModel.AdminPanelViewModel;
|
import cn.octopusyan.alistgui.viewModel.AdminPanelViewModel;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.PasswordField;
|
import javafx.scene.control.PasswordField;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
@ -23,20 +25,20 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public class PasswordController extends BaseController<AdminPanelViewModel> {
|
public class PasswordController extends BaseController<AdminPanelViewModel> {
|
||||||
@FXML
|
public AnchorPane adminPanel;
|
||||||
private AnchorPane adminPanel;
|
|
||||||
|
|
||||||
@FXML
|
@I18n(key = "admin.pwd.toptip")
|
||||||
|
public Label toptip;
|
||||||
|
@I18n(key = "admin.pwd.user-field")
|
||||||
|
public Label usernameLabel;
|
||||||
public TextField usernameField;
|
public TextField usernameField;
|
||||||
@FXML
|
@FXML
|
||||||
public Button copyUsername;
|
public Button copyUsername;
|
||||||
@FXML
|
@I18n(key = "admin.pwd.pwd-field")
|
||||||
|
public Label passwordLabel;
|
||||||
public PasswordField passwordField;
|
public PasswordField passwordField;
|
||||||
@FXML
|
|
||||||
public Button refreshPassword;
|
public Button refreshPassword;
|
||||||
@FXML
|
|
||||||
public Button savePassword;
|
public Button savePassword;
|
||||||
@FXML
|
|
||||||
public Button copyPassword;
|
public Button copyPassword;
|
||||||
|
|
||||||
private RootController root;
|
private RootController root;
|
||||||
|
@ -3,18 +3,19 @@ package cn.octopusyan.alistgui.controller;
|
|||||||
import atlantafx.base.controls.ModalPane;
|
import atlantafx.base.controls.ModalPane;
|
||||||
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.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;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.control.TabPane;
|
import javafx.scene.control.TabPane;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
@ -31,27 +32,28 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public class RootController extends BaseController<RootViewModel> {
|
public class RootController extends BaseController<RootViewModel> {
|
||||||
// 布局
|
// 布局
|
||||||
@FXML
|
public StackPane rootPane;
|
||||||
private StackPane rootPane;
|
public HBox windowHeader;
|
||||||
@FXML
|
public FontIcon alwaysOnTopIcon;
|
||||||
private HBox windowHeader;
|
public FontIcon minimizeIcon;
|
||||||
@FXML
|
public FontIcon closeIcon;
|
||||||
private FontIcon alwaysOnTopIcon;
|
|
||||||
@FXML
|
|
||||||
private FontIcon minimizeIcon;
|
|
||||||
@FXML
|
|
||||||
private FontIcon closeIcon;
|
|
||||||
|
|
||||||
// 界面
|
// 界面
|
||||||
@FXML
|
public TabPane tabPane;
|
||||||
private TabPane tabPane;
|
|
||||||
|
@I18n(key = "root.tab.main")
|
||||||
|
public Tab mainTab;
|
||||||
|
@I18n(key = "root.tab.setup")
|
||||||
|
public Tab setupTab;
|
||||||
|
@I18n(key = "root.tab.about")
|
||||||
|
public Tab aboutTab;
|
||||||
|
|
||||||
// footer
|
// footer
|
||||||
@FXML
|
@I18n(key = "root.foot.doc")
|
||||||
public Button document;
|
public Button document;
|
||||||
@FXML
|
@I18n(key = "root.foot.github")
|
||||||
public Button github;
|
public Button github;
|
||||||
@FXML
|
@I18n(key = "root.foot.sponsor")
|
||||||
public Button sponsor;
|
public Button sponsor;
|
||||||
|
|
||||||
private final ModalPane modalPane = new ModalPane();
|
private final ModalPane modalPane = new ModalPane();
|
||||||
@ -94,6 +96,7 @@ public class RootController extends BaseController<RootViewModel> {
|
|||||||
sponsor.setGraphic(juice);
|
sponsor.setGraphic(juice);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 遮罩
|
||||||
getRootPanel().getChildren().add(modalPane);
|
getRootPanel().getChildren().add(modalPane);
|
||||||
modalPane.setId("modalPane");
|
modalPane.setId("modalPane");
|
||||||
// reset side and transition to reuse a single modal pane between different examples
|
// reset side and transition to reuse a single modal pane between different examples
|
||||||
@ -126,22 +129,25 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void openDocument() {
|
public void openDocument() {
|
||||||
String locale = Context.getCurrentLocale().equals(Locale.ENGLISH) ? "" : "zh/";
|
String locale = Context.getCurrentLocale().equals(Locale.ENGLISH) ? "" : "zh/";
|
||||||
Context.openUrl(STR."https://alist.nn.ci/\{locale}");
|
Context.openUrl(STR."https://alist.nn.ci/\{locale}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void openGithub() {
|
public void openGithub() {
|
||||||
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);
|
||||||
|
@ -3,16 +3,15 @@ package cn.octopusyan.alistgui.controller;
|
|||||||
import atlantafx.base.theme.Theme;
|
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.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;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
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 javafx.util.StringConverter;
|
||||||
@ -32,26 +31,24 @@ public class SetupController extends BaseController<SetupViewModel> implements I
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public VBox setupView;
|
public VBox setupView;
|
||||||
@FXML
|
@I18n(key = "setup.auto-start.label")
|
||||||
public CheckBox autoStartCheckBox;
|
public CheckBox autoStartCheckBox;
|
||||||
@FXML
|
@I18n(key = "setup.silent-startup.label")
|
||||||
public CheckBox silentStartupCheckBox;
|
public CheckBox silentStartupCheckBox;
|
||||||
@FXML
|
@I18n(key = "setup.close-to-tray.label")
|
||||||
public CheckBox closeToTrayCheckBox;
|
public CheckBox closeToTrayCheckBox;
|
||||||
@FXML
|
|
||||||
public ComboBox<Locale> languageComboBox;
|
public ComboBox<Locale> languageComboBox;
|
||||||
@FXML
|
|
||||||
public ComboBox<Theme> themeComboBox;
|
public ComboBox<Theme> themeComboBox;
|
||||||
@FXML
|
|
||||||
public ComboBox<ProxySetup> proxySetupComboBox;
|
public ComboBox<ProxySetup> proxySetupComboBox;
|
||||||
@FXML
|
|
||||||
public Pane proxySetupPane;
|
public Pane proxySetupPane;
|
||||||
@FXML
|
@I18n(key = "setup.proxy.test")
|
||||||
public Button proxyCheck;
|
public Button proxyCheck;
|
||||||
@FXML
|
|
||||||
public TextField proxyHost;
|
public TextField proxyHost;
|
||||||
@FXML
|
|
||||||
public TextField proxyPort;
|
public TextField proxyPort;
|
||||||
|
@I18n(key = "setup.proxy.host")
|
||||||
|
public Label hostLabel;
|
||||||
|
@I18n(key = "setup.proxy.port")
|
||||||
|
public Label portLabel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VBox getRootPanel() {
|
public VBox getRootPanel() {
|
||||||
@ -64,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) {
|
||||||
@ -82,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());
|
||||||
@ -103,7 +111,6 @@ public class SetupController extends BaseController<SetupViewModel> implements I
|
|||||||
viewModel.proxySetupProperty().bind(proxySetupComboBox.getSelectionModel().selectedItemProperty());
|
viewModel.proxySetupProperty().bind(proxySetupComboBox.getSelectionModel().selectedItemProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void proxyTest() {
|
public void proxyTest() {
|
||||||
viewModel.proxyTest();
|
viewModel.proxyTest();
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -3,9 +3,10 @@ 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.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -47,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) {
|
||||||
@ -76,7 +77,7 @@ public class SystemTrayManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
initTrayIcon();
|
initTrayIcon(AListManager.isRunning());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!isShowing())
|
if (!isShowing())
|
||||||
@ -95,11 +96,12 @@ public class SystemTrayManager {
|
|||||||
|
|
||||||
//========================================={ private }===========================================
|
//========================================={ private }===========================================
|
||||||
|
|
||||||
private static void initTrayIcon() {
|
private static void initTrayIcon(boolean running) {
|
||||||
if (trayIcon != null) return;
|
if (trayIcon != null) return;
|
||||||
|
|
||||||
// 系统托盘图标
|
// 系统托盘图标
|
||||||
Image image = Toolkit.getDefaultToolkit().getImage(WindowsUtil.class.getResource("/assets/logo-disabled.png"));
|
URL resource = ViewUtil.class.getResource(STR."/assets/logo\{running ? "" : "-disabled"}.png");
|
||||||
|
Image image = Toolkit.getDefaultToolkit().getImage(resource);
|
||||||
trayIcon = new TrayIcon(image);
|
trayIcon = new TrayIcon(image);
|
||||||
|
|
||||||
// 设置图标尺寸自动适应
|
// 设置图标尺寸自动适应
|
||||||
@ -129,7 +131,7 @@ public class SystemTrayManager {
|
|||||||
if (event.isPopupTrigger()) {
|
if (event.isPopupTrigger()) {
|
||||||
// 弹出菜单
|
// 弹出菜单
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
initPopupMenu();
|
initPopupMenu(running);
|
||||||
popupMenu.show(event);
|
popupMenu.show(event);
|
||||||
});
|
});
|
||||||
} else if (event.getButton() == MouseEvent.BUTTON1) {
|
} else if (event.getButton() == MouseEvent.BUTTON1) {
|
||||||
@ -143,15 +145,19 @@ public class SystemTrayManager {
|
|||||||
/**
|
/**
|
||||||
* 构建托盘菜单
|
* 构建托盘菜单
|
||||||
*/
|
*/
|
||||||
private static void initPopupMenu() {
|
private static void initPopupMenu(boolean running) {
|
||||||
if (popupMenu != null) return;
|
if (popupMenu != null) return;
|
||||||
|
|
||||||
MenuItem start = PopupMenu.menuItem(getString("main.control.start"), _ -> AListManager.openScheme());
|
MenuItem start = PopupMenu.menuItem(
|
||||||
MenuItem browser = PopupMenu.menuItem(getString("main.more.browser"), _ -> AListManager.openScheme());
|
getStringBinding(STR."main.control.\{running ? "stop" : "start"}"),
|
||||||
browser.setDisable(true);
|
_ -> AListManager.openScheme()
|
||||||
|
);
|
||||||
|
MenuItem browser = PopupMenu.menuItem(getStringBinding("main.more.browser"), _ -> AListManager.openScheme());
|
||||||
|
browser.setDisable(!running);
|
||||||
|
|
||||||
AListManager.runningProperty().addListener((_, _, newValue) -> {
|
AListManager.runningProperty().addListener((_, _, newValue) -> {
|
||||||
start.setText(getString(STR."main.control.\{newValue ? "stop" : "start"}"));
|
start.textProperty().unbind();
|
||||||
|
start.textProperty().bind(getStringBinding(STR."main.control.\{newValue ? "stop" : "start"}"));
|
||||||
browser.disableProperty().set(!newValue);
|
browser.disableProperty().set(!newValue);
|
||||||
toolTip(STR."AList \{newValue ? "running" : "stopped"}");
|
toolTip(STR."AList \{newValue ? "running" : "stopped"}");
|
||||||
icon(STR."/assets/logo\{newValue ? "" : "-disabled"}.png");
|
icon(STR."/assets/logo\{newValue ? "" : "-disabled"}.png");
|
||||||
@ -168,19 +174,19 @@ public class SystemTrayManager {
|
|||||||
AListManager.start();
|
AListManager.start();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.addItem(getString("main.control.restart"), _ -> AListManager.restart())
|
.addItem(getStringBinding("main.control.restart"), _ -> AListManager.restart())
|
||||||
.addMenu(getString("main.control.more"), browser,
|
.addMenu(getStringBinding("main.control.more"), browser,
|
||||||
PopupMenu.menuItem(getString("main.more.open-config"), _ -> AListManager.openConfig()),
|
PopupMenu.menuItem(getStringBinding("main.more.open-config"), _ -> AListManager.openConfig()),
|
||||||
PopupMenu.menuItem(getString("main.more.open-log"), _ -> AListManager.openLogFolder()))
|
PopupMenu.menuItem(getStringBinding("main.more.open-log"), _ -> AListManager.openLogFolder()))
|
||||||
.addSeparator()
|
.addSeparator()
|
||||||
.addExitItem();
|
.addExitItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getString(String key) {
|
private static StringBinding getStringBinding(String key) {
|
||||||
return Context.getLanguageBinding(key).get();
|
return Context.getLanguageBinding(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
// 目录
|
// 目录
|
||||||
|
@ -25,7 +25,7 @@ public class FxmlUtil {
|
|||||||
FxmlUtil.class.getResource(prefix + name + suffix),
|
FxmlUtil.class.getResource(prefix + name + suffix),
|
||||||
bundle,
|
bundle,
|
||||||
new JavaFXBuilderFactory(),
|
new JavaFXBuilderFactory(),
|
||||||
null,
|
Context.getControlFactory(),
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ public class Registry {
|
|||||||
RESTORE,
|
RESTORE,
|
||||||
SAVE,
|
SAVE,
|
||||||
UNLOAD,
|
UNLOAD,
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Root {
|
public enum Root {
|
||||||
@ -75,6 +74,5 @@ public class Registry {
|
|||||||
REG_LINK,
|
REG_LINK,
|
||||||
REG_FULL_RESOURCE_DESCRIPTOR,
|
REG_FULL_RESOURCE_DESCRIPTOR,
|
||||||
REG_EXPAND_SZ,
|
REG_EXPAND_SZ,
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,8 +2,9 @@ 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.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
@ -47,6 +48,12 @@ public class PopupMenu {
|
|||||||
return addItem(new MenuItem(label), handler);
|
return addItem(new MenuItem(label), handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PopupMenu addItem(StringBinding bind, EventHandler<ActionEvent> handler) {
|
||||||
|
MenuItem menuItem = new MenuItem();
|
||||||
|
menuItem.textProperty().bind(bind);
|
||||||
|
return addItem(menuItem, handler);
|
||||||
|
}
|
||||||
|
|
||||||
public PopupMenu addItem(MenuItem node, EventHandler<ActionEvent> handler) {
|
public PopupMenu addItem(MenuItem node, EventHandler<ActionEvent> handler) {
|
||||||
node.setOnAction(handler);
|
node.setOnAction(handler);
|
||||||
return addItem(node);
|
return addItem(node);
|
||||||
@ -68,6 +75,12 @@ public class PopupMenu {
|
|||||||
return addMenu(new Menu(label), items);
|
return addMenu(new Menu(label), items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PopupMenu addMenu(StringBinding label, MenuItem... items) {
|
||||||
|
Menu menu = new Menu();
|
||||||
|
menu.textProperty().bind(label);
|
||||||
|
return addMenu(menu, items);
|
||||||
|
}
|
||||||
|
|
||||||
public PopupMenu addMenu(Menu menu, MenuItem... items) {
|
public PopupMenu addMenu(Menu menu, MenuItem... items) {
|
||||||
menu.getItems().addAll(items);
|
menu.getItems().addAll(items);
|
||||||
return addItem(menu);
|
return addItem(menu);
|
||||||
@ -102,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();
|
||||||
@ -114,4 +127,11 @@ public class PopupMenu {
|
|||||||
menuItem.setOnAction(handler);
|
menuItem.setOnAction(handler);
|
||||||
return menuItem;
|
return menuItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MenuItem menuItem(StringBinding stringBinding, EventHandler<ActionEvent> handler) {
|
||||||
|
MenuItem menuItem = new MenuItem();
|
||||||
|
menuItem.textProperty().bind(stringBinding);
|
||||||
|
menuItem.setOnAction(handler);
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,11 +1,9 @@
|
|||||||
package cn.octopusyan.alistgui.viewModel;
|
package cn.octopusyan.alistgui.viewModel;
|
||||||
|
|
||||||
import cn.octopusyan.alistgui.base.BaseViewModel;
|
import cn.octopusyan.alistgui.base.BaseViewModel;
|
||||||
import cn.octopusyan.alistgui.config.Context;
|
|
||||||
import cn.octopusyan.alistgui.manager.AListManager;
|
import cn.octopusyan.alistgui.manager.AListManager;
|
||||||
import javafx.application.Platform;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主界面VM
|
* 主界面VM
|
||||||
@ -13,56 +11,14 @@ import javafx.collections.FXCollections;
|
|||||||
* @author octopus_yan
|
* @author octopus_yan
|
||||||
*/
|
*/
|
||||||
public class MainViewModel extends BaseViewModel {
|
public class MainViewModel extends BaseViewModel {
|
||||||
private final ListProperty<String> startBtnStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
||||||
private final StringProperty startBtnText = new SimpleStringProperty();
|
|
||||||
private final ListProperty<String> statusLabelStyleCss = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
||||||
private final StringProperty statusLabelText = new SimpleStringProperty();
|
|
||||||
private final BooleanProperty browserButtonDisable = new SimpleBooleanProperty();
|
|
||||||
private final BooleanProperty running = new SimpleBooleanProperty();
|
private final BooleanProperty running = new SimpleBooleanProperty();
|
||||||
|
|
||||||
public MainViewModel() {
|
public MainViewModel() {
|
||||||
running.addListener((_, _, running) -> {
|
|
||||||
resetStatus(running);
|
|
||||||
browserButtonDisable.set(!running);
|
|
||||||
});
|
|
||||||
// 先添加监听再绑定,解决切换locale后,界面状态显示错误的问题
|
// 先添加监听再绑定,解决切换locale后,界面状态显示错误的问题
|
||||||
running.bind(AListManager.runningProperty());
|
running.bind(AListManager.runningProperty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListProperty<String> startBtnStyleCssProperty() {
|
public BooleanProperty runningProperty() {
|
||||||
return startBtnStyleCss;
|
return running;
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty startBtnTextProperty() {
|
|
||||||
return startBtnText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ListProperty<String> statusLabelStyleCssProperty() {
|
|
||||||
return statusLabelStyleCss;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty statusLabelTextProperty() {
|
|
||||||
return statusLabelText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanProperty browserButtonDisableProperty() {
|
|
||||||
return browserButtonDisable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetStatus(boolean running) {
|
|
||||||
String removeStyle = running ? "success" : "danger";
|
|
||||||
String addStyle = running ? "danger" : "success";
|
|
||||||
String button = Context.getLanguageBinding(STR."main.control.\{running ? "stop" : "start"}").get();
|
|
||||||
String status = Context.getLanguageBinding(STR."main.status.label-\{running ? "running" : "stop"}").get();
|
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
startBtnStyleCss.remove(removeStyle);
|
|
||||||
startBtnStyleCss.add(addStyle);
|
|
||||||
startBtnText.set(button);
|
|
||||||
|
|
||||||
statusLabelStyleCss.remove(addStyle);
|
|
||||||
statusLabelStyleCss.add(removeStyle);
|
|
||||||
statusLabelText.set(status);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ public class SetupViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
|
|
||||||
public SetupViewModel() {
|
public SetupViewModel() {
|
||||||
theme.bindBidirectional(Context.themeProperty());
|
|
||||||
theme.addListener((_, _, newValue) -> ConfigManager.theme(newValue));
|
theme.addListener((_, _, newValue) -> ConfigManager.theme(newValue));
|
||||||
silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
|
silentStartup.addListener((_, _, newValue) -> ConfigManager.silentStartup(newValue));
|
||||||
autoStart.addListener((_, _, newValue) -> {
|
autoStart.addListener((_, _, newValue) -> {
|
||||||
|
@ -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}
|
@ -22,11 +22,11 @@
|
|||||||
</StackPane>
|
</StackPane>
|
||||||
|
|
||||||
<HBox alignment="CENTER" styleClass="shield">
|
<HBox alignment="CENTER" styleClass="shield">
|
||||||
<Label styleClass="shield-name" text="%about.alist.version"/>
|
<Label fx:id="aListVersionLabel" styleClass="shield-name" text="%about.alist.version"/>
|
||||||
<Label fx:id="aListVersion" styleClass="shield-version"/>
|
<Label fx:id="aListVersion" styleClass="shield-version"/>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox alignment="CENTER" styleClass="shield">
|
<HBox alignment="CENTER" styleClass="shield">
|
||||||
<Label styleClass="shield-name" text="%about.app.version"/>
|
<Label fx:id="appVersionLabel" 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" onAction="#checkGuiUpdate" styleClass="flat" text="%about.app.update"/>
|
<Button fx:id="checkAppVersion" onAction="#checkGuiUpdate" styleClass="flat" text="%about.app.update"/>
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
<VBox alignment="CENTER" spacing="20"
|
<VBox alignment="CENTER" spacing="20"
|
||||||
AnchorPane.bottomAnchor="30" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0">
|
AnchorPane.bottomAnchor="30" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0">
|
||||||
|
|
||||||
<Label style="-fx-background-radius: 10;-fx-background-color: -color-button-bg-hover;"
|
<Label fx:id="toptip" style="-fx-background-radius: 10;-fx-background-color: -color-button-bg-hover;"
|
||||||
styleClass="admin-toptip, button, flat, danger" text="%admin.pwd.toptip"/>
|
styleClass="admin-toptip, button, flat, danger" text="%admin.pwd.toptip"/>
|
||||||
|
|
||||||
<Pane style="-fx-background-color: transparent"/>
|
<Pane style="-fx-background-color: transparent"/>
|
||||||
|
|
||||||
<HBox alignment="CENTER" styleClass="admin-field">
|
<HBox alignment="CENTER" styleClass="admin-field">
|
||||||
<Label text="%admin.pwd.user-field"/>
|
<Label fx:id="usernameLabel" text="%admin.pwd.user-field"/>
|
||||||
<InputGroup fx:id="userField" styleClass="admin-field-value">
|
<InputGroup fx:id="userField" styleClass="admin-field-value">
|
||||||
<TextField fx:id="usernameField" text="admin" editable="false"/>
|
<TextField fx:id="usernameField" text="admin" editable="false"/>
|
||||||
<Button fx:id="copyUsername" onAction="#copyUsername">
|
<Button fx:id="copyUsername" onAction="#copyUsername">
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<HBox alignment="CENTER" styleClass="admin-field">
|
<HBox alignment="CENTER" styleClass="admin-field">
|
||||||
<Label text="%admin.pwd.pwd-field"/>
|
<Label fx:id="passwordLabel" text="%admin.pwd.pwd-field"/>
|
||||||
<InputGroup styleClass="admin-field-value">
|
<InputGroup styleClass="admin-field-value">
|
||||||
<PasswordField fx:id="passwordField" editable="false"/>
|
<PasswordField fx:id="passwordField" editable="false"/>
|
||||||
<Button fx:id="refreshPassword" onAction="#savePassword" visible="false" managed="false">
|
<Button fx:id="refreshPassword" onAction="#savePassword" visible="false" managed="false">
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
<MenuButton fx:id="moreButton" styleClass="button-outlined, no-arrow" text="%main.control.more">
|
<MenuButton fx:id="moreButton" styleClass="button-outlined, no-arrow" text="%main.control.more">
|
||||||
<items>
|
<items>
|
||||||
<MenuItem fx:id="browserButton" onAction="#openInBrowser" disable="true" text="%main.more.browser"/>
|
<MenuItem fx:id="browserButton" onAction="#openInBrowser" disable="true" text="%main.more.browser"/>
|
||||||
<MenuItem onAction="#openConfig" text="%main.more.open-config"/>
|
<MenuItem fx:id="configButton" onAction="#openConfig" text="%main.more.open-config"/>
|
||||||
<MenuItem onAction="#openLogFolder" text="%main.more.open-log"/>
|
<MenuItem fx:id="logButton" onAction="#openLogFolder" text="%main.more.open-log"/>
|
||||||
</items>
|
</items>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
@ -24,14 +24,14 @@
|
|||||||
<padding>
|
<padding>
|
||||||
<Insets left="20.0" right="20.0"/>
|
<Insets left="20.0" right="20.0"/>
|
||||||
</padding>
|
</padding>
|
||||||
<Tab text="%root.tab.main">
|
<Tab fx:id="mainTab" text="%root.tab.main">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontIcon iconColor="white" iconLiteral="fa-th-large"/>
|
<FontIcon iconColor="white" iconLiteral="fa-th-large"/>
|
||||||
</graphic>
|
</graphic>
|
||||||
<!-- 引入主页 -->
|
<!-- 引入主页 -->
|
||||||
<fx:include fx:id="mainController" source="main-view.fxml" prefWidth="Infinity" prefHeight="-Infinity"/>
|
<fx:include fx:id="mainController" source="main-view.fxml" prefWidth="Infinity" prefHeight="-Infinity"/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab text="%root.tab.setup">
|
<Tab fx:id="setupTab" text="%root.tab.setup">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontIcon iconColor="white" iconLiteral="fa-cog"/>
|
<FontIcon iconColor="white" iconLiteral="fa-cog"/>
|
||||||
</graphic>
|
</graphic>
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<fx:include fx:id="setupController" source="setup-view.fxml" prefWidth="Infinity"
|
<fx:include fx:id="setupController" source="setup-view.fxml" prefWidth="Infinity"
|
||||||
prefHeight="-Infinity"/>
|
prefHeight="-Infinity"/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab text="%root.tab.about">
|
<Tab fx:id="aboutTab" text="%root.tab.about">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontIcon iconColor="white" iconLiteral="fa-info-circle"/>
|
<FontIcon iconColor="white" iconLiteral="fa-info-circle"/>
|
||||||
</graphic>
|
</graphic>
|
||||||
|
@ -38,9 +38,9 @@
|
|||||||
<padding>
|
<padding>
|
||||||
<Insets left="30"/>
|
<Insets left="30"/>
|
||||||
</padding>
|
</padding>
|
||||||
<Label text="%setup.proxy.host"/>
|
<Label fx:id="hostLabel" text="%setup.proxy.host"/>
|
||||||
<TextField fx:id="proxyHost" promptText="127.0.0.1" GridPane.columnIndex="1"/>
|
<TextField fx:id="proxyHost" promptText="127.0.0.1" GridPane.columnIndex="1"/>
|
||||||
<Label text="%setup.proxy.port" GridPane.rowIndex="1"/>
|
<Label fx:id="portLabel" text="%setup.proxy.port" GridPane.rowIndex="1"/>
|
||||||
<TextField fx:id="proxyPort" promptText="8080" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
<TextField fx:id="proxyPort" promptText="8080" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
Loading…
Reference in New Issue
Block a user