mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-28 17:22:15 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
044335a324 | ||
|
|
3953e125b2 | ||
|
|
cbd5ed73a5 | ||
|
|
02e5e0e4a6 | ||
|
|
0498ba3e4f | ||
|
|
f39644ee6b | ||
|
|
488f022c05 | ||
|
|
eefd025806 |
@@ -0,0 +1,80 @@
|
||||
name: Contract Parity
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "src-tauri/**/*.rs"
|
||||
- "crates/**/*.rs"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "src-tauri/Cargo.toml"
|
||||
- "crates/**/Cargo.toml"
|
||||
- "rust-toolchain.toml"
|
||||
- "src-tauri/tauri.conf*.json"
|
||||
- "src/services/bindings.ts"
|
||||
- "scripts/gen-contract.mjs"
|
||||
- "scripts/check-contract-changes.mjs"
|
||||
- "biome.json"
|
||||
- "biome.jsonc"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "scripts/contract-inputs.json"
|
||||
- ".github/workflows/contract-parity.yml"
|
||||
- ".husky/pre-push"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
HUSKY: 0
|
||||
|
||||
jobs:
|
||||
contract-parity:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install Rust Stable
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: 'v1-rust'
|
||||
key: 'rust-shared-stable-ubuntu-22.04-x86_64-unknown-linux-gnu-contract'
|
||||
workspaces: |
|
||||
. -> target
|
||||
cache-all-crates: true
|
||||
cache-workspace-crates: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libxslt1.1 libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v6
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: '24.22.1'
|
||||
cache: 'pnpm'
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Provision sidecar placeholders for tauri-build
|
||||
run: |
|
||||
mkdir -p src-tauri/sidecar src-tauri/resources dist
|
||||
touch dist/index.html
|
||||
for bin in clash-verge-service clash-verge-service-install clash-verge-service-uninstall verge-mihomo verge-mihomo-alpha; do
|
||||
touch "src-tauri/sidecar/${bin}-x86_64-unknown-linux-gnu"
|
||||
done
|
||||
|
||||
- name: Check generated contract without changing the checkout
|
||||
run: pnpm gen:contract --check
|
||||
@@ -2,11 +2,23 @@ name: Frontend Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "src/**"
|
||||
- "**/*.js"
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
- "**/*.css"
|
||||
- "**/*.scss"
|
||||
- "**/*.json"
|
||||
- "**/*.md"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "vite.config.*"
|
||||
- ".github/workflows/frontend-check.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
env:
|
||||
HUSKY: 0
|
||||
@@ -17,46 +29,17 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Check frontend changes
|
||||
id: check_frontend
|
||||
uses: dorny/paths-filter@v4
|
||||
with:
|
||||
filters: |
|
||||
frontend:
|
||||
- 'src/**'
|
||||
- '**/*.js'
|
||||
- '**/*.ts'
|
||||
- '**/*.tsx'
|
||||
- '**/*.css'
|
||||
- '**/*.scss'
|
||||
- '**/*.json'
|
||||
- '**/*.md'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'pnpm-workspace.yaml'
|
||||
- 'knip.json'
|
||||
- 'eslint.config.ts'
|
||||
- 'tsconfig.json'
|
||||
- 'vite.config.*'
|
||||
|
||||
- name: Skip if no frontend changes
|
||||
if: steps.check_frontend.outputs.frontend != 'true'
|
||||
run: echo "No frontend changes, skipping frontend checks."
|
||||
|
||||
- name: Install pnpm
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
uses: pnpm/action-setup@v6
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v7
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
with:
|
||||
node-version: '24.22.1'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Restore pnpm cache
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
@@ -65,94 +48,21 @@ jobs:
|
||||
pnpm-shared-stable-${{ runner.os }}-
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
|
||||
- name: Run Prettier check
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: pnpm format:check
|
||||
|
||||
- name: Run ESLint
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: pnpm lint
|
||||
|
||||
- name: Run TypeScript typecheck
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: pnpm typecheck
|
||||
|
||||
- name: Run tests
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: pnpm test
|
||||
|
||||
- name: Run Knip
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: pnpm knip:check
|
||||
|
||||
- name: Architecture gates (listen/emit only in the event bus, invoke only in services)
|
||||
if: steps.check_frontend.outputs.frontend == 'true'
|
||||
run: node scripts/check-architecture.mjs listen emit invoke
|
||||
|
||||
contract-parity:
|
||||
runs-on: ubuntu-26.04
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Check contract inputs
|
||||
id: check_inputs
|
||||
uses: dorny/paths-filter@v4
|
||||
with:
|
||||
filters: scripts/contract-inputs.json
|
||||
|
||||
- name: Skip if contract inputs unchanged
|
||||
if: steps.check_inputs.outputs.contract != 'true'
|
||||
run: echo "No contract inputs changed, skipping parity check."
|
||||
|
||||
- name: Install Rust Stable
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: Rust Cache
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: 'v1-rust'
|
||||
key: 'rust-shared-stable-ubuntu-22.04-x86_64-unknown-linux-gnu-contract'
|
||||
workspaces: |
|
||||
. -> target
|
||||
cache-all-crates: true
|
||||
cache-workspace-crates: true
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libxslt1.1 libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Install pnpm
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
uses: pnpm/action-setup@v6
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- uses: actions/setup-node@v7
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
with:
|
||||
node-version: '24.22.1'
|
||||
cache: 'pnpm'
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
|
||||
- name: Provision sidecar placeholders for tauri-build
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
run: |
|
||||
mkdir -p src-tauri/sidecar src-tauri/resources dist
|
||||
touch dist/index.html
|
||||
for bin in clash-verge-service clash-verge-service-install clash-verge-service-uninstall verge-mihomo verge-mihomo-alpha; do
|
||||
touch "src-tauri/sidecar/${bin}-x86_64-unknown-linux-gnu"
|
||||
done
|
||||
|
||||
- name: Check generated contract without changing the checkout
|
||||
if: steps.check_inputs.outputs.contract == 'true'
|
||||
run: pnpm gen:contract --check
|
||||
|
||||
@@ -2,6 +2,13 @@ name: Clippy Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "src-tauri/**"
|
||||
- "crates/**"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "rust-toolchain.toml"
|
||||
- ".github/workflows/lint-clippy.yml"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
HUSKY: 0
|
||||
@@ -23,28 +30,6 @@ jobs:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Check src-tauri changes
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
id: check_changes
|
||||
uses: dorny/paths-filter@v4
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'src-tauri/**'
|
||||
|
||||
- name: Skip if src-tauri not changed
|
||||
if: github.event_name != 'workflow_dispatch' && steps.check_changes.outputs.rust != 'true'
|
||||
run: echo "No src-tauri changes, skipping clippy lint."
|
||||
|
||||
- name: Continue if src-tauri changed
|
||||
if: github.event_name != 'workflow_dispatch' && steps.check_changes.outputs.rust == 'true'
|
||||
run: echo "src-tauri changed, running clippy lint."
|
||||
|
||||
- name: Manual trigger - always run
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
echo "Manual trigger detected: skipping changes check and running clippy."
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
@@ -79,7 +64,7 @@ jobs:
|
||||
run: cargo clippy-all
|
||||
|
||||
- name: Run Windows security tests
|
||||
if: matrix.os == 'windows-latest' && (github.event_name == 'workflow_dispatch' || steps.check_changes.outputs.rust == 'true')
|
||||
if: matrix.os == 'windows-latest'
|
||||
working-directory: ./src-tauri
|
||||
run: cargo test --all-features --target ${{ matrix.target }}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ name: Check Formatting
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "src-tauri/**"
|
||||
- "**/*.rs"
|
||||
- ".github/workflows/rustfmt.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -19,25 +23,10 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Check Rust changes
|
||||
id: check_rust
|
||||
uses: dorny/paths-filter@v4
|
||||
with:
|
||||
filters: |
|
||||
rust:
|
||||
- 'src-tauri/**'
|
||||
- '**/*.rs'
|
||||
|
||||
- name: Skip if no Rust changes
|
||||
if: steps.check_rust.outputs.rust != 'true'
|
||||
run: echo "No Rust changes, skipping rustfmt."
|
||||
|
||||
- name: install Rust stable and rustfmt
|
||||
if: steps.check_rust.outputs.rust == 'true'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
|
||||
- name: run cargo fmt
|
||||
if: steps.check_rust.outputs.rust == 'true'
|
||||
run: cargo fmt --manifest-path ./src-tauri/Cargo.toml --all -- --check
|
||||
|
||||
+2
-2
@@ -63,11 +63,11 @@ tracing = "0.1.44"
|
||||
|
||||
tauri = { version = "2.12.4" }
|
||||
tauri-plugin-clipboard-manager = "2.5.0"
|
||||
parking_lot = { version = "0.12.5", features = ["hardware-lock-elision"] }
|
||||
parking_lot = { version = "0.13.0", features = ["hardware-lock-elision"] }
|
||||
anyhow = "1.0.104"
|
||||
chrono = "0.4.45"
|
||||
criterion = { version = "0.8.2", features = ["async_tokio"] }
|
||||
tokio = { version = "1.53.3", features = [
|
||||
tokio = { version = "1.54.1", features = [
|
||||
"rt-multi-thread",
|
||||
"macros",
|
||||
"time",
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
<details>
|
||||
<summary><strong> 🐞 修复问题 </strong></summary>
|
||||
|
||||
- 修复规则扩展包含空列表项时,「编辑规则」界面报错的问题
|
||||
- 修复托盘测速与代理页行为不一致的问题,移除托盘「测试延迟」入口
|
||||
- 修复通过 URL 导入订阅时,即使导入的订阅并非当前使用的订阅,也会重新加载当前配置
|
||||
- 修复 首页 网站测速失败后卡片一直显示测试中
|
||||
- 修复 代理 页展开分组后不显示最新测速结果,需切换节点才刷新
|
||||
- 修复 代理 在全局模式下无法展开节点组
|
||||
- 修复 自定义 CSS 无法修改编辑器字体和字号的问题
|
||||
|
||||
**🐧 Linux**
|
||||
|
||||
@@ -18,6 +21,8 @@
|
||||
<summary><strong> ✨ 新增功能 </strong></summary>
|
||||
|
||||
- 新增虚拟网卡设置的「DNS 模式」选项,支持配置 mihomo 系统 DNS 行为
|
||||
- 新增「IP 信息」自动刷新开关,关闭后仍可手动刷新
|
||||
- 新增 Muse AI 解锁检测,针对 Muse AI 特有的 Cloudflare 人机验证增加「Risky」状态标记
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
specta = { version = "=2.0.0-rc.25", features = ["derive", "function"] }
|
||||
specta = { version = "=2.0.0-rc.27", features = ["derive", "function"] }
|
||||
clash-verge-logging = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
||||
@@ -11,6 +11,7 @@ mod chatgpt;
|
||||
mod claude;
|
||||
mod disney_plus;
|
||||
mod gemini;
|
||||
mod muse;
|
||||
mod netflix;
|
||||
mod prime_video;
|
||||
mod spotify;
|
||||
@@ -30,6 +31,7 @@ enum UnlockCheck {
|
||||
ChatGptWeb,
|
||||
Claude,
|
||||
Gemini,
|
||||
MuseAi,
|
||||
YouTubePremium,
|
||||
BahamutAnime,
|
||||
Netflix,
|
||||
@@ -46,6 +48,7 @@ impl UnlockCheck {
|
||||
Self::ChatGptWeb,
|
||||
Self::Claude,
|
||||
Self::Gemini,
|
||||
Self::MuseAi,
|
||||
Self::YouTubePremium,
|
||||
Self::BahamutAnime,
|
||||
Self::Netflix,
|
||||
@@ -66,6 +69,7 @@ impl UnlockCheck {
|
||||
Self::ChatGptWeb => chatgpt::CHATGPT_WEB_NAME,
|
||||
Self::Claude => claude::CLAUDE_NAME,
|
||||
Self::Gemini => gemini::GEMINI_NAME,
|
||||
Self::MuseAi => muse::MUSE_AI_NAME,
|
||||
Self::YouTubePremium => youtube::YOUTUBE_PREMIUM_NAME,
|
||||
Self::BahamutAnime => bahamut::BAHAMUT_ANIME_NAME,
|
||||
Self::Netflix => netflix::NETFLIX_NAME,
|
||||
@@ -83,6 +87,7 @@ impl UnlockCheck {
|
||||
Self::ChatGptWeb => chatgpt::check_chatgpt(client).await,
|
||||
Self::Claude => claude::check_claude(client).await,
|
||||
Self::Gemini => gemini::check_gemini(client).await,
|
||||
Self::MuseAi => muse::check_muse_ai(client).await,
|
||||
Self::YouTubePremium => youtube::check_youtube_premium(client).await,
|
||||
Self::BahamutAnime => bahamut::check_bahamut_anime(client).await,
|
||||
Self::Netflix => netflix::check_netflix(client).await,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use reqwest::Client;
|
||||
|
||||
use crate::utils::{classify_restricted_status, get_trace_location};
|
||||
|
||||
use super::UnlockItem;
|
||||
|
||||
pub(crate) const MUSE_AI_NAME: &str = "Muse AI";
|
||||
|
||||
const MUSE_URL: &str = "https://muse.ai";
|
||||
const CLOUDFLARE_TRACE_URL: &str = "https://www.cloudflare.com/cdn-cgi/trace";
|
||||
|
||||
// The aymh ("Are You a Human") gateway answers plain HTTP requests with a
|
||||
// generic Meta error page that always contains the Facebook logo asset.
|
||||
const AYMH_ERROR_MARKERS: &[&str] = &["Sorry, something went wrong", "static.facebook.com/images/logos"];
|
||||
|
||||
pub(super) async fn check_muse_ai(client: &Client) -> UnlockItem {
|
||||
// muse.ai itself is served by Vercel, so resolve the exit region through
|
||||
// the generic Cloudflare trace endpoint instead of a service-specific one.
|
||||
let region = get_trace_location(client, CLOUDFLARE_TRACE_URL)
|
||||
.await
|
||||
.map(|code| code.trim().to_ascii_uppercase())
|
||||
.map(|code| UnlockItem::region_label(&code));
|
||||
|
||||
let Ok(response) = client.get(MUSE_URL).send().await else {
|
||||
return UnlockItem::checked(MUSE_AI_NAME, "Failed (Network Connection)", region);
|
||||
};
|
||||
|
||||
let status = response.status();
|
||||
let landed_on_aymh = response.url().host_str() == Some("auth.muse.ai");
|
||||
let body = response.text().await.unwrap_or_default();
|
||||
|
||||
// Every region is redirected to the aymh anti-bot gateway before the app
|
||||
// loads, and a non-browser HTTP client cannot finish the JavaScript
|
||||
// challenge. It returns the Meta error page, so reaching this point only
|
||||
// proves the exit can connect to Muse's auth infrastructure; availability
|
||||
// cannot be verified over plain HTTP and is reported as `Risky`.
|
||||
let behind_anti_bot = landed_on_aymh || AYMH_ERROR_MARKERS.iter().any(|marker| body.contains(marker));
|
||||
|
||||
let result = if behind_anti_bot {
|
||||
"Risky"
|
||||
} else if status.is_success() {
|
||||
"Yes"
|
||||
} else {
|
||||
classify_restricted_status(status).unwrap_or("Failed")
|
||||
};
|
||||
|
||||
UnlockItem::checked(MUSE_AI_NAME, result, region)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ edition = "2024"
|
||||
rust-version = "1.91"
|
||||
|
||||
[dependencies]
|
||||
specta = { version = "=2.0.0-rc.25", features = ["derive", "function"] }
|
||||
specta = { version = "=2.0.0-rc.27", features = ["derive", "function"] }
|
||||
tauri = { workspace = true }
|
||||
tauri-plugin-clipboard-manager = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
|
||||
+3
-2
@@ -14,7 +14,7 @@
|
||||
"build:fast": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build -- --profile fast-release",
|
||||
"tauri": "tauri",
|
||||
"web:dev": "vite",
|
||||
"web:build": "tsc --noEmit && vite build",
|
||||
"web:build": "tsrs -p . --noEmit && vite build",
|
||||
"web:serve": "vite preview",
|
||||
"prebuild": "node scripts/prebuild.mjs",
|
||||
"updater": "node scripts/updater.mjs",
|
||||
@@ -32,7 +32,7 @@
|
||||
"i18n:types": "node scripts/generate-i18n-keys.mjs",
|
||||
"gen:contract": "node scripts/gen-contract.mjs",
|
||||
"arch:check": "node scripts/check-architecture.mjs listen emit invoke",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"typecheck": "tsrs -p . --noEmit",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"knip:check": "knip",
|
||||
@@ -128,6 +128,7 @@
|
||||
"sass": "^1.104.1",
|
||||
"tar": "^7.5.22",
|
||||
"terser": "^5.51.2",
|
||||
"tsrs": "0.20.0-ts7.1.0-beta",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.70.0",
|
||||
"vite": "^8.3.0",
|
||||
|
||||
Generated
+88
-3
@@ -416,6 +416,9 @@ importers:
|
||||
terser:
|
||||
specifier: ^5.51.2
|
||||
version: 5.51.2
|
||||
tsrs:
|
||||
specifier: 0.20.0-ts7.1.0-beta
|
||||
version: 0.20.0-ts7.1.0-beta
|
||||
typescript:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
@@ -2218,6 +2221,52 @@ packages:
|
||||
'@tauri-apps/plugin-updater@2.14.0':
|
||||
resolution: {integrity: sha512-gdylJ9tger4hkyOn24QZd6MNOKVo2Eh53iw5th2Qj1vKTR/+u4PIwJWuiis5hohYvobn6iOvlnALfrqIPSzh7Q==}
|
||||
|
||||
'@tsrs/darwin-arm64@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-mhHj8QGUmdJDBvJEnMXx5P/jvAKXYU3hy/z3qxrWBo8XHlbLES32PgC0ZpTRbJA960ReTpVqqvCOYaC6EL32/Q==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@tsrs/darwin-x64@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-CsRUnyYRLrhmChS7ol7LgmdqMXTu+mVlDU+7JgbW8RpkJRGLZ/zgEDEOeD8qrndt8rpP9oW1T1SJ36HSzB3/sg==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@tsrs/linux-arm64-gnu@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-VNwpdI/iICwQMMlS/MoSZCvKFByEn2+g7D0HREWG+3r3GRayXgbLv8iaNSHKT3QGcu8pXr3lH9170ghJQi2zRg==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tsrs/linux-arm64-musl@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-cXnqPpmj5gzeGi4u1OV0ctd5df5t4ivwyeToCa4pBrKtjYodu0EeAo5Y76SHbJwggbiA1gzEJVj1vvuciQm5mQ==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tsrs/linux-x64-gnu@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-jlhJSrO9lxNh0TF5EU1i+Frok5sRWsBvCuQhmdqMZKIN2pSHsDZl3CSmKUsJ4tNr50np9USCPpkkxwby2Eiqhg==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tsrs/linux-x64-musl@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-pestGEPplhEPzIERc7zwuQ5zhh9ZwMSvAPNQy5TM0je/QuaizmM1zKoPYJ4NiaPzLh2M25HtP4HcpumTqmF3KQ==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tsrs/win32-x64@0.20.0-ts7.1.0-beta':
|
||||
resolution: {integrity: sha512-sstxBfhjjOSYvSHFfSmROau2oGAVNLwAnj+H0h+ywLo7N7ueFKIDk14HAkIYa/F9iVboiICCpHDY/pmBO71sSg==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@tybys/wasm-util@0.10.4':
|
||||
resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==}
|
||||
|
||||
@@ -4770,6 +4819,11 @@ packages:
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tsrs@0.20.0-ts7.1.0-beta:
|
||||
resolution: {integrity: sha512-8NifAn2tcna3t/nluu1yFvp0fYE28vElDpnD4jiWik69+MDjiHgxdjH8sUYUEFmf/2hl6QIE5ExVGpJzQbBDPw==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
hasBin: true
|
||||
|
||||
tunnel@0.0.6:
|
||||
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
|
||||
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
|
||||
@@ -6882,6 +6936,27 @@ snapshots:
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.12.4
|
||||
|
||||
'@tsrs/darwin-arm64@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/darwin-x64@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/linux-arm64-gnu@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/linux-arm64-musl@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/linux-x64-gnu@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/linux-x64-musl@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tsrs/win32-x64@0.20.0-ts7.1.0-beta':
|
||||
optional: true
|
||||
|
||||
'@tybys/wasm-util@0.10.4':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -7222,7 +7297,7 @@ snapshots:
|
||||
|
||||
'@wdio/globals@9.31.3(expect-webdriverio@6.1.0)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0))':
|
||||
dependencies:
|
||||
expect-webdriverio: 6.1.0(@wdio/globals@9.31.3)(@wdio/logger@10.1.0)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0))
|
||||
expect-webdriverio: 6.1.0(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0))
|
||||
webdriverio: 10.1.0(supports-color@7.2.0)(yauzl@2.10.0)
|
||||
|
||||
'@wdio/logger@10.1.0':
|
||||
@@ -8206,11 +8281,11 @@ snapshots:
|
||||
|
||||
expect-type@1.4.0: {}
|
||||
|
||||
expect-webdriverio@6.1.0(@wdio/globals@9.31.3)(@wdio/logger@10.1.0)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0)):
|
||||
expect-webdriverio@6.1.0(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0)):
|
||||
dependencies:
|
||||
'@vitest/snapshot': 4.1.11
|
||||
'@wdio/globals': 9.31.3(expect-webdriverio@6.1.0)(webdriverio@10.1.0(supports-color@7.2.0)(yauzl@2.10.0))
|
||||
'@wdio/logger': 10.1.0
|
||||
'@wdio/logger': 9.29.1
|
||||
deep-eql: 5.0.2
|
||||
expect: 30.5.2
|
||||
jest-matcher-utils: 30.5.2
|
||||
@@ -9865,6 +9940,16 @@ snapshots:
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tsrs@0.20.0-ts7.1.0-beta:
|
||||
optionalDependencies:
|
||||
'@tsrs/darwin-arm64': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/darwin-x64': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/linux-arm64-gnu': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/linux-arm64-musl': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/linux-x64-gnu': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/linux-x64-musl': 0.20.0-ts7.1.0-beta
|
||||
'@tsrs/win32-x64': 0.20.0-ts7.1.0-beta
|
||||
|
||||
tunnel@0.0.6: {}
|
||||
|
||||
type-check@0.4.0:
|
||||
|
||||
@@ -10,3 +10,11 @@ allowBuilds:
|
||||
unrs-resolver: true
|
||||
minimumReleaseAgeExclude:
|
||||
- dayjs@1.11.21
|
||||
- "@tsrs/darwin-arm64@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/darwin-x64@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/linux-arm64-gnu@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/linux-arm64-musl@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/linux-x64-gnu@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/linux-x64-musl@0.20.0-ts7.1.0-beta"
|
||||
- "@tsrs/win32-x64@0.20.0-ts7.1.0-beta"
|
||||
- tsrs@0.20.0-ts7.1.0-beta
|
||||
|
||||
@@ -79,6 +79,13 @@
|
||||
"matchPackageNames": ["typescript"],
|
||||
"allowedVersions": "<7.0.0 || >=7.1.0"
|
||||
},
|
||||
{
|
||||
"description": "Review tsrs bumps alone; the version encodes the pinned TypeScript release",
|
||||
"matchPackageNames": ["tsrs", "/^@tsrs//"],
|
||||
"groupName": "tsrs",
|
||||
"rangeStrategy": "pin",
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Prevent project from supply chain attack",
|
||||
"matchDatasources": ["npm"],
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"pnpm-lock.yaml",
|
||||
"pnpm-workspace.yaml",
|
||||
"scripts/contract-inputs.json",
|
||||
".github/workflows/frontend-check.yml",
|
||||
".github/workflows/contract-parity.yml",
|
||||
".husky/pre-push"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ smartstring = { workspace = true, features = ["serde"] }
|
||||
bitflags = { workspace = true }
|
||||
socket2 = { workspace = true }
|
||||
warp = { version = "0.4.3", features = ["server"] }
|
||||
open = "5.4.4"
|
||||
rfd = { version = "0.16.0", default-features = false, features = ["common-controls-v6"] }
|
||||
open = "5.4.5"
|
||||
rfd = { version = "0.17.2", default-features = false, features = ["common-controls-v6"] }
|
||||
dirs = "7.0.0"
|
||||
dunce = "1.0.5"
|
||||
nanoid = "0.5"
|
||||
@@ -79,7 +79,7 @@ tauri-plugin-fs = "2.7.1"
|
||||
tauri-plugin-process = "2.4.0"
|
||||
tauri-plugin-deep-link = "2.6.2"
|
||||
tauri-plugin-window-state = "2.5.0"
|
||||
zip = "9.0.4"
|
||||
zip = "9.1.3"
|
||||
flate2 = "1.1.10"
|
||||
reqwest_dav = "0.3.3"
|
||||
aes-gcm = { version = "0.11.1" }
|
||||
@@ -101,16 +101,16 @@ async-trait = "0.1.92"
|
||||
clash_verge_service_ipc = { git = "https://github.com/clash-verge-rev/clash-verge-service-ipc.git", tag = "v2.7.6", version = "2.7.6", features = [
|
||||
"client",
|
||||
] }
|
||||
arc-swap = "1.9.2"
|
||||
arc-swap = "1.9.3"
|
||||
tokio-rustls = "0.26.6"
|
||||
rustls = { version = "0.23.46", features = ["ring"] }
|
||||
webpki-roots = "1.0.9"
|
||||
webpki-roots = "1.0.11"
|
||||
dark-light = "3.0.0"
|
||||
bytes = "1.12.1"
|
||||
tokio-util = { version = "0.7.20", features = ["time"] }
|
||||
specta = { version = "=2.0.0-rc.25", features = ["derive", "function", "serde_json"] }
|
||||
specta = { version = "=2.0.0-rc.27", features = ["derive", "function", "serde_json"] }
|
||||
tauri-specta = { version = "=2.0.0-rc.25", features = ["derive", "typescript"] }
|
||||
specta-typescript = "=0.0.12"
|
||||
specta-typescript = "=0.0.14"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2.191"
|
||||
|
||||
@@ -4,10 +4,19 @@ import {
|
||||
VisibilityOffOutlined,
|
||||
VisibilityOutlined,
|
||||
} from '@mui/icons-material'
|
||||
import { Box, Button, IconButton, Skeleton, Typography } from '@mui/material'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Skeleton,
|
||||
Switch,
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { useEffect } from 'foxact/use-abortable-effect'
|
||||
import { useIntersection } from 'foxact/use-intersection'
|
||||
import { useLocalStorage } from 'foxact/use-local-storage'
|
||||
import type { XOR } from 'foxts/ts-xor'
|
||||
import {
|
||||
forwardRef,
|
||||
@@ -99,9 +108,13 @@ const IPInfoCardContainer = forwardRef<HTMLElement, React.PropsWithChildren>(
|
||||
export const IpInfoCard = () => {
|
||||
const { t } = useTranslation()
|
||||
const [showIp, setShowIp] = useState(false)
|
||||
const [autoRefresh, setAutoRefresh] = useLocalStorage(
|
||||
'ip-info-auto-refresh',
|
||||
true,
|
||||
)
|
||||
const appWindow = useMemo(() => getCurrentWebviewWindow(), [])
|
||||
|
||||
// Once intersected, refreshes stay enabled until unmount.
|
||||
// Once intersected, the card stays eligible for refresh until unmount.
|
||||
const [containerRef, hasIntersected, _resetIntersected] = useIntersection({
|
||||
rootMargin: '0px',
|
||||
})
|
||||
@@ -151,6 +164,8 @@ export const IpInfoCard = () => {
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoRefresh) return
|
||||
|
||||
let timer: number | null = null
|
||||
|
||||
// Prefer DOM intersection state; Tauri visibility is unreliable on some platforms.
|
||||
@@ -190,7 +205,7 @@ export const IpInfoCard = () => {
|
||||
if (timer != null) clearInterval(timer)
|
||||
document.removeEventListener('visibilitychange', onVisibilityChange)
|
||||
}
|
||||
}, [hasIntersected])
|
||||
}, [autoRefresh, hasIntersected])
|
||||
|
||||
const toggleShowIp = useCallback(() => {
|
||||
setShowIp((prev) => !prev)
|
||||
@@ -364,12 +379,25 @@ export const IpInfoCard = () => {
|
||||
fontSize: '0.7rem',
|
||||
}}
|
||||
>
|
||||
<Typography variant="caption">
|
||||
{t('home.components.ipInfo.labels.autoRefresh')}
|
||||
{countdown.type === 'countdown'
|
||||
? `: ${countdown.remainingSeconds}s`
|
||||
: '...'}
|
||||
</Typography>
|
||||
<FormControlLabel
|
||||
sx={{ m: 0 }}
|
||||
control={
|
||||
<Switch
|
||||
size="small"
|
||||
checked={autoRefresh}
|
||||
onChange={(_, checked) => setAutoRefresh(checked)}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography variant="caption">
|
||||
{t('home.components.ipInfo.labels.autoRefresh')}
|
||||
{autoRefresh &&
|
||||
(countdown.type === 'countdown'
|
||||
? `: ${countdown.remainingSeconds}s`
|
||||
: '...')}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
|
||||
@@ -397,9 +397,9 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
return
|
||||
}
|
||||
|
||||
setPrependSeq(obj?.prepend || [])
|
||||
setAppendSeq(obj?.append || [])
|
||||
setDeleteSeq(obj?.delete || [])
|
||||
setPrependSeq((obj?.prepend || []).filter((rule) => rule !== null))
|
||||
setAppendSeq((obj?.append || []).filter((rule) => rule !== null))
|
||||
setDeleteSeq((obj?.delete || []).filter((rule) => rule !== null))
|
||||
hasLoadedSeqConfigRef.current = true
|
||||
}, [property])
|
||||
|
||||
@@ -417,9 +417,9 @@ export const RulesEditorViewer = (props: Props) => {
|
||||
|
||||
hasLoadedSeqConfigRef.current = true
|
||||
startTransition(() => {
|
||||
setPrependSeq(obj?.prepend ?? [])
|
||||
setAppendSeq(obj?.append ?? [])
|
||||
setDeleteSeq(obj?.delete ?? [])
|
||||
setPrependSeq((obj?.prepend ?? []).filter((rule) => rule !== null))
|
||||
setAppendSeq((obj?.append ?? []).filter((rule) => rule !== null))
|
||||
setDeleteSeq((obj?.delete ?? []).filter((rule) => rule !== null))
|
||||
})
|
||||
setVisualization(true)
|
||||
}
|
||||
|
||||
@@ -608,7 +608,7 @@ function NormalProxyGroups(props: { mode: string }) {
|
||||
/>
|
||||
</DragDropProvider>
|
||||
|
||||
{mode === 'rule' && (
|
||||
{(mode === 'rule' || mode === 'global') && (
|
||||
<ProxyGroupNavigator
|
||||
proxyGroupNames={proxyGroupNames}
|
||||
onGroupLocation={handleGroupLocationByName}
|
||||
|
||||
@@ -211,7 +211,7 @@ export const useRenderList = (
|
||||
if (!proxyView) return []
|
||||
if (isChainMode)
|
||||
return selectedGroup ? [selectedGroup] : [CHAIN_DELAY_GROUP]
|
||||
return mode === 'rule' || mode === 'script'
|
||||
return mode === 'rule' || mode === 'global'
|
||||
? proxyView.groups.map(({ name }) => name)
|
||||
: proxyView.global
|
||||
? [proxyView.global.name]
|
||||
@@ -257,7 +257,7 @@ export const useRenderList = (
|
||||
}))
|
||||
}
|
||||
|
||||
const useRule = mode === 'rule' || mode === 'script'
|
||||
const useRule = mode === 'rule' || mode === 'global'
|
||||
const renderGroups = useRule
|
||||
? proxyView.groups
|
||||
: proxyView.global === null
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"failed": "Failed",
|
||||
"risky": "غير مؤكد",
|
||||
"completed": "Completed",
|
||||
"disallowedIsp": "Disallowed ISP",
|
||||
"originalsOnly": "Originals Only",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Unterstützt",
|
||||
"no": "Nicht unterstützt",
|
||||
"failed": "Test fehlgeschlagen",
|
||||
"risky": "Ungewiss",
|
||||
"completed": "Prüfung abgeschlossen",
|
||||
"disallowedIsp": "Nicht zugelassener Internetdienstanbieter",
|
||||
"originalsOnly": "Nur Original",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"failed": "Failed",
|
||||
"risky": "Risky",
|
||||
"completed": "Completed",
|
||||
"disallowedIsp": "Disallowed ISP",
|
||||
"originalsOnly": "Originals Only",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Soportado",
|
||||
"no": "No soportado",
|
||||
"failed": "Prueba fallida",
|
||||
"risky": "Dudoso",
|
||||
"completed": "Detección completada",
|
||||
"disallowedIsp": "Proveedor de servicios de Internet no permitido",
|
||||
"originalsOnly": "Solo originales",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"failed": "Failed",
|
||||
"risky": "نامشخص",
|
||||
"completed": "Completed",
|
||||
"disallowedIsp": "Disallowed ISP",
|
||||
"originalsOnly": "Originals Only",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"failed": "Failed",
|
||||
"risky": "Tidak pasti",
|
||||
"completed": "Completed",
|
||||
"disallowedIsp": "Disallowed ISP",
|
||||
"originalsOnly": "Originals Only",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "サポートする",
|
||||
"no": "サポートしない",
|
||||
"failed": "テストに失敗しました。",
|
||||
"risky": "要確認",
|
||||
"completed": "検査完了",
|
||||
"disallowedIsp": "許可されていないインターネットサービスプロバイダー",
|
||||
"originalsOnly": "オリジナルのみ",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "예",
|
||||
"no": "아니오",
|
||||
"failed": "실패",
|
||||
"risky": "확인 필요",
|
||||
"completed": "완료",
|
||||
"disallowedIsp": "허용되지 않는 ISP",
|
||||
"originalsOnly": "오리지널만",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Sim",
|
||||
"no": "Não",
|
||||
"failed": "Falhou",
|
||||
"risky": "Incerto",
|
||||
"completed": "Concluído",
|
||||
"disallowedIsp": "ISP não permitido",
|
||||
"originalsOnly": "Somente originais",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Да",
|
||||
"no": "Нет",
|
||||
"failed": "Ошибка",
|
||||
"risky": "Неясно",
|
||||
"completed": "Завершено",
|
||||
"disallowedIsp": "Провайдер заблокирован",
|
||||
"originalsOnly": "Только Originals",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Evet",
|
||||
"no": "Hayır",
|
||||
"failed": "Başarısız",
|
||||
"risky": "Belirsiz",
|
||||
"completed": "Tamamlandı",
|
||||
"disallowedIsp": "İzin Verilmeyen ISP",
|
||||
"originalsOnly": "Yalnızca Orijinaller",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"failed": "Failed",
|
||||
"risky": "Билгесез",
|
||||
"completed": "Completed",
|
||||
"disallowedIsp": "Disallowed ISP",
|
||||
"originalsOnly": "Originals Only",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "支持",
|
||||
"no": "不支持",
|
||||
"failed": "测试失败",
|
||||
"risky": "存疑",
|
||||
"completed": "检测完成",
|
||||
"disallowedIsp": "不允许的 ISP",
|
||||
"originalsOnly": "仅限原创",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"yes": "支援",
|
||||
"no": "不支援",
|
||||
"failed": "測試失敗",
|
||||
"risky": "存疑",
|
||||
"completed": "檢測完成",
|
||||
"disallowedIsp": "不允許的網際網路服務供應商",
|
||||
"originalsOnly": "僅限原創",
|
||||
|
||||
@@ -55,7 +55,7 @@ const wrapCssInjectionWithScope = (css?: string) => {
|
||||
return null
|
||||
}
|
||||
const scopeRoot = CSS_INJECTION_SCOPE_ROOT
|
||||
const scopeLimit = CSS_INJECTION_SCOPE_LIMIT
|
||||
const scopeLimit = `${CSS_INJECTION_SCOPE_LIMIT} > *`
|
||||
const scopedBlock = `@scope (${scopeRoot}) to (${scopeLimit}) {
|
||||
${css}
|
||||
}`
|
||||
|
||||
@@ -40,6 +40,7 @@ const STATUS_LABEL_KEYS: Record<string, string> = {
|
||||
Yes: 'tests.statuses.test.yes',
|
||||
No: 'tests.statuses.test.no',
|
||||
Failed: 'tests.statuses.test.failed',
|
||||
Risky: 'tests.statuses.test.risky',
|
||||
Completed: 'tests.statuses.test.completed',
|
||||
'Disallowed ISP': 'tests.statuses.test.disallowedIsp',
|
||||
'Originals Only': 'tests.statuses.test.originalsOnly',
|
||||
@@ -196,7 +197,7 @@ const UnlockPage = () => {
|
||||
if (status === 'Pending') return 'default'
|
||||
if (status === 'Yes') return 'success'
|
||||
if (status === 'No') return 'error'
|
||||
if (status === 'Soon') return 'warning'
|
||||
if (status === 'Soon' || status === 'Risky') return 'warning'
|
||||
if (status.includes('Failed')) return 'error'
|
||||
if (status === 'Completed') return 'info'
|
||||
if (
|
||||
@@ -222,7 +223,8 @@ const UnlockPage = () => {
|
||||
const getStatusBorderColor = (status: string) => {
|
||||
if (status === 'Yes') return theme.palette.success.main
|
||||
if (status === 'No') return theme.palette.error.main
|
||||
if (status === 'Soon') return theme.palette.warning.main
|
||||
if (status === 'Soon' || status === 'Risky')
|
||||
return theme.palette.warning.main
|
||||
if (status.includes('Failed')) return theme.palette.error.main
|
||||
if (status === 'Completed') return theme.palette.info.main
|
||||
return theme.palette.divider
|
||||
|
||||
Reference in New Issue
Block a user