mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-28 05:30:29 +08:00
Compare commits
3 Commits
a81f970baa
...
f7b9eb2113
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7b9eb2113 | ||
|
|
d8aeb63584 | ||
|
|
f153217372 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ out
|
|||||||
*.log*
|
*.log*
|
||||||
.idea
|
.idea
|
||||||
*.ttf
|
*.ttf
|
||||||
|
party.md
|
||||||
@ -54,8 +54,9 @@ pkg:
|
|||||||
file: build/background.png
|
file: build/background.png
|
||||||
linux:
|
linux:
|
||||||
desktop:
|
desktop:
|
||||||
Name: Mihomo Party
|
entry:
|
||||||
MimeType: 'x-scheme-handler/clash;x-scheme-handler/mihomo'
|
Name: Mihomo Party
|
||||||
|
MimeType: 'x-scheme-handler/clash;x-scheme-handler/mihomo'
|
||||||
target:
|
target:
|
||||||
- deb
|
- deb
|
||||||
- rpm
|
- rpm
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
|
import tailwindcss from '@tailwindcss/vite'
|
||||||
// https://github.com/vdesjs/vite-plugin-monaco-editor/issues/21#issuecomment-1827562674
|
// https://github.com/vdesjs/vite-plugin-monaco-editor/issues/21#issuecomment-1827562674
|
||||||
import monacoEditorPluginModule from 'vite-plugin-monaco-editor'
|
import monacoEditorPluginModule from 'vite-plugin-monaco-editor'
|
||||||
const isObjectWithDefaultFunction = (
|
const isObjectWithDefaultFunction = (
|
||||||
@ -37,6 +38,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
|
tailwindcss(),
|
||||||
monacoEditorPlugin({
|
monacoEditorPlugin({
|
||||||
languageWorkers: ['editorWorkerService', 'typescript', 'css'],
|
languageWorkers: ['editorWorkerService', 'typescript', 'css'],
|
||||||
customDistPath: (_, out) => `${out}/monacoeditorwork`,
|
customDistPath: (_, out) => `${out}/monacoeditorwork`,
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
|
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
|
||||||
"@electron-toolkit/eslint-config-ts": "^3.1.0",
|
"@electron-toolkit/eslint-config-ts": "^3.1.0",
|
||||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||||
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
"@types/adm-zip": "^0.5.7",
|
"@types/adm-zip": "^0.5.7",
|
||||||
"@types/express": "^5.0.3",
|
"@types/express": "^5.0.3",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.1.0",
|
||||||
@ -59,7 +60,6 @@
|
|||||||
"@types/react-dom": "^19.1.7",
|
"@types/react-dom": "^19.1.7",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"@vitejs/plugin-react": "^4.7.0",
|
"@vitejs/plugin-react": "^4.7.0",
|
||||||
"autoprefixer": "^10.4.21",
|
|
||||||
"cron-validator": "^1.4.0",
|
"cron-validator": "^1.4.0",
|
||||||
"driver.js": "^1.3.6",
|
"driver.js": "^1.3.6",
|
||||||
"electron": "^37.2.5",
|
"electron": "^37.2.5",
|
||||||
|
|||||||
219
pnpm-lock.yaml
generated
219
pnpm-lock.yaml
generated
@ -87,6 +87,9 @@ importers:
|
|||||||
'@electron-toolkit/tsconfig':
|
'@electron-toolkit/tsconfig':
|
||||||
specifier: ^1.0.1
|
specifier: ^1.0.1
|
||||||
version: 1.0.1(@types/node@24.1.0)
|
version: 1.0.1(@types/node@24.1.0)
|
||||||
|
'@tailwindcss/vite':
|
||||||
|
specifier: ^4.1.11
|
||||||
|
version: 4.1.11(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.0))
|
||||||
'@types/adm-zip':
|
'@types/adm-zip':
|
||||||
specifier: ^0.5.7
|
specifier: ^0.5.7
|
||||||
version: 0.5.7
|
version: 0.5.7
|
||||||
@ -111,9 +114,6 @@ importers:
|
|||||||
'@vitejs/plugin-react':
|
'@vitejs/plugin-react':
|
||||||
specifier: ^4.7.0
|
specifier: ^4.7.0
|
||||||
version: 4.7.0(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.0))
|
version: 4.7.0(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.0))
|
||||||
autoprefixer:
|
|
||||||
specifier: ^10.4.21
|
|
||||||
version: 10.4.21(postcss@8.5.6)
|
|
||||||
cron-validator:
|
cron-validator:
|
||||||
specifier: ^1.4.0
|
specifier: ^1.4.0
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
@ -1906,6 +1906,96 @@ packages:
|
|||||||
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
|
resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
'@tailwindcss/node@4.1.11':
|
||||||
|
resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==}
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-android-arm64@4.1.11':
|
||||||
|
resolution: {integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-arm64@4.1.11':
|
||||||
|
resolution: {integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-x64@4.1.11':
|
||||||
|
resolution: {integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-freebsd-x64@4.1.11':
|
||||||
|
resolution: {integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11':
|
||||||
|
resolution: {integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu@4.1.11':
|
||||||
|
resolution: {integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.11':
|
||||||
|
resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.11':
|
||||||
|
resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl@4.1.11':
|
||||||
|
resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi@4.1.11':
|
||||||
|
resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
cpu: [wasm32]
|
||||||
|
bundledDependencies:
|
||||||
|
- '@napi-rs/wasm-runtime'
|
||||||
|
- '@emnapi/core'
|
||||||
|
- '@emnapi/runtime'
|
||||||
|
- '@tybys/wasm-util'
|
||||||
|
- '@emnapi/wasi-threads'
|
||||||
|
- tslib
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc@4.1.11':
|
||||||
|
resolution: {integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc@4.1.11':
|
||||||
|
resolution: {integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@tailwindcss/oxide@4.1.11':
|
||||||
|
resolution: {integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
|
'@tailwindcss/vite@4.1.11':
|
||||||
|
resolution: {integrity: sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==}
|
||||||
|
peerDependencies:
|
||||||
|
vite: ^5.2.0 || ^6 || ^7
|
||||||
|
|
||||||
'@tanstack/react-virtual@3.11.3':
|
'@tanstack/react-virtual@3.11.3':
|
||||||
resolution: {integrity: sha512-vCU+OTylXN3hdC8RKg68tPlBPjjxtzon7Ys46MgrSLE+JhSjSTPvoQifV6DQJeJmA8Q3KT6CphJbejupx85vFw==}
|
resolution: {integrity: sha512-vCU+OTylXN3hdC8RKg68tPlBPjjxtzon7Ys46MgrSLE+JhSjSTPvoQifV6DQJeJmA8Q3KT6CphJbejupx85vFw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2268,13 +2358,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
|
|
||||||
autoprefixer@10.4.21:
|
|
||||||
resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
|
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
postcss: ^8.1.0
|
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -2760,6 +2843,10 @@ packages:
|
|||||||
end-of-stream@1.4.5:
|
end-of-stream@1.4.5:
|
||||||
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
||||||
|
|
||||||
|
enhanced-resolve@5.18.2:
|
||||||
|
resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
entities@6.0.1:
|
entities@6.0.1:
|
||||||
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
|
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
@ -3013,9 +3100,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
fraction.js@4.3.7:
|
|
||||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
|
||||||
|
|
||||||
framer-motion@12.23.12:
|
framer-motion@12.23.12:
|
||||||
resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==}
|
resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3995,10 +4079,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
normalize-range@0.1.2:
|
|
||||||
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
normalize-url@6.1.0:
|
normalize-url@6.1.0:
|
||||||
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
|
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -4144,9 +4224,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0:
|
|
||||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
@ -4686,6 +4763,10 @@ packages:
|
|||||||
tailwindcss@4.1.11:
|
tailwindcss@4.1.11:
|
||||||
resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==}
|
resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==}
|
||||||
|
|
||||||
|
tapable@2.2.2:
|
||||||
|
resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
tar-stream@2.2.0:
|
tar-stream@2.2.0:
|
||||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -7557,6 +7638,77 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
defer-to-connect: 2.0.1
|
defer-to-connect: 2.0.1
|
||||||
|
|
||||||
|
'@tailwindcss/node@4.1.11':
|
||||||
|
dependencies:
|
||||||
|
'@ampproject/remapping': 2.3.0
|
||||||
|
enhanced-resolve: 5.18.2
|
||||||
|
jiti: 2.5.1
|
||||||
|
lightningcss: 1.30.1
|
||||||
|
magic-string: 0.30.17
|
||||||
|
source-map-js: 1.2.1
|
||||||
|
tailwindcss: 4.1.11
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-android-arm64@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-arm64@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-darwin-x64@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-freebsd-x64@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc@4.1.11':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@tailwindcss/oxide@4.1.11':
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.0.4
|
||||||
|
tar: 7.4.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@tailwindcss/oxide-android-arm64': 4.1.11
|
||||||
|
'@tailwindcss/oxide-darwin-arm64': 4.1.11
|
||||||
|
'@tailwindcss/oxide-darwin-x64': 4.1.11
|
||||||
|
'@tailwindcss/oxide-freebsd-x64': 4.1.11
|
||||||
|
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.11
|
||||||
|
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.11
|
||||||
|
'@tailwindcss/oxide-linux-arm64-musl': 4.1.11
|
||||||
|
'@tailwindcss/oxide-linux-x64-gnu': 4.1.11
|
||||||
|
'@tailwindcss/oxide-linux-x64-musl': 4.1.11
|
||||||
|
'@tailwindcss/oxide-wasm32-wasi': 4.1.11
|
||||||
|
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.11
|
||||||
|
'@tailwindcss/oxide-win32-x64-msvc': 4.1.11
|
||||||
|
|
||||||
|
'@tailwindcss/vite@4.1.11(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.0))':
|
||||||
|
dependencies:
|
||||||
|
'@tailwindcss/node': 4.1.11
|
||||||
|
'@tailwindcss/oxide': 4.1.11
|
||||||
|
tailwindcss: 4.1.11
|
||||||
|
vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.0)
|
||||||
|
|
||||||
'@tanstack/react-virtual@3.11.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
|
'@tanstack/react-virtual@3.11.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tanstack/virtual-core': 3.11.3
|
'@tanstack/virtual-core': 3.11.3
|
||||||
@ -8080,16 +8232,6 @@ snapshots:
|
|||||||
|
|
||||||
at-least-node@1.0.0: {}
|
at-least-node@1.0.0: {}
|
||||||
|
|
||||||
autoprefixer@10.4.21(postcss@8.5.6):
|
|
||||||
dependencies:
|
|
||||||
browserslist: 4.25.1
|
|
||||||
caniuse-lite: 1.0.30001731
|
|
||||||
fraction.js: 4.3.7
|
|
||||||
normalize-range: 0.1.2
|
|
||||||
picocolors: 1.1.1
|
|
||||||
postcss: 8.5.6
|
|
||||||
postcss-value-parser: 4.2.0
|
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
possible-typed-array-names: 1.1.0
|
possible-typed-array-names: 1.1.0
|
||||||
@ -8671,6 +8813,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
|
|
||||||
|
enhanced-resolve@5.18.2:
|
||||||
|
dependencies:
|
||||||
|
graceful-fs: 4.2.11
|
||||||
|
tapable: 2.2.2
|
||||||
|
|
||||||
entities@6.0.1: {}
|
entities@6.0.1: {}
|
||||||
|
|
||||||
env-paths@2.2.1: {}
|
env-paths@2.2.1: {}
|
||||||
@ -9072,8 +9219,6 @@ snapshots:
|
|||||||
|
|
||||||
forwarded@0.2.0: {}
|
forwarded@0.2.0: {}
|
||||||
|
|
||||||
fraction.js@4.3.7: {}
|
|
||||||
|
|
||||||
framer-motion@12.23.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
|
framer-motion@12.23.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
motion-dom: 12.23.12
|
motion-dom: 12.23.12
|
||||||
@ -9599,8 +9744,7 @@ snapshots:
|
|||||||
filelist: 1.0.4
|
filelist: 1.0.4
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
|
|
||||||
jiti@2.5.1:
|
jiti@2.5.1: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
@ -9703,7 +9847,6 @@ snapshots:
|
|||||||
lightningcss-linux-x64-musl: 1.30.1
|
lightningcss-linux-x64-musl: 1.30.1
|
||||||
lightningcss-win32-arm64-msvc: 1.30.1
|
lightningcss-win32-arm64-msvc: 1.30.1
|
||||||
lightningcss-win32-x64-msvc: 1.30.1
|
lightningcss-win32-x64-msvc: 1.30.1
|
||||||
optional: true
|
|
||||||
|
|
||||||
locate-path@6.0.0:
|
locate-path@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10211,8 +10354,6 @@ snapshots:
|
|||||||
|
|
||||||
normalize-path@3.0.0: {}
|
normalize-path@3.0.0: {}
|
||||||
|
|
||||||
normalize-range@0.1.2: {}
|
|
||||||
|
|
||||||
normalize-url@6.1.0: {}
|
normalize-url@6.1.0: {}
|
||||||
|
|
||||||
npmlog@6.0.2:
|
npmlog@6.0.2:
|
||||||
@ -10366,8 +10507,6 @@ snapshots:
|
|||||||
|
|
||||||
possible-typed-array-names@1.1.0: {}
|
possible-typed-array-names@1.1.0: {}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0: {}
|
|
||||||
|
|
||||||
postcss@8.5.6:
|
postcss@8.5.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 3.3.11
|
nanoid: 3.3.11
|
||||||
@ -11007,6 +11146,8 @@ snapshots:
|
|||||||
|
|
||||||
tailwindcss@4.1.11: {}
|
tailwindcss@4.1.11: {}
|
||||||
|
|
||||||
|
tapable@2.2.2: {}
|
||||||
|
|
||||||
tar-stream@2.2.0:
|
tar-stream@2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
bl: 4.1.0
|
bl: 4.1.0
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -20,15 +20,22 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
|
|||||||
|
|
||||||
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
|
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
|
||||||
const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig()
|
const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig()
|
||||||
if (!controlDns) {
|
|
||||||
|
// DNS 配置覆写逻辑
|
||||||
|
if (controlDns) {
|
||||||
|
if (!controledMihomoConfig.dns || controledMihomoConfig.dns?.ipv6 === undefined) {
|
||||||
|
controledMihomoConfig.dns = { ...defaultControledMihomoConfig.dns }
|
||||||
|
}
|
||||||
|
const originalEnable = controledMihomoConfig.dns?.enable
|
||||||
|
controledMihomoConfig.dns = deepMerge(controledMihomoConfig.dns || {}, defaultControledMihomoConfig.dns || {})
|
||||||
|
if (originalEnable !== undefined) {
|
||||||
|
controledMihomoConfig.dns.enable = originalEnable
|
||||||
|
}
|
||||||
|
} else {
|
||||||
delete controledMihomoConfig.dns
|
delete controledMihomoConfig.dns
|
||||||
delete controledMihomoConfig.hosts
|
delete controledMihomoConfig.hosts
|
||||||
} else {
|
|
||||||
// 从不接管状态恢复
|
|
||||||
if (controledMihomoConfig.dns?.ipv6 === undefined) {
|
|
||||||
controledMihomoConfig.dns = defaultControledMihomoConfig.dns
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controlSniff) {
|
if (!controlSniff) {
|
||||||
delete controledMihomoConfig.sniffer
|
delete controledMihomoConfig.sniffer
|
||||||
} else {
|
} else {
|
||||||
@ -37,6 +44,7 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
|
|||||||
controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer
|
controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patch.hosts) {
|
if (patch.hosts) {
|
||||||
controledMihomoConfig.hosts = patch.hosts
|
controledMihomoConfig.hosts = patch.hosts
|
||||||
}
|
}
|
||||||
@ -44,7 +52,9 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
|
|||||||
controledMihomoConfig.dns = controledMihomoConfig.dns || {}
|
controledMihomoConfig.dns = controledMihomoConfig.dns || {}
|
||||||
controledMihomoConfig.dns['nameserver-policy'] = patch.dns['nameserver-policy']
|
controledMihomoConfig.dns['nameserver-policy'] = patch.dns['nameserver-policy']
|
||||||
}
|
}
|
||||||
|
|
||||||
controledMihomoConfig = deepMerge(controledMihomoConfig, patch)
|
controledMihomoConfig = deepMerge(controledMihomoConfig, patch)
|
||||||
|
|
||||||
if (!useNameserverPolicy) {
|
if (!useNameserverPolicy) {
|
||||||
delete controledMihomoConfig?.dns?.['nameserver-policy']
|
delete controledMihomoConfig?.dns?.['nameserver-policy']
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,15 +37,21 @@ export async function getProfileItem(id: string | undefined): Promise<IProfileIt
|
|||||||
export async function changeCurrentProfile(id: string): Promise<void> {
|
export async function changeCurrentProfile(id: string): Promise<void> {
|
||||||
const config = await getProfileConfig()
|
const config = await getProfileConfig()
|
||||||
const current = config.current
|
const current = config.current
|
||||||
|
|
||||||
|
if (current === id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
config.current = id
|
config.current = id
|
||||||
await setProfileConfig(config)
|
await setProfileConfig(config)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await restartCore()
|
await restartCore()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// 如果重启失败,恢复原来的配置
|
||||||
config.current = current
|
config.current = current
|
||||||
throw e
|
|
||||||
} finally {
|
|
||||||
await setProfileConfig(config)
|
await setProfileConfig(config)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -212,7 +212,12 @@ export async function restartCore(): Promise<void> {
|
|||||||
try {
|
try {
|
||||||
await startCore()
|
await startCore()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dialog.showErrorBox(i18next.t('mihomo.error.coreStartFailed'), `${e}`)
|
// 记录错误到日志而不是显示阻塞对话框
|
||||||
|
await writeFile(logPath(), `[Manager]: restart core failed, ${e}\n`, {
|
||||||
|
flag: 'a'
|
||||||
|
})
|
||||||
|
// 重新抛出错误,让调用者处理
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,8 +79,10 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
|
|||||||
'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'],
|
'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'],
|
||||||
'use-hosts': false,
|
'use-hosts': false,
|
||||||
'use-system-hosts': false,
|
'use-system-hosts': false,
|
||||||
nameserver: ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'],
|
'respect-rules': false,
|
||||||
'proxy-server-nameserver': ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'],
|
'default-nameserver': ['tls://223.5.5.5'],
|
||||||
|
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
||||||
|
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
||||||
'direct-nameserver': []
|
'direct-nameserver': []
|
||||||
},
|
},
|
||||||
sniffer: {
|
sniffer: {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ const FloatingApp: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-drag h-screen w-screen overflow-hidden">
|
<div className="app-drag h-screen w-screen overflow-hidden">
|
||||||
<div className="floating-bg border-1 border-divider flex rounded-full bg-content1 h-[calc(100%-2px)] w-[calc(100%-2px)]">
|
<div className="floating-bg border border-divider flex rounded-full bg-content1 h-[calc(100%-2px)] w-[calc(100%-2px)]">
|
||||||
<div className="flex justify-center items-center h-full aspect-square">
|
<div className="flex justify-center items-center h-full aspect-square">
|
||||||
<div
|
<div
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
@plugin './hero.ts';
|
||||||
|
|
||||||
|
@source '../**/*.{js,ts,jsx,tsx}';
|
||||||
|
@source '../../../../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
|
||||||
|
|
||||||
.floating-text {
|
.floating-text {
|
||||||
font-family:
|
font-family:
|
||||||
|
|||||||
2
src/renderer/src/assets/hero.ts
Normal file
2
src/renderer/src/assets/hero.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import { heroui } from '@heroui/react'
|
||||||
|
export default heroui()
|
||||||
@ -1,4 +1,12 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
@plugin './hero.ts';
|
||||||
|
|
||||||
|
@source '../**/*.{js,ts,jsx,tsx}';
|
||||||
|
@source '../../../../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--default-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Noto Color Emoji';
|
font-family: 'Noto Color Emoji';
|
||||||
|
|||||||
@ -39,7 +39,7 @@ const ConnectionItem: React.FC<Props> = (props) => {
|
|||||||
<Chip
|
<Chip
|
||||||
color={`${info.isActive ? 'primary' : 'danger'}`}
|
color={`${info.isActive ? 'primary' : 'danger'}`}
|
||||||
size="sm"
|
size="sm"
|
||||||
radius="sm"
|
radius="xs"
|
||||||
variant="dot"
|
variant="dot"
|
||||||
>
|
>
|
||||||
{info.metadata.type}({info.metadata.network.toUpperCase()})
|
{info.metadata.type}({info.metadata.network.toUpperCase()})
|
||||||
@ -65,16 +65,16 @@ const ConnectionItem: React.FC<Props> = (props) => {
|
|||||||
<Chip
|
<Chip
|
||||||
className="flag-emoji text-ellipsis whitespace-nowrap overflow-hidden"
|
className="flag-emoji text-ellipsis whitespace-nowrap overflow-hidden"
|
||||||
size="sm"
|
size="sm"
|
||||||
radius="sm"
|
radius="xs"
|
||||||
variant="bordered"
|
variant="bordered"
|
||||||
>
|
>
|
||||||
{info.chains[0]}
|
{info.chains[0]}
|
||||||
</Chip>
|
</Chip>
|
||||||
<Chip size="sm" radius="sm" variant="bordered">
|
<Chip size="sm" radius="xs" variant="bordered">
|
||||||
↑ {calcTraffic(info.upload)} ↓ {calcTraffic(info.download)}
|
↑ {calcTraffic(info.upload)} ↓ {calcTraffic(info.download)}
|
||||||
</Chip>
|
</Chip>
|
||||||
{info.uploadSpeed !== 0 || info.downloadSpeed !== 0 ? (
|
{info.uploadSpeed !== 0 || info.downloadSpeed !== 0 ? (
|
||||||
<Chip color="primary" size="sm" radius="sm" variant="bordered">
|
<Chip color="primary" size="sm" radius="xs" variant="bordered">
|
||||||
↑ {calcTraffic(info.uploadSpeed || 0)}/s ↓ {calcTraffic(info.downloadSpeed || 0)}
|
↑ {calcTraffic(info.uploadSpeed || 0)}/s ↓ {calcTraffic(info.downloadSpeed || 0)}
|
||||||
/s
|
/s
|
||||||
</Chip>
|
</Chip>
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
import { calcPercent, calcTraffic } from '@renderer/utils/calc'
|
import { calcPercent, calcTraffic } from '@renderer/utils/calc'
|
||||||
import { IoMdMore, IoMdRefresh } from 'react-icons/io'
|
import { IoMdMore, IoMdRefresh } from 'react-icons/io'
|
||||||
import dayjs from '@renderer/utils/dayjs'
|
import dayjs from '@renderer/utils/dayjs'
|
||||||
import React, { Key, useEffect, useMemo, useState } from 'react'
|
import React, { Key, useMemo, useState } from 'react'
|
||||||
import EditFileModal from './edit-file-modal'
|
import EditFileModal from './edit-file-modal'
|
||||||
import EditInfoModal from './edit-info-modal'
|
import EditInfoModal from './edit-info-modal'
|
||||||
import { useSortable } from '@dnd-kit/sortable'
|
import { useSortable } from '@dnd-kit/sortable'
|
||||||
@ -72,7 +72,8 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
id: info.id
|
id: info.id
|
||||||
})
|
})
|
||||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||||
const [disableSelect, setDisableSelect] = useState(false)
|
const [isActuallyDragging, setIsActuallyDragging] = useState(false)
|
||||||
|
const [clickStartPos, setClickStartPos] = useState<{ x: number; y: number } | null>(null)
|
||||||
|
|
||||||
const menuItems: MenuItem[] = useMemo(() => {
|
const menuItems: MenuItem[] = useMemo(() => {
|
||||||
const list = [
|
const list = [
|
||||||
@ -150,19 +151,35 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
setDropdownOpen(true)
|
setDropdownOpen(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
// 智能区分点击和拖拽的事件处理
|
||||||
if (isDragging) {
|
const handleMouseDown = (e: React.MouseEvent) => {
|
||||||
setTimeout(() => {
|
setClickStartPos({ x: e.clientX, y: e.clientY })
|
||||||
setDisableSelect(true)
|
setIsActuallyDragging(false)
|
||||||
}, 200)
|
}
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
const handleMouseMove = (e: React.MouseEvent) => {
|
||||||
setDisableSelect(false)
|
if (clickStartPos) {
|
||||||
}, 200)
|
const dx = e.clientX - clickStartPos.x
|
||||||
|
const dy = e.clientY - clickStartPos.y
|
||||||
|
// 移动距离超过 5px 认为是拖拽
|
||||||
|
if (dx * dx + dy * dy > 25) {
|
||||||
|
setIsActuallyDragging(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [isDragging])
|
}
|
||||||
|
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
// 如果没有拖拽,则处理为点击事件
|
||||||
|
if (!isActuallyDragging && !isDragging && clickStartPos) {
|
||||||
|
setSelecting(true)
|
||||||
|
onPress().finally(() => {
|
||||||
|
setSelecting(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setClickStartPos(null)
|
||||||
|
setTimeout(() => setIsActuallyDragging(false), 100)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -186,18 +203,19 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
<Card
|
<Card
|
||||||
as="div"
|
as="div"
|
||||||
fullWidth
|
fullWidth
|
||||||
isPressable
|
isPressable={false}
|
||||||
onPress={() => {
|
|
||||||
if (disableSelect) return
|
|
||||||
setSelecting(true)
|
|
||||||
onPress().finally(() => {
|
|
||||||
setSelecting(false)
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
className={`${isCurrent ? 'bg-primary' : ''} ${selecting ? 'blur-sm' : ''}`}
|
className={`${isCurrent ? 'bg-primary' : ''} ${selecting ? 'blur-sm' : ''} cursor-pointer`}
|
||||||
>
|
>
|
||||||
<div ref={setNodeRef} {...attributes} {...listeners} className="w-full h-full">
|
<div
|
||||||
|
ref={setNodeRef}
|
||||||
|
{...attributes}
|
||||||
|
{...listeners}
|
||||||
|
className="w-full h-full"
|
||||||
|
onMouseDownCapture={handleMouseDown}
|
||||||
|
onMouseMoveCapture={handleMouseMove}
|
||||||
|
onMouseUpCapture={handleMouseUp}
|
||||||
|
>
|
||||||
<CardBody className="pb-1">
|
<CardBody className="pb-1">
|
||||||
<div className="flex justify-between h-[32px]">
|
<div className="flex justify-between h-[32px]">
|
||||||
<h3
|
<h3
|
||||||
|
|||||||
@ -60,7 +60,7 @@ const ProxyItem: React.FC<Props> = (props) => {
|
|||||||
onPress={() => onSelect(group.name, proxy.name)}
|
onPress={() => onSelect(group.name, proxy.name)}
|
||||||
isPressable
|
isPressable
|
||||||
fullWidth
|
fullWidth
|
||||||
shadow="sm"
|
shadow="xs"
|
||||||
className={`${
|
className={`${
|
||||||
fixed
|
fixed
|
||||||
? 'bg-secondary/30 border-r-2 border-r-secondary border-l-2 border-l-secondary'
|
? 'bg-secondary/30 border-r-2 border-r-secondary border-l-2 border-l-secondary'
|
||||||
@ -68,7 +68,7 @@ const ProxyItem: React.FC<Props> = (props) => {
|
|||||||
? 'bg-primary/30 border-r-2 border-r-primary border-l-2 border-l-primary'
|
? 'bg-primary/30 border-r-2 border-r-primary border-l-2 border-l-primary'
|
||||||
: 'bg-content2'
|
: 'bg-content2'
|
||||||
}`}
|
}`}
|
||||||
radius="sm"
|
radius="xs"
|
||||||
>
|
>
|
||||||
<CardBody className="p-1">
|
<CardBody className="p-1">
|
||||||
{proxyDisplayMode === 'full' ? (
|
{proxyDisplayMode === 'full' ? (
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-c
|
|||||||
import BorderSwitch from '@renderer/components/base/border-swtich'
|
import BorderSwitch from '@renderer/components/base/border-swtich'
|
||||||
import { LuServer } from 'react-icons/lu'
|
import { LuServer } from 'react-icons/lu'
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import { patchMihomoConfig } from '@renderer/utils/ipc'
|
import { restartCore } from '@renderer/utils/ipc'
|
||||||
import { useSortable } from '@dnd-kit/sortable'
|
import { useSortable } from '@dnd-kit/sortable'
|
||||||
import { CSS } from '@dnd-kit/utilities'
|
import { CSS } from '@dnd-kit/utilities'
|
||||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||||
@ -15,15 +15,14 @@ interface Props {
|
|||||||
}
|
}
|
||||||
const DNSCard: React.FC<Props> = (props) => {
|
const DNSCard: React.FC<Props> = (props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { appConfig } = useAppConfig()
|
const { appConfig, patchAppConfig } = useAppConfig()
|
||||||
const { iconOnly } = props
|
const { iconOnly } = props
|
||||||
const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {}
|
const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {}
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const match = location.pathname.includes('/dns')
|
const match = location.pathname.includes('/dns')
|
||||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||||
const { dns, tun } = controledMihomoConfig || {}
|
const { tun } = controledMihomoConfig || {}
|
||||||
const { enable = true } = dns || {}
|
|
||||||
const {
|
const {
|
||||||
attributes,
|
attributes,
|
||||||
listeners,
|
listeners,
|
||||||
@ -35,20 +34,33 @@ const DNSCard: React.FC<Props> = (props) => {
|
|||||||
id: 'dns'
|
id: 'dns'
|
||||||
})
|
})
|
||||||
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
|
||||||
const onChange = async (enable: boolean): Promise<void> => {
|
const onChange = async (controlDnsEnabled: boolean): Promise<void> => {
|
||||||
await patchControledMihomoConfig({ dns: { enable } })
|
try {
|
||||||
await patchMihomoConfig({ dns: { enable } })
|
await patchAppConfig({ controlDns: controlDnsEnabled })
|
||||||
|
await patchControledMihomoConfig({})
|
||||||
|
await restartCore()
|
||||||
|
} catch (e) {
|
||||||
|
alert(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconOnly) {
|
if (iconOnly) {
|
||||||
return (
|
return (
|
||||||
<div className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''} flex justify-center`}>
|
<div className={`${dnsCardStatus} flex justify-center`}>
|
||||||
<Tooltip content={t('sider.cards.dns')} placement="right">
|
<Tooltip
|
||||||
|
content={
|
||||||
|
controlDns
|
||||||
|
? `${t('sider.cards.dns')} (${t('sider.cards.dns.overrideMode')})`
|
||||||
|
: `${t('sider.cards.dns')} (${t('sider.cards.dns.originalConfig')})`
|
||||||
|
}
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
isIconOnly
|
isIconOnly
|
||||||
color={match ? 'primary' : 'default'}
|
color={match ? 'primary' : 'default'}
|
||||||
variant={match ? 'solid' : 'light'}
|
variant={match ? 'solid' : 'light'}
|
||||||
|
className={!controlDns ? 'opacity-60' : ''}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate('/dns')
|
navigate('/dns')
|
||||||
}}
|
}}
|
||||||
@ -68,14 +80,14 @@ const DNSCard: React.FC<Props> = (props) => {
|
|||||||
transition,
|
transition,
|
||||||
zIndex: isDragging ? 'calc(infinity)' : undefined
|
zIndex: isDragging ? 'calc(infinity)' : undefined
|
||||||
}}
|
}}
|
||||||
className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''} dns-card`}
|
className={`${dnsCardStatus} dns-card`}
|
||||||
>
|
>
|
||||||
<Card
|
<Card
|
||||||
fullWidth
|
fullWidth
|
||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`}
|
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!controlDns ? 'opacity-60' : ''}`}
|
||||||
>
|
>
|
||||||
<CardBody className="pb-1 pt-0 px-0">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
@ -90,8 +102,8 @@ const DNSCard: React.FC<Props> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<BorderSwitch
|
<BorderSwitch
|
||||||
isShowBorder={match && enable}
|
isShowBorder={match && controlDns}
|
||||||
isSelected={enable}
|
isSelected={controlDns}
|
||||||
isDisabled={tun?.enable}
|
isDisabled={tun?.enable}
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -42,13 +42,14 @@ const SniffCard: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
if (iconOnly) {
|
if (iconOnly) {
|
||||||
return (
|
return (
|
||||||
<div className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''} flex justify-center`}>
|
<div className={`${sniffCardStatus} flex justify-center`}>
|
||||||
<Tooltip content={t('sider.cards.sniff')} placement="right">
|
<Tooltip content={t('sider.cards.sniff')} placement="right">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
isIconOnly
|
isIconOnly
|
||||||
color={match ? 'primary' : 'default'}
|
color={match ? 'primary' : 'default'}
|
||||||
variant={match ? 'solid' : 'light'}
|
variant={match ? 'solid' : 'light'}
|
||||||
|
className={!enable ? 'opacity-60' : ''}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate('/sniffer')
|
navigate('/sniffer')
|
||||||
}}
|
}}
|
||||||
@ -68,14 +69,14 @@ const SniffCard: React.FC<Props> = (props) => {
|
|||||||
transition,
|
transition,
|
||||||
zIndex: isDragging ? 'calc(infinity)' : undefined
|
zIndex: isDragging ? 'calc(infinity)' : undefined
|
||||||
}}
|
}}
|
||||||
className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''} sniff-card`}
|
className={`${sniffCardStatus} sniff-card`}
|
||||||
>
|
>
|
||||||
<Card
|
<Card
|
||||||
fullWidth
|
fullWidth
|
||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`}
|
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
|
||||||
>
|
>
|
||||||
<CardBody className="pb-1 pt-0 px-0">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|||||||
@ -58,6 +58,7 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
|
|||||||
isIconOnly
|
isIconOnly
|
||||||
color={match ? 'primary' : 'default'}
|
color={match ? 'primary' : 'default'}
|
||||||
variant={match ? 'solid' : 'light'}
|
variant={match ? 'solid' : 'light'}
|
||||||
|
className={!enable ? 'opacity-60' : ''}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate('/sysproxy')
|
navigate('/sysproxy')
|
||||||
}}
|
}}
|
||||||
@ -84,7 +85,7 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
|
|||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`}
|
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
|
||||||
>
|
>
|
||||||
<CardBody className="pb-1 pt-0 px-0">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|||||||
@ -56,6 +56,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
|||||||
isIconOnly
|
isIconOnly
|
||||||
color={match ? 'primary' : 'default'}
|
color={match ? 'primary' : 'default'}
|
||||||
variant={match ? 'solid' : 'light'}
|
variant={match ? 'solid' : 'light'}
|
||||||
|
className={!enable ? 'opacity-60' : ''}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
navigate('/tun')
|
navigate('/tun')
|
||||||
}}
|
}}
|
||||||
@ -82,7 +83,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
|
|||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`}
|
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
|
||||||
>
|
>
|
||||||
<CardBody className="pb-1 pt-0 px-0">
|
<CardBody className="pb-1 pt-0 px-0">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|||||||
@ -71,13 +71,34 @@ export const ProfileConfigProvider: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changeCurrentProfile = async (id: string): Promise<void> => {
|
const changeCurrentProfile = async (id: string): Promise<void> => {
|
||||||
|
if (profileConfig?.current === id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 乐观更新:立即更新 UI 状态,提供即时反馈
|
||||||
|
if (profileConfig) {
|
||||||
|
const optimisticUpdate = { ...profileConfig, current: id }
|
||||||
|
mutateProfileConfig(optimisticUpdate, false)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await change(id)
|
// 异步执行后台切换,不阻塞 UI
|
||||||
|
change(id).then(() => {
|
||||||
|
window.electron.ipcRenderer.send('updateTrayMenu')
|
||||||
|
mutateProfileConfig()
|
||||||
|
}).catch((e) => {
|
||||||
|
const errorMsg = e?.message || String(e)
|
||||||
|
// 处理 IPC 超时错误
|
||||||
|
if (errorMsg.includes('reply was never sent')) {
|
||||||
|
setTimeout(() => mutateProfileConfig(), 1000)
|
||||||
|
} else {
|
||||||
|
alert(`切换 Profile 失败: ${errorMsg}`)
|
||||||
|
mutateProfileConfig()
|
||||||
|
}
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(`切换 Profile 失败: ${e}`)
|
||||||
} finally {
|
|
||||||
mutateProfileConfig()
|
mutateProfileConfig()
|
||||||
window.electron.ipcRenderer.send('updateTrayMenu')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
"mihomo.cpuPriority.low": "Low",
|
"mihomo.cpuPriority.low": "Low",
|
||||||
"mihomo.workDir.title": "Separate Work Directory for Different Subscriptions",
|
"mihomo.workDir.title": "Separate Work Directory for Different Subscriptions",
|
||||||
"mihomo.workDir.tooltip": "Enable to avoid conflicts when different subscriptions have proxy groups with the same name",
|
"mihomo.workDir.tooltip": "Enable to avoid conflicts when different subscriptions have proxy groups with the same name",
|
||||||
"mihomo.controlDns": "Control DNS Settings",
|
"mihomo.controlDns": "Override DNS Settings",
|
||||||
"mihomo.controlSniff": "Control Domain Sniffing",
|
"mihomo.controlSniff": "Control Domain Sniffing",
|
||||||
"mihomo.autoCloseConnection": "Auto Close Connection",
|
"mihomo.autoCloseConnection": "Auto Close Connection",
|
||||||
"mihomo.pauseSSID.title": "Direct Connection for Specific WiFi SSIDs",
|
"mihomo.pauseSSID.title": "Direct Connection for Specific WiFi SSIDs",
|
||||||
@ -216,7 +216,9 @@
|
|||||||
"sider.cards.override": "Override",
|
"sider.cards.override": "Override",
|
||||||
"sider.cards.connections": "Connections",
|
"sider.cards.connections": "Connections",
|
||||||
"sider.cards.core": "Core Settings",
|
"sider.cards.core": "Core Settings",
|
||||||
"sider.cards.dns": "DNS",
|
"sider.cards.dns": "DNS OVR",
|
||||||
|
"sider.cards.dns.originalConfig": "Using Original Config",
|
||||||
|
"sider.cards.dns.overrideMode": "Override Mode",
|
||||||
"sider.cards.sniff": "Sniffing",
|
"sider.cards.sniff": "Sniffing",
|
||||||
"sider.cards.logs": "Logs",
|
"sider.cards.logs": "Logs",
|
||||||
"sider.cards.substore": "Sub-Store",
|
"sider.cards.substore": "Sub-Store",
|
||||||
@ -316,6 +318,7 @@
|
|||||||
"tun.notifications.firewallResetSuccess": "Firewall Reset Successful",
|
"tun.notifications.firewallResetSuccess": "Firewall Reset Successful",
|
||||||
"tun.error.tunPermissionDenied": "TUN interface start failed, please try to manually grant core permissions",
|
"tun.error.tunPermissionDenied": "TUN interface start failed, please try to manually grant core permissions",
|
||||||
"dns.title": "DNS Settings",
|
"dns.title": "DNS Settings",
|
||||||
|
"dns.enable.title": "Enable DNS",
|
||||||
"dns.enhancedMode.title": "Domain Mapping Mode",
|
"dns.enhancedMode.title": "Domain Mapping Mode",
|
||||||
"dns.enhancedMode.fakeIp": "Fake IP",
|
"dns.enhancedMode.fakeIp": "Fake IP",
|
||||||
"dns.enhancedMode.redirHost": "Real IP",
|
"dns.enhancedMode.redirHost": "Real IP",
|
||||||
@ -513,7 +516,7 @@
|
|||||||
"guide.override.title": "Override",
|
"guide.override.title": "Override",
|
||||||
"guide.override.description": "Mihomo Party provides powerful override functionality to customize your imported subscription configurations, such as adding rules and customizing proxy groups. You can directly import override files written by others or write your own. <b>Remember to enable the override file on the subscription you want to override</b>. For override file syntax, please refer to the <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">official documentation</a>.",
|
"guide.override.description": "Mihomo Party provides powerful override functionality to customize your imported subscription configurations, such as adding rules and customizing proxy groups. You can directly import override files written by others or write your own. <b>Remember to enable the override file on the subscription you want to override</b>. For override file syntax, please refer to the <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">official documentation</a>.",
|
||||||
"guide.dns.title": "DNS",
|
"guide.dns.title": "DNS",
|
||||||
"guide.dns.description": "The software takes control of the core's DNS settings by default. If you need to use the DNS settings from your subscription configuration, you can disable 'Control DNS Settings' in the application settings. The same applies to domain sniffing.",
|
"guide.dns.description": "The software overrides subscription DNS settings with application DNS settings by default. If you need to use the DNS settings from your subscription configuration, you can disable 'Override DNS Settings' in the application settings. The same applies to domain sniffing.",
|
||||||
"guide.end.title": "Tutorial Complete",
|
"guide.end.title": "Tutorial Complete",
|
||||||
"guide.end.description": "Now that you understand the basic usage of the software, import your subscription and start using it. Enjoy!\nYou can also join our official <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram group</a> for the latest news."
|
"guide.end.description": "Now that you understand the basic usage of the software, import your subscription and start using it. Enjoy!\nYou can also join our official <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram group</a> for the latest news."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,7 +101,7 @@
|
|||||||
"mihomo.cpuPriority.low": "低",
|
"mihomo.cpuPriority.low": "低",
|
||||||
"mihomo.workDir.title": "不同订阅使用独立工作目录",
|
"mihomo.workDir.title": "不同订阅使用独立工作目录",
|
||||||
"mihomo.workDir.tooltip": "启用后可避免不同订阅中存在相同名称的代理组时发生冲突",
|
"mihomo.workDir.tooltip": "启用后可避免不同订阅中存在相同名称的代理组时发生冲突",
|
||||||
"mihomo.controlDns": "控制 DNS 设置",
|
"mihomo.controlDns": "覆写 DNS 设置",
|
||||||
"mihomo.controlSniff": "控制域名嗅探",
|
"mihomo.controlSniff": "控制域名嗅探",
|
||||||
"mihomo.autoCloseConnection": "自动关闭连接",
|
"mihomo.autoCloseConnection": "自动关闭连接",
|
||||||
"mihomo.pauseSSID.title": "指定 WiFi SSID 直连",
|
"mihomo.pauseSSID.title": "指定 WiFi SSID 直连",
|
||||||
@ -216,7 +216,9 @@
|
|||||||
"sider.cards.override": "覆写",
|
"sider.cards.override": "覆写",
|
||||||
"sider.cards.connections": "连接",
|
"sider.cards.connections": "连接",
|
||||||
"sider.cards.core": "内核设置",
|
"sider.cards.core": "内核设置",
|
||||||
"sider.cards.dns": "DNS",
|
"sider.cards.dns": "DNS覆写",
|
||||||
|
"sider.cards.dns.originalConfig": "使用原始配置",
|
||||||
|
"sider.cards.dns.overrideMode": "覆写模式",
|
||||||
"sider.cards.sniff": "域名嗅探",
|
"sider.cards.sniff": "域名嗅探",
|
||||||
"sider.cards.logs": "日志",
|
"sider.cards.logs": "日志",
|
||||||
"sider.cards.substore": "Sub-Store",
|
"sider.cards.substore": "Sub-Store",
|
||||||
@ -316,6 +318,7 @@
|
|||||||
"tun.notifications.firewallResetSuccess": "防火墙重设成功",
|
"tun.notifications.firewallResetSuccess": "防火墙重设成功",
|
||||||
"tun.error.tunPermissionDenied": "虚拟网卡启动失败,请尝试手动授予内核权限",
|
"tun.error.tunPermissionDenied": "虚拟网卡启动失败,请尝试手动授予内核权限",
|
||||||
"dns.title": "DNS 设置",
|
"dns.title": "DNS 设置",
|
||||||
|
"dns.enable.title": "启用 DNS",
|
||||||
"dns.enhancedMode.title": "域名映射模式",
|
"dns.enhancedMode.title": "域名映射模式",
|
||||||
"dns.enhancedMode.fakeIp": "虚假 IP",
|
"dns.enhancedMode.fakeIp": "虚假 IP",
|
||||||
"dns.enhancedMode.redirHost": "真实 IP",
|
"dns.enhancedMode.redirHost": "真实 IP",
|
||||||
@ -513,7 +516,7 @@
|
|||||||
"guide.override.title": "覆写",
|
"guide.override.title": "覆写",
|
||||||
"guide.override.description": "Mihomo Party 提供强大的覆写功能,可以对您导入的订阅配置进行个性化修改,如添加规则、自定义代理组等,您可以直接导入别人写好的覆写文件,也可以自己动手编写,<b>编辑好覆写文件一定要记得在需要覆写的订阅上启用</b>,覆写文件的语法请参考 <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">官方文档</a>",
|
"guide.override.description": "Mihomo Party 提供强大的覆写功能,可以对您导入的订阅配置进行个性化修改,如添加规则、自定义代理组等,您可以直接导入别人写好的覆写文件,也可以自己动手编写,<b>编辑好覆写文件一定要记得在需要覆写的订阅上启用</b>,覆写文件的语法请参考 <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">官方文档</a>",
|
||||||
"guide.dns.title": "DNS",
|
"guide.dns.title": "DNS",
|
||||||
"guide.dns.description": "软件默认接管了内核的 DNS 设置,如果您需要使用订阅配置中的 DNS 设置,可以到应用设置中关闭\"接管 DNS 设置\",域名嗅探同理",
|
"guide.dns.description": "软件默认使用应用的 DNS 设置覆写订阅配置,如果您需要使用订阅配置中的 DNS 设置,可以到应用设置中关闭\"覆写 DNS 设置\",域名嗅探同理",
|
||||||
"guide.end.title": "教程结束",
|
"guide.end.title": "教程结束",
|
||||||
"guide.end.description": "现在您已经了解了软件的基本用法,导入您的订阅开始使用吧,祝您使用愉快!\n您还可以加入我们的官方 <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram 群组</a> 获取最新资讯"
|
"guide.end.description": "现在您已经了解了软件的基本用法,导入您的订阅开始使用吧,祝您使用愉快!\n您还可以加入我们的官方 <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram 群组</a> 获取最新资讯"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ const DNS: React.FC = () => {
|
|||||||
const { nameserverPolicy, useNameserverPolicy } = appConfig || {}
|
const { nameserverPolicy, useNameserverPolicy } = appConfig || {}
|
||||||
const { dns, hosts } = controledMihomoConfig || {}
|
const { dns, hosts } = controledMihomoConfig || {}
|
||||||
const {
|
const {
|
||||||
|
enable = true,
|
||||||
ipv6 = false,
|
ipv6 = false,
|
||||||
'fake-ip-range': fakeIPRange = '198.18.0.1/16',
|
'fake-ip-range': fakeIPRange = '198.18.0.1/16',
|
||||||
'fake-ip-filter': fakeIPFilter = [
|
'fake-ip-filter': fakeIPFilter = [
|
||||||
@ -40,6 +41,7 @@ const DNS: React.FC = () => {
|
|||||||
} = dns || {}
|
} = dns || {}
|
||||||
const [changed, setChanged] = useState(false)
|
const [changed, setChanged] = useState(false)
|
||||||
const [values, originSetValues] = useState({
|
const [values, originSetValues] = useState({
|
||||||
|
enable,
|
||||||
ipv6,
|
ipv6,
|
||||||
useHosts,
|
useHosts,
|
||||||
enhancedMode,
|
enhancedMode,
|
||||||
@ -143,6 +145,7 @@ const DNS: React.FC = () => {
|
|||||||
color="primary"
|
color="primary"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
const dnsConfig = {
|
const dnsConfig = {
|
||||||
|
enable: values.enable,
|
||||||
ipv6: values.ipv6,
|
ipv6: values.ipv6,
|
||||||
'fake-ip-range': values.fakeIPRange,
|
'fake-ip-range': values.fakeIPRange,
|
||||||
'fake-ip-filter': values.fakeIPFilter,
|
'fake-ip-filter': values.fakeIPFilter,
|
||||||
@ -177,6 +180,15 @@ const DNS: React.FC = () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SettingCard>
|
<SettingCard>
|
||||||
|
<SettingItem title={t('dns.enable.title')} divider>
|
||||||
|
<Switch
|
||||||
|
size="sm"
|
||||||
|
isSelected={values.enable}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
setValues({ ...values, enable: v })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
<SettingItem title={t('dns.enhancedMode.title')} divider>
|
<SettingItem title={t('dns.enhancedMode.title')} divider>
|
||||||
<Tabs
|
<Tabs
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -85,7 +85,7 @@ const Profiles: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
{sub.tag?.map((tag) => {
|
{sub.tag?.map((tag) => {
|
||||||
return (
|
return (
|
||||||
<Chip key={tag} size="sm" className="ml-1" radius="sm">
|
<Chip key={tag} size="sm" className="ml-1" radius="xs">
|
||||||
{tag}
|
{tag}
|
||||||
</Chip>
|
</Chip>
|
||||||
)
|
)
|
||||||
@ -108,7 +108,7 @@ const Profiles: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
{sub.tag?.map((tag) => {
|
{sub.tag?.map((tag) => {
|
||||||
return (
|
return (
|
||||||
<Chip key={tag} size="sm" className="ml-1" radius="sm">
|
<Chip key={tag} size="sm" className="ml-1" radius="xs">
|
||||||
{tag}
|
{tag}
|
||||||
</Chip>
|
</Chip>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -324,7 +324,7 @@ const Proxies: React.FC = () => {
|
|||||||
<Avatar
|
<Avatar
|
||||||
className="bg-transparent mr-2"
|
className="bg-transparent mr-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
radius="sm"
|
radius="xs"
|
||||||
src={
|
src={
|
||||||
groups[index].icon.startsWith('<svg')
|
groups[index].icon.startsWith('<svg')
|
||||||
? `data:image/svg+xml;utf8,${groups[index].icon}`
|
? `data:image/svg+xml;utf8,${groups[index].icon}`
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
|
||||||
const { heroui } = require('@heroui/react')
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
content: [
|
|
||||||
'./src/renderer/src/**/*.{js,ts,jsx,tsx}',
|
|
||||||
'./node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}'
|
|
||||||
],
|
|
||||||
theme: {
|
|
||||||
extend: {}
|
|
||||||
},
|
|
||||||
darkMode: 'class',
|
|
||||||
plugins: [heroui()]
|
|
||||||
}
|
|
||||||
@ -3,6 +3,7 @@
|
|||||||
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "src/shared/**/*"],
|
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "src/shared/**/*"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"types": ["electron-vite/node"]
|
"types": ["electron-vite/node"],
|
||||||
|
"moduleResolution": "bundler"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user