@@ -136,9 +136,11 @@ jobs:
|
|||||||
|
|
||||||
sudo dpkg --add-architecture arm64
|
sudo dpkg --add-architecture arm64
|
||||||
sudo apt-get update && sudo apt-get upgrade -y
|
sudo apt-get update && sudo apt-get upgrade -y
|
||||||
sudo apt install libwebkit2gtk-4.0-dev:arm64
|
sudo apt install gcc-aarch64-linux-gnu
|
||||||
|
sudo apt install libwebkit2gtk-4.1-dev:arm64
|
||||||
sudo apt install libssl-dev:arm64
|
sudo apt install libssl-dev:arm64
|
||||||
echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/" >> "$GITHUB_ENV"
|
echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/" >> "$GITHUB_ENV"
|
||||||
|
echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: Build GUI
|
- name: Build GUI
|
||||||
if: ${{ matrix.GUI_TARGET != '' }}
|
if: ${{ matrix.GUI_TARGET != '' }}
|
||||||
|
|||||||
@@ -8,18 +8,18 @@
|
|||||||
# dependencies are only needed on ubuntu as that's the only place where
|
# dependencies are only needed on ubuntu as that's the only place where
|
||||||
# we make cross-compilation
|
# we make cross-compilation
|
||||||
if [[ $OS =~ ^ubuntu.*$ ]]; then
|
if [[ $OS =~ ^ubuntu.*$ ]]; then
|
||||||
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools
|
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools libappindicator3-dev
|
||||||
# for easytier-gui
|
# for easytier-gui
|
||||||
if [[ $GUI_TARGET != '' ]]; then
|
if [[ $GUI_TARGET != '' && $GUI_TARGET =~ ^x86_64.*$ ]]; then
|
||||||
sudo apt install libwebkit2gtk-4.0-dev \
|
sudo apt install -qq libwebkit2gtk-4.1-dev \
|
||||||
build-essential \
|
build-essential \
|
||||||
curl \
|
curl \
|
||||||
wget \
|
wget \
|
||||||
file \
|
file \
|
||||||
libssl-dev \
|
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
libayatana-appindicator3-dev \
|
|
||||||
librsvg2-dev \
|
librsvg2-dev \
|
||||||
|
libxdo-dev \
|
||||||
|
libssl-dev \
|
||||||
patchelf
|
patchelf
|
||||||
fi
|
fi
|
||||||
# curl -s musl.cc | grep mipsel
|
# curl -s musl.cc | grep mipsel
|
||||||
@@ -57,8 +57,8 @@ fi
|
|||||||
|
|
||||||
# see https://github.com/rust-lang/rustup/issues/3709
|
# see https://github.com/rust-lang/rustup/issues/3709
|
||||||
rustup set auto-self-update disable
|
rustup set auto-self-update disable
|
||||||
rustup install 1.75
|
rustup install 1.79
|
||||||
rustup default 1.75
|
rustup default 1.79
|
||||||
|
|
||||||
# mips/mipsel cannot add target from rustup, need compile by ourselves
|
# mips/mipsel cannot add target from rustup, need compile by ourselves
|
||||||
if [[ $OS =~ ^ubuntu.*$ && $TARGET =~ ^mips.*$ ]]; then
|
if [[ $OS =~ ^ubuntu.*$ && $TARGET =~ ^mips.*$ ]]; then
|
||||||
|
|||||||
@@ -71,3 +71,7 @@ stop_network: 停止网络
|
|||||||
network_running: 运行中
|
network_running: 运行中
|
||||||
network_stopped: 已停止
|
network_stopped: 已停止
|
||||||
dhcp_experimental_warning: 实验性警告!使用DHCP时如果组网环境中发生IP冲突,将自动更改IP。
|
dhcp_experimental_warning: 实验性警告!使用DHCP时如果组网环境中发生IP冲突,将自动更改IP。
|
||||||
|
|
||||||
|
tray:
|
||||||
|
show: 显示 / 隐藏
|
||||||
|
exit: 退出
|
||||||
|
|||||||
@@ -71,3 +71,7 @@ stop_network: Stop Network
|
|||||||
network_running: running
|
network_running: running
|
||||||
network_stopped: stopped
|
network_stopped: stopped
|
||||||
dhcp_experimental_warning: Experimental warning! if there is an IP conflict in the network when using DHCP, the IP will be automatically changed.
|
dhcp_experimental_warning: Experimental warning! if there is an IP conflict in the network when using DHCP, the IP will be automatically changed.
|
||||||
|
|
||||||
|
tray:
|
||||||
|
show: Show / Hide
|
||||||
|
exit: Exit
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "easytier-gui",
|
"name": "easytier-gui",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.0",
|
"version": "1.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -12,39 +12,45 @@
|
|||||||
"lint:fix": "eslint . --ignore-pattern src-tauri --fix"
|
"lint:fix": "eslint . --ignore-pattern src-tauri --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^1.5.5",
|
"@primevue/themes": "^4.0.0",
|
||||||
|
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.4",
|
||||||
|
"@tauri-apps/plugin-process": "2.0.0-beta.6",
|
||||||
|
"@tauri-apps/plugin-shell": "2.0.0-beta.7",
|
||||||
|
"aura": "link:@primevue/themes/aura",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"primeflex": "^3.3.1",
|
"primeflex": "^3.3.1",
|
||||||
"primeicons": "^7.0.0",
|
"primeicons": "^7.0.0",
|
||||||
"primevue": "^3.52.0",
|
"primevue": "^4.0.0",
|
||||||
"vue": "^3.4.27",
|
"vue": "^3.4.31",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue-i18n": "^9.13.1",
|
||||||
"vue-router": "^4.3.2"
|
"vue-router": "^4.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^2.17.0",
|
"@antfu/eslint-config": "^2.21.3",
|
||||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||||
"@tauri-apps/cli": "^1.5.13",
|
"@primevue/auto-import-resolver": "^4.0.0",
|
||||||
"@types/node": "^20.12.11",
|
"@tauri-apps/api": "2.0.0-beta.14",
|
||||||
|
"@tauri-apps/cli": "2.0.0-beta.21",
|
||||||
|
"@types/node": "^20.14.10",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"@vue-macros/volar": "^0.19.0",
|
"@vue-macros/volar": "^0.19.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"eslint": "^9.2.0",
|
"eslint": "^9.6.0",
|
||||||
"eslint-plugin-format": "^0.1.1",
|
"eslint-plugin-format": "^0.1.2",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.39",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.4",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.5.3",
|
||||||
"unplugin-auto-import": "^0.17.6",
|
"unplugin-auto-import": "^0.17.6",
|
||||||
"unplugin-vue-components": "^0.27.0",
|
"unplugin-vue-components": "^0.27.2",
|
||||||
"unplugin-vue-macros": "^2.9.2",
|
"unplugin-vue-macros": "^2.9.5",
|
||||||
"unplugin-vue-markdown": "^0.26.2",
|
"unplugin-vue-markdown": "^0.26.2",
|
||||||
"unplugin-vue-router": "^0.8.6",
|
"unplugin-vue-router": "^0.8.8",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vite": "^5.2.11",
|
"vite": "^5.3.3",
|
||||||
"vite-plugin-vue-devtools": "^7.1.3",
|
"vite-plugin-vue-devtools": "^7.3.5",
|
||||||
"vite-plugin-vue-layouts": "^0.11.0",
|
"vite-plugin-vue-layouts": "^0.11.0",
|
||||||
"vue-i18n": "^9.13.1",
|
"vue-i18n": "^9.13.1",
|
||||||
"vue-tsc": "^2.0.17"
|
"vue-tsc": "^2.0.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "easytier-gui"
|
name = "easytier-gui"
|
||||||
version = "0.0.0"
|
version = "1.2.0"
|
||||||
description = "EasyTier GUI"
|
description = "EasyTier GUI"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -8,14 +8,11 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "1", features = [] }
|
tauri-build = { version = "2.0.0-beta", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "1", features = [ "clipboard-all", "path-all",
|
tauri = { version = "2.0.0-beta", features = [ "tray-icon", "image-png", "image-ico"] }
|
||||||
"process-exit",
|
|
||||||
"system-tray",
|
|
||||||
"shell-open",
|
|
||||||
] }
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|
||||||
@@ -33,6 +30,11 @@ gethostname = "0.4.3"
|
|||||||
auto-launch = "0.5.0"
|
auto-launch = "0.5.0"
|
||||||
dunce = "1.0.4"
|
dunce = "1.0.4"
|
||||||
|
|
||||||
|
tauri-plugin-shell = "2.0.0-beta.8"
|
||||||
|
tauri-plugin-process = "2.0.0-beta.7"
|
||||||
|
tauri-plugin-clipboard-manager = "2.1.0-beta.5"
|
||||||
|
tauri-plugin-positioner = { version = "2.0.0-beta", features = ["tray-icon"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"identifier": "migrated",
|
||||||
|
"description": "permissions that were migrated from v1",
|
||||||
|
"local": true,
|
||||||
|
"windows": [
|
||||||
|
"main"
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
"path:default",
|
||||||
|
"event:default",
|
||||||
|
|
||||||
|
"window:default",
|
||||||
|
"window:allow-is-visible",
|
||||||
|
"window:allow-show",
|
||||||
|
"window:allow-hide",
|
||||||
|
"window:allow-set-focus",
|
||||||
|
|
||||||
|
"app:default",
|
||||||
|
"resources:default",
|
||||||
|
"menu:default",
|
||||||
|
"tray:default",
|
||||||
|
"shell:allow-open",
|
||||||
|
"process:allow-exit",
|
||||||
|
"clipboard-manager:allow-read-text",
|
||||||
|
"clipboard-manager:allow-write-text",
|
||||||
|
"shell:default",
|
||||||
|
"process:default",
|
||||||
|
"clipboard-manager:default",
|
||||||
|
|
||||||
|
"tray:default",
|
||||||
|
"tray:allow-new",
|
||||||
|
"tray:allow-set-menu",
|
||||||
|
"tray:allow-set-title",
|
||||||
|
"tray:allow-remove-by-id",
|
||||||
|
"tray:allow-get-by-id",
|
||||||
|
"tray:allow-set-icon",
|
||||||
|
"tray:allow-set-icon-as-template",
|
||||||
|
"tray:allow-set-show-menu-on-left-click",
|
||||||
|
"tray:allow-set-tooltip"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 24 KiB |
@@ -16,10 +16,7 @@ use easytier::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use tauri::{
|
use tauri::Manager as _;
|
||||||
CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
|
|
||||||
Window,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, PartialEq, Debug)]
|
#[derive(Deserialize, Serialize, PartialEq, Debug)]
|
||||||
enum NetworkingMethod {
|
enum NetworkingMethod {
|
||||||
@@ -34,6 +31,8 @@ impl Default for NetworkingMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
struct NetworkConfig {
|
struct NetworkConfig {
|
||||||
instance_id: String,
|
instance_id: String,
|
||||||
@@ -234,12 +233,14 @@ fn set_logging_level(level: String) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_window_visibility(window: &Window) {
|
fn toggle_window_visibility<R: tauri::Runtime>(app: &tauri::AppHandle<R>) {
|
||||||
if window.is_visible().unwrap() {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
window.hide().unwrap();
|
if window.is_visible().unwrap_or_default() {
|
||||||
} else {
|
let _ = window.hide();
|
||||||
window.show().unwrap();
|
} else {
|
||||||
window.set_focus().unwrap();
|
let _ = window.show();
|
||||||
|
let _ = window.set_focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,16 +320,13 @@ fn main() {
|
|||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let quit = CustomMenuItem::new("quit".to_string(), "退出 Quit");
|
|
||||||
let hide = CustomMenuItem::new("hide".to_string(), "显示 Show / 隐藏 Hide");
|
|
||||||
let tray_menu = SystemTrayMenu::new()
|
|
||||||
.add_item(quit)
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
|
||||||
.add_item(hide);
|
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_clipboard_manager::init())
|
||||||
|
.plugin(tauri_plugin_process::init())
|
||||||
|
.plugin(tauri_plugin_shell::init())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let Some(log_dir) = app.path_resolver().app_log_dir() else {
|
// for logging config
|
||||||
|
let Ok(log_dir) = app.path().app_log_dir() else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let config = TomlConfigLoader::default();
|
let config = TomlConfigLoader::default();
|
||||||
@@ -342,6 +340,22 @@ fn main() {
|
|||||||
};
|
};
|
||||||
unsafe { LOGGER_LEVEL_SENDER.replace(logger_reinit) };
|
unsafe { LOGGER_LEVEL_SENDER.replace(logger_reinit) };
|
||||||
|
|
||||||
|
// for tray icon, menu need to be built in js
|
||||||
|
let _tray_menu = TrayIconBuilder::with_id("main")
|
||||||
|
.menu_on_left_click(false)
|
||||||
|
.on_tray_icon_event(|tray, event| {
|
||||||
|
if let TrayIconEvent::Click {
|
||||||
|
button: MouseButton::Left,
|
||||||
|
button_state: MouseButtonState::Up,
|
||||||
|
..
|
||||||
|
} = event
|
||||||
|
{
|
||||||
|
let app = tray.app_handle();
|
||||||
|
toggle_window_visibility(app);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build(app)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
@@ -353,31 +367,9 @@ fn main() {
|
|||||||
set_auto_launch_status,
|
set_auto_launch_status,
|
||||||
set_logging_level
|
set_logging_level
|
||||||
])
|
])
|
||||||
.system_tray(SystemTray::new().with_menu(tray_menu))
|
.on_window_event(|win, event| match event {
|
||||||
.on_system_tray_event(|app, event| match event {
|
|
||||||
SystemTrayEvent::DoubleClick {
|
|
||||||
position: _,
|
|
||||||
size: _,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let window = app.get_window("main").unwrap();
|
|
||||||
toggle_window_visibility(&window);
|
|
||||||
}
|
|
||||||
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
|
||||||
"quit" => {
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
"hide" => {
|
|
||||||
let window = app.get_window("main").unwrap();
|
|
||||||
toggle_window_visibility(&window);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
})
|
|
||||||
.on_window_event(|event| match event.event() {
|
|
||||||
tauri::WindowEvent::CloseRequested { api, .. } => {
|
tauri::WindowEvent::CloseRequested { api, .. } => {
|
||||||
event.window().hide().unwrap();
|
let _ = win.hide();
|
||||||
api.prevent_close();
|
api.prevent_close();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -2,31 +2,29 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
"beforeBuildCommand": "pnpm build",
|
"beforeBuildCommand": "pnpm build",
|
||||||
"devPath": "http://localhost:1420",
|
"frontendDist": "../dist",
|
||||||
"distDir": "../dist"
|
"devUrl": "http://localhost:1420"
|
||||||
},
|
},
|
||||||
"package": {
|
"bundle": {
|
||||||
"productName": "easytier-gui",
|
"active": true,
|
||||||
"version": "0.0.0"
|
"targets": "all",
|
||||||
|
"icon": [
|
||||||
|
"icons/icon.png",
|
||||||
|
"icons/icon.rgba",
|
||||||
|
"icons/icon.icns",
|
||||||
|
"icons/icon.ico"
|
||||||
|
],
|
||||||
|
"createUpdaterArtifacts": false
|
||||||
},
|
},
|
||||||
"tauri": {
|
"productName": "easytier-gui",
|
||||||
"allowlist": {
|
"version": "1.2.0",
|
||||||
"all": false,
|
"identifier": "com.kkrainbow.easyiter-client",
|
||||||
"shell": {
|
"plugins": {},
|
||||||
"all": false,
|
"app": {
|
||||||
"open": ".*"
|
"trayIcon": {
|
||||||
},
|
"iconPath": "icons/icon.ico",
|
||||||
"process": {
|
"menuOnLeftClick": true,
|
||||||
"exit": true
|
"iconAsTemplate": true
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"all": true
|
|
||||||
},
|
|
||||||
"clipboard": {
|
|
||||||
"all": true,
|
|
||||||
"writeText": true,
|
|
||||||
"readText": true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
@@ -37,21 +35,6 @@
|
|||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
"csp": null
|
"csp": null
|
||||||
},
|
|
||||||
"systemTray": {
|
|
||||||
"iconPath": "icons/icon.ico",
|
|
||||||
"iconAsTemplate": true
|
|
||||||
},
|
|
||||||
"bundle": {
|
|
||||||
"active": true,
|
|
||||||
"targets": "all",
|
|
||||||
"identifier": "com.kkrainbow.easyiter-client",
|
|
||||||
"icon": [
|
|
||||||
"icons/icon.png",
|
|
||||||
"icons/icon.rgba",
|
|
||||||
"icons/icon.icns",
|
|
||||||
"icons/icon.ico"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
{
|
{
|
||||||
"tauri": {
|
"bundle": {
|
||||||
"bundle": {
|
"externalBin": [],
|
||||||
"externalBin": [],
|
"resources": [
|
||||||
"resources": [
|
"./wintun.dll",
|
||||||
"./wintun.dll",
|
"./Packet.dll"
|
||||||
"./Packet.dll"
|
],
|
||||||
],
|
"windows": {
|
||||||
"windows": {
|
"webviewInstallMode": {
|
||||||
"webviewInstallMode": {
|
"type": "embedBootstrapper"
|
||||||
"type": "embedBootstrapper"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
|
const MenuItemExit: typeof import('./composables/tray')['MenuItemExit']
|
||||||
|
const MenuItemShow: typeof import('./composables/tray')['MenuItemShow']
|
||||||
|
const ReinitTray: typeof import('./composables/tray')['ReinitTray']
|
||||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||||
const collectNetworkInfos: typeof import('./composables/network')['collectNetworkInfos']
|
const collectNetworkInfos: typeof import('./composables/network')['collectNetworkInfos']
|
||||||
const computed: typeof import('vue')['computed']
|
const computed: typeof import('vue')['computed']
|
||||||
@@ -17,6 +20,7 @@ declare global {
|
|||||||
const definePage: typeof import('unplugin-vue-router/runtime')['definePage']
|
const definePage: typeof import('unplugin-vue-router/runtime')['definePage']
|
||||||
const defineStore: typeof import('pinia')['defineStore']
|
const defineStore: typeof import('pinia')['defineStore']
|
||||||
const effectScope: typeof import('vue')['effectScope']
|
const effectScope: typeof import('vue')['effectScope']
|
||||||
|
const generateMenuItem: typeof import('./composables/tray')['generateMenuItem']
|
||||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
@@ -62,6 +66,9 @@ declare global {
|
|||||||
const setAutoLaunchStatus: typeof import('./composables/network')['setAutoLaunchStatus']
|
const setAutoLaunchStatus: typeof import('./composables/network')['setAutoLaunchStatus']
|
||||||
const setLoggingLevel: typeof import('./composables/network')['setLoggingLevel']
|
const setLoggingLevel: typeof import('./composables/network')['setLoggingLevel']
|
||||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||||
|
const setTrayMenu: typeof import('./composables/tray')['setTrayMenu']
|
||||||
|
const setTrayRunState: typeof import('./composables/tray')['setTrayRunState']
|
||||||
|
const setTrayTooltip: typeof import('./composables/tray')['setTrayTooltip']
|
||||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
const shallowRef: typeof import('vue')['shallowRef']
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
@@ -81,6 +88,7 @@ declare global {
|
|||||||
const useRoute: typeof import('vue-router/auto')['useRoute']
|
const useRoute: typeof import('vue-router/auto')['useRoute']
|
||||||
const useRouter: typeof import('vue-router/auto')['useRouter']
|
const useRouter: typeof import('vue-router/auto')['useRouter']
|
||||||
const useSlots: typeof import('vue')['useSlots']
|
const useSlots: typeof import('vue')['useSlots']
|
||||||
|
const useTray: typeof import('./composables/tray')['useTray']
|
||||||
const watch: typeof import('vue')['watch']
|
const watch: typeof import('vue')['watch']
|
||||||
const watchEffect: typeof import('vue')['watchEffect']
|
const watchEffect: typeof import('vue')['watchEffect']
|
||||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||||
@@ -98,6 +106,8 @@ declare module 'vue' {
|
|||||||
interface GlobalComponents {}
|
interface GlobalComponents {}
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||||
|
readonly MenuItemExit: UnwrapRef<typeof import('./composables/tray')['MenuItemExit']>
|
||||||
|
readonly MenuItemShow: UnwrapRef<typeof import('./composables/tray')['MenuItemShow']>
|
||||||
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
||||||
readonly collectNetworkInfos: UnwrapRef<typeof import('./composables/network')['collectNetworkInfos']>
|
readonly collectNetworkInfos: UnwrapRef<typeof import('./composables/network')['collectNetworkInfos']>
|
||||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||||
@@ -109,6 +119,7 @@ declare module 'vue' {
|
|||||||
readonly definePage: UnwrapRef<typeof import('unplugin-vue-router/runtime')['definePage']>
|
readonly definePage: UnwrapRef<typeof import('unplugin-vue-router/runtime')['definePage']>
|
||||||
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
||||||
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
||||||
|
readonly generateMenuItem: UnwrapRef<typeof import('./composables/tray')['generateMenuItem']>
|
||||||
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
|
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
|
||||||
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||||
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||||
@@ -154,6 +165,9 @@ declare module 'vue' {
|
|||||||
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
||||||
readonly setLoggingLevel: UnwrapRef<typeof import('./composables/network')['setLoggingLevel']>
|
readonly setLoggingLevel: UnwrapRef<typeof import('./composables/network')['setLoggingLevel']>
|
||||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||||
|
readonly setTrayMenu: UnwrapRef<typeof import('./composables/tray')['setTrayMenu']>
|
||||||
|
readonly setTrayRunState: UnwrapRef<typeof import('./composables/tray')['setTrayRunState']>
|
||||||
|
readonly setTrayTooltip: UnwrapRef<typeof import('./composables/tray')['setTrayTooltip']>
|
||||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||||
@@ -173,6 +187,7 @@ declare module 'vue' {
|
|||||||
readonly useRoute: UnwrapRef<typeof import('vue-router/auto')['useRoute']>
|
readonly useRoute: UnwrapRef<typeof import('vue-router/auto')['useRoute']>
|
||||||
readonly useRouter: UnwrapRef<typeof import('vue-router/auto')['useRouter']>
|
readonly useRouter: UnwrapRef<typeof import('vue-router/auto')['useRouter']>
|
||||||
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
||||||
|
readonly useTray: UnwrapRef<typeof import('./composables/tray')['useTray']>
|
||||||
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
||||||
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
||||||
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
||||||
@@ -183,6 +198,8 @@ declare module '@vue/runtime-core' {
|
|||||||
interface GlobalComponents {}
|
interface GlobalComponents {}
|
||||||
interface ComponentCustomProperties {
|
interface ComponentCustomProperties {
|
||||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||||
|
readonly MenuItemExit: UnwrapRef<typeof import('./composables/tray')['MenuItemExit']>
|
||||||
|
readonly MenuItemShow: UnwrapRef<typeof import('./composables/tray')['MenuItemShow']>
|
||||||
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
||||||
readonly collectNetworkInfos: UnwrapRef<typeof import('./composables/network')['collectNetworkInfos']>
|
readonly collectNetworkInfos: UnwrapRef<typeof import('./composables/network')['collectNetworkInfos']>
|
||||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||||
@@ -194,6 +211,7 @@ declare module '@vue/runtime-core' {
|
|||||||
readonly definePage: UnwrapRef<typeof import('unplugin-vue-router/runtime')['definePage']>
|
readonly definePage: UnwrapRef<typeof import('unplugin-vue-router/runtime')['definePage']>
|
||||||
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
||||||
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
||||||
|
readonly generateMenuItem: UnwrapRef<typeof import('./composables/tray')['generateMenuItem']>
|
||||||
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
|
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
|
||||||
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||||
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||||
@@ -239,6 +257,9 @@ declare module '@vue/runtime-core' {
|
|||||||
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
||||||
readonly setLoggingLevel: UnwrapRef<typeof import('./composables/network')['setLoggingLevel']>
|
readonly setLoggingLevel: UnwrapRef<typeof import('./composables/network')['setLoggingLevel']>
|
||||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||||
|
readonly setTrayMenu: UnwrapRef<typeof import('./composables/tray')['setTrayMenu']>
|
||||||
|
readonly setTrayRunState: UnwrapRef<typeof import('./composables/tray')['setTrayRunState']>
|
||||||
|
readonly setTrayTooltip: UnwrapRef<typeof import('./composables/tray')['setTrayTooltip']>
|
||||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||||
@@ -258,6 +279,7 @@ declare module '@vue/runtime-core' {
|
|||||||
readonly useRoute: UnwrapRef<typeof import('vue-router/auto')['useRoute']>
|
readonly useRoute: UnwrapRef<typeof import('vue-router/auto')['useRoute']>
|
||||||
readonly useRouter: UnwrapRef<typeof import('vue-router/auto')['useRouter']>
|
readonly useRouter: UnwrapRef<typeof import('vue-router/auto')['useRouter']>
|
||||||
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
||||||
|
readonly useTray: UnwrapRef<typeof import('./composables/tray')['useTray']>
|
||||||
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
||||||
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
||||||
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-column h-full">
|
<div class="flex flex-column h-full">
|
||||||
<div class="flex flex-column">
|
<div class="flex flex-column">
|
||||||
<div class="w-7/12 self-center ">
|
<div class="w-10/12 self-center ">
|
||||||
<Message severity="warn">
|
<Message severity="warn">
|
||||||
{{ t('dhcp_experimental_warning') }}
|
{{ t('dhcp_experimental_warning') }}
|
||||||
</Message>
|
</Message>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-7/12 self-center ">
|
<div class="w-10/12 self-center ">
|
||||||
<Panel :header="t('basic_settings')">
|
<Panel :header="t('basic_settings')">
|
||||||
<div class="flex flex-column gap-y-2">
|
<div class="flex flex-column gap-y-2">
|
||||||
<div class="flex flex-row gap-x-9 flex-wrap">
|
<div class="flex flex-row gap-x-9 flex-wrap">
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { invoke } from '@tauri-apps/api/tauri'
|
import { invoke } from "@tauri-apps/api/core"
|
||||||
|
|
||||||
import type { NetworkConfig, NetworkInstanceRunningInfo } from '~/types/network'
|
import type { NetworkConfig, NetworkInstanceRunningInfo } from '~/types/network'
|
||||||
|
|
||||||
export async function parseNetworkConfig(cfg: NetworkConfig) {
|
export async function parseNetworkConfig(cfg: NetworkConfig) {
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import { getCurrent } from '@tauri-apps/api/window'
|
||||||
|
import { Menu, MenuItem, PredefinedMenuItem } from '@tauri-apps/api/menu'
|
||||||
|
import { TrayIcon } from '@tauri-apps/api/tray'
|
||||||
|
import pkg from '~/../package.json'
|
||||||
|
|
||||||
|
const DEFAULT_TRAY_NAME = 'main'
|
||||||
|
|
||||||
|
async function toggleVisibility() {
|
||||||
|
if (await getCurrent().isVisible()) {
|
||||||
|
await getCurrent().hide()
|
||||||
|
} else {
|
||||||
|
await getCurrent().show()
|
||||||
|
await getCurrent().setFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function useTray(init: boolean = false) {
|
||||||
|
let tray = await TrayIcon.getById(DEFAULT_TRAY_NAME)
|
||||||
|
if (!tray) {
|
||||||
|
tray = await TrayIcon.new({
|
||||||
|
tooltip: `EasyTier\n${pkg.version}`,
|
||||||
|
title: `EasyTier\n${pkg.version}`,
|
||||||
|
id: DEFAULT_TRAY_NAME,
|
||||||
|
menu: await Menu.new({
|
||||||
|
id: 'main',
|
||||||
|
items: await generateMenuItem(),
|
||||||
|
}),
|
||||||
|
action: async () => {
|
||||||
|
toggleVisibility()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
tray.setTooltip(`EasyTier\n${pkg.version}`)
|
||||||
|
tray.setMenuOnLeftClick(false);
|
||||||
|
tray.setMenu(await Menu.new({
|
||||||
|
id: 'main',
|
||||||
|
items: await generateMenuItem(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
return tray
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateMenuItem() {
|
||||||
|
return [
|
||||||
|
await MenuItemExit('Exit'),
|
||||||
|
await PredefinedMenuItem.new({ item: 'Separator' }),
|
||||||
|
await MenuItemShow('Show / Hide'),
|
||||||
|
] || []
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function MenuItemExit(text: string) {
|
||||||
|
return await PredefinedMenuItem.new({
|
||||||
|
text: text,
|
||||||
|
item: 'Quit',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function MenuItemShow(text: string) {
|
||||||
|
return await MenuItem.new({
|
||||||
|
id: 'show',
|
||||||
|
text,
|
||||||
|
action: async () => {
|
||||||
|
await toggleVisibility();
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setTrayMenu(items: (MenuItem | PredefinedMenuItem)[] | undefined = undefined) {
|
||||||
|
const tray = await useTray()
|
||||||
|
const menu = await Menu.new({
|
||||||
|
id: 'main',
|
||||||
|
items: items || await generateMenuItem(),
|
||||||
|
})
|
||||||
|
tray.setMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setTrayRunState(isRunning: boolean = false) {
|
||||||
|
const tray = await useTray()
|
||||||
|
tray.setIcon(isRunning ? 'icons/icon-inactive.ico' : 'icons/icon.ico')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setTrayTooltip(tooltip: string) {
|
||||||
|
if (tooltip) {
|
||||||
|
const tray = await useTray()
|
||||||
|
tray.setTooltip(`EasyTier\n${pkg.version}\n${tooltip}`)
|
||||||
|
tray.setTitle(`EasyTier\n${pkg.version}\n${tooltip}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import ToastService from 'primevue/toastservice'
|
|||||||
import App from '~/App.vue'
|
import App from '~/App.vue'
|
||||||
|
|
||||||
import '~/styles.css'
|
import '~/styles.css'
|
||||||
import 'primevue/resources/themes/aura-light-green/theme.css'
|
import Aura from '@primevue/themes/aura'
|
||||||
import 'primeicons/primeicons.css'
|
import 'primeicons/primeicons.css'
|
||||||
import 'primeflex/primeflex.css'
|
import 'primeflex/primeflex.css'
|
||||||
import { i18n, loadLanguageAsync } from '~/modules/i18n'
|
import { i18n, loadLanguageAsync } from '~/modules/i18n'
|
||||||
@@ -41,7 +41,15 @@ async function main() {
|
|||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
app.use(i18n, { useScope: 'global' })
|
app.use(i18n, { useScope: 'global' })
|
||||||
app.use(PrimeVue)
|
app.use(PrimeVue, {
|
||||||
|
theme: {
|
||||||
|
preset: Aura,
|
||||||
|
options: {
|
||||||
|
prefix: 'p',
|
||||||
|
darkModeSelector: 'system',
|
||||||
|
cssLayer: false
|
||||||
|
}
|
||||||
|
}})
|
||||||
app.use(ToastService)
|
app.use(ToastService)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Stepper from 'primevue/stepper'
|
|
||||||
import StepperPanel from 'primevue/stepperpanel'
|
|
||||||
|
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
|
|
||||||
import { exit } from '@tauri-apps/api/process'
|
import { exit } from '@tauri-apps/plugin-process';
|
||||||
import Config from '~/components/Config.vue'
|
import Config from '~/components/Config.vue'
|
||||||
import Status from '~/components/Status.vue'
|
import Status from '~/components/Status.vue'
|
||||||
|
|
||||||
@@ -14,14 +11,17 @@ import { getAutoLaunchStatusAsync as getAutoLaunchStatus, loadAutoLaunchStatusAs
|
|||||||
import { loadRunningInstanceIdsFromLocalStorage } from '~/stores/network'
|
import { loadRunningInstanceIdsFromLocalStorage } from '~/stores/network'
|
||||||
import { setLoggingLevel } from '~/composables/network'
|
import { setLoggingLevel } from '~/composables/network'
|
||||||
import TieredMenu from 'primevue/tieredmenu'
|
import TieredMenu from 'primevue/tieredmenu'
|
||||||
import { open } from '@tauri-apps/api/shell'
|
import { open } from '@tauri-apps/plugin-shell';
|
||||||
import { appLogDir } from '@tauri-apps/api/path'
|
import { appLogDir } from '@tauri-apps/api/path'
|
||||||
import { writeText } from '@tauri-apps/api/clipboard'
|
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||||
|
import { useTray } from '~/composables/tray';
|
||||||
|
|
||||||
const { t, locale } = useI18n()
|
const { t, locale } = useI18n()
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const tomlConfig = ref('')
|
const tomlConfig = ref('')
|
||||||
|
|
||||||
|
useTray(true)
|
||||||
|
|
||||||
const items = ref([
|
const items = ref([
|
||||||
{
|
{
|
||||||
label: () => t('show_config'),
|
label: () => t('show_config'),
|
||||||
@@ -81,8 +81,8 @@ networkStore.$subscribe(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
async function runNetworkCb(cfg: NetworkConfig, cb: (e: MouseEvent) => void) {
|
async function runNetworkCb(cfg: NetworkConfig, cb: () => void) {
|
||||||
cb({} as MouseEvent)
|
cb()
|
||||||
networkStore.removeNetworkInstance(cfg.instance_id)
|
networkStore.removeNetworkInstance(cfg.instance_id)
|
||||||
await retainNetworkInstance(networkStore.networkInstanceIds)
|
await retainNetworkInstance(networkStore.networkInstanceIds)
|
||||||
networkStore.addNetworkInstance(cfg.instance_id)
|
networkStore.addNetworkInstance(cfg.instance_id)
|
||||||
@@ -96,9 +96,9 @@ async function runNetworkCb(cfg: NetworkConfig, cb: (e: MouseEvent) => void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stopNetworkCb(cfg: NetworkConfig, cb: (e: MouseEvent) => void) {
|
async function stopNetworkCb(cfg: NetworkConfig, cb: () => void) {
|
||||||
// console.log('stopNetworkCb', cfg, cb)
|
// console.log('stopNetworkCb', cfg, cb)
|
||||||
cb({} as MouseEvent)
|
cb()
|
||||||
networkStore.removeNetworkInstance(cfg.instance_id)
|
networkStore.removeNetworkInstance(cfg.instance_id)
|
||||||
await retainNetworkInstance(networkStore.networkInstanceIds)
|
await retainNetworkInstance(networkStore.networkInstanceIds)
|
||||||
}
|
}
|
||||||
@@ -108,15 +108,19 @@ async function updateNetworkInfos() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let intervalId = 0
|
let intervalId = 0
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
intervalId = window.setInterval(async () => {
|
intervalId = window.setInterval(async () => {
|
||||||
await updateNetworkInfos()
|
await updateNetworkInfos()
|
||||||
}, 500)
|
}, 500)
|
||||||
|
await setTrayMenu([
|
||||||
|
await MenuItemExit(t('tray.exit')),
|
||||||
|
await MenuItemShow(t('tray.show'))
|
||||||
|
])
|
||||||
})
|
})
|
||||||
onUnmounted(() => clearInterval(intervalId))
|
onUnmounted(() => clearInterval(intervalId))
|
||||||
|
|
||||||
const activeStep = computed(() => {
|
const activeStep = computed(() => {
|
||||||
return networkStore.networkInstanceIds.includes(networkStore.curNetworkId) ? 1 : 0
|
return networkStore.networkInstanceIds.includes(networkStore.curNetworkId) ? '2' : '1'
|
||||||
})
|
})
|
||||||
|
|
||||||
let current_log_level = 'off'
|
let current_log_level = 'off'
|
||||||
@@ -128,6 +132,10 @@ const setting_menu_items = ref([
|
|||||||
icon: 'pi pi-language',
|
icon: 'pi pi-language',
|
||||||
command: async () => {
|
command: async () => {
|
||||||
await loadLanguageAsync((locale.value === 'en' ? 'cn' : 'en'))
|
await loadLanguageAsync((locale.value === 'en' ? 'cn' : 'en'))
|
||||||
|
await setTrayMenu([
|
||||||
|
await MenuItemExit(t('tray.exit')),
|
||||||
|
await MenuItemShow(t('tray.show'))
|
||||||
|
])
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -274,25 +282,29 @@ function isRunning(id: string) {
|
|||||||
</Toolbar>
|
</Toolbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Stepper class="h-full overflow-y-auto" :active-step="activeStep">
|
<Panel class="h-full overflow-y-auto" >
|
||||||
<StepperPanel :header="t('config_network')">
|
<Stepper :value="activeStep">
|
||||||
<template #content="{ nextCallback }">
|
<StepList value="1">
|
||||||
<Config :instance-id="networkStore.curNetworkId" :config-invalid="messageBarSeverity !== Severity.None"
|
<Step value="1">{{ t('config_network') }}</Step>
|
||||||
@run-network="runNetworkCb($event, nextCallback)" />
|
<Step value="2">{{ t('running') }}</Step>
|
||||||
</template>
|
</StepList>
|
||||||
</StepperPanel>
|
<StepPanels value="1">
|
||||||
<StepperPanel :header="t('running')">
|
<StepPanel v-slot="{ activateCallback = (s: string) => {} } = {}" value="1">
|
||||||
<template #content="{ prevCallback }">
|
<Config :instance-id="networkStore.curNetworkId" :config-invalid="messageBarSeverity !== Severity.None"
|
||||||
<div class="flex flex-column">
|
@run-network="runNetworkCb($event, () => activateCallback('2'))" />
|
||||||
<Status :instance-id="networkStore.curNetworkId" />
|
</StepPanel>
|
||||||
</div>
|
<StepPanel v-slot="{ activateCallback = (s: string) => {} } = {}" value="2">
|
||||||
<div class="flex pt-4 justify-content-center">
|
<div class="flex flex-column">
|
||||||
<Button :label="t('stop_network')" severity="danger" icon="pi pi-arrow-left"
|
<Status :instance-id="networkStore.curNetworkId" />
|
||||||
@click="stopNetworkCb(networkStore.curNetwork, prevCallback)" />
|
</div>
|
||||||
</div>
|
<div class="flex pt-4 justify-content-center">
|
||||||
</template>
|
<Button :label="t('stop_network')" severity="danger" icon="pi pi-arrow-left"
|
||||||
</StepperPanel>
|
@click="stopNetworkCb(networkStore.curNetwork, () => activateCallback('1'))" />
|
||||||
</Stepper>
|
</div>
|
||||||
|
</StepPanel>
|
||||||
|
</StepPanels>
|
||||||
|
</Stepper>
|
||||||
|
</Panel>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Menubar :model="items" breakpoint="300px" />
|
<Menubar :model="items" breakpoint="300px" />
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export function DEFAULT_NETWORK_CONFIG(): NetworkConfig {
|
|||||||
return {
|
return {
|
||||||
instance_id: uuidv4(),
|
instance_id: uuidv4(),
|
||||||
|
|
||||||
dhcp: false,
|
dhcp: true,
|
||||||
virtual_ipv4: '',
|
virtual_ipv4: '',
|
||||||
network_name: 'easytier',
|
network_name: 'easytier',
|
||||||
network_secret: '',
|
network_secret: '',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import VueI18n from '@intlify/unplugin-vue-i18n/vite'
|
|||||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||||
import VueRouter from 'unplugin-vue-router/vite'
|
import VueRouter from 'unplugin-vue-router/vite'
|
||||||
import { VueRouterAutoImports } from 'unplugin-vue-router'
|
import { VueRouterAutoImports } from 'unplugin-vue-router'
|
||||||
import { PrimeVueResolver } from 'unplugin-vue-components/resolvers'
|
import { PrimeVueResolver } from '@primevue/auto-import-resolver';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(async () => ({
|
export default defineConfig(async () => ({
|
||||||
|
|||||||
@@ -1001,6 +1001,9 @@ impl PeerRouteServiceImpl {
|
|||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
tracing::error!(?ret, ?my_peer_id, ?dst_peer_id, "sync_route_info failed");
|
tracing::error!(?ret, ?my_peer_id, ?dst_peer_id, "sync_route_info failed");
|
||||||
|
session
|
||||||
|
.need_sync_initiator_info
|
||||||
|
.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||