feat: migrate tauri 2.0
Some checks failed
Alpha Build / alpha (macos-latest, aarch64-apple-darwin) (push) Has been cancelled
Alpha Build / alpha (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
Alpha Build / alpha (windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
Alpha Build / alpha (windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
Alpha Build / alpha (windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Alpha Build / alpha-for-linux (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Has been cancelled
Alpha Build / alpha-for-fixed-webview2 (arm64, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
Alpha Build / alpha-for-fixed-webview2 (x64, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Alpha Build / alpha-for-fixed-webview2 (x86, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
Alpha Build / Update tag (push) Has been cancelled

This commit is contained in:
huzibaca 2024-09-04 08:54:15 +08:00
parent ae1c6d4617
commit b9be5e8c44
No known key found for this signature in database
GPG Key ID: D4364EE4851DC302
22 changed files with 842 additions and 14750 deletions

View File

@ -1,4 +1,4 @@
FROM rust:buster
FROM rust:bookworm
COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]

View File

@ -6,48 +6,12 @@ export PATH=$(pwd)/node-v20.10.0-linux-x64/bin:$PATH
npm install pnpm -g
rustup target add "$INPUT_TARGET"
echo "rustc version: $(rustc --version)"
if [ "$INPUT_TARGET" = "x86_64-unknown-linux-gnu" ]; then
apt-get update
apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev patchelf
elif [ "$INPUT_TARGET" = "i686-unknown-linux-gnu" ]; then
dpkg --add-architecture i386
apt-get update
apt-get install -y libstdc++6:i386 libgdk-pixbuf2.0-dev:i386 libatomic1:i386 gcc-multilib g++-multilib libwebkit2gtk-4.0-dev:i386 libssl-dev:i386 libgtk-3-dev:i386 librsvg2-dev:i386 patchelf:i386 libayatana-appindicator3-dev:i386
export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig/:$PKG_CONFIG_PATH
export PKG_CONFIG_SYSROOT_DIR=/
elif [ "$INPUT_TARGET" = "aarch64-unknown-linux-gnu" ]; then
dpkg --add-architecture arm64
apt-get update
apt-get install -y libncurses6:arm64 libtinfo6:arm64 linux-libc-dev:arm64 libncursesw6:arm64 libssl3:arm64 libcups2:arm64
apt-get install -y --no-install-recommends g++-aarch64-linux-gnu libc6-dev-arm64-cross libwebkit2gtk-4.0-dev:arm64 libgtk-3-dev:arm64 patchelf:arm64 librsvg2-dev:arm64 libayatana-appindicator3-dev:arm64
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
elif [ "$INPUT_TARGET" = "armv7-unknown-linux-gnueabihf" ]; then
dpkg --add-architecture armhf
apt-get update
apt-get install -y libncurses6:armhf libtinfo6:armhf linux-libc-dev:armhf libncursesw6:armhf libssl3:armhf libcups2:armhf
apt-get install -y --no-install-recommends g++-arm-linux-gnueabihf libc6-dev-armhf-cross libwebkit2gtk-4.0-dev:armhf libgtk-3-dev:armhf patchelf:armhf librsvg2-dev:armhf libayatana-appindicator3-dev:armhf
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
export CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc
export CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++
export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
elif [ "$INPUT_TARGET" = "riscv64gc-unknown-linux-gnu" ]; then
dpkg --add-architecture riscv64
apt-get update
apt-get install -y libncurses6:riscv64 libtinfo6:riscv64 linux-libc-dev:riscv64 libncursesw6:riscv64 libssl3:riscv64 libcups2:riscv64
apt-get install -y --no-install-recommends g++-riscv64-linux-gnu libc6-dev-riscv64-cross libwebkit2gtk-4.0-dev:riscv64 libgtk-3-dev:riscv64 patchelf:riscv64 librsvg2-dev:riscv64 libayatana-appindicator3-dev:riscv64
export CARGO_TARGET_RISCV64_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc
export CC_riscv64_unknown_linux_gnu=riscv64-linux-gnu-gcc
export CXX_riscv64_unknown_linux_gnu=riscv64-linux-gnu-g++
export PKG_CONFIG_PATH=/usr/lib/riscv64-linux-gnu/pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
else
echo "Unknown target: $INPUT_TARGET" && exit 1
apt-get install -y libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
fi
bash .github/build-for-linux/build.sh
bash .github/build-for-linux/build.sh

View File

@ -99,12 +99,6 @@ jobs:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: i686-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
- os: ubuntu-latest
target: armv7-unknown-linux-gnueabihf
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
@ -114,15 +108,15 @@ jobs:
uses: ./.github/build-for-linux
env:
NODE_OPTIONS: "--max_old_space_size=4096"
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
target: ${{ matrix.target }}
- name: Get Version
run: |
sudo apt-get update
sudo apt-get install jq
sudo apt-get install jq
echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
@ -195,8 +189,8 @@ jobs:
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tauriScript: pnpm
args: --target ${{ matrix.target }}
@ -252,9 +246,6 @@ jobs:
### Linux
- Linux 64位: amd64.deb/amd64.rpm
- Linux 32位: i386.deb/i386.rpm
- Linux arm64架构: arm64.deb/aarch64.rpm
- Linux armv7架构: armhf.deb/armhfp.rpm
### Windows (Win7 用户请查看下面FAQ中的解决方案)
#### 正常版本(推荐)

View File

@ -1,6 +1,8 @@
# Generated by Cargo
# will have compiled files and executables
/target/
gen/
WixTools
resources
sidecar

364
src-tauri/Cargo.lock generated
View File

@ -350,6 +350,28 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "async-stream"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.77",
]
[[package]]
name = "async-task"
version = "4.7.1"
@ -413,6 +435,51 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
"itoa 1.0.11",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"sync_wrapper 0.1.2",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.73"
@ -866,6 +933,7 @@ dependencies = [
"tauri",
"tauri-build",
"tauri-plugin-clipboard-manager",
"tauri-plugin-devtools",
"tauri-plugin-dialog",
"tauri-plugin-fs",
"tauri-plugin-global-shortcut",
@ -955,6 +1023,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
]
[[package]]
name = "combine"
version = "4.6.7"
@ -1324,6 +1402,48 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7"
[[package]]
name = "devtools-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f21c374111065b917a9ed5d1e377cd5792cd19f641ee0bf316f72878908bb99"
dependencies = [
"async-stream",
"bytes",
"devtools-wire-format",
"futures",
"http 0.2.12",
"hyper 0.14.30",
"log",
"prost-types",
"ringbuf",
"thiserror",
"tokio",
"tokio-stream",
"tonic",
"tonic-health",
"tonic-web",
"tower",
"tower-http",
"tower-layer",
"tracing",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "devtools-wire-format"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d841ad485c6bc179ffed4886197490045644f2f194b52ce090c8488bb0028b"
dependencies = [
"bitflags 2.6.0",
"prost",
"prost-types",
"tonic",
"tracing-core",
]
[[package]]
name = "digest"
version = "0.9.0"
@ -2466,6 +2586,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
[[package]]
name = "http-range-header"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f"
[[package]]
name = "httparse"
version = "1.9.4"
@ -2546,6 +2672,18 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-timeout"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper 0.14.30",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@ -3104,6 +3242,18 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
[[package]]
name = "local-ip-address"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612ed4ea9ce5acfb5d26339302528a5e1e59dfed95e9e11af3c083236ff1d15d"
dependencies = [
"libc",
"neli",
"thiserror",
"windows-sys 0.48.0",
]
[[package]]
name = "lock_api"
version = "0.4.12"
@ -3238,6 +3388,12 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.7.4"
@ -3420,6 +3576,31 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "neli"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43"
dependencies = [
"byteorder",
"libc",
"log",
"neli-proc-macros",
]
[[package]]
name = "neli-proc-macros"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4"
dependencies = [
"either",
"proc-macro2",
"quote",
"serde",
"syn 1.0.109",
]
[[package]]
name = "network-interface"
version = "2.0.0"
@ -4329,6 +4510,38 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prost"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-derive"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn 2.0.77",
]
[[package]]
name = "prost-types"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
dependencies = [
"prost",
]
[[package]]
name = "qoi"
version = "0.4.1"
@ -4640,7 +4853,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.1",
"system-configuration",
"tokio",
"tokio-native-tls",
@ -4695,6 +4908,15 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "ringbuf"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f7f1b88601a8ee13cabf203611ccdf64345dc1c5d24de8b11e1a678ee619b6"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "rs-snowflake"
version = "0.6.0"
@ -5456,6 +5678,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.1"
@ -5654,6 +5882,7 @@ dependencies = [
"tauri-utils",
"thiserror",
"tokio",
"tracing",
"tray-icon",
"url",
"urlpattern",
@ -5759,6 +5988,33 @@ dependencies = [
"thiserror",
]
[[package]]
name = "tauri-plugin-devtools"
version = "2.0.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f7333811c0b81f32e980d34894effc92454f464409fb97a7e566294b7ebddd0"
dependencies = [
"async-stream",
"bytes",
"cocoa 0.25.0",
"colored",
"devtools-core",
"futures",
"local-ip-address",
"log",
"objc",
"serde",
"serde_json",
"swift-rs",
"tauri",
"tauri-plugin",
"tokio",
"tonic",
"tonic-health",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tauri-plugin-dialog"
version = "2.0.0-rc.3"
@ -5927,6 +6183,7 @@ dependencies = [
"tao",
"tauri-runtime",
"tauri-utils",
"tracing",
"url",
"webkit2gtk",
"webview2-com",
@ -6209,6 +6466,16 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-io-timeout"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
dependencies = [
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-macros"
version = "2.4.0"
@ -6241,6 +6508,17 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.21.0"
@ -6325,6 +6603,66 @@ dependencies = [
"winnow",
]
[[package]]
name = "tonic"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e"
dependencies = [
"async-stream",
"async-trait",
"axum",
"base64 0.21.7",
"bytes",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
"hyper-timeout",
"percent-encoding",
"pin-project",
"prost",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic-health"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1"
dependencies = [
"async-stream",
"prost",
"tokio",
"tokio-stream",
"tonic",
]
[[package]]
name = "tonic-web"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fddb2a37b247e6adcb9f239f4e5cefdcc5ed526141a416b943929f13aea2cce"
dependencies = [
"base64 0.21.7",
"bytes",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.30",
"pin-project",
"tokio-stream",
"tonic",
"tower-http",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -6333,9 +6671,32 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand 0.8.5",
"slab",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
dependencies = [
"bitflags 2.6.0",
"bytes",
"futures-core",
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"http-range-header",
"pin-project-lite",
"tower-layer",
"tower-service",
]
@ -7486,6 +7847,7 @@ dependencies = [
"soup3",
"tao-macros",
"thiserror",
"tracing",
"webkit2gtk",
"webkit2gtk-sys",
"webview2-com",

View File

@ -51,6 +51,7 @@ tauri-plugin-fs = "2.0.0-rc"
tauri-plugin-notification = "2.0.0-rc"
tauri-plugin-process = "2.0.0-rc"
tauri-plugin-clipboard-manager = "2.1.0-beta.7"
tauri-plugin-devtools = "2.0.0-rc"
[target.'cfg(windows)'.dependencies]
runas = "=1.2.0"
deelevate = "0.2.0"

View File

@ -1,5 +1,7 @@
{
"identifier": "desktop-capability",
"platforms": ["macOS", "windows", "linux"],
"webviews": ["main"],
"windows": ["main"],
"permissions": ["global-shortcut:default", "updater:default"]
}

View File

@ -46,6 +46,9 @@
"core:webview:allow-print",
"shell:allow-execute",
"shell:allow-open",
"shell:allow-kill",
"shell:allow-spawn",
"shell:allow-stdin-write",
"dialog:allow-open",
"notification:default",
"global-shortcut:allow-is-registered",
@ -59,7 +62,6 @@
"clipboard-manager:allow-write-text",
"shell:default",
"dialog:default",
"fs:default",
"notification:default"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
{
"desktop-capability": {
"identifier": "desktop-capability",
"description": "",
"local": true,
"permissions": ["global-shortcut:default", "updater:default"],
"platforms": ["macOS", "windows", "linux"]
},
"migrated": {
"identifier": "migrated",
"description": "permissions that were migrated from v1",
"local": true,
"windows": ["main"],
"permissions": [
"core:default",
"fs:allow-read-file",
"fs:allow-exists",
{
"identifier": "fs:scope",
"allow": ["$APPDATA/**", "$RESOURCE/../**", "**"]
},
"core:window:allow-create",
"core:window:allow-center",
"core:window:allow-request-user-attention",
"core:window:allow-set-resizable",
"core:window:allow-set-maximizable",
"core:window:allow-set-minimizable",
"core:window:allow-set-closable",
"core:window:allow-set-title",
"core:window:allow-maximize",
"core:window:allow-unmaximize",
"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-close",
"core:window:allow-set-decorations",
"core:window:allow-set-always-on-top",
"core:window:allow-set-content-protected",
"core:window:allow-set-size",
"core:window:allow-set-min-size",
"core:window:allow-set-max-size",
"core:window:allow-set-position",
"core:window:allow-set-fullscreen",
"core:window:allow-set-focus",
"core:window:allow-set-icon",
"core:window:allow-set-skip-taskbar",
"core:window:allow-set-cursor-grab",
"core:window:allow-set-cursor-visible",
"core:window:allow-set-cursor-icon",
"core:window:allow-set-cursor-position",
"core:window:allow-set-ignore-cursor-events",
"core:window:allow-start-dragging",
"core:webview:allow-print",
"shell:allow-execute",
"shell:allow-open",
"dialog:allow-open",
"notification:default",
"global-shortcut:allow-is-registered",
"global-shortcut:allow-register",
"global-shortcut:allow-register-all",
"global-shortcut:allow-unregister",
"global-shortcut:allow-unregister-all",
"process:allow-restart",
"process:allow-exit",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text",
"shell:default",
"dialog:default",
"fs:default",
"notification:default"
]
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -36,8 +36,10 @@ impl CoreManager {
pub fn init(&self, app_handle: &AppHandle) -> Result<()> {
*self.app_handle.lock() = Some(app_handle.clone());
tauri::async_runtime::spawn(async {
log::trace!("run core start");
// 启动clash
log_err!(Self::global().run_core().await);
log::trace!("run core end");
});
Ok(())
@ -69,9 +71,9 @@ impl CoreManager {
let test_dir = dirs::path_to_str(&test_dir)?;
let app_handle_option = {
let lock = self.app_handle.lock();
lock.as_ref().cloned()
lock.as_ref().cloned()
};
if let Some(app_handle) = app_handle_option {
let output = app_handle
.shell()

View File

@ -1,126 +1,50 @@
use crate::{
cmds,
config::Config,
feat,
utils::{dirs, resolve},
feat, t,
utils::{
dirs,
resolve::{self, VERSION},
},
};
use anyhow::Result;
use tauri::menu::{MenuBuilder, MenuEvent, MenuItemBuilder, PredefinedMenuItem, SubmenuBuilder};
use tauri::tray::{MouseButton, MouseButtonState, TrayIcon, TrayIconBuilder, TrayIconEvent};
use tauri::tray::{MouseButton, MouseButtonState, TrayIconEvent};
use tauri::{
menu::{MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
Wry,
};
use tauri::{AppHandle, Manager};
pub struct Tray {}
impl Tray {
pub fn update_systray(app_handle: &AppHandle) -> Result<()> {
let zh = { Config::verge().latest().language == Some("zh".into()) };
macro_rules! t {
($en: expr, $zh: expr) => {
if zh {
$zh
} else {
$en
let tray = app_handle.tray_by_id("main").unwrap();
tray.on_tray_icon_event(|tray, event| {
let tray_event = { Config::verge().latest().tray_event.clone() };
let tray_event: String = tray_event.unwrap_or("main_window".into());
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
let app = tray.app_handle();
match tray_event.as_str() {
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"main_window" => resolve::create_window(app),
_ => {}
}
};
}
}
});
tray.on_menu_event(on_menu_event);
let version = app_handle.package_info().version.to_string();
let open_window = MenuItemBuilder::with_id("open_window", t!("Dashboard", "打开面板"))
.build(app_handle)?;
let rule_mode =
MenuItemBuilder::with_id("rule_mode", t!("Rule Mode", "规则模式")).build(app_handle)?;
let global_mode = MenuItemBuilder::with_id("global_mode", t!("Global Mode", "全局模式"))
.build(app_handle)?;
let direct_mode = MenuItemBuilder::with_id("direct_mode", t!("Direct Mode", "直连模式"))
.build(app_handle)?;
let system_proxy = MenuItemBuilder::with_id("system_proxy", t!("System Proxy", "系统代理"))
.build(app_handle)?;
let tun_mode =
MenuItemBuilder::with_id("tun_mode", t!("TUN Mode", "Tun 模式")).build(app_handle)?;
let copy_env = MenuItemBuilder::with_id("copy_env", t!("Copy Env", "复制环境变量"))
.build(app_handle)?;
let open_app_dir = MenuItemBuilder::with_id("open_app_dir", t!("App Dir", "应用目录"))
.build(app_handle)?;
let open_core_dir = MenuItemBuilder::with_id("open_core_dir", t!("Core Dir", "内核目录"))
.build(app_handle)?;
let open_logs_dir = MenuItemBuilder::with_id("open_logs_dir", t!("Logs Dir", "日志目录"))
.build(app_handle)?;
let open_dir = SubmenuBuilder::with_id(app_handle, "open_dir", t!("Open Dir", "打开目录"))
.items(&[&open_app_dir, &open_core_dir, &open_logs_dir])
.build()?;
let restart_clash =
MenuItemBuilder::with_id("restart_clash", t!("Restart Clash", "重启 Clash"))
.build(app_handle)?;
let restart_app = MenuItemBuilder::with_id("restart_app", t!("Restart App", "重启应用"))
.build(app_handle)?;
let app_version = MenuItemBuilder::with_id("app_version", format!("Version {version}"))
.build(app_handle)?;
let more = SubmenuBuilder::with_id(app_handle, "more", t!("More", "更多"))
.items(&[&restart_clash, &restart_app, &app_version])
.build()?;
let quit = MenuItemBuilder::with_id("quit", t!("Quit", "退出"))
.accelerator("CmdOrControl+Q")
.build(app_handle)?;
let separator = PredefinedMenuItem::separator(app_handle)?;
let menu = MenuBuilder::new(app_handle)
.items(&[
&open_window,
&separator,
&rule_mode,
&global_mode,
&direct_mode,
&separator,
&system_proxy,
&tun_mode,
&copy_env,
&open_dir,
&more,
&separator,
&quit,
])
.build()?;
let _ = TrayIconBuilder::with_id("verge_tray")
.menu(&menu)
.on_menu_event(Self::on_menu_event)
.on_tray_icon_event(|tray, event| {
let tray_event = { Config::verge().latest().tray_event.clone() };
let tray_event: String = tray_event.unwrap_or("main_window".into());
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
..
} = event
{
let app = tray.app_handle();
match tray_event.as_str() {
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"main_window" => resolve::create_window(app),
_ => {}
}
}
})
.build(app_handle);
Tray::update_part(app_handle)?;
Ok(())
}
pub fn update_part(app_handle: &AppHandle) -> Result<()> {
let zh = { Config::verge().latest().language == Some("zh".into()) };
let version = app_handle.package_info().version.to_string();
macro_rules! t {
($en: expr, $zh: expr) => {
if zh {
$zh
} else {
$en
}
};
}
let use_zh = { Config::verge().latest().language == Some("zh".into()) };
let version = VERSION.get().unwrap();
let mode = {
Config::clash()
.latest()
@ -131,264 +55,324 @@ impl Tray {
.to_owned()
};
if let Some(menu) = app_handle.menu() {
if let Some(item) = menu.get("rule_mode") {
let item = item.as_check_menuitem().unwrap();
let _ = item.set_checked(mode == "rule");
let verge = Config::verge().latest().clone();
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
#[cfg(target_os = "macos")]
let tray_icon = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
let common_tray_icon = verge.common_tray_icon.as_ref().unwrap_or(&false);
let sysproxy_tray_icon = verge.sysproxy_tray_icon.as_ref().unwrap_or(&false);
let tun_tray_icon = verge.tun_tray_icon.as_ref().unwrap_or(&false);
let tray = app_handle.tray_by_id("main").unwrap();
let _ = tray.set_menu(Some(create_tray_menu(
app_handle,
Some(mode.as_str()),
*system_proxy,
*tun_mode,
)?));
// let _ = tray.
#[cfg(target_os = "macos")]
match tray_icon.as_str() {
"monochrome" => {
let _ = tray.set_icon_as_template(true);
}
if let Some(item) = menu.get("global_mode") {
let item = item.as_check_menuitem().unwrap();
let _ = item.set_checked(mode == "global");
"colorful" => {
let _ = tray.set_icon_as_template(false);
}
if let Some(item) = menu.get("direct_mode") {
let item = item.as_check_menuitem().unwrap();
let _ = item.set_checked(mode == "direct");
}
#[cfg(target_os = "linux")]
match mode.as_str() {
"rule" => {
if let Some(item) = menu.get("rule_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Rule Mode ✔", "规则模式 ✔"));
}
if let Some(item) = menu.get("global_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Global Mode", "全局模式"));
}
if let Some(item) = menu.get("direct_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Direct Mode", "直连模式"));
}
}
"global" => {
if let Some(item) = menu.get("rule_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Rule Mode", "规则模式"));
}
if let Some(item) = menu.get("global_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Global Mode ✔", "全局模式 ✔"));
}
if let Some(item) = menu.get("direct_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Direct Mode", "直连模式"));
}
}
"direct" => {
if let Some(item) = menu.get("rule_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Rule Mode", "规则模式"));
}
if let Some(item) = menu.get("global_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Global Mode", "全局模式"));
}
if let Some(item) = menu.get("direct_mode") {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("Direct Mode ✔", "直连模式 ✔"));
}
}
_ => {}
}
let verge = Config::verge();
let verge = verge.latest();
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
#[cfg(target_os = "macos")]
let tray_icon = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
let common_tray_icon = verge.common_tray_icon.as_ref().unwrap_or(&false);
let sysproxy_tray_icon = verge.sysproxy_tray_icon.as_ref().unwrap_or(&false);
let tun_tray_icon = verge.tun_tray_icon.as_ref().unwrap_or(&false);
let tray: TrayIcon = app_handle.tray_by_id("verge_tray").unwrap();
#[cfg(target_os = "macos")]
match tray_icon.as_str() {
"monochrome" => {
let _ = tray.set_icon_as_template(true);
}
"colorful" => {
let _ = tray.set_icon_as_template(false);
}
_ => {}
}
let mut indication_icon = if *system_proxy {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon-sys.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon-sys.ico").to_vec();
if *sysproxy_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("sysproxy.png");
let ico_path = icon_dir_path.join("sysproxy.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} else {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon.ico").to_vec();
if *common_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("common.png");
let ico_path = icon_dir_path.join("common.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
};
if *tun_mode {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon-tun.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon-tun.ico").to_vec();
if *tun_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("tun.png");
let ico_path = icon_dir_path.join("tun.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
indication_icon = icon
}
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&indication_icon)?));
if let Some(item) = menu.get("system_proxy") {
let item = item.as_check_menuitem().unwrap();
let _ = item.set_checked(mode == "system_proxy");
}
if let Some(item) = menu.get("tun_mode") {
let item = item.as_check_menuitem().unwrap();
let _ = item.set_checked(mode == "tun_mode");
}
#[cfg(target_os = "linux")]
{
if let Some(item) = menu.get("system_proxy") {
if *system_proxy {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("System Proxy ✔", "系统代理 ✔"));
} else {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("System Proxy", "系统代理"));
}
}
if let Some(item) = menu.get("tun_mode") {
if *tun_mode {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("TUN Mode ✔", "Tun 模式 ✔"));
} else {
let _ = item
.as_menuitem()
.unwrap()
.set_text(t!("TUN Mode", "Tun 模式"));
}
}
}
let switch_map = {
let mut map = std::collections::HashMap::new();
map.insert(true, "on");
map.insert(false, "off");
map
};
let mut current_profile_name = "None".to_string();
let profiles = Config::profiles();
let profiles = profiles.latest();
if let Some(current_profile_uid) = profiles.get_current() {
let current_profile = profiles.get_item(&current_profile_uid);
current_profile_name = match &current_profile.unwrap().name {
Some(profile_name) => profile_name.to_string(),
None => current_profile_name,
};
};
let _ = tray.set_tooltip(Some(&format!(
"Clash Verge {version}\n{}: {}\n{}: {}\n{}: {}",
t!("SysProxy", "系统代理"),
switch_map[system_proxy],
t!("TUN", "Tun模式"),
switch_map[tun_mode],
t!("Profile", "当前订阅"),
current_profile_name
)));
}
Ok(())
}
pub fn on_menu_event(app_handle: &AppHandle, event: MenuEvent) {
match event.id.as_ref() {
mode @ ("rule_mode" | "global_mode" | "direct_mode") => {
let mode = &mode[0..mode.len() - 5];
feat::change_clash_mode(mode.into());
}
"open_window" => resolve::create_window(app_handle),
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"copy_env" => feat::copy_clash_env(app_handle),
"open_app_dir" => crate::log_err!(cmds::open_app_dir()),
"open_core_dir" => crate::log_err!(cmds::open_core_dir()),
"open_logs_dir" => crate::log_err!(cmds::open_logs_dir()),
"restart_clash" => feat::restart_clash_core(),
"restart_app" => tauri::process::restart(&app_handle.env()),
"quit" => cmds::exit_app(app_handle.clone()),
_ => {}
}
let mut indication_icon = if *system_proxy {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon-sys.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon-sys.ico").to_vec();
if *sysproxy_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("sysproxy.png");
let ico_path = icon_dir_path.join("sysproxy.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} else {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon.ico").to_vec();
if *common_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("common.png");
let ico_path = icon_dir_path.join("common.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
};
if *tun_mode {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"monochrome" => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(),
"colorful" => include_bytes!("../../icons/tray-icon-tun.ico").to_vec(),
_ => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../icons/tray-icon-tun.ico").to_vec();
if *tun_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("tun.png");
let ico_path = icon_dir_path.join("tun.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
indication_icon = icon
}
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&indication_icon)?));
let switch_map = {
let mut map = std::collections::HashMap::new();
map.insert(true, "on");
map.insert(false, "off");
map
};
let mut current_profile_name = "None".to_string();
let profiles = Config::profiles();
let profiles = profiles.latest();
if let Some(current_profile_uid) = profiles.get_current() {
let current_profile = profiles.get_item(&current_profile_uid);
current_profile_name = match &current_profile.unwrap().name {
Some(profile_name) => profile_name.to_string(),
None => current_profile_name,
};
};
let _ = tray.set_tooltip(Some(&format!(
"Clash Verge {version}\n{}: {}\n{}: {}\n{}: {}",
t!("SysProxy", "系统代理", use_zh),
switch_map[system_proxy],
t!("TUN", "Tun模式", use_zh),
switch_map[tun_mode],
t!("Profile", "当前订阅", use_zh),
current_profile_name
)));
Ok(())
}
}
fn create_tray_menu(
app_handle: &AppHandle,
mode: Option<&str>,
system_proxy_enabled: bool,
tun_mode_enabled: bool,
) -> Result<tauri::menu::Menu<Wry>> {
let mode = mode.unwrap_or("");
let use_zh = { Config::verge().latest().language == Some("zh".into()) };
let version = VERSION.get().unwrap();
let rule_mode_text = if mode == "rule" {
"✓ 规则模式"
} else {
"规则模式"
};
let global_mode_text = if mode == "global" {
"✓ 全局模式"
} else {
"全局模式"
};
let direct_mode_text = if mode == "direct" {
"✓ 直连模式"
} else {
"直连模式"
};
let system_proxy_text = if system_proxy_enabled {
"✓ 系统代理"
} else {
"系统代理"
};
let tun_mode_text = if tun_mode_enabled {
"✓ Tun 模式"
} else {
"Tun 模式"
};
let restart_clash = &MenuItem::with_id(
app_handle,
"restart_clash",
t!("Restart App", "重启 Clash", use_zh),
true,
None::<&str>,
)
.unwrap();
let restart_app = &MenuItem::with_id(
app_handle,
"restart_app",
t!("Restart App", "重启应用", use_zh),
true,
None::<&str>,
)
.unwrap();
let app_version = &MenuItem::with_id(
app_handle,
"app_version",
format!("Version {version}"),
true,
None::<&str>,
)
.unwrap();
let menu = tauri::menu::MenuBuilder::new(app_handle)
.item(
&MenuItem::with_id(
app_handle,
"open_window",
t!("Dashboard", "打开面板", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"rule_mode",
t!("Rule Mode", rule_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"global_mode",
t!("Global Mode", global_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"direct_mode",
t!("Direct Mode", direct_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"system_proxy",
t!("System Proxy", system_proxy_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"tun_mode",
t!("TUN Mode", tun_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"copy_env",
t!("Copy Env", "复制环境变量", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"open_dir",
t!("Open Dir", "打开目录", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&Submenu::with_id_and_items(
app_handle,
"more",
t!("More", "更多", use_zh),
true,
&[restart_clash, restart_app, app_version],
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"quit",
t!("Quit", "退出", use_zh),
true,
Some("CmdOrControl+Q"),
)
.unwrap(),
)
.build()
.unwrap();
Ok(menu)
}
fn on_menu_event(app_handle: &AppHandle, event: MenuEvent) {
match event.id.as_ref() {
mode @ ("rule_mode" | "global_mode" | "direct_mode") => {
let mode = &mode[0..mode.len() - 5];
println!("change mode to: {}", mode);
feat::change_clash_mode(mode.into());
}
"open_window" => resolve::create_window(app_handle),
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"copy_env" => feat::copy_clash_env(app_handle),
"open_dir" => crate::log_err!(cmds::open_app_dir()),
"restart_clash" => feat::restart_clash_core(),
"restart_app" => tauri::process::restart(&app_handle.env()),
"quit" => cmds::exit_app(app_handle.clone()),
_ => {}
}
}

View File

@ -10,8 +10,7 @@ mod enhance;
mod feat;
mod utils;
use crate::utils::{init, resolve, server};
use tauri::tray::TrayIconBuilder;
use crate::utils::{resolve, server};
fn main() -> std::io::Result<()> {
// 单例检测
@ -30,7 +29,8 @@ fn main() -> std::io::Result<()> {
#[cfg(target_os = "linux")]
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
crate::log_err!(init::init_config());
#[cfg(debug_assertions)]
let devtools = tauri_plugin_devtools::init();
#[allow(unused_mut)]
let mut builder = tauri::Builder::default()
@ -43,26 +43,9 @@ fn main() -> std::io::Result<()> {
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init())
.setup(|app| {
TrayIconBuilder::new().build(app)?;
#[cfg(target_os = "macos")]
{
use tauri::menu::MenuBuilder;
let _ = MenuBuilder::new(app)
.copy()
.paste()
.undo()
.redo()
.cut()
.select_all()
.quit()
.close_window()
.build();
}
tauri::async_runtime::block_on(async move {
resolve::resolve_setup(app).await;
});
Ok(())
})
.invoke_handler(tauri::generate_handler![
@ -120,6 +103,11 @@ fn main() -> std::io::Result<()> {
cmds::clash_api_get_proxy_delay
]);
#[cfg(debug_assertions)]
{
builder = builder.plugin(devtools);
}
let app = builder
.build(tauri::generate_context!())
.expect("error while running tauri application");

View File

@ -6,7 +6,6 @@ use serde_yaml::{Mapping, Value};
use std::{fs, path::PathBuf, str::FromStr};
use tauri_plugin_shell::ShellExt;
/// read data from yaml as struct T
pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
if !path.exists() {
@ -160,6 +159,17 @@ macro_rules! ret_err {
};
}
#[macro_export]
macro_rules! t {
($en:expr, $zh:expr, $use_zh:expr) => {
if $use_zh {
$zh
} else {
$en
}
};
}
#[test]
fn test_parse_value() {
let test_1 = "upload=111; download=2222; total=3333; expire=444";

View File

@ -7,7 +7,7 @@ use once_cell::sync::OnceCell;
use serde_yaml::Mapping;
use std::net::TcpListener;
use tauri::{App, AppHandle, Manager};
#[cfg(not(target_os = "linux"))]
//#[cfg(not(target_os = "linux"))]
// use window_shadows::set_shadow;
use tauri_plugin_notification::NotificationExt;
@ -33,11 +33,11 @@ pub fn find_unused_port() -> Result<u16> {
/// handle something when start app
pub async fn resolve_setup(app: &mut App) {
#[cfg(target_os = "macos")]
app.set_activation_policy(tauri::ActivationPolicy::Regular);
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
let version = app.package_info().version.to_string();
handle::Handle::global().init(app.app_handle());
VERSION.get_or_init(|| version.clone());
log_err!(init::init_config());
log_err!(init::init_resources());
log_err!(init::init_scheme());
log_err!(init::startup_script(app.app_handle()).await);

View File

@ -43,7 +43,7 @@
"scope": ["$APPDATA/**", "$RESOURCE/../**", "**"],
"enable": true
},
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: asset: 'unsafe-eval' 'unsafe-inline' 'self';; connect-src ipc: http://ipc.localhost"
"csp": null
},
"windows": []
}

View File

@ -1,30 +1,26 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"tauri": {
"systemTray": {
"iconPath": "icons/tray-icon.ico"
},
"bundle": {
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"targets": ["nsis", "updater"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.arm64/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"license": "../LICENSE",
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["nsis"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.arm64/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
},
}
},
"plugins": {
"updater": {
"active": true,
"dialog": false,
@ -34,5 +30,11 @@
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
}
},
"app": {
"trayIcon": {
"iconPath": "icons/tray-icon.ico",
"iconAsTemplate": true
}
}
}

View File

@ -1,30 +1,26 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"tauri": {
"systemTray": {
"iconPath": "icons/tray-icon.ico"
},
"bundle": {
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"targets": ["nsis", "updater"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x64/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"license": "../LICENSE",
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["nsis"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x64/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
},
}
},
"plugins": {
"updater": {
"active": true,
"dialog": false,
@ -34,5 +30,11 @@
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
}
},
"app": {
"trayIcon": {
"iconPath": "icons/tray-icon.ico",
"iconAsTemplate": true
}
}
}

View File

@ -1,30 +1,26 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"tauri": {
"systemTray": {
"iconPath": "icons/tray-icon.ico"
},
"bundle": {
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"targets": ["nsis", "updater"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x86/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"license": "../LICENSE",
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["nsis"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"webviewInstallMode": {
"type": "fixedRuntime",
"path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x86/"
},
"nsis": {
"displayLanguageSelector": true,
"installerIcon": "icons/icon.ico",
"languages": ["SimpChinese", "English"],
"installMode": "perMachine",
"template": "./template/installer.nsi"
}
},
}
},
"plugins": {
"updater": {
"active": true,
"dialog": false,
@ -34,5 +30,11 @@
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
}
},
"app": {
"trayIcon": {
"iconPath": "icons/tray-icon.ico",
"iconAsTemplate": true
}
}
}

View File

@ -137,7 +137,12 @@ const ProfilePage = () => {
mutate("getProfiles", newProfiles);
const remoteItem = newProfiles.items?.find((e) => e.type === "remote");
if (newProfiles.current && remoteItem) {
const profilesCount = newProfiles.items?.filter(
(e) => e.type === "remote" || e.type === "local"
).length as number;
if (remoteItem && (profilesCount == 1 || !newProfiles.current)) {
const current = remoteItem.uid;
await patchProfiles({ current });
mutateLogs();