Compare commits

...

2320 Commits
main ... alpha

Author SHA1 Message Date
Tunglies
abe0750d07 chore: update version to 2.2.1-alpha and add alpha update logs
refactor: simplify version change detection in alpha workflow

chore: alpha delete old release then release new one

fix: update alpha workflow to handle missing ALPHA_LOGS and improve release notes generation

fix: update job dependencies in alpha workflow to include delete_otld_release
2025-03-20 19:11:48 +08:00
Tunglies
2195576553 fix: remove macOS application menu setup due to CMD+C/V/A issues 2025-03-20 18:14:18 +08:00
Tunglies
1dc015f411 chore: bug report template remove os label 2025-03-20 16:39:29 +08:00
Tunglies
49d13c9ecb chore: UPDATELOG update 2025-03-20 15:49:00 +08:00
Tunglies
d8cd91b725 fix: ensure main window title is set correctly on macOS 2025-03-20 15:43:59 +08:00
wonfen
40eede325b release 2.2.0 2025-03-20 14:44:26 +08:00
Tunglies
59e07a3e55 Revert "fix: update permission config with app icon and name"
This reverts commit 46af096cb1152fa7ba7c7b5ff82daf949079fca5.
2025-03-20 14:17:41 +08:00
Tunglies
3d32d2d08f feat(hotkey): macos support CMD+W to close window as default 2025-03-20 13:02:26 +08:00
wonfen
46af096cb1 fix: update permission config with app icon and name 2025-03-20 12:43:22 +08:00
Tunglies
486f33fd7a fix: update system architecture retrieval method in PlatformSpecification 2025-03-20 06:20:19 +08:00
Tunglies
5ebfcc6f98 fix: update service response check for correct status code and message 2025-03-20 06:18:14 +08:00
Tunglies
7fa1767645 feat: implement auto lightweight mode timer functionality
This commit implements the automatic lightweight mode feature with timer functionality:

- Rename configuration properties from auto_enter_lite_mode to enable_auto_light_weight_mode and auto_enter_lite_mode_delay to auto_light_weight_minutes for better clarity
- Add window event listeners to detect when window is closed or gets focus
- Implement timer system to automatically enter lightweight mode after configured time
- Remove exit_lightweight_mode function as it's no longer needed with the new implementation
- Update UI components to reflect the new property names
- Add logging for lightweight mode operations
- Initialize lightweight mode based on user configuration at startup

The feature now allows users to set a timer that will automatically enter lightweight mode
after closing the main window, which can be cancelled by focusing the window again.
2025-03-20 06:01:38 +08:00
Tunglies
33d54b27f4 feat: implement lightweight mode functionality and update related settings 2025-03-20 03:23:14 +08:00
wonfen
f8dbc7bea0 feat: lite mode settings 2025-03-20 01:44:43 +08:00
Tunglies
83d338eaa4 fix: hotkeys on windows crash 2025-03-19 18:41:26 +08:00
wonfen
9732b2be14 chore: update deps 2025-03-19 11:07:57 +08:00
wonfen
8a5232df20 feat: add up/down name to home traffic graph card 2025-03-19 10:38:21 +08:00
wonfen
5f0f6db0d5 chore: change defaut start page to home 2025-03-19 05:48:20 +08:00
wonfen
7a86e4bd85 fix: cannot detect service mode on home card 2025-03-19 05:25:38 +08:00
Tunglies
f18a8c901f feat: add lite mode toggle to home page 2025-03-19 02:18:20 +08:00
Tunglies
23d161c298 refactor: improve proxy retrieval and add window destruction method 2025-03-19 02:04:01 +08:00
Tunglies
3e2148e236 feat: add macOS application menu integration 2025-03-18 18:40:53 +08:00
Tunglies
70a4bd1074 chore: remove tray icon configuration from webview JSON files 2025-03-18 15:31:23 +08:00
Tunglies
e13d3e7f83 Revert "feat: add Rust installation step and configure alpha release details"
This reverts commit 1d5471e70dc2da7d15df3fdd8566e14023384f90.
2025-03-18 14:37:56 +08:00
wonfen
e21bc22fa3 chore: add missing colorful svg for home and unlock menu 2025-03-18 10:37:00 +08:00
wonfen
d8e85c9cfc refactor: revise data retrieval for homepage traffic stats 2025-03-18 09:05:44 +08:00
Tunglies
1d5471e70d feat: add Rust installation step and configure alpha release details 2025-03-18 01:08:46 +08:00
wonfen
a2a8dd182a feat: persist graph data after page reload 2025-03-18 00:37:10 +08:00
wonfen
511fb9e2cf feat: limit max url lenght on home profile card 2025-03-18 00:18:26 +08:00
wonfen
14f90ac925 fix: auto launch 2025-03-17 13:51:52 +08:00
wonfen
8e09bf525e fix: resolve Netflix detection error 2025-03-17 11:57:12 +08:00
wonfen
7e7ef5766e perf: optimize all home page components 2025-03-17 11:47:02 +08:00
wonfen
b078560ac1 feat: sync auto-start status 2025-03-17 09:48:44 +08:00
wonfen
1e481ed1c1 chore: update i18n for unlock test 2025-03-17 07:45:49 +08:00
wonfen
e957c10138 perf: optimize CPU and memory usage of homepage traffic chart 2025-03-16 14:34:29 +08:00
wonfen
79bb0f29f9 fix: sync proxy node selection 2025-03-16 14:24:58 +08:00
wonfen
f4cb978118 feat: unlock test page 2025-03-16 12:15:35 +08:00
Tunglies
e16b23946a refactor(timer): improve timer management with robust error handling
This commit improves the timer management system with the following enhancements:

Replace Mutex with RwLock for better read concurrency in timer state
Add structured TimerTask type to store task metadata
Use atomic boolean for initialization flag instead of mutex
Implement comprehensive error handling with detailed logging
Add rollback capability when task operations fail
Reduce lock contention by generating task diffs outside locks
Add timing metrics for task execution
Improve code organization and documentation
2025-03-15 18:58:12 +08:00
Tunglies
df538ca9a3 refactor(config): use bitflags for tracking update operations
Replace multiple boolean variables with a bitflag approach for tracking
required update operations in the patch_verge function. This improves
code maintainability and potentially performance by:

1. Using a single integer variable with bit operations instead of multiple booleans
2. Defining clear flags as enum variants for better code readability
3. Simplifying flag checks with bitwise operations

The UpdateFlags enum provides a clear and type-safe way to represent
different types of updates needed when patching Verge configuration.
2025-03-15 18:42:57 +08:00
Tunglies
b97f0734d0 Optimize hotkey management to reduce lock contention and improve performance
- Minimize mutex lock durations in update() by processing data outside critical sections
- Pre-allocate collections to avoid unnecessary reallocations
- Replace forEach-style loops with more efficient for loops
- Add defensive null checks when accessing app_handle
- Improve error handling with more robust Option unwrapping
- Enhance code readability with descriptive comments
2025-03-15 17:52:14 +08:00
Tunglies
cbd2dd972a structure: move out crate_mihomo_api 2025-03-15 14:47:02 +08:00
Tunglies
00d6bcc00f refactor: update request method handling to use reqwest::Method enum
fix: duplicated checks tray menu
2025-03-15 13:23:17 +08:00
Tunglies
43ffb3c9e0 fix: optimize speed rate update logic for small values 2025-03-14 22:40:56 +08:00
wonfen
9fd75f0efb feat: home page 2025-03-14 13:31:34 +08:00
Tunglies
49f0ac407e Revert "feat: add trigger updater workflow to GitHub actions for release and alpha workflows"
This reverts commit ff8426d95e118fca572e98f618f28bb5b3d4d271.
2025-03-14 02:00:55 +08:00
Tunglies
ff8426d95e feat: add trigger updater workflow to GitHub actions for release and alpha workflows 2025-03-14 01:31:19 +08:00
GKarbon
3ca4ac2726
chore: correct typo in src/locales/en.json (#2978)
This pull request corrects a typo in src/locales/en.json by replacing “than” with “then”, gives more accurate instructions.
2025-03-14 01:04:44 +08:00
Christine.
07441ba95e
fix: build failed due to vite unexpected output dir config. (#2981) 2025-03-14 00:57:17 +08:00
Tunglies
e74fd068d5 chore: remove tray icon configuration from Linux app settings 2025-03-13 19:03:27 +08:00
Tunglies
965e281348 fix: increase request timeout to 60 seconds for better reliability 2025-03-13 15:16:54 +08:00
Tunglies
a7f66c3d65 chore: git hooks for linter and formatter 2025-03-13 12:51:20 +08:00
Mimi
f7f15544ba feat: additional macos tray event handling option for menu display (#2958) 2025-03-13 10:08:38 +08:00
MaqicXu
6ea79daf73
refactor(timer): enhance timer initialization and task handling (#2956)
- Add initialization flag to prevent duplicate timer initialization
- Improve logging for better debugging and monitoring
- Refactor async task function with proper error handling
- Add more detailed log messages throughout the timer lifecycle
2025-03-12 22:36:25 +08:00
Christine.
99abbfbc4c
chore: Change default TUN stack from 'mixed' to 'gvisor' (#2967) 2025-03-12 21:45:14 +08:00
Tunglies
24df5e02d6 fix: windows unmatched tray 2025-03-12 13:55:11 +08:00
Tunglies
6aaec3de5d fix: windows different tray icon display 2025-03-12 13:28:04 +08:00
Tunglies
39d811cc62 feat: update systray creation to use TrayIconBuilder and pass app reference
fix: macos systray duplicated icon
2025-03-12 13:04:15 +08:00
Tunglies
832a0ac281 feat: add alpha update endpoints to tauri configuration 2025-03-11 01:31:31 +08:00
Tunglies
7b0df043be feat: add support for alpha updates and enhance updater functionality
feat: improve release handling by adding creation logic for non-existent releases
2025-03-11 01:27:17 +08:00
Tunglies
d470bf2dd9 rm: label issues workflow 2025-03-10 01:01:12 +08:00
Tunglies
b5e8a1ddb5 chore: rename "DNS Settings" to "DNS Overwrite" in UI for consistency
This change updates the label for the DNS toggle setting from "DNS Settings" to "DNS Overwrite"
in the ClashVerge settings interface. The change provides better consistency with the translation
keys and more clearly communicates the function of the setting, which is to override system DNS.
The corresponding translation keys have been updated in both English and Chinese localization files.
2025-03-10 00:57:55 +08:00
Tunglies
08f3357d9a feat: add scheduled workflow and commit change check to alpha build 2025-03-09 17:42:13 +08:00
Tunglies
107c54921d refactor: update MihomoManager to handle traffic WebSocket URL and authorization 2025-03-09 14:44:15 +08:00
wonfen
ca1f7a2b31 feat: enhance latency test logging and error handling 2025-03-09 04:22:34 +08:00
wonfen
95e8fe38f2 refactor: improve webSocket connection handling and error recovery 2025-03-09 04:22:01 +08:00
wonfen
cd6eb26a41 feat: add icon file content check to prevent saving failed downloads 2025-03-09 02:34:57 +08:00
Tunglies
9f2c4b4f35 refactor: migrate clash client info retrieval to MihomoManager 2025-03-09 00:40:16 +08:00
Tunglies
adbf98cb15 rm: clash-api dead code 2025-03-09 00:29:14 +08:00
Tunglies
c9b3fec09c refactor: improve request handling and response processing in MihomoManager 2025-03-09 00:27:12 +08:00
Tunglies
364fb16b7b refactor: streamline clash delay test and improve API interactions 2025-03-09 00:04:48 +08:00
Tunglies
634ed9cb46 refactor: streamline clash mode handling and improve API interactions 2025-03-08 22:41:14 +08:00
wonfen
cddb117402 feat: optimize icon cache download and DNS view styling 2025-03-08 13:31:20 +08:00
wonfen
bd6c4e00c4 refactor: restructure DNS setting logic 2025-03-08 11:25:00 +08:00
wonfen
bbcfb4901f refactor: refine DNS handling to follow config and merge settings 2025-03-08 03:34:25 +08:00
wonfen
230a0eeb64 fix: regex for first character matching 2025-03-07 14:07:10 +08:00
wonfen
c4c49f61df perf: faster app exit 2025-03-07 13:44:07 +08:00
TianHua Liu
6d5c4f86d3
fix: Notice @ts-ignore (#2896)
thx
2025-03-07 12:46:30 +08:00
0XE
59f22b9cd2
feat: Add x-data-grid component localization (#2925)
thx
2025-03-07 12:45:56 +08:00
wonfen
6caf2cd057 test: remove entitlements.plist items 2025-03-07 06:49:24 +08:00
Tunglies
684128ca68 Update dependencies and refactor encryption logic
Updates multiple dependencies to their latest versions in Cargo.lock and Cargo.toml.
Refactors encryption logic to use updated getrandom API.
Improves tray speed rate display by using ab_glyph for font rendering.
2025-03-06 18:56:31 +08:00
wonfen
6925adc66f feat: enable dns settings by default 2025-03-06 14:40:35 +08:00
wonfen
e1e9d91d86 feat: add dns settings 2025-03-06 14:30:43 +08:00
Christine.
881c136b1e
add: missing i18n text. (#2917) 2025-03-05 22:28:28 +08:00
0XE
5bc699b19c
fix: ISSUES #2727 (#2913) 2025-03-05 14:20:07 +08:00
Christine.
52ba1c5a30
workflow: remove renaming behavior. (#2909) 2025-03-05 11:41:15 +08:00
Tunglies
817d68546e
feat(mihomo): refactor MihomoManager for global access and improve proxy retrieval (#2906) 2025-03-05 10:58:54 +08:00
wonfen
c0f5c231ad feat: add admin permission prompt for system service 2025-03-05 10:22:57 +08:00
Tunglies
9677d8670b test: crate_mihomo_api additional headers 2025-03-05 08:14:37 +08:00
Tunglies
b01630d31c fix: extern controler api secert with headers 2025-03-05 08:09:42 +08:00
Tunglies
f771f4720f
refacture: Mihomo API integration (#2900)
* feat: add mihomo_api crate as a workspace member

Added a new mihomo_api crate to handle interactions with the Mihomo API. This modular approach provides a dedicated interface for fetching and managing proxy data from Mihomo servers. The implementation includes functionality to refresh and retrieve both proxies and provider proxies with proper error handling and timeouts. Added this crate as a workspace member and included it as a dependency in the main project.

* Refactors Mihomo API integration

Simplifies proxy fetching by removing the MihomoManager structure.

Updates the get_proxies and get_providers_proxies functions to directly use the mihomo_api module.

Removes unused Mihomo API related files and modules for cleaner codebase.

Enhances overall maintainability and performance.
2025-03-05 00:45:08 +08:00
0XE
f0becb5003
fix: issues #2838 (#2886) 2025-03-04 20:46:17 +08:00
Tunglies
405e8df825
feat(sysinfo): Add diagnostic information enhancements (#2880)
Enhanced the PlatformSpecification struct with additional diagnostic information including:
- Added Verge version information to diagnostic output
- Added running mode information (Service/Sidecar/Not Running)
- Improved Debug implementation to display all diagnostic fields
- Implemented asynchronous detection of core running mode

This change helps users provide more complete system information when reporting issues.
2025-03-04 11:52:22 +08:00
wonfen
49fc7ff7ca fix: sync system proxy status indicator with hotkey 2025-03-04 06:57:42 +08:00
wonfen
fde9c8aaee fix: correct type declarations for getProxiesInner and getProxyProviders 2025-03-04 02:26:26 +08:00
Tunglies
8f95c28050 feat(proxy): add proxy commands and integrate with API
Add new proxy.rs module with get_proxies and get_providers_proxies commands.
Update mod.rs and lib.rs to re-export and register proxy commands.
Update API.ts to use invoke for proxy commands.
Minor formatting improvements in module/mihomo.rs.
2025-03-04 01:01:24 +08:00
Tunglies
2cd97c7785
feat: add Mihomo API modules and manager (#2869)
• Introduce new API caller implementations for Mihomo in model and module layers.
• Add configuration and API integration files under /src-tauri/src/config/api and /src-tauri/src/model/api.
• Implement a singleton MihomoAPICaller with async API call support and integration tests.
• Create a new MihomoManager module to refresh and fetch proxies from the API.
• Update Cargo.lock and Cargo.toml with additional dependencies (async-trait, env_logger, mockito, tempfile, etc.) related to the Mihomo API support.
2025-03-03 19:31:44 +08:00
wonfen
6e48781687 Revert "refactor: improve proxy group UI and spacing (#2835)"
This reverts commit b31cbda61507f68473762e5b5e86e8ddcab7b3c6.
2025-03-03 14:47:05 +08:00
wonfen
dd510b2ee9 feat: show service mode installation prompts in user mode 2025-03-03 14:42:31 +08:00
Tunglies
fadae3f7dc fix: speed format runns by docs 2025-03-03 11:36:21 +08:00
Tunglies
fdf8a6b2ba Revert "style: update box styling in settings page for improved layout (#2857)"
This reverts commit 4382df7951aefc973ec6f9d9cba0fafc88134e93.
2025-03-03 08:00:10 +08:00
Tunglies
4382df7951
style: update box styling in settings page for improved layout (#2857) 2025-03-03 06:38:32 +08:00
Tunglies
6cb7d48530
feat: add export diagnostic info functionality (#2856) 2025-03-03 05:58:12 +08:00
wonfen
9d74b93ee0 feat: Add sidecar mode as an alternative to service mode
- Auto-fallback to sidecar mode if service mode fails
2025-03-03 03:34:34 +08:00
Tunglies
d370868222 fix: windows/linux runtime crash 2025-03-03 02:27:45 +08:00
Christine.
9278f9e193
workflow: remove 32-bit platform (#2855)
* chore: build portable by self

* chore: remove 32bit platform

* Update CONTRIBUTING.md

* update alpha version
2025-03-03 01:16:33 +08:00
Tunglies
a708db6f2b Revert "chore: alpha ci should remove old builds"
This reverts commit d2c4a44297d98ca3b7df308f2d2422c88e9aa1aa.
2025-03-03 00:16:17 +08:00
Tunglies
d2c4a44297 chore: alpha ci should remove old builds 2025-03-02 23:46:20 +08:00
Tunglies
3a24623e4b feat: fish env export support 2025-03-02 23:20:10 +08:00
Tunglies
d2084d8d21 version: 2.1.3 a 2025-03-02 20:46:53 +08:00
Tunglies
d9b4ca91e7 version: 2.1.3 alpha 2025-03-02 20:43:54 +08:00
Tunglies
13da571ad2
version: 2.1.3 alpha (#2851)
* version: 2.1.3 alpha
2025-03-02 19:08:27 +08:00
Tunglies
662d60c0f5 chore: automatically label issues (#2844) 2025-03-02 18:50:31 +08:00
Tunglies
368095d2d4
docs: add fast build and clean commands to contributing guide (#2842)
docs: add fast build and clean commands to contributing guide

- Added documentation for the `pnpm build:fast` command which uses Rust's fast-release profile to reduce compilation time
- Added explanation that fast builds disable optimization and LTO, resulting in larger but quicker builds
- Added documentation for the `pnpm clean` command to clean Rust build files
2025-03-02 15:13:17 +08:00
Tunglies
496aeeb06d
chore: fast-dev and fast-build profile (#2841)
* refactor: improve proxy group UI and spacing

- Increased spacing in proxy-groups.tsx by adjusting the right position
  of the alphabet selector to provide better visual separation
- Enhanced spacing in proxy-render.tsx with larger margins and padding
  - Increased group item margins from 8px to 10px with 16px horizontal spacing
  - Expanded border radius from 8px to 10px for smoother appearance
  - Improved ProxyHead component spacing with pl: 3, pr: 3.5
  - Enhanced grid spacing in proxy collection items from 1 to 1.5
  - Adjusted padding for better visual hierarchy

These changes create a more polished, spacious layout with improved
readability and touch targets.

* - Update package.json with improved dev and build scripts:
  - Add fast-dev profile to development scripts
  - Configure build:fast with fast-release profile
  - Add clean command for cargo cleaning
2025-03-02 14:58:59 +08:00
Tunglies
b31cbda615
refactor: improve proxy group UI and spacing (#2835)
- Increased spacing in proxy-groups.tsx by adjusting the right position
  of the alphabet selector to provide better visual separation
- Enhanced spacing in proxy-render.tsx with larger margins and padding
  - Increased group item margins from 8px to 10px with 16px horizontal spacing
  - Expanded border radius from 8px to 10px for smoother appearance
  - Improved ProxyHead component spacing with pl: 3, pr: 3.5
  - Enhanced grid spacing in proxy collection items from 1 to 1.5
  - Adjusted padding for better visual hierarchy

These changes create a more polished, spacious layout with improved
readability and touch targets.
2025-03-02 05:36:18 +08:00
Tunglies
7898f3a119 fix: macos frameless title 2025-03-02 04:30:58 +08:00
wonfen
ba0a291d97 feat: refactor logging system into a global service 2025-03-02 04:20:38 +08:00
wonfen
b3e4defc0f fix: remove macos window title 2025-03-02 04:09:50 +08:00
wonfen
1ae0ad8a0e fix: add bottom padding to prevent jitter 2025-03-02 04:08:13 +08:00
Tunglies
79b20694c7
feat: add fast compilation options for development and release (#2831)
- Added fast compilation profiles in Cargo.toml
  - fast-dev profile with max codegen units and disabled optimizations
  - fast-release profile with debugging support and faster build time
- Added new npm scripts for quick development iterations
  - dev:fast command for standard development without extra features
  - build:fast command for quick release builds
- Updated default dev command to use verge-dev feature flag
- Both profiles retain debug symbols and disable stripping for better debugging
2025-03-02 00:40:07 +08:00
Tunglies
1ad4941ed8
refactor: rename cmds module to cmd for better consistency (#2830)
- Renamed `cmds` module to `cmd` for better naming consistency
- Reorganized command modules into separate files under src/cmd/
- Updated all imports and references to use the new module name
- Fixed missing dependency in webdav.rs to reference core::backup
- Updated tray module to use new cmd namespace
- Improved uwp.rs module structure using platform-specific implementations
- Removed unnecessary imports from various command files
2025-03-01 22:52:43 +08:00
Tunglies
b3fd44d165
refactor: reorganize feat.rs into modular structure (#2827)
Split the monolithic feat.rs file into specialized modules:
- backup.rs: WebDAV backup and restore functions
- clash.rs: Core management and testing functions
- config.rs: Configuration handling
- profile.rs: Profile management
- proxy.rs: Proxy and TUN mode controls
- window.rs: Dashboard window management

This improves code organization, readability, and maintainability
by grouping related functionality into logical modules.
2025-03-01 20:44:35 +08:00
Christine.
391a494af6
fix: build failed with Windows (#2825) 2025-03-01 19:52:42 +08:00
Tunglies
623d075ab8 add: issues type template 2025-03-01 19:12:12 +08:00
Tunglies
5d70b77316
Issues label options template (#2820)
* fix: macos dock display icon and text

* add: issues label option template
2025-03-01 02:46:16 -08:00
Tunglies
f5f54c0f0e
fix: macos dock display icon and text (#2818) 2025-03-01 02:29:40 -08:00
wonfen
91b0b1f279 perf: improve scrolling performance and interaction in proxy group list 2025-03-01 08:31:31 +08:00
wonfen
e0fa1f3efe fix: v2 action file rename 2025-03-01 08:04:31 +08:00
wonfen
b00abf3337 chore: updatelog 2025-03-01 03:45:03 +08:00
wonfen
a5d846ce4e feat: add exit status check in core config validation 2025-03-01 03:39:13 +08:00
wonfen
7743c42dd1 Release - 2.1.2 真·臻 2025-03-01 01:49:01 +08:00
Christine.
3f3dab9495
add: i18n text for settings page. (#2815) 2025-03-01 01:36:36 +08:00
Tunglies
2dc9672b20 feat: better setting UI layout (#2814) 2025-03-01 01:29:23 +08:00
wonfen
2c90d1ca69 chore: v2 updater 2025-03-01 01:29:23 +08:00
Tunglies
1555e2910d feat: better setting layout ui (#2809) 2025-03-01 01:29:23 +08:00
Tunglies
19b6bd35f5 feat: quiting when enable tun mode no more blocking system network (#2805) 2025-03-01 01:29:23 +08:00
wonfen
3d4d60edc8 test updater 2025-03-01 01:29:23 +08:00
wonfen
db0a000ecb chore: updater v2 Capabilities 2025-02-28 10:55:53 +08:00
wonfen
24ff48b41c fix: updater 2025-02-28 09:33:50 +08:00
wonfen
18a67d0b2f chore: updatelog 2025-02-28 07:34:56 +08:00
wonfen
e23af1ad58 feat: add ability to check service version and auto-reinstall 2025-02-28 06:45:30 +08:00
wonfen
70af392059 feat: enhance updater script with comprehensive platform support and logging 2025-02-27 17:19:04 +08:00
Christine.
d255df23ee
fix: connection details (#2778) 2025-02-27 14:53:17 +08:00
wonfen
1317a8b2db feat: enhance merge config validation and error handling 2025-02-27 14:49:55 +08:00
wonfen
4cac118442 style: UI tweak 2025-02-27 13:04:46 +08:00
wonfen
2ce43ccd23 Release - 2.1.1 臻fix 2025-02-27 03:18:23 +08:00
Tunglies
d23b2949d8 feat: macos display colorful icon with speed rate (#2771) 2025-02-27 01:51:52 +08:00
wonfen
3471476ba2 feat: improve file type detection for better script recognition 2025-02-26 15:59:19 +08:00
wonfen
cee61e5619 chore: downgrade Tauri updater plugin and add i18n for core switching 2025-02-26 15:04:47 +08:00
wonfen
5026e2bade feat: optimize hotkey behavior and window management logic 2025-02-26 11:03:50 +08:00
wonfen
83f005c256 fix: CI 2025-02-26 09:52:15 +08:00
wonfen
80843c5ee3 Release 2.1.0 - 臻 2025-02-26 08:36:02 +08:00
wonfen
ee00defe43 feat: enhance script validation and error handling 2025-02-26 05:21:14 +08:00
wonfen
7696504d97 feat: Add window state monitoring and auto-save in real-time 2025-02-26 00:36:02 +08:00
wonfen
7a0e38a1b4 perf: Improve config validation error messages and handling 2025-02-25 13:47:29 +08:00
wonfen
bc5d577553 chore: revise translation 2025-02-24 23:26:04 +08:00
wonfen
cfed2b7236 chore: Change default TUN stack from 'mixed' to 'gvisor' 2025-02-24 23:10:09 +08:00
Christine.
e34e6654bc
add: i18n text for config check (#2750) 2025-02-24 22:23:42 +08:00
wonfen
d6b85f1a01 fix: remove node related group info when deleting a node 2025-02-24 11:40:28 +08:00
wonfen
16af7b53cb fix: menu switching issue 2025-02-24 11:37:23 +08:00
wonfen
befc856207 feat: Improve core change configuration validation and error handling 2025-02-24 07:34:03 +08:00
wonfen
5ab8e7a7c7 feat: Enhance configuration validation and error handling during app startup 2025-02-24 06:21:32 +08:00
zhaoyuan
443bfa5928
feat: 通过添加CLASH_VERGE_REV_IP环境变量的方式,修改复制环境变量按钮的IP (#2734)
Co-authored-by: zymouse <zymouse@pixmoving.net>
2025-02-24 03:42:40 +08:00
wonfen
52627575ff feat: Enhance configuration validation and error handling
- Improve config validation process with detailed logging and error tracking
- Add more robust error handling in profile updates and config patches
- Implement comprehensive config validation using clash core subprocess
2025-02-23 10:53:09 +08:00
Christine.
39973f2d24
feat: auto rename alpha version (#2740) 2025-02-23 02:30:15 +08:00
wonfen
2b01857d15 chore: Disable automatic alpha tag update in workflow 2025-02-20 14:25:58 +08:00
wonfen
2650aa845f refactor: Optimize proxy rendering and layout calculation 2025-02-20 14:21:55 +08:00
wonfen
8400a61bf0 refactor: Simplify tray icon event handling across platforms 2025-02-20 07:03:28 +08:00
wonfen
763b6b9003 chore: Update Node.js version and remove updater file generation 2025-02-20 02:55:47 +08:00
wonfen
053f414f3c feat: Add system proxy status indicators 2025-02-19 13:56:22 +08:00
wonfen
2defa2cc56 refactor: Simplify log data management and improve search functionality 2025-02-19 13:06:15 +08:00
wonfen
bb1dbfcfc3 fix: connections page traffic calculation 2025-02-19 02:24:21 +08:00
Tunglies
1378068a30
rm dead code (#2718)
* rm: verge service takes full control of mihomo process. no more required.

* rm: dead code
2025-02-19 01:13:52 +08:00
wonfen
5d9dce7d10 style: tweak 2025-02-18 11:40:41 +08:00
wonfen
acb66a3012 feat: Add persistent column width settings for connection table & process filtering 2025-02-18 11:04:22 +08:00
wonfen
054f902cc6 refactor: Remove unused routing select component from settings page 2025-02-18 09:04:23 +08:00
wonfen
4333153a59 feat: Improve letter item hover interaction with debounce mechanism 2025-02-18 09:00:03 +08:00
wonfen
19e623d7c2 feat: Add pause/resume functionality for connection tracking 2025-02-18 08:14:09 +08:00
wonfen
2dd646537e fix: resolve deprecated warnings in console 2025-02-18 07:10:28 +08:00
wonfen
1ece079978 perf: Improve proxy list interaction and UI responsiveness 2025-02-18 05:54:16 +08:00
wonfen
0d8f779634 feat: Enhance alphabet selector with dynamic tooltip and scrolling 2025-02-18 01:55:44 +08:00
wonfen
a7ffc9fc38 refactor: Improve proxy data update mechanism with optimistic UI and error handling 2025-02-18 00:37:55 +08:00
wonfen
932b29e66f fix: Refine TypeScript types for proxy groups component 2025-02-17 16:27:06 +08:00
wonfen
6be7a3b94c feat: Enhance proxy groups with Initials navigation and performance optimizations 2025-02-17 16:07:46 +08:00
wonfen
8e8dd1ec03 feat: Optimize tray speed rate rendering and update logic 2025-02-17 15:08:19 +08:00
wonfen
772f3268ce feat: Improve Virtuoso list rendering for proxy groups 2025-02-17 14:30:21 +08:00
wonfen
a179591ac2 feat: Add persistent scroll position for proxy groups 2025-02-17 14:24:33 +08:00
wonfen
d071e5971f fix: alpha build win webview pack rename issue 2025-02-17 12:06:57 +08:00
wonfen
a9032f5f20 chore: Update updater artifacts configuration 2025-02-17 11:22:14 +08:00
Akioe Yu
0190702616 fix: check script error (#2453)
(cherry picked from commit 97bde64fd6516019a190d52f05af54ade623d57c)
2025-02-17 03:10:19 +08:00
wonfen
c35bf38420 chore: Add macOS-specific test for format_bytes_speed function 2025-02-17 03:10:03 +08:00
wonfen
89d20e564a Revert "perf: Improve kernel management logic & add more dev mode logs"
This reverts commit 18c7ed1ccc15b98e4873a276ac75e27276ab9d65.
2025-02-15 05:51:46 +08:00
Christine.
3c24ff3afc
add: i18n text for lightweight mode (#2692) 2025-02-13 14:27:12 +08:00
Tunglies
daf0398750
fix: build front cannot find IvergeConfig.enable_lite_mode and macos port switching causes crash (#2691)
* fix: macos switch protocol port or enable protocol port causes crash

* fix: build time front cannot find IVergeConfig attribute enable_lite_mode
2025-02-12 18:14:13 -08:00
wonfen
6b14c2b763 feat: add lightweight mode 2025-02-13 02:18:17 +08:00
wonfen
5bf2f9b8ed fix(macos): add missing required dependencies 2025-02-12 15:06:42 +08:00
wonfen
10a2655288 fix: remove unused imports to resolve compile warnings 2025-02-12 14:35:49 +08:00
wonfen
ac07397818 refactor: improve hotkey management, logging, and error handling; fix tray freeze and hotkey failure on silent startup 2025-02-12 14:23:42 +08:00
wonfen
30d061d00f fix(tray): resolve blank icon issue on Windows and optimize creation logic 2025-02-12 13:56:33 +08:00
Christine.
360d8a5143
fix: use remoteDestination replace DestinationIP in connection page, #2668 (#2679)
* fix: use remoteDestination replace DestinationIP  in connection page, #2668

* add: missing i18n text

* fix: display the target address details in connection page
2025-02-11 14:52:27 +08:00
wonfen
70e0a5adc8 refactor: Improve tray icon and event handling across platforms & unify click behavior 2025-02-11 14:48:31 +08:00
wonfen
ef52f81494 fix: app crash without a default global_hotkey vaule 2025-02-11 01:50:48 +08:00
wonfen
e5c1de3ad3 fix: deprecated CLI warnings 2025-02-11 01:05:51 +08:00
wonfen
576fd700ae feat: Add independent alpha update channel 2025-02-11 00:53:44 +08:00
wonfen
476df65a1b fix: try to fix linux CI updater problem 2025-02-11 00:53:44 +08:00
Christine.
bd0a4863a8
add: i18n text (#2675) 2025-02-10 00:29:43 -08:00
wonfen
d25fbc05e2 perf: Optimize kernel shutdown speed & logic 2025-02-10 13:18:00 +08:00
wonfen
b8a0b6f1f4 fix: crash caused by global_hotkey 2025-02-10 12:39:07 +08:00
wonfen
18c7ed1ccc perf: Improve kernel management logic & add more dev mode logs 2025-02-09 14:19:15 +08:00
Tunglies
b14db06955
perf: imporve clash mode switching performance on the main window (#2667) 2025-02-09 07:45:46 +08:00
Tunglies
215dcee3f1
feat: option to enable global hotkey (#2665) 2025-02-09 07:45:22 +08:00
Tunglies
37e5c22a5a
fix: duplicate checked tray menu when profile name are same (#2660) 2025-02-08 09:36:04 +08:00
wonfen
bb0b6c3f77 feat: Optimize UI layout and page hierarchy 2025-02-07 09:13:30 +08:00
wonfen
a37df46ce7 perf: optimize node latency refresh rate for faster updates 2025-02-06 07:58:42 +08:00
wonfen
73fbec2514 chore: update deps 2025-02-05 14:19:43 +08:00
Tunglies
f66fa08b2c
Feature: Switch Proxy Profile from Tray Menu (#2644) 2025-02-05 08:52:47 +08:00
wonfen
bae606bc9d fix: restore hotkey functionality after silent startup 2025-02-02 11:37:10 +08:00
wonfen
1a2d5e988a feat: allow users to customize enhanced-mode and fakeip-range in tun mode by wonfen 2025-02-02 05:12:16 +08:00
wonfen
d20bd62b90 style: refine tray speed display 2025-02-02 03:43:15 +08:00
wonfen
204bf43b9a fix: windows rounded corners 2025-01-19 09:47:43 +08:00
wonfen
3ea0d20e2c add donation 2025-01-18 16:08:24 +08:00
wonfen
6d527a1cdb release 2.0.3 2025-01-16 03:30:07 +08:00
白铭骢 (Mingcong Bai)
9c1ece754e
fix(locales): clean up typesetting (#2539)
Following localisation guidelines from 《大陆简中自由软件本地化工作指南》
1.5.4 版 (Simplified Chinese - Mainland China FOSS Localization
Guidelines, version 1.5.4).

Link: https://repo.aosc.io/aosc-l10n/zh_CN_l10n_1.5.4.pdf
2025-01-14 13:00:30 +08:00
huzibaca
9070260d41
chore: update 2025-01-14 12:56:08 +08:00
huzibaca
cd8df52aad
revert: update deps 2025-01-14 12:41:52 +08:00
huzibaca
fa86efcdfb
chore: avoid duplicate updates when tray rate is off 2025-01-14 11:48:43 +08:00
huzibaca
1a61fab79a
feat: maoos tray speed can be closed 2025-01-13 20:48:25 +08:00
huzibaca
41a27641df
fix: fix: try to fix the language pack issue(2) 2025-01-13 17:09:38 +08:00
huzibaca
a39696151d
fix: windows tray icon color not updated 2025-01-13 13:49:56 +08:00
huzibaca
4a4ca5c409
chore: update husky/pre-commit 2025-01-13 13:03:46 +08:00
huzibaca
5bff7ea469
fix: tray tooltip not updating 2025-01-13 13:01:12 +08:00
huzibaca
f2cc116ff9
chore: update 2025-01-13 12:41:07 +08:00
huzibaca
80a18c9172
chore: update deps 2025-01-12 23:10:15 +08:00
huzibaca
a56732e0a3
fix: try to fix the language pack issue 2025-01-12 22:22:06 +08:00
huzibaca
9655f7712b
Merge branch 'languagefixes' into dev
# Conflicts:
#	src-tauri/Cargo.lock
#	src-tauri/Cargo.toml
#	src-tauri/src/core/tray/mod.rs
2025-01-11 15:07:30 +08:00
huzibaca
13b63b5d96
fix: fixes #2502 2025-01-11 12:55:20 +08:00
lucidhz
c5989d2735
fix: put_configs response add detail error message (#2492)
感谢pr
2025-01-05 01:27:12 -08:00
huzibaca
fb4032d6ce
fix: modify the external control access key, the tray rate display is abnormal 2025-01-02 15:27:28 +08:00
huzibaca
a29c2d4b14
chore: update deps 2025-01-02 15:02:07 +08:00
huzibaca
aa7e911c63
chore: update 2025-01-01 08:25:31 +08:00
huzibaca
eeff4d41f4
feat: the tray displays the shortcut keys that have been set 2025-01-01 08:14:15 +08:00
huzibaca
086f023ebc
chore: update 2024-12-31 11:11:29 +08:00
huzibaca
b70336c026
fix: unused code 2024-12-31 08:08:52 +08:00
huzibaca
7d84279370
fix: syntax issues 2024-12-31 04:50:12 +08:00
huzibaca
1b2f1b6106
Merge branch 'feat-macos-spped-rate-icon' into dev 2024-12-31 04:43:54 +08:00
huzibaca
fb41c915cc
feat: macos system tray addition rate display 2024-12-31 04:42:55 +08:00
blagodaren
bab291a60b fix: small refactor 2024-12-28 13:57:30 +03:00
blagodaren
8461046a4f fix: add more lang and lang fix for tray 2024-12-28 10:05:30 +03:00
blagodaren
fc925ea032 fix: add system language sup 2024-12-28 08:12:46 +03:00
huzibaca
542baf9d69
fix: fixes #2460 2024-12-28 06:05:09 +08:00
huzibaca
3f02859203
chore:add macos entitlements.list 2024-12-27 04:38:34 +08:00
huzibaca
af97bd15a9
chore: update 2024-12-27 02:42:35 +08:00
huzibaca
2c081e5a04
chore: secret is empty and no parameters are passed 2024-12-25 02:15:06 +08:00
huzibaca
2d2521e434
chore: update 2024-12-24 06:03:23 +08:00
huzibaca
d9291d4f79
refactor: when updating the tray, the logic is split to improve performance. 2024-12-24 04:52:14 +08:00
huzibaca
0669f7a10b
chore: after saving the configuration file, restart the core 2024-12-24 02:22:46 +08:00
huzibaca
f0d953ff59
chore: update default_bypass
1. add 172.29.0.0/16
2024-12-23 06:06:46 +08:00
huzibaca
4f6ca40811
fix: turn off window shadow fixer, fixes #2425 2024-12-23 04:36:41 +08:00
huzibaca
47848099be
chore: update 2024-12-15 01:14:16 +08:00
huzibaca
f839d3bc88
fix: fixer #2346 2024-12-14 17:30:58 +08:00
huzibaca
800f994b10
chore: update deps 2024-12-14 16:21:16 +08:00
Langning Chen
b149084e39
Fix l10n issues (#2315)
* Complete the missing translation

* Match the Chinese language file order with others
2024-12-11 01:02:21 +08:00
huzibaca
e6580f2f05
chorea: update deps 2024-12-10 22:36:13 +08:00
huzibaca
c5c840d378
feat: improve system bypass settings 2024-12-10 14:37:11 +08:00
huzibaca
2e0be4b426
chore: enable default proxy bypass and hide custom bypass settings 2024-12-10 13:59:13 +08:00
huzibaca
460d72f392
chore: update deps(tauri-plugin-autostart) 2024-12-08 22:10:15 +08:00
huzibaca
aa18c4870d
chore: deeplink uses the latest API 2024-12-08 15:54:46 +08:00
huzibaca
61533646ad
chore: update deps 2024-12-08 09:58:59 +08:00
huzibaca
b42d13f573
fix: when the window is hidden, close the websocket connection, reduce the risk of memory leaks 2024-12-07 16:47:41 +08:00
wonfen
0e3b631118 chore: change fakeip range 2024-12-06 15:34:41 +08:00
huzibaca
38745d4513
chore:set the sysproxy_rs version to a fixed version 2024-12-06 15:03:04 +08:00
huzibaca
d22b37c7bf
fix: extension script dns is overwritten fixer #2235 2024-12-06 12:35:09 +08:00
Myles Mo
d233a84362
feat: add nullshell env variable (#2285) 2024-12-04 19:01:13 +08:00
huzibaca
589324b582
fix: shift hotkey conversion fixer #2278 2024-12-04 13:19:56 +08:00
huzibaca
c11efcb9be
chore: update version 2024-12-04 00:30:46 +08:00
huzibaca
6197249377
fix: set fontLigatures to false fixer #2267 2024-12-04 00:28:33 +08:00
lollapalooza
c71e18e97e
feat: add bypass check feature (#2272) 2024-12-03 16:18:07 +08:00
Christine.
f400f900e6
fix: #2126 (#2233) 2024-12-03 16:03:21 +08:00
wonfen
ae5b2cfb79 release 2.0.2 2024-12-01 11:00:09 +08:00
huzibaca
0bb8786ef2
fix: resource file initialization failed 2024-12-01 09:38:29 +08:00
huzibaca
f7d5be774d
fix: resolve service permission failed(2) 2024-11-30 10:45:53 +08:00
huzibaca
c0a0b82fa6
chore: update 2024-11-30 10:38:15 +08:00
huzibaca
277ef51375
fix: resolve service permission failed 2024-11-30 10:29:16 +08:00
huzibaca
67b1cf9e1b
feat: user uploaded icons can use templates, provided they are monochrome icons fixer #2213 2024-11-30 09:49:43 +08:00
huzibaca
4f797eb7b8
chore: update 2024-11-30 07:04:09 +08:00
huzibaca
29ccabc054
refactor: update_core_config, simplify logic and delete invalid notifications 2024-11-30 05:43:59 +08:00
yyhhyy
857574cbc1
🐛 fix: Dynamically set IPv6 DNS configuration based on existing config (#2198)
thanks
2024-11-30 00:55:15 +08:00
wonfen
acc97f28b5 chore: change mac tun dns 2024-11-29 11:10:41 +08:00
huzibaca
02e32aec41
chore: update 2024-11-29 03:46:37 +08:00
huzibaca
fe0fdc5603
chore: remove debug code 2024-11-28 14:44:13 +08:00
Yu-Haifeng
66941a18c0
fix: macOS tray icon not changed when use system proxy or tun mode (#2176) 2024-11-28 14:42:05 +08:00
huzibaca
f772f92b88
fix: the deadlock caused by incorrect call of window_state due to document error 2024-11-28 12:54:55 +08:00
huzibaca
d80db8c91e
chore: clean startup registry keys for older versions(2) 2024-11-28 06:40:44 +08:00
huzibaca
a1e67820c7
chore: clean startup registry keys for older versions 2024-11-28 05:34:56 +08:00
wonfen
ebe0cfbb0c chore: set tun default stack 2024-11-28 04:22:13 +08:00
huzibaca
59c52199e3
chore: update 2024-11-27 14:27:16 +08:00
wonfen
148def4c0f release 2.0.2 2024-11-27 12:41:51 +08:00
huzibaca
3177ea0f4d
chore: update 2024-11-27 11:34:52 +08:00
huzibaca
7d65ce847a
fix: when tun is closed, the full profile configuration is not restored 2024-11-27 10:35:42 +08:00
huzibaca
2ac27fcfa7
refactor: backup implementation
1. timeouts can be set for different operations
2. performance optimization
2024-11-27 07:34:34 +08:00
huzibaca
373c8ec0e5
chore: update 2024-11-27 07:09:03 +08:00
huzibaca
7df5ca1912
fix: linux build failed 2024-11-27 05:54:48 +08:00
huzibaca
d8dc60ff0d
fix: fixer #2158 2024-11-27 05:47:08 +08:00
huzibaca
56deafee61
chore: update version 2024-11-27 05:09:46 +08:00
huzibaca
4c29850e1c
fix: build failed. #2156 2024-11-27 05:07:02 +08:00
huzibaca
90bf5e0782
chore: timeout adjusted to 15 seconds 2024-11-26 15:09:58 +08:00
huzibaca
c2d07ce4c1
fix: add scroll bar and scroll to top button to the test page . fixer #2118 2024-11-26 14:44:43 +08:00
wonfen
564d81fd31 style: adjust 2024-11-26 12:11:20 +08:00
huzibaca
f8b7b82ba9
chore: remove window title 2024-11-26 10:11:55 +08:00
huzibaca
71cb2a97c0
fix: kernel-caused silent mode failure to start windows 2024-11-26 09:00:01 +08:00
huzibaca
1cc6472002
chore: update 2024-11-26 05:46:34 +08:00
huzibaca
9b2c80494d
refactor: Implement using third-party libraries 2024-11-26 04:51:19 +08:00
huzibaca
4ccc2a2961
chore: update 2024-11-26 03:30:15 +08:00
huzibaca
17a8dfb58a
fix: file drag and drop import cannot be used 2024-11-26 03:07:25 +08:00
wonfen
184b588f20 style: Increased light color contrast to prevent blurring on some displays 2024-11-26 01:05:30 +08:00
huzibaca
87c4ebe0da
chore: replace mui grid with mui grid2 2024-11-25 12:51:13 +08:00
wonfen
18a0a15e16 update change log 2024-11-25 06:46:29 +08:00
huzibaca
c8fd62f388
fix: Try to fix vcruntime duplicate installation 2024-11-25 06:33:47 +08:00
huzibaca
97f03de295
fix: update failed(updater.install called before updater.download) 2024-11-25 05:27:26 +08:00
huzibaca
2c0a5666fc
fix: when restoring webdav, the current username, password and url are not preserved 2024-11-25 03:41:35 +08:00
huzibaca
5c3f0d5b60
fix: password failed due to character escaping 2024-11-25 02:48:56 +08:00
huzibaca
746763ed34
fix: remove comments from svg icons to prevent front-end crashes. fixer #2093 2024-11-25 01:58:02 +08:00
wonfen
e3800a575f fix: fakeip dns 2024-11-25 01:50:30 +08:00
huzibaca
c78c936762
chore: replace mui grid with mui grid2 2024-11-25 01:34:18 +08:00
huzibaca
ea5d6f9c46
fix: tun allocates the wrong private network segment, causing conflicts. 2024-11-25 01:06:51 +08:00
wonfen
97f8022276 release 2.0.1 2024-11-24 09:00:20 +08:00
huzibaca
d718bd9141
fix: If an older version of the executable exists, delete it(2) 2024-11-24 08:25:46 +08:00
huzibaca
8ddd48eda1
feat: try to use vscode first, if not found then use system default app 2024-11-24 08:20:00 +08:00
huzibaca
3e20404959
fix: If an older version of the executable exists, delete it 2024-11-24 01:24:51 +08:00
huzibaca
dde7ead751
Merge branch 'fix-migrate-tauri2-errors'
* fix-migrate-tauri2-errors: (288 commits)

# Conflicts:
#	.github/ISSUE_TEMPLATE/bug_report.yml
2024-11-24 00:14:46 +08:00
huzibaca
be719680b0
fix: windows cannot open yaml file 2024-11-23 19:46:53 +08:00
wonfen
d6f5a79ac9 fix: release workflow 2024-11-23 12:36:16 +08:00
wonfen
a3140f48b4 release 2.0.0 2024-11-23 11:34:17 +08:00
huzibaca
335883f9f0
chore: set the request timeout to 3 seconds 2024-11-23 06:50:28 +08:00
huzibaca
f2b1b88242
chore: remove notes 2024-11-23 06:47:43 +08:00
huzibaca
4163ee484c
chore: update 2024-11-23 06:42:05 +08:00
huzibaca
a14c3f81b0
fix: restore the window state first, then set the window size 2024-11-23 06:39:25 +08:00
huzibaca
f08d2c998d
chore: update 2024-11-23 06:22:46 +08:00
huzibaca
1b0cf938d9
chore: add debug codes & logs(2) 2024-11-23 06:20:13 +08:00
huzibaca
03d714f2d4
chore: add debug codes & logs 2024-11-23 05:43:13 +08:00
huzibaca
4feef53cb0
chore: set the request timeout to 5 seconds 2024-11-22 14:15:31 +08:00
huzibaca
397e6a9d57
feat: added scroll top button for agent and rule pages 2024-11-22 09:22:44 +08:00
huzibaca
9df2ceba84
chore: remove debug code 2024-11-22 09:08:25 +08:00
huzibaca
1b65dc7256
fix: macOS DNS restore failed 2024-11-22 03:09:39 +08:00
huzibaca
4ffadab4c5
chore: hide DNS cache file 2024-11-22 02:42:55 +08:00
huzibaca
7ed90ff7f8
fix: husky - install command is DEPRECATED 2024-11-21 12:06:52 +08:00
huzibaca
ec79126b4a
chore: remove unused code 2024-11-21 11:44:19 +08:00
huzibaca
ee13bb559e
chore: remove unused code 2024-11-21 11:24:19 +08:00
huzibaca
ffbc0cdff4
fix: password should not be trimmed 2024-11-21 11:14:40 +08:00
huzibaca
801b79b728
chore: remove unused code 2024-11-21 11:13:11 +08:00
huzibaca
cd1d719a92
fix: serde::json passing IVerge to the front end without deserialization 2024-11-21 06:01:56 +08:00
huzibaca
cf3848f15d
chore: update 2024-11-20 07:37:30 +08:00
huzibaca
df5d43283b
chore: remove notes 2024-11-20 07:37:03 +08:00
huzibaca
91f0f9f65e
feat: encryption configuration properties 2024-11-20 07:27:42 +08:00
huzibaca
708e5d1941
fix: auto launch does not worki 2024-11-20 03:52:19 +08:00
huzibaca
8773117e50
chore: update 2024-11-20 01:15:03 +08:00
huzibaca
8840e63c1c
fix: exit_app does not work 2024-11-20 01:04:55 +08:00
huzibaca
4e2d9d6acd
fix: windows cannot save window state(2) 2024-11-20 00:27:53 +08:00
huzibaca
94259f9515
fix: windows cannot save window state 2024-11-19 23:32:32 +08:00
huzibaca
5b0ff01cbf
chore: update deps 2024-11-19 13:35:57 +08:00
huzibaca
3ae1109a31
chore: format 2024-11-19 13:28:17 +08:00
wonfen
f50b9655ae feat: improve set dns logic 2024-11-19 11:38:23 +08:00
huzibaca
081daee53f
chore: update web:build comman, use tsc --noEmit 2024-11-19 04:42:37 +08:00
huzibaca
95123aceb5
feat: add logger highlighting, support regular and case matching 2024-11-19 04:10:10 +08:00
huzibaca
2a7b22c96f
feat: add logger highlighting 2024-11-19 03:29:44 +08:00
huzibaca
c1b15490c1
fix: log pause button not working 2024-11-19 02:56:58 +08:00
huzibaca
f8cb84a706
feat: logger support all level filters 2024-11-19 01:40:45 +08:00
huzibaca
063f9034a1
chore: update deps 2024-11-18 23:51:43 +08:00
huzibaca
9c1b2ff89c
chore: remove unused code 2024-11-18 23:48:02 +08:00
Christine.
44c05d9fd9
fix: field error, #2044 (#2045) 2024-11-18 07:34:57 -08:00
huzibaca
dd3c149e98
refactor: remove useSWRSubscription and use useEffect 2024-11-18 16:41:17 +08:00
huzibaca
0623fe4dc3
chore: remove unused code 2024-11-18 08:16:31 +08:00
huzibaca
2746ff68c8
feat: Log level status is saved to local storage 2024-11-18 08:14:21 +08:00
huzibaca
62eb070c1b
refactor: use zustand store, rewrite log clearing logic 2024-11-18 06:48:23 +08:00
huzibaca
3b8147b6ad
chore: typo warn -> warning 2024-11-18 06:01:51 +08:00
huzibaca
221b732472
refactor: logger fetch logic 2024-11-18 05:58:06 +08:00
huzibaca
132641f269
fix: the CJS build of Vite's Node API is deprecated, part 2 2024-11-18 01:21:00 +08:00
huzibaca
d8cf585fc5
fix: the CJS build of Vite's Node API is deprecated 2024-11-18 01:07:16 +08:00
Christine.
7f0d9952aa
chore: Replace test URL to support iPv4&iPv6 (#2033) 2024-11-18 00:20:21 +08:00
huzibaca
415b4879f1
fix: webdav list interface compatibility issue 2024-11-17 23:57:28 +08:00
huzibaca
7e5d6ef9b6
fix: webdav refreshes data and clears the original data when an error occurs. 2024-11-17 23:50:34 +08:00
huzibaca
ff297957c7
chore: update 2024-11-17 01:01:36 +08:00
huzibaca
7489f5e62d
chore: update 2024-11-17 00:46:35 +08:00
huzibaca
3575c16326
fix: fixes #1968 2024-11-16 23:09:10 +08:00
wonfen
04f4f5f713 release rc.7 2024-11-16 10:15:50 +08:00
huzibaca
eb78af7c77
chore: remove debug code 2024-11-16 07:35:34 +08:00
huzibaca
114d5ab541
fix: fixes #1940 2024-11-16 06:08:49 +08:00
huzibaca
f13140e39e
fix: When the shortcut key closes the window, the window is minimized 2024-11-16 04:46:20 +08:00
huzibaca
97717c648e
fix: windows arm64 vsruntime is not installed 2024-11-16 03:12:11 +08:00
huzibaca
ec6705eaf4
Merge branch 'fix-tray-menu-flash-on-windows' into fix-migrate-tauri2-errors
* fix-tray-menu-flash-on-windows:
  chore: update
2024-11-16 02:54:24 +08:00
Chenx Dust
1e11eff811
feat: support mptcp and smux display (#1995)
Corresponding pull request in mihomo: https://github.com/MetaCubeX/mihomo/pull/1646
2024-11-16 01:35:22 +08:00
huzibaca
13fb8c5d7d
chore: update 2024-11-15 17:19:14 +08:00
huzibaca
e87e06dd37
chore: unified code format 2024-11-14 03:21:18 +08:00
huzibaca
b9bb79b4dc
fix: call parameter error 2024-11-14 03:16:32 +08:00
wonfen
d0f907f349 chore: update info & i18n 2024-11-14 03:01:37 +08:00
huzibaca
867c83b84c
chore: update dep(tauri-bubild) 2024-11-13 21:49:53 +08:00
huzibaca
632d389411
chore: update deps 2024-11-13 21:39:55 +08:00
huzibaca
b4df1b6e42
feat: add refresh button 2024-11-13 00:53:52 +08:00
huzibaca
176620e3bb
fix: InputProps is deprecated 2024-11-13 00:30:30 +08:00
huzibaca
c37f22dc65
fix: mui grid has been deprecated 2024-11-13 00:21:22 +08:00
huzibaca
9d9cf27460
fix: application restart, window status not saved 2024-11-12 22:49:08 +08:00
huzibaca
6e8def3ef7
fix: syntax issues caused by upgrading mui5 2024-11-12 20:05:28 +08:00
huzibaca
ec0d872f11
chore: update 2024-11-12 19:44:57 +08:00
huzibaca
9e4a8708e7
fix: import error caused by dependency upgrade 2024-11-12 19:35:56 +08:00
huzibaca
a681fdeee1
fix: undefined error 2024-11-12 19:34:53 +08:00
huzibaca
8763a76475
chore: update deps 2024-11-12 19:06:04 +08:00
wonfen
4306fba997 release rc.6 2024-11-12 03:49:21 +08:00
huzibaca
3759239dac
feat: add webdav backup 2024-11-12 02:55:02 +08:00
huzibaca
4ec0b1d6e4
chore: update 2024-11-09 12:13:50 +08:00
huzibaca
6271726f07
Merge branch 'feat-webdav-backup' of ssh://github.com/clash-verge-rev/clash-verge-rev into feat-webdav-backup
# Conflicts:
#	src/locales/fa.json
#	src/locales/ru.json
#	src/locales/zh.json
2024-11-09 11:54:33 +08:00
wonfen
26dd097962 update: Readme 2024-11-09 09:00:53 +08:00
wonfen
e5740579f4 fix: translation 2024-11-09 08:59:30 +08:00
huzibaca
ca97e3a3e6
chore: update 2024-11-09 06:56:58 +08:00
huzibaca
d3f6822080
chore: update 2024-11-09 05:50:51 +08:00
huzibaca
9d9a6dfddb
chore: update 2024-11-08 23:42:00 +08:00
huzibaca
c3e24d7b96
chore: update 2024-11-08 21:46:15 +08:00
huzibaca
20d163cf3a
Merge branch 'feat-add-unified-delay' into fix-migrate-tauri2-errors 2024-11-06 13:56:36 +08:00
huzibaca
cf90f3abc9
chore: update 2024-11-06 13:52:36 +08:00
huzibaca
8871660f0e
chore: update 2024-11-06 10:07:02 +08:00
huzibaca
97a030c22e
fix: @use rules must be written before any other rules. 2024-11-06 09:48:31 +08:00
huzibaca
8a6ce0f0db
fix: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. 2024-11-06 09:46:17 +08:00
huzibaca
285b6b9287
chore: update 2024-11-05 21:40:02 +08:00
huzibaca
3515cc8e63
chore: update 2024-11-05 21:35:17 +08:00
huzibaca
b0132c9718
chore: update 2024-11-05 18:38:50 +08:00
huzibaca
ef84c31761
chore: update 2024-11-05 18:30:28 +08:00
huzibaca
4953d4b4d0
chore: add tooltip 2024-11-05 17:39:59 +08:00
huzibaca
2833718c90
feat: add unified delay 2024-11-05 16:24:58 +08:00
huzibaca
ab7775e1ef
fix: wrong window state save point 2024-11-04 09:53:40 +08:00
huzibaca
a5c4562f59
chore: update deps 2024-11-02 10:25:38 +08:00
huzibaca
00bd5b0e1e
chore: update 2024-11-02 07:27:08 +08:00
huzibaca
b66c07bd96
chore: update (+1 squashed commit)
Squashed commits:
[78899ef] fix: bbr2 not working in windows 11(24H2)
2024-11-02 07:10:47 +08:00
huzibaca
d8d0a59371
chore: update 2024-11-01 06:03:01 +08:00
The1111mp
953153ea1a
chore: added support for compiling linux arm architecture (#1945)
* chore: added support for compiling linux arm architecture

Signed-off-by: The1111mp <The1111mp@outlook.com>

* chore: remove debug code

Signed-off-by: The1111mp <The1111mp@outlook.com>

---------

Signed-off-by: The1111mp <The1111mp@outlook.com>
2024-10-31 17:20:16 +08:00
downer
fc03ce1247
fix: fix TUN icon is overwritten by system proxy icon (#1961)
Co-authored-by: 周晓亮 <zhouxl@jiyitech.com>
2024-10-31 09:07:21 +08:00
huzibaca
08bf70681c
feat: use tauri_plugin_window_state 2024-10-30 18:52:53 +08:00
huzibaca
00bc6a6301
revert: feat: use tauri-plugin-persisted-scope 2024-10-30 18:28:55 +08:00
huzibaca
c5916cf5ec
feat: use tauri-plugin-persisted-scope 2024-10-30 16:37:47 +08:00
huzibaca
4213a5fad1
chore: window hide replaces window minimize 2024-10-30 13:51:58 +08:00
wonfen
17fc9cf0eb release: rc.5 2024-10-30 13:08:37 +08:00
wonfen
eb1a1b3786 chore: update bug report template 2024-10-30 12:59:19 +08:00
huzibaca
dce72a16f0
chore: remove useless hooks
the window is not closed, it is minimized, so the position still exists
2024-10-30 10:06:54 +08:00
huzibaca
7550c2321c
fix: linux file permissions problem
check-config configuration file moved from temp_dir to home_dir, resolved
2024-10-30 09:08:44 +08:00
huzibaca
f0c4360210
chore: restore linux custom close button 2024-10-30 06:30:49 +08:00
huzibaca
d10323701a
fix: performance issues caused by closing windows on mac 2024-10-30 06:27:29 +08:00
huzibaca
94c437c3e3
chore: update 2024-10-29 10:15:07 +08:00
huzibaca
202fb19ab1
chore: update 2024-10-29 10:13:53 +08:00
huzibaca
2bb3498602
chore: disable websocket logging by default to reduce performance consumption. 2024-10-29 09:19:21 +08:00
huzibaca
9d476d7add
fix incorrect usage of useCustomTheme 2024-10-29 09:07:08 +08:00
huzibaca
014829e69a
chore: optimised the logic of dns processing 2024-10-28 13:09:55 +08:00
huzibaca
a127cd6444
fix: dns not restored when exiting the app 2024-10-28 00:24:57 +08:00
Christine.
486ffbdc08
add more contribution details for Windows (#1939)
* doc: add more building details

Some friends said the build failed.

* chore: replace test url

replace default delay check URL, some user say that the delay numbers seen in CVR are very different from those in other software, and this default test result is not a valid reference.
2024-10-27 13:00:47 +08:00
huzibaca
526c5bdd91
fix: unused variable 2024-10-27 10:19:42 +08:00
huzibaca
db11651f85
chore: update 2024-10-27 06:47:16 +08:00
huzibaca
4ce7d9f7a9
feat: macos service installation query, can't avoid it, add service run check, if installation not confirmed, exit automatically after 10 seconds 2024-10-27 06:32:25 +08:00
huzibaca
df3c296850
Revert "chore: update resource"
This reverts commit e3c52781f34b9bb921ac590ff4d672d1f1d5ec06.
2024-10-27 05:10:26 +08:00
huzibaca
5ef9220175
chore: update 2024-10-27 05:06:42 +08:00
huzibaca
e3c52781f3
chore: update resource 2024-10-27 04:46:24 +08:00
huzibaca
1cb1946497
chore: update deps 2024-10-27 01:24:13 +08:00
huzibaca
9e486e6836
chore: update 2024-10-26 19:23:49 +08:00
wonfen
e5dc4a55b0 release rc.4 2024-10-26 12:05:09 +08:00
huzibaca
76d04805a4
fix:public DNS not set in macos, tun+fake-ip 2024-10-26 08:55:00 +08:00
huzibaca
652a20c523
chore: update 2024-10-26 01:44:06 +08:00
huzibaca
6c2af1bef5
chore: update 2024-10-25 21:25:06 +08:00
huzibaca
ba2aa9d6e7
chore: update 2024-10-25 14:13:30 +08:00
huzibaca
a1c72fe780
chore: update 2024-10-25 14:12:27 +08:00
huzibaca
197f9fd964
fix: the tray icon does not display the correct colours on macos. 2024-10-25 13:58:22 +08:00
wonfen
fc2c10bb3f chore: add mac sun ico 2024-10-25 12:27:22 +08:00
wonfen
d7dd797494 release 2.0rc3 2024-10-24 12:52:20 +08:00
huzibaca
4f954657a1
chore: update 2024-10-24 11:14:18 +08:00
huzibaca
3eddcafeb6
Revert "chore: global mode doesn't show proxy groups, use placeholder images instead"
This reverts commit 3df4718709c49084a635ab190892d14b1744574b.
2024-10-24 07:44:21 +08:00
huzibaca
3df4718709
chore: global mode doesn't show proxy groups, use placeholder images instead 2024-10-24 07:30:30 +08:00
huzibaca
b5fddf8fa1
chore: update 2024-10-24 06:58:21 +08:00
huzibaca
fdc8a83f25
fix: proxy view display error 2024-10-24 06:54:27 +08:00
huzibaca
e79121e46a
refactor: the logic of profiles activation 2024-10-24 05:02:47 +08:00
huzibaca
aab71e55de
fix: restart app failure 2024-10-24 02:54:57 +08:00
huzibaca
caf4ee6863
fix: tun mode switch is not effective 2024-10-24 02:16:28 +08:00
huzibaca
30b0c45539
refactor: IRuntime::patch_config() 2024-10-23 10:34:14 +08:00
huzibaca
2ab75db9c9
chore: update 2024-10-23 09:26:14 +08:00
huzibaca
f9009de894
chore: update 2024-10-23 05:48:01 +08:00
huzibaca
da8ed1ac5a
fix: failed to install service on macos 2024-10-23 04:46:47 +08:00
huzibaca
afde7e4a44
feat: add windows uninstall script 2024-10-22 04:46:08 +08:00
huzibaca
3e94adb4b1
feat: add linux uninstall script 2024-10-22 03:17:04 +08:00
huzibaca
5c577e533f
fix: debian executable file has no permissions 2024-10-22 02:37:36 +08:00
huzibaca
c64b9d5a2b
chore: update 2024-10-22 01:34:26 +08:00
huzibaca
545ea16ae8
fix: change the window close to minimize the window.
there is currently an error in the tauri library.
2024-10-21 23:16:45 +08:00
huzibaca
bf245a4ee1
fix: pac url error ,fixes #1889 2024-10-21 22:52:10 +08:00
wonfen
b28fc26ae6 chore: update bug_report template 2024-10-21 11:30:07 +08:00
huzibaca
750dfdb3a8
Merge branch 'fix-migrate-tauri2-errors' of ssh://github.com/clash-verge-rev/clash-verge-rev into fix-migrate-tauri2-errors
* 'fix-migrate-tauri2-errors' of ssh://github.com/clash-verge-rev/clash-verge-rev:
  chore: update to 2.0 rc2
2024-10-21 04:35:42 +08:00
huzibaca
5b93c2b907
chore: update 2024-10-21 04:35:21 +08:00
wonfen
bbd72a79cb chore: update to 2.0 rc2 2024-10-21 03:15:02 +08:00
huzibaca
babf5d840c
chore: replace sudo with pkexec execution 2024-10-21 02:31:43 +08:00
huzibaca
90091db3b1
chore: update 2024-10-21 02:17:41 +08:00
huzibaca
ef03dc12bb
chore: update 2024-10-21 01:35:28 +08:00
huzibaca
a35014f0b5
chore: update 2024-10-21 01:30:13 +08:00
huzibaca
abb0a049a8
chore: update 2024-10-21 01:12:52 +08:00
huzibaca
3de18e2a86
chore: update 2024-10-21 00:50:43 +08:00
huzibaca
399bbd56ec
chore: update deps 2024-10-21 00:45:06 +08:00
huzibaca
38999d284a
chore: update 2024-10-21 00:34:28 +08:00
huzibaca
b61b63d100
fix: failed to start system proxy with PAC mode 2024-10-20 23:13:23 +08:00
huzibaca
0dc92fbc99
chore: update deps 2024-10-20 22:35:16 +08:00
huzibaca
1cb7cd8859
Merge branch 'fix-linux-errors' into fix-migrate-tauri2-errors
* fix-linux-errors:
  chore: try to fix service not started on linux
2024-10-20 21:57:41 +08:00
huzibaca
199700cf09
fix: mac commad+q global hijack is not released 2024-10-20 06:06:47 +08:00
huzibaca
ee78b7898b
chore: try to fix service not started on linux 2024-10-20 04:48:42 +08:00
huzibaca
a47ded7cf2
chore: update 2024-10-18 22:50:03 +08:00
huzibaca
770f031b8b
fix: try to fix service not started on linux 2024-10-18 07:08:34 +08:00
wonfen
18139c7114 chore: adjust translation 2024-10-17 05:09:00 +08:00
huzibaca
4a64654f49
chore: update deps 2024-10-16 22:49:24 +08:00
huzibaca
377ff279b8
chore: update 2024-10-16 02:55:23 +08:00
huzibaca
d5d39e1c2a
fix: system proxy cannot be closed on mac 2024-10-16 02:52:48 +08:00
huzibaca
f7b1da7557
chore: update 2024-10-16 01:55:22 +08:00
huzibaca
5e8c6c6b23
chore : update version 2024-10-16 01:53:33 +08:00
huzibaca
64634ef07b
chore: t emporarily cancel window closure and change to minimize 2024-10-16 01:53:16 +08:00
huzibaca
7de2474611
Merge branch 'fix-migrate-tauri2-errors' of ssh://github.com/clash-verge-rev/clash-verge-rev into fix-migrate-tauri2-errors 2024-10-15 02:38:57 +08:00
huzibaca
ea2b6a9ad8
fix: path escape issue 2024-10-15 02:35:50 +08:00
wonfen
6ee7be7cae chore: update changelog and texts 2024-10-15 02:32:25 +08:00
huzibaca
12690ed464
chore: remove windows esc shortcut key 2024-10-14 13:45:26 +08:00
huzibaca
90361242ac
chore: update 2024-10-13 03:01:32 +08:00
huzibaca
cd8daa929a
chore: update deps 2024-10-13 02:55:35 +08:00
huzibaca
a07c579497
chore: adjust tun default parameters 2024-10-13 02:42:37 +08:00
huzibaca
e78f619be1
fox: external-controller cors error 2024-10-11 22:01:57 +08:00
huzibaca
5e7ff36e8e
chore: complete field identifier 2024-10-11 14:33:11 +08:00
huzibaca
e7e0caaa41
Merge branch 'main' into fix-migrate-tauri2-errors 2024-10-11 02:56:30 +08:00
Lvc Revincx
00c6e41239
fix: task bar icon misssing under linux wayland (#1816) 2024-10-11 02:52:57 +08:00
huzibaca
c604ae38dd
fix: installation service error 2024-10-11 00:59:34 +08:00
huzibaca
25e25c2285
chore: update 2024-10-10 23:34:55 +08:00
huzibaca
b4180b5b48
chore:update 2024-10-10 18:52:20 +08:00
huzibaca
d14bda7e7a
chore: update 2024-10-10 18:40:39 +08:00
huzibaca
045ddc5ca5
chore: update 2024-10-10 02:21:22 +08:00
huzibaca
3f3fad0db7
feat: Modify startup logic and install services by default 2024-10-10 00:34:36 +08:00
huzibaca
30c77b891d
chore: update 2024-10-09 01:14:03 +08:00
huzibaca
5e126364ed
refactor: core logic 2024-10-08 02:39:17 +08:00
huzibaca
7f2f9588ac
chore: update 2024-10-06 02:03:32 +08:00
huzibaca
e299e246e3
chore: revert 2024-10-06 01:09:59 +08:00
huzibaca
0541a0c69f
refactor: tun mode is turned on and off, does not depend on services, and does not affect other configurations 2024-10-05 22:45:59 +08:00
huzibaca
1178f7c892
refactor: init_log 2024-10-05 12:19:44 +08:00
huzibaca
a3e78bd76d
refactor: get_bypass func 2024-10-05 02:58:41 +08:00
huzibaca
bcf33b779e
chore: update 2024-10-05 00:03:11 +08:00
huzibaca
d0ba506011
chore: update deps 2024-10-04 23:56:50 +08:00
huzibaca
477d1f2aee
feat: add color to log 2024-10-04 22:38:06 +08:00
huzibaca
aa4b1ad8e8
chore: update 2024-10-04 05:37:53 +08:00
huzibaca
6b902a7ad8
chore: update 2024-10-04 05:27:59 +08:00
huzibaca
a626f2ce29
chore: update 2024-10-03 14:31:40 +08:00
huzibaca
2685a02e1a
chore: update 2024-10-03 12:01:06 +08:00
huzibaca
bf1f201d4b
feat: windows uses sysproxy.exe for system proxy 2024-10-03 02:09:22 +08:00
huzibaca
335578dd91
refactor: simplify sysproxy logic
1. close all proxies directly when reset_proxy
2. init_sysproxy and update_sysproxy combined into one
3. optimize lock usage
4 ptimize the thread loop of guard_sysproxy,
2024-10-03 01:31:37 +08:00
huzibaca
3a3fc986c4
chore: replace sysproxy-rs repo 2024-10-02 17:43:14 +08:00
huzibaca
0e1e54aff4
feat: test item, when icon is svg, add svg format check 2024-10-01 20:49:03 +08:00
huzibaca
0b8f24a92e
chore: optimize lock 2024-10-01 00:27:08 +08:00
huzibaca
3cbcd4630c
chore: remove the manual release lock 2024-09-30 23:07:46 +08:00
wonfen
709ab3dd88 chore: add service mode info 2024-09-30 01:04:15 +08:00
huzibaca
b3d93d0761
chore: update 2024-09-28 20:20:40 +08:00
huzibaca
79d1539149
refactor: logic optimization 2024-09-28 12:37:01 +08:00
huzibaca
ba1a7e0fd6
,fix: when updating the verge configuration, notification error 2024-09-27 22:25:23 +08:00
wonfen
30ebfd84cf chore: update bug report template 2024-09-27 14:08:50 +08:00
huzibaca
aef215d810
chore: update 2024-09-27 10:05:31 +08:00
huzibaca
cee872e944
chore: remove compatibility code 2024-09-27 10:04:23 +08:00
huzibaca
c50e8f9de8
refactor: logic optimization 2024-09-27 00:24:05 +08:00
huzibaca
11a8e3465f
chore: update 2024-09-26 19:47:25 +08:00
huzibaca
e8ed7c1e3e
chore: remove compatibility code 2024-09-26 19:47:00 +08:00
huzibaca
5b822d238d
chore: update 2024-09-26 19:23:16 +08:00
huzibaca
053754fea8
chore: update 2024-09-26 12:20:57 +08:00
huzibaca
7a9fd118a3
chore: update 2024-09-25 21:20:36 +08:00
huzibaca
2aa3c8cfe1
chore: update 2024-09-25 21:07:01 +08:00
huzibaca
ec2bf37ad4
Revert "chore: cover panic error"
This reverts commit b8cb48aeada25ae71371ee48a0010f6fa9b68c8c.
2024-09-25 20:22:49 +08:00
huzibaca
fc5c959a55
chore: unified hotkey registration 2024-09-25 15:45:12 +08:00
huzibaca
b8cb48aead
chore: cover panic error 2024-09-25 15:44:05 +08:00
huzibaca
4eccedcd78
fix: the save_indow_size_position method has been triggered twice, at the same time
1. remove windowEvent::destoryed  hook
2024-09-25 13:54:05 +08:00
huzibaca
08b1160d63
chore: remove useless exit codes 2024-09-25 11:47:01 +08:00
huzibaca
3bcd8b8b2c
fix: code lint 2024-09-24 20:11:33 +08:00
huzibaca
4b20b65a22
fix: code lint 2024-09-24 20:09:30 +08:00
huzibaca
4b234a3211
fix: code lint 2024-09-24 20:06:25 +08:00
huzibaca
2ca7310baf
chore: add cross-env dev dependency 2024-09-24 16:35:19 +08:00
huzibaca
5d742a9037
chore: update 2024-09-23 23:57:08 +08:00
huzibaca
a3465d292c
refactor: unify and simplify the call of app_handle(2) 2024-09-23 23:15:51 +08:00
huzibaca
8a3a094414
chore: update 2024-09-23 17:15:28 +08:00
huzibaca
52d5f2c992
chore: update 2024-09-23 16:53:00 +08:00
huzibaca
60e0f972d0
refactor: unify and simplify the call of app_handle 2024-09-23 16:31:58 +08:00
huzibaca
0a9182519d
chore: update 2024-09-22 22:15:36 +08:00
huzibaca
bfded924d7
chore: rename method 2024-09-22 20:29:43 +08:00
huzibaca
c653c458b9
Revert "chore: update"
This reverts commit 4b7ffa146525d035434f3104a82319b6ad527ce9.
2024-09-22 16:46:24 +08:00
huzibaca
4b7ffa1465
chore: update 2024-09-22 15:59:59 +08:00
huzibaca
a5c871e933
chore: update 2024-09-22 15:39:52 +08:00
huzibaca
56983c4d2a
chore: update 2024-09-22 14:08:08 +08:00
huzibaca
e9721ecc4d
Revert "chore: remove useless exit codes and hooks"
This reverts commit 40ff3fd4bf59f52f23904c3150de6ff17974d23f.
2024-09-22 00:41:20 +08:00
huzibaca
84fe9c84a8
fix: remove unused variable 2024-09-22 00:32:40 +08:00
huzibaca
40ff3fd4bf
chore: remove useless exit codes and hooks 2024-09-21 21:05:34 +08:00
huzibaca
e92074e586
chore: try adjusting the triggering of the tray mouse button 2024-09-21 15:38:14 +08:00
huzibaca
424c1f7d8f
chore : update 2024-09-20 18:02:19 +08:00
huzibaca
868707dbde
fix: tray menu text was not aligned 2024-09-20 17:59:24 +08:00
huzibaca
29d54fe589
chore: update 2024-09-20 17:49:31 +08:00
huzibaca
c246ae3bcf
Fix: Custom tray icon not working
1. Contains potential deadlock
2024-09-20 16:26:23 +08:00
huzibaca
ab887c656a
fix: function parameter call error 2024-09-20 08:27:06 +08:00
Sukka
eefeec7f0a
chore: drop fs-extra (#1739)
nb!
2024-09-20 02:01:36 +08:00
huzibaca
74777df344
chore: update dev dependencis 2024-09-18 21:34:20 +08:00
huzibaca
c21ce578f5
fix: exit hotkey conflict 2024-09-18 15:16:43 +08:00
huzibaca
7d1b7adda5
fix: whether the window starts as fullscreen or not. 2024-09-18 13:23:27 +08:00
huzibaca
f64528dd87
chore: revert 2024-09-18 12:24:52 +08:00
huzibaca
3ca1d03d34
refactor: exit app 2024-09-18 02:48:55 +08:00
huzibaca
49929bd473
fix: the shortcut key to exit cannot be used 2024-09-18 01:41:46 +08:00
huzibaca
25f15e12cf
fix: hotkey status not accurately processed, resulting in two triggers 2024-09-17 10:59:39 +08:00
huzibaca
b6d15c27b6
chore: update 2024-09-17 08:28:13 +08:00
huzibaca
2f8c5c9b20
chore: update 2024-09-17 08:02:29 +08:00
huzibaca
bee1373f92
chore: add window to allow full screen configuration 2024-09-16 15:25:01 +08:00
huzibaca
8a4535d55e
chore: update 2024-09-16 07:08:22 +08:00
huzibaca
613fb60859
chore: update 2024-09-16 06:43:25 +08:00
huzibaca
18f9978fcf
chore: update 2024-09-16 06:37:39 +08:00
huzibaca
9b527cb53c
chore: update 2024-09-16 06:17:22 +08:00
huzibaca
c06e4af79d
chore: update 2024-09-16 05:50:05 +08:00
huzibaca
e89c3ed65e
chore: modify application description definition 2024-09-16 05:38:52 +08:00
huzibaca
eb60cfb083
fox: try to restore the processing logic of windows custom scheme 2024-09-16 05:30:29 +08:00
huzibaca
65ce7429b7
chore: update dev workflow 2024-09-15 07:57:34 +08:00
huzibaca
4b4a4927c4
chore: add log 2024-09-15 07:03:04 +08:00
huzibaca
f57d2df5ec
chore: follow official standards and adjust the main file 2024-09-15 06:24:53 +08:00
wonfen
d70e18ba8d chore: update change log and texts 2024-09-15 00:33:54 +08:00
huzibaca
962aeb1c75
fix: when importing subscriptions, force the window to open 2024-09-14 10:03:19 +08:00
huzibaca
6d7711f3ea
fix: after importing a subscription, it cannot be automatically switched to the current subscription. 2024-09-13 18:17:14 +08:00
huzibaca
ba487611ee
chore: update action(rust-toolchain) 2024-09-13 14:21:51 +08:00
huzibaca
6a636444a7
chore: update action(rust-toolchain) 2024-09-13 14:14:27 +08:00
wonfen
25c766ed94 chore: change folder name 2024-09-13 12:03:28 +08:00
huzibaca
dbc3723bdc
feat: Added web notification of successful subscription import 2024-09-13 11:24:49 +08:00
huzibaca
3963c60fc1
fix: when the service is not installed, the tray hides the Tun mode 2024-09-13 04:12:25 +08:00
huzibaca
b888c7729e
refactor: url scheme implementation 2024-09-13 03:21:55 +08:00
huzibaca
a39ece6156
chore: delete useless emebd server api 2024-09-12 19:01:08 +08:00
huzibaca
624eb5b085
fix:tray click event 2024-09-12 17:02:17 +08:00
huzibaca
9ec8c903c5
feat: Optimize kernel startup logic
1. tun mode startup logic
2. Remove invalid creation process PID logic
2024-09-12 15:35:08 +08:00
huzibaca
2396a6b35a
feat: log panic 2024-09-12 07:59:51 +08:00
huzibaca
1fc54e49d9
chore: update deps 2024-09-12 06:14:23 +08:00
huzibaca
30ee7a9e85
fix: missing items in system tray 2024-09-12 05:45:15 +08:00
huzibaca
b9be5e8c44
feat: migrate tauri 2.0 2024-09-11 08:15:03 +08:00
huzibaca
ae1c6d4617
chore: update 2024-09-04 07:53:16 +08:00
huzibaca
7b11e157c4
chore: update capabilities 2024-09-04 05:57:37 +08:00
wonfen
5783b7b392 chore: 2.0.0 beta release 2024-09-03 00:00:12 +08:00
huzibaca
507d52bcb9
chore: update 2024-09-02 19:33:17 +08:00
wonfen
d45929c604 chore: use in-house update proxy 2024-08-24 02:02:17 +08:00
wonfen
632c32addb Style: fix macos new version btn position 2024-08-22 07:33:51 +08:00
wonfen
7d2b18759e Release 1.7.7 2024-08-22 03:47:33 +08:00
wonfen
aa8f6f4ad6 chore: Shorten text to prevent Windows tooltip truncation. 2024-08-22 03:41:16 +08:00
wonfen
592167ffb7 fix: profiles will not be selected after import 2024-08-22 00:57:04 +08:00
wonfen
12a6bfad00 Release 1.7.6 2024-08-18 00:49:23 +08:00
tony-sung
1ea3b956ad
Update web-ui-viewer.tsx Fix yacd parameter hostname error (#1484) 2024-08-18 00:23:24 +08:00
MystiPanda
1b7dafe743
feat: auto select profile 2024-07-30 09:06:12 +08:00
MystiPanda
624eb2a2ba
chore: prepend new added rules 2024-07-24 14:25:06 +08:00
MystiPanda
88d98517c8
fix: wrap the password in quotes
#1460
2024-07-24 14:22:23 +08:00
Avan
9528606906
style: AddressDisplay padding (#1457) 2024-07-23 22:17:51 +08:00
nhsmw
09b44a3af3
fix: update test url 2024-07-19 10:32:41 +08:00
MystiPanda
dc861eca7d
chore: remove unnecessary console log 2024-07-18 23:37:54 +08:00
MystiPanda
e749fe70e2
fix: use group testUrl
#1384
2024-07-18 15:04:55 +08:00
MystiPanda
d20c082deb
fix: windows x86 updater url 2024-07-18 14:38:31 +08:00
MystiPanda
c4abc3ade3
fix: error command status 2024-07-16 18:37:56 +08:00
MystiPanda
ff28aab56e
fix: MacOS service install error 2024-07-16 13:01:27 +08:00
MystiPanda
1a6f842492
fix(#1335): support cidr 2024-07-16 12:22:11 +08:00
MystiPanda
af0cd4a342
fix: try to fix install service 2024-07-16 12:07:23 +08:00
MystiPanda
d98b3224cf
chore: disable okBtn 2024-07-15 23:38:49 +08:00
MystiPanda
f2e5f0754c
ci: fix winget uploader 2024-07-15 23:27:38 +08:00
MystiPanda
ec1601f317
Release 1.7.5 2024-07-15 22:35:33 +08:00
MystiPanda
54116608dc
ci: fix winget uploader 2024-07-15 22:33:57 +08:00
MystiPanda
fea6735ea1
fix: copy necessary files 2024-07-15 22:25:04 +08:00
MystiPanda
2f77a07b3d
Release 1.7.4 2024-07-15 20:56:18 +08:00
MystiPanda
4cd7ccda57
fix: unified switch style 2024-07-15 20:42:00 +08:00
MystiPanda
ef337ffb69
feat: optimize the service mode interaction logic. 2024-07-15 20:02:05 +08:00
MystiPanda
9ff5d8d4e0
Revert "fix: try to fix abnormal stuck"
This reverts commit e14ddbe23cae0bc5437b9ba9184e35909e6825c4.
2024-07-14 12:49:06 +08:00
Sukka
199a5eed60
fix(#1387): avoid catastrophic backtracking (#1396) 2024-07-14 12:26:02 +08:00
MystiPanda
e14ddbe23c
fix: try to fix abnormal stuck
#1387
2024-07-13 21:41:04 +08:00
MystiPanda
3878e66ea4
chore: update locale 2024-07-13 19:15:07 +08:00
MystiPanda
c14a33444b
chore: unified icon style 2024-07-13 19:01:16 +08:00
MystiPanda
48f7c15035
feat: display network interface 2024-07-13 14:15:13 +08:00
Avan
32212a46e2
feature: copy clash env (#1391)
* feat: copy clash env

* style: use ContentCopyRounded replace CopyAll
2024-07-13 01:03:46 +08:00
Avan
b4025c45da
style: EditorViewer title align center (#1390) 2024-07-12 23:29:55 +08:00
MystiPanda
bd589c4422
fix: service install failed on macos 2024-07-12 20:54:31 +08:00
dongchengjie
f85f7758e6 chore: checkbox items' title & button icons 2024-07-12 18:24:19 +08:00
dongchengjie
49e36b6e00 chore: editor resizing debounce 2024-07-08 23:18:06 +08:00
dongchengjie
df6e245e5c chore: remove dialog overflow-scroll 2024-07-08 22:07:43 +08:00
dongchengjie
4e4f9af5b7 fix: editor fails to resize after toggling on macos 2024-07-08 21:40:56 +08:00
MystiPanda
aa9e63b51a
fix dev.yml 2024-07-08 16:17:23 +08:00
MystiPanda
82340582b2
ci: add dev workflow 2024-07-08 13:20:36 +08:00
Akioe Yu
9d045e24db
fix: dnd box z-index (#1353)
* fix: dnd box z-index

* fix: dnd boxes
2024-07-08 10:49:57 +08:00
MystiPanda
1dcc95d16a
perf: optimized response speed 2024-07-08 00:29:49 +08:00
dongchengjie
78c32d51db chore: group types locale 2024-07-07 21:56:20 +08:00
❤是纱雾酱哟~
545a2c6688
ci: Integrate "Winget Releaser" (#1326) 2024-07-07 20:42:17 +08:00
MystiPanda
359d9285fe
perf: change port too slow 2024-07-07 18:22:02 +08:00
MystiPanda
1bd51be99c
feat: get network interface 2024-07-07 18:13:10 +08:00
dongchengjie
ee56080af0 fix: usage percent style 2024-07-07 18:08:02 +08:00
MystiPanda
18196c4a77
fix: trojan uri parser 2024-07-07 11:47:49 +08:00
MystiPanda
14cd3b99cc
fix: tray icon size
#1341
2024-07-07 11:18:22 +08:00
MystiPanda
ff75fe47ee
chore: disable browser autocomplete 2024-07-07 11:16:59 +08:00
MystiPanda
7e2cc180c3
Release 1.7.3 2024-07-06 18:48:25 +08:00
MystiPanda
bef9eea87b
fix: bypass reg error
#1335
2024-07-06 18:23:23 +08:00
MystiPanda
9cd1aef1db
fix: limite cipher types 2024-07-06 10:49:42 +08:00
MystiPanda
ab25cf0637
fix: rule parser 2024-07-06 10:35:29 +08:00
MystiPanda
32f37720dd
Revert "chore: add base64 decode step"
This reverts commit 38eb3123beb9820e19cbeba3cbd015e38ee282cf.
2024-07-06 10:12:51 +08:00
MystiPanda
766cf3aeae
chore: decode base64 2024-07-06 10:12:40 +08:00
MystiPanda
905353d540
fix: some error 2024-07-06 09:54:16 +08:00
MystiPanda
38eb3123be
chore: add base64 decode step 2024-07-06 00:57:38 +08:00
MystiPanda
0183edd450
fix: style 2024-07-06 00:45:21 +08:00
MystiPanda
2f640a946e
fix: type 2024-07-06 00:23:52 +08:00
MystiPanda
ec6c2adf9b
chore: Improve URI parser 2024-07-05 22:44:05 +08:00
MystiPanda
5a1edc5ffb
feat: finish rpoxies editor 2024-07-05 19:49:32 +08:00
MystiPanda
149d482c7d
fix: groups config type error
feat(unfinished): add proxy editor
2024-07-05 00:38:50 +08:00
MystiPanda
c9f784e4fa
feat: add profile name param for script 2024-07-04 23:11:54 +08:00
MystiPanda
9edafa75e7
build: remove unused resource file 2024-07-04 22:34:48 +08:00
MystiPanda
08baba545d
chore: disable unnecessary ports by default 2024-07-04 18:58:34 +08:00
MystiPanda
60d0b29236
feat: support cache for groups editor 2024-07-04 18:53:39 +08:00
MystiPanda
f5ee4fb5b5
chore: unified style 2024-07-04 18:50:21 +08:00
MystiPanda
5b7b3be6f9
fix: useseq error 2024-07-04 14:30:34 +08:00
MystiPanda
c933560102
fix: locale typo 2024-07-04 14:18:21 +08:00
MystiPanda
12a80f35fe
feat: support visual edit for proxy group 2024-07-04 14:13:19 +08:00
MystiPanda
43f901eeb9
fix: rules editor get groups error 2024-07-04 11:03:51 +08:00
MystiPanda
e8440e06a1
feat: support get merged rule-set name 2024-07-03 22:13:24 +08:00
dongchengjie
19e9e9d032 fix: remove rule condition where is not required 2024-07-03 17:03:12 +08:00
MystiPanda
8ff2d687e4
Release 1.7.2 2024-07-03 13:26:06 +08:00
MystiPanda
e616e8f9aa
fix: Insertion order
#1300
2024-07-03 13:13:54 +08:00
MystiPanda
1fbc67fe98
fix: dialog styles 2024-07-03 13:13:29 +08:00
MystiPanda
a49e4d8d0c
fix: panic 2024-07-03 12:49:29 +08:00
MystiPanda
fa4ac00504
feat: support edit rules file 2024-07-03 12:37:08 +08:00
MystiPanda
dc066edec4
fix: edit groups error 2024-07-03 10:58:57 +08:00
MystiPanda
eaed7b2899
Release 1.7.1 2024-07-03 09:52:19 +08:00
MystiPanda
123ecc3548
fix: rules drag error 2024-07-03 09:45:14 +08:00
MystiPanda
c857fcf035
fix: compatibility 2024-07-03 08:15:13 +08:00
dongchengjie
923f710e53 fix: search-box takes no effect in rule-editor #1288 2024-07-03 03:08:01 +08:00
dongchengjie
8d8c2ed262 fix: sub usage percent fails to display when number is too small #1290 2024-07-03 02:59:32 +08:00
MystiPanda
8558673a5a
Release 1.7.0 2024-07-03 00:32:14 +08:00
MystiPanda
7372f330a4
perf: optimize performance of the rule editor 2024-07-02 23:55:29 +08:00
dongchengjie
07c145c661 feat: editor add tool-tar buttons 2024-07-02 23:24:44 +08:00
dongchengjie
f69e1d2a0c refactor: editor-viewer using react-monaco-editor 2024-07-02 21:02:29 +08:00
dongchengjie
0021fc24bb chore: bump schema to 1.18.5-alpha7 2024-07-02 19:38:44 +08:00
MystiPanda
82bc1d5da5
chore: disable autocomplete 2024-07-02 19:02:05 +08:00
MystiPanda
ffc343b471
fix: default value of global extend config 2024-07-02 18:46:23 +08:00
dongchengjie
86e43123b0 chore: add rule list search-box 2024-07-02 17:32:49 +08:00
dongchengjie
b558202441 chore: rule types locale 2024-07-02 17:04:22 +08:00
MystiPanda
83947b6725
chore: check the validity of the rule content 2024-07-02 13:11:54 +08:00
MystiPanda
7e8b65e61f
chore: Adjust the chain processing execution order and default value 2024-07-02 12:40:28 +08:00
MystiPanda
cff0ea425c
build: update depends 2024-07-02 12:21:17 +08:00
MystiPanda
f6ba6d0310
chore: update locale 2024-07-01 23:30:14 +08:00
MystiPanda
7b9bf9e552
feat: allow set bypass without using default value 2024-07-01 22:53:32 +08:00
Sukka
c91ad1e016
ci: speed up cargo install by enabling cache (webview2) (#1283) 2024-07-01 14:23:21 +08:00
MystiPanda
b1444b8635
feat: global merge and script 2024-07-01 08:25:03 +08:00
MystiPanda
51a49b94d8
feat: drag to reorder rules 2024-06-30 23:16:21 +08:00
MystiPanda
720b46d790
chore: select rule-set name 2024-06-30 22:46:11 +08:00
MystiPanda
9089c30d57
feat: display rules list 2024-06-30 22:34:26 +08:00
MystiPanda
e2d522803c
fix: editor init error 2024-06-30 18:05:38 +08:00
Sukka
babcb00621
ci: speed up cargo install by enabling cache (#1279) 2024-06-30 17:21:55 +08:00
MystiPanda
901a983150
feat: rules editor 2024-06-30 17:17:04 +08:00
MystiPanda
955182b05b
chore: locale 2024-06-30 13:03:36 +08:00
MystiPanda
f4dfe8eeb4
feat(unfinished): rules editor 2024-06-30 12:46:31 +08:00
MystiPanda
93904b8278
refactor: pure merge 2024-06-30 07:58:44 +08:00
MystiPanda
495580ae2b
fix: delete logic 2024-06-30 07:37:52 +08:00
MystiPanda
3051004217
chore: update locale 2024-06-30 07:18:10 +08:00
MystiPanda
b854b5e1ac
feat: support seq editor 2024-06-30 00:22:05 +08:00
MystiPanda
cf61a96ef6
refactor: Associate Profile with Merge/Script. 2024-06-29 23:07:44 +08:00
MystiPanda
1293d25e1b
refactor: use async instead of block_on 2024-06-29 19:02:37 +08:00
dongchengjie
c1a201f358 fix: do not reactive when changed profile is not current 2024-06-29 11:22:11 +08:00
dongchengjie
9ee5390ec7 feat: reactive after save when profile content changes 2024-06-29 09:21:50 +08:00
dongchengjie
3f1caa702b fix: #1261 2024-06-29 05:02:06 +08:00
wonfen
24f9573c05 chore: add TG link & descriptions 2024-06-29 04:55:43 +08:00
dongchengjie
83b25920ea chore: add descriptions for Miscellaneous 2024-06-28 15:54:27 +08:00
MystiPanda
834edcd03e
fix: unset dns when exit 2024-06-28 12:18:18 +08:00
MystiPanda
8f3801e3c2
feat: set dns by service 2024-06-28 11:45:44 +08:00
dongchengjie
b5f7c58276 chore: remove duplicate locales 2024-06-26 19:11:39 +08:00
dongchengjie
66ae293ddd fix: await compatibility in #8e78b9e 2024-06-26 18:29:50 +08:00
dongchengjie
8e78b9e405 feat: support manual memory cleanup when running in debug mode 2024-06-26 17:44:42 +08:00
dongchengjie
9da1759247 chore: cleanup 2024-06-26 08:24:43 +08:00
dongchengjie
704c41c0f2 refactor: extract tooltip icon as component 2024-06-26 08:10:18 +08:00
dongchengjie
1f422afe3d chore: tooltips and locales 2024-06-26 05:33:06 +08:00
dongchengjie
709a23cf09 chore: fix connection table bg 2024-06-23 20:40:09 +08:00
dongchengjie
bfa3fa293f fix: update_interval won't save when creating local profile while updating does & number input locales 2024-06-23 06:47:51 +08:00
MystiPanda
d8b878b1bb
feat: handle break change update 2024-06-22 21:05:46 +08:00
dongchengjie
b2589dbc04 chore: hotkeys display delimiter 2024-06-21 18:24:58 +08:00
MystiPanda
2a4b605794
chore: hide delay for preset outbound 2024-06-21 00:16:41 +08:00
MystiPanda
a3080a3373
revert: just kill 2024-06-20 14:27:13 +08:00
MystiPanda
b4b9ae5d7f
feat: custom dmg background 2024-06-20 13:50:28 +08:00
dongchengjie
bb9a93e462 chore: fix table header bg in connections 2024-06-20 02:01:51 +08:00
dongchengjie
e55fbf675e chore: disable shortcuts #1239 2024-06-20 01:39:51 +08:00
MystiPanda
0342477733
fix: runtime error 2024-06-19 11:10:40 +08:00
MystiPanda
e6e2b1f142
refactor: change core binary name 2024-06-19 10:04:28 +08:00
MystiPanda
95c23a93cd
refactor: kill core by process name 2024-06-18 12:36:58 +08:00
MystiPanda
ae784cb985
fix: reg error 2024-06-17 16:38:30 +08:00
Sukka
17765bdba9
fix(#1226): missing conn unsub (#1228) 2024-06-17 13:36:35 +08:00
Sukka
45f791b3c8
refactor(connections): use swr subscription (#1226) 2024-06-17 13:14:36 +08:00
dongchengjie
b0ad39ed0b fix: resizing reset when data changes 2024-06-17 13:03:47 +08:00
Sukka
1988aeb945
refactor(log): use swr subscription (#1220) 2024-06-17 10:48:37 +08:00
MystiPanda
f48a5710aa
chore: update depends 2024-06-17 10:46:18 +08:00
Sukka
c8d2410c27
feat: add a wrapper around sockette w/ error retry (#1219)
* feat: add a wrapper around sockette w/ error retry

* chore: use import path alias

* perf: reduce retry
2024-06-16 18:25:33 +08:00
MystiPanda
a9ef32c32f
Revert "feat: disable running with admin permission and check service mode"
This reverts commit a0f9fb90ee7034043f1d8279db9e31f753efe74d.
2024-06-16 12:06:23 +08:00
Sukka
19b6f78c8a
ci(alpha): avoid race by cancel non-latest concurrent runs (#1213) 2024-06-16 01:10:30 +08:00
Sukka
4ab507fd43
fix: hide save button in readonly editor view (#1208) 2024-06-15 19:24:26 +08:00
Sukka
2662df2547
fix(#1203): correct types (#1207) 2024-06-15 19:23:58 +08:00
Sukka
0332415ac9
perf: replace Array#map Array#filter chain w/ Array#reduce (#1203) 2024-06-15 12:22:33 +08:00
MystiPanda
a0f9fb90ee
feat: disable running with admin permission and check service mode 2024-06-14 23:15:49 +08:00
MystiPanda
1b8c4cb832
build: downgrade auto-launch 2024-06-14 21:26:30 +08:00
MystiPanda
cfd50d281b
fix: fix bypass check regex 2024-06-14 21:23:58 +08:00
Sukka
1667856894
chore: use swr subscription for layout traffic / memory (#1202)
* chore: update swr to 2

* refactor: use swr subscription for memory & traffic

* refactor: introduce `sockette`
2024-06-14 18:23:29 +08:00
dongchengjie
c5c76ab539 chore: update metacubexd #1200 2024-06-14 17:09:12 +08:00
dongchengjie
eb060d2e43 feat: local profile name autofill #1191 2024-06-13 16:29:25 +08:00
MystiPanda
b5556613cf
refactor: remove grant logic 2024-06-13 16:07:56 +08:00
MystiPanda
ad1a057edb
fix: check service 2024-06-13 12:58:47 +08:00
MystiPanda
8342f985e5
ci: fix release 2024-06-12 12:25:12 +08:00
MystiPanda
9d32e58915
chore: update publisher 2024-06-12 11:51:44 +08:00
MystiPanda
84027cbae1
Release 1.6.6 2024-06-12 10:33:20 +08:00
MystiPanda
5343040ef3
fix: start param error 2024-06-12 10:19:23 +08:00
MystiPanda
75cd7dd4b9
chore: update & fmt & clippy 2024-06-12 10:00:22 +08:00
dongchengjie
fb6ffd8e09 chore: missing locale 2024-06-11 16:19:25 +08:00
dongchengjie
aca9e61f39 chore: locale "Invalid Bypass Format" 2024-06-09 20:02:20 +08:00
MystiPanda
56078098a4
fix: start param error 2024-06-09 20:00:17 +08:00
MystiPanda
1f197965e0
feat: check bypass format 2024-06-09 13:37:47 +08:00
MystiPanda
183f0f6c42
feat: keep default bypass 2024-06-09 12:45:57 +08:00
dongchengjie
76624c7d83 chore: missing locale 2024-06-09 11:16:13 +08:00
dongchengjie
ab47c56ec5 chore: locale reorganization 2024-06-09 09:12:14 +08:00
Eric Huang
ad35ed96c8
feat(settings page): add loading state (#1157)
* feat(settings page): add loading state

* fix: type
2024-06-09 06:26:07 +08:00
wonfen
97bd51cf5f chore: update ci with apple notarization 2024-06-09 02:01:33 +08:00
MystiPanda
f4a110cfd7
ci: fix error 2024-06-08 20:58:57 +08:00
MystiPanda
e9ed06adfd
ci: update 2024-06-08 20:45:28 +08:00
MystiPanda
bc5eaf34fe
feat: add download button on updater dialog
#1129
2024-06-08 20:35:23 +08:00
MystiPanda
3e8b891dd0
fix: run app as normal user 2024-06-08 20:20:47 +08:00
MystiPanda
3f2ea4bc64
build: update depends 2024-06-08 20:02:25 +08:00
MystiPanda
ae81b37c1d
build: remove appimage 2024-06-08 19:36:58 +08:00
MystiPanda
b4349afb1b
ci: codesign 2024-06-08 18:52:34 +08:00
dongchengjie
0cffe8e3f7 chore: disbale Meta+Q on macOS 2024-06-08 13:12:24 +08:00
Sukka
7a1f4f9abe
refactor: simplify useConnectionSetting (#1141) 2024-06-07 17:23:53 +08:00
wonfen
5768b01786 fix: apple sign error again 2024-06-07 17:19:44 +08:00
MystiPanda
7e9079467f
fix: sign error 2024-06-07 16:39:06 +08:00
MystiPanda
615e96922e
fix: sign error 2024-06-07 16:37:58 +08:00
Eric Huang
8b94c452fb
feat: make SettingItem clickable (#1138)
* feat: make `SettingItem` clickable

* clean up
2024-06-07 15:51:51 +08:00
Sukka
66dd510acc
refactor: replace recoil (#1137) 2024-06-07 12:27:37 +08:00
wonfen
96e044566c Style: modify proxy pages 2024-06-07 10:32:27 +08:00
MystiPanda
726ad84d7f
fix: sign error 2024-06-06 16:06:58 +08:00
wonfen
4fc422f880 chore: apple developer sign test 2024-06-06 15:21:53 +08:00
dongchengjie
1938024ab3 chore: test_delay trace 2024-06-05 19:17:43 +08:00
dongchengjie
05b1de6fd5 chore: theme colors to uppercase 2024-06-05 14:20:24 +08:00
dongchengjie
0bf8807b50 build: no legacy chunks 2024-06-05 09:04:08 +08:00
Sukka
23668ee74e
fix(#1126): add Object.hasOwn polyfill (#1127) 2024-06-05 00:12:06 +08:00
dongchengjie
6bc5c5a808 fix: csp missing asset: 2024-06-04 15:26:39 +08:00
MystiPanda
330004dc72
build: update depends 2024-06-04 12:16:42 +08:00
MystiPanda
a900d6d742
Release 1.6.5 2024-06-04 12:11:38 +08:00
MystiPanda
bfea70eec9
fix: package error 2024-06-04 10:47:17 +08:00
MystiPanda
13babbf330
feat: support rpm package 2024-06-04 10:16:25 +08:00
MystiPanda
0a6fe382ac
build: use latest tauri 2024-06-04 10:09:04 +08:00
Zhenfu Shi
dd6dea9dfc
chore: Enable Ad Hoc signing on macOS (#1117)
Closes #1116
2024-06-03 09:01:33 +08:00
wonfen
11434fba68 Revert "chore: change default test url"
This reverts commit 69b65d06a4cd0988f28ed52f91c13c833583b0dc.
2024-06-03 08:25:06 +08:00
dongchengjie
10bf90c92a chore: use icons files instead of hard coding 2024-06-03 07:21:40 +08:00
dongchengjie
5193fe4bab fix: group selected be overwritten when saving test 2024-06-03 06:38:20 +08:00
dongchengjie
4df4995623 chore: improve UI in connections page 2024-06-02 21:52:31 +08:00
aixiao0621
f5f4ecf46a fix: a display error on the connections page 2024-06-02 17:26:23 +08:00
MystiPanda
69b65d06a4
chore: change default test url 2024-06-01 23:14:47 +08:00
MystiPanda
e6bf4e836d
build: update depends 2024-06-01 23:01:27 +08:00
dongchengjie
01d67eb239 refactor: polyfills review 2024-05-30 20:27:12 +08:00
dongchengjie
3514cfbd44 fix: research when search box mode changes 2024-05-30 10:45:24 +08:00
dongchengjie
cade35fe10 chore: Content-Security-Policy 2024-05-29 10:20:56 +08:00
dongchengjie
2c6df77f5a ci: fix heap oom 2024-05-29 09:49:11 +08:00
dongchengjie
0276ae91b5 build: polyfills 2024-05-29 09:39:26 +08:00
dongchengjie
60fee2accb build: import babel 2024-05-28 09:59:41 +08:00
dongchengjie
03e2632294 fix: try to fix #1084 2024-05-27 23:19:44 +08:00
dongchengjie
194fe59458 typo: inconsistent style in layout-viewer 2024-05-27 16:37:48 +08:00
MystiPanda
e400111f8a Release 1.6.4 2024-05-26 22:07:53 +08:00
MystiPanda
8bc7607783 Revert "refactor: use axios tauri adapter"
This reverts commit 7e361cb3f195f18353446947b66775c36644237b.
2024-05-26 21:18:02 +08:00
dongchengjie
4108451ebe chore: %mixed-port% hint for PAC script 2024-05-26 19:53:42 +08:00
MystiPanda
0f56257aa1 Release 1.6.3 2024-05-26 19:43:26 +08:00
MystiPanda
2a575284b9 chore: add content type 2024-05-26 19:26:57 +08:00
MystiPanda
444bcbfb30 fix: auto proxy changed by guard 2024-05-26 19:07:14 +08:00
MystiPanda
212021c878 feat: Support PAC Mode 2024-05-26 17:59:39 +08:00
dongchengjie
600b687253 chore: emoji display support in editor 2024-05-25 18:02:32 +08:00
farzadhallaji
ae3aada172
Update fa.json (#1060) 2024-05-24 19:39:40 +08:00
MystiPanda
50cc8af8c3 ci: use rust 1.77.0 2024-05-23 11:47:41 +08:00
dongchengjie
1809cdbf37 fix: no snippets and warnings in runtime config editor 2024-05-21 06:18:09 +08:00
dongchengjie
fb38047769 chore: update locale in connection 2024-05-20 13:42:45 +08:00
dongchengjie
08e0d6a34a chore: text overflow word-wrap & cleanup 2024-05-20 12:38:41 +08:00
MystiPanda
b4fddaec7f build: use compatible 2024-05-19 19:30:53 +08:00
MystiPanda
3f19d22941 fix: installer package error 2024-05-19 19:13:21 +08:00
MystiPanda
c7d51cfc4c build: use latest core 2024-05-19 13:00:27 +08:00
dongchengjie
6829d34e90 chore: schema 1.18.5-alpha 2024-05-19 12:37:18 +08:00
dongchengjie
021e430103 chore: fix select component bg in connection 2024-05-18 18:42:51 +08:00
dongchengjie
ae6f42a7fb chore: fix search-box bg 2024-05-18 18:20:05 +08:00
MystiPanda
da98097394 chore: support more asset scope 2024-05-18 15:47:45 +08:00
oomeow
43f0b935cf
perf: memoize the proxy col items (#1029) 2024-05-18 15:14:22 +08:00
oomeow
db5d14e0ce
fix: clipboard doesn't work and set_shadow method is not supported in Linux (#1030) 2024-05-18 15:14:00 +08:00
dongchengjie
b25cf5eadb feat: editor import PAC definition 2024-05-18 14:59:17 +08:00
dongchengjie
bd3b41c809 chore: hint for canceling fixed #840 2024-05-17 20:44:18 +08:00
dongchengjie
31d301064a chore: use search-box in logs and connections 2024-05-17 19:44:42 +08:00
dongchengjie
b95b9bdaf3 chore: component base-search-box 2024-05-17 19:13:33 +08:00
dongchengjie
937f0b5687 chore: fix editor dialog scroll overflow 2024-05-17 04:03:49 +08:00
dongchengjie
ffbc892e44 fix: missing locale 2024-05-15 23:27:31 +08:00
dongchengjie
9e872932d1 chore: current bypass wrap 2024-05-15 22:59:53 +08:00
MystiPanda
ecb2fbf900 feat: support monochrome tray icon 2024-05-15 14:50:10 +08:00
dongchengjie
72edd2e15d chore: logo svg 2024-05-14 16:53:39 +08:00
dongchengjie
c3d22c554f feat: doc reference link on settings header 2024-05-14 14:40:47 +08:00
dongchengjie
e72f4a1582 chore: use coding fonts in editor 2024-05-14 14:20:50 +08:00
dongchengjie
5e43c060fa fix: switch missing break 2024-05-14 01:24:23 +08:00
dongchengjie
e8dee1ddd9 chore: @ts-ignore schema check 2024-05-14 01:21:28 +08:00
dongchengjie
d85b8c776f chore: revert schema to beta4 2024-05-14 00:59:05 +08:00
dongchengjie
fb518b6218 chore: palette locale 2024-05-13 23:12:29 +08:00
dongchengjie
8d510cde21 typo: unused import 2024-05-13 22:59:24 +08:00
dongchengjie
da4bf167ee feat: css injection editor 2024-05-13 22:58:25 +08:00
Remember
dc1abf8dcb
Update 172.16.0.0/12 on Windows (#1013) 2024-05-13 18:28:41 +08:00
MystiPanda
3fc969a50b fix: use default bypass when empty 2024-05-13 18:27:19 +08:00
MystiPanda
4064129d49 chore: Adapt Mac icon 2024-05-13 13:11:05 +08:00
MystiPanda
22b4e0bfff docs: Update README 2024-05-12 22:17:05 +08:00
MystiPanda
53fa1f88fd chore: Change HomePage Logo 2024-05-12 21:17:21 +08:00
MystiPanda
5fefcd92f3 chore: Try a new icon 2024-05-12 19:31:06 +08:00
dongchengjie
d20bc936da chore: ru locale 2024-05-12 16:18:49 +08:00
RikudouPatrickstar
e79f036a70
chore: update notification message and zh translation (#1011) 2024-05-12 14:40:18 +08:00
MystiPanda
0f2af91a04 perf: Disable Tun mode before shutting down 2024-05-12 11:06:44 +08:00
MystiPanda
7e361cb3f1 refactor: use axios tauri adapter 2024-05-11 21:54:56 +08:00
MystiPanda
1f7acd4027 feat: Allow disable unused ports 2024-05-09 09:22:32 +08:00
MystiPanda
dddca7bf4b chore: Update locale 2024-05-08 23:45:55 +08:00
MystiPanda
e520be80c0 perf: Limit drawing frame rate 2024-05-08 22:33:13 +08:00
MystiPanda
0b78dedf04 fix: bundle error 2024-05-08 14:52:38 +08:00
MystiPanda
8f409477c8 build: fix bundle error 2024-05-08 14:20:30 +08:00
MystiPanda
9c22f7ce69 fix: depend error 2024-05-08 13:24:34 +08:00
MystiPanda
05fa916915 Release 1.6.2 2024-05-08 13:14:00 +08:00
MystiPanda
9a593d7a61 feat: support upgrade for release core 2024-05-08 12:48:27 +08:00
MystiPanda
30017eeaa0 docs: Update FAQ URL 2024-05-08 11:44:57 +08:00
MystiPanda
9b03cacc94 ci: update ci 2024-05-08 11:12:06 +08:00
MystiPanda
557970cf54 refactor: remove prepend and append for provider 2024-05-08 00:22:14 +08:00
MystiPanda
d90dac60ef feat: deep merge
#983
2024-05-08 00:13:32 +08:00
MystiPanda
b4b2e67260 build: Add portable for fixed webview2 2024-05-06 19:13:08 +08:00
MystiPanda
bcd5e935e7 ci: debug ci 2024-05-06 16:16:47 +08:00
MystiPanda
b322627609 ci: fix ci script 2024-05-06 15:30:00 +08:00
MystiPanda
09861095ff ci: update release body 2024-05-06 15:15:07 +08:00
MystiPanda
47e567fb40 docs: update url 2024-05-06 15:05:56 +08:00
MystiPanda
5bb30ad28f build: try support fixed webview2 runtime 2024-05-06 14:18:12 +08:00
MystiPanda
a46bbf05ec ci: try resupport x86 2024-05-06 13:04:29 +08:00
dongchengjie
04a4705dbd fix: non-ascii character secret causes controller link error
https://github.com/clash-verge-rev/clash-verge-rev/issues/973#issuecomment-2094839700
2024-05-05 23:04:33 +08:00
MystiPanda
3271c96531 fix: enhance when change tun config 2024-05-04 16:12:10 +08:00
dongchengjie
05fa6b9aba chore: profile template typo 2024-05-04 14:24:11 +08:00
MystiPanda
7edd7f27cb fix: try to set env 2024-05-03 18:00:55 +08:00
dongchengjie
4a6b12eda1 fix: #974 2024-05-03 12:50:04 +08:00
MystiPanda
a354e1a0eb chore: update locale 2024-05-02 23:44:09 +08:00
dongchengjie
c2c419522a chore: add service mode locale 2024-05-02 22:16:05 +08:00
MystiPanda
7a3cc7d242 feat: Support drag and drop local files 2024-05-02 20:41:43 +08:00
MystiPanda
bd6f02f6af fix: change script execution path 2024-05-01 11:39:09 +08:00
MystiPanda
bd33728fd7 Release 1.6.1 2024-04-30 23:43:51 +08:00
MystiPanda
8400ee8a3d fix: MacOS tray click 2024-04-30 23:21:25 +08:00
lxk955
80ee7aef8e
feat: Support for using regular expressions on the log page #707 (#959) 2024-04-30 22:59:42 +08:00
MystiPanda
41762be3a5 fix: service install path 2024-04-30 20:20:39 +08:00
MystiPanda
605dda7b76 build: Restore core version 2024-04-30 09:42:25 +08:00
dongchengjie
8d6e3b5a58 fixup: wrong version 2024-04-30 02:13:24 +08:00
dongchengjie
53920fc368
chore: update pnpm-lock.yaml (#952)
* chore: update schema version

* Update pnpm-lock.yaml
2024-04-30 01:44:05 +08:00
dongchengjie
96d10423d9
chore: update schema version (#950) 2024-04-29 22:46:29 +08:00
MystiPanda
42be9b5b51 chore: Config issue template 2024-04-29 15:43:43 +08:00
MystiPanda
0add041516
docs: Update FAQ URL 2024-04-28 20:04:03 +08:00
MystiPanda
dee76cac8d
build: cargo update 2024-04-28 19:59:46 +08:00
MystiPanda
9646fab22c fix: Open the link with browser 2024-04-28 18:46:49 +08:00
dongchengjie
a54e9cb244
fixup: can't edit file (#943) 2024-04-28 17:00:33 +08:00
dongchengjie
f8339c7a9a
chore: disable WebView keyboard shortcuts (#942) 2024-04-28 16:19:13 +08:00
lxk955
9e2c864117
feat: support display current profile when the mouse is placed on the tray icon #782 (#938) 2024-04-27 20:54:02 +08:00
PlayerNeo
e1ccd71455
fix: disable left click menu on macOS (#930) 2024-04-27 20:52:29 +08:00
LiuTianYu
0e82426ea1
fix: #730 icon not change when the window is opened maximized (#924)
Co-authored-by: tyliu9 <tyliu9@toycloud.com>
2024-04-24 22:36:15 +08:00
wonfen
6c7afd168a Release 1.6.0 2024-04-23 14:25:09 +08:00
MystiPanda
e014fdf3da
feat: support ico format for tray icon (#911) 2024-04-22 20:43:15 +08:00
dongchengjie
2074da05c8
fix: #907 (#908) 2024-04-22 01:40:25 +08:00
dongchengjie
84cd87b70a
chore: update locale (#904)
* chore: missing locale

* chore: External Controller locale
2024-04-21 14:10:34 +08:00
dongchengjie
75f87044f6
chore: Proxy Bypass placeholder (#901) 2024-04-20 19:27:17 +08:00
dongchengjie
f71b51e64a
fix: minor glitches (#900)
* feat: show actual proxy name instead of proxy group when hovering on a group outbound

* fix: open empty edit form and save will cause `UID not found`

* chore: tauri.conf.json json schema

* chore: missing locales
2024-04-20 18:02:15 +08:00
MystiPanda
9d741cdd63 fix: startup script blocking 2024-04-20 17:52:54 +08:00
MystiPanda
56be17000a fix: default value for tun 2024-04-20 17:42:36 +08:00
MystiPanda
f6aacbc31d build: add depends 2024-04-19 15:55:46 +08:00
MystiPanda
ad4b57c327 chore: update lock file 2024-04-19 15:38:32 +08:00
dongchengjie
3794b2f0de
fix: 使用npm安装meta-json-schema (#895)
* feat: allow manual selection of url-test group

* feat: fixed proxy indicator

* fix: try to fix traffic websocket no longer updating

* fixup: group delay test use defined url

* feat: connections sorted by start by default

* feat: Connection details show the full path of the process

* fix: editor no hints and add yaml support

* feat: quick suggestions

* chore: use monaco-editor

* chore: update schema url

* chore: change default merge config content

* fix: load schema via npm

* feat: runtime config viewer style auto adjust

* feat: adjust fixed proxy style

* fix: headState "showType" won't toggle hover text

* chore: switch version

* chore: Update pnpm lockfile
2024-04-19 13:54:16 +08:00
MystiPanda
e0e8412728 refactor: change default value of mtu 2024-04-18 10:27:09 +08:00
dongchengjie
05b8175aad
chore: 修改Merge配置文件默认内容 (#889) 2024-04-17 22:56:54 +08:00
MystiPanda
339c89dd1c chore: Update pnpm lockfile 2024-04-17 22:16:50 +08:00
dongchengjie
402299e9c8
feat: Clash配置、Merge配置提供JSON Schema语法支持、[连接]界面调整 (#887) 2024-04-17 21:19:37 +08:00
MystiPanda
d0e8f450fd fix: SymbolicLink
#750
2024-04-13 15:46:11 +08:00
MystiPanda
e97b1ccd7a fix: service install path 2024-04-13 15:12:41 +08:00
汐殇
68691b91ef
fix: Allow core files in specific directories to be upgraded normally (#857) 2024-04-12 01:16:57 +08:00
dongchengjie
213d417481
feat: url-test支持手动选择、节点组fixed节点使用角标展示 (#840)
* feat: allow manual selection of url-test group

* feat: fixed proxy indicator

* fix: try to fix traffic websocket no longer updating

* fixup: group delay test use defined url
2024-04-09 13:15:45 +08:00
MystiPanda
2ec841eb61 fix: Update the home while updating profile 2024-04-04 15:07:55 +08:00
MystiPanda
60b5c54be1 fix: Use System Browser 2024-04-04 14:56:10 +08:00
Damian Johnson
448412a191
style: adjust confirm dialog & web ui settings dialog (#821) 2024-04-03 23:19:00 +08:00
Damian Johnson
e06327936e
fix: service mode install script download not found (#822) 2024-04-03 23:18:10 +08:00
dongchengjie
5f044e1aed
feat: support URL Schema 'profile-web-page-url' (#816) 2024-04-01 19:28:28 +08:00
HZ is not Chatty
d90fb6fc9b
fixup! feat: Service Mode for Linux (#804) (#815)
* fixup! feat: Service Mode for Linux (#804)

* fixup! feat: Service Mode for Linux (#804)

* Partially revert "fixup! feat: Service Mode for Linux (#804)"

This reverts commit e6a5a2b4961dba4e891b1b62d6f35db4ca9ee5ce.
2024-04-01 19:25:58 +08:00
MystiPanda
1c583d2ea9 feat: Try support service mode for MacOS 2024-03-31 23:16:47 +08:00
MystiPanda
ddab131102
fix: script error 2024-03-31 16:37:33 +08:00
HZ is not Chatty
3b06cf8a2a
feat: Service Mode for Linux (#804) 2024-03-31 16:16:23 +08:00
wonfen
c5d7c29f3d Sytle: fix mac logo padding 2024-03-30 16:31:17 +08:00
Damian Johnson
26af860eac
fix: icon not change when toggle window maxinized (#799) 2024-03-30 01:16:40 +08:00
cismous
ec9852eb98
Style filter input (#724)
* refactor: reduce duplicate code

* style: add a white background to the light color theme to avoid the gray text being too light
2024-03-30 01:14:03 +08:00
Damian Johnson
f2b8c6d0ca
fix: missing proxy group delay check animations (#788)
* fix: missing proxy group delay check animation

* chore: cleanup

* chore: adjust content style
2024-03-29 08:20:31 +08:00
wonfen
2cf7a048cf Release 1.5.11 2024-03-28 12:06:41 +08:00
MystiPanda
3dbb71a076 feat: Support Persian
#715
2024-03-21 20:51:33 +08:00
MystiPanda
ddf6760543 fix: Duplicate icon display error
#719
2024-03-21 20:29:16 +08:00
MystiPanda
a6fa323f33 fix: The update button cannot be clicked
#716
2024-03-21 19:56:30 +08:00
MystiPanda
2df8f1acdb fix: Check if the install directory is empty when uninstall 2024-03-21 15:24:12 +08:00
MystiPanda
74a3290abc
chore: fix typo 2024-03-21 14:09:59 +08:00
MystiPanda
ab306d21f3
Release 1.5.10 2024-03-21 13:47:39 +08:00
MystiPanda
1bd7795851
chore: Change a little 2024-03-21 12:55:22 +08:00
MystiPanda
302c142346
build: Update depends 2024-03-21 11:53:25 +08:00
MystiPanda
7c254c9b45
fix: a little 2024-03-21 11:43:16 +08:00
MystiPanda
b1c458359d
feat: Confirm before deletion
#703
2024-03-21 11:39:01 +08:00
MystiPanda
2d925c62f5
feat: Support config redir port and tproxy port 2024-03-21 10:54:56 +08:00
MystiPanda
ef4711987f chore: limit port config
#699
2024-03-20 21:23:10 +08:00
MystiPanda
8910dfaecf fix: Limit icon width
#697
2024-03-20 20:38:45 +08:00
MystiPanda
e8b2e79c7d fix: service logs are not cleared
#695
2024-03-20 20:31:00 +08:00
MystiPanda
333ee1e1f7
docs: Improve the issue template 2024-03-20 18:06:02 +08:00
MystiPanda
ba013bbe96
feat: Optimize Linux tray menu 2024-03-18 11:11:18 +08:00
MystiPanda
636e66fe7a
Revert "fix: remove activation policy" 2024-03-18 09:53:48 +08:00
MystiPanda
372a45e667
Release 1.5.9 2024-03-17 11:25:25 +08:00
MystiPanda
ab6b796ce2 fix: drag error
#643
2024-03-16 20:37:39 +08:00
MystiPanda
71e6c02897
fix: drag error 2024-03-16 17:06:59 +08:00
MystiPanda
3edeaa7038 fix: Try to fix touch drag
#456
2024-03-16 10:54:19 +08:00
MystiPanda
f2f75d4015 build: Update to Tauri 1.6.1 2024-03-16 00:03:34 +08:00
MystiPanda
69adade738 ci: update alpha script 2024-03-15 21:52:56 +08:00
MystiPanda
1bd88828e4 ci: remove 2024-03-15 21:42:55 +08:00
MystiPanda
977fcbe6cd feat: Try to support more architecture 2024-03-15 21:14:05 +08:00
MystiPanda
aa76a5c436 refactor: Try to migrate to boa_engine
#634
2024-03-15 19:58:22 +08:00
MystiPanda
ea5fad428d fix: Avoid empty user-agent 2024-03-15 18:27:24 +08:00
MystiPanda
0e1e27b35a feat: Try to cache remote images
#603
2024-03-15 16:43:39 +08:00
screw-hand
d41f67a156
fix: mac setting theme font-famil not working (#632) 2024-03-15 15:17:05 +08:00
MystiPanda
6f10dec808 fix: remove activation policy
#592
2024-03-15 12:44:25 +08:00
xkww3n
9b79da2cdf
fix: Set REJECT-DROP policy the same text color as REJECT (#622) 2024-03-14 18:54:26 +08:00
MystiPanda
c11b8519f1 Release 1.5.8 2024-03-13 14:17:06 +08:00
wonfen
b9e23a0b59 Sytle: A little tweak 2024-03-13 14:09:08 +08:00
MystiPanda
75d41b6fe5 feat: Add border-radius for window on linux 2024-03-13 13:58:29 +08:00
Amnesiash
4256590735
update profile ui (#594) 2024-03-13 10:53:39 +08:00
MystiPanda
462fb05ea8 fix: Try to fix #577 again 2024-03-11 22:52:29 +08:00
MystiPanda
812dbfd836 fix: script 2024-03-11 22:10:20 +08:00
MystiPanda
cfca837777 fix: typo 2024-03-11 22:05:56 +08:00
MystiPanda
ac5fb1948a fix: Try to fix #577 2024-03-11 22:03:45 +08:00
MystiPanda
22d8b73625 feat: Allow open devtools 2024-03-11 20:19:21 +08:00
MystiPanda
edde40c298 docs: Update Readme 2024-03-11 18:38:58 +08:00
MystiPanda
50ade92238 Release 1.5.7 2024-03-11 17:09:01 +08:00
MystiPanda
b598d00aef fix: display error 2024-03-11 16:18:39 +08:00
MystiPanda
97bee17e4e chore: Change IP 2024-03-11 16:05:09 +08:00
MystiPanda
6aa5c79332 fix: a little 2024-03-11 15:02:41 +08:00
MystiPanda
7c5ce756f9 fix: Change DNS for MacOS Tun Mode
#568
2024-03-11 14:55:00 +08:00
MystiPanda
43d53a9ffa fix: default value 2024-03-11 13:17:45 +08:00
MystiPanda
e6589bee5b fix: Try to fix touch drag
#456
2024-03-11 12:36:20 +08:00
MystiPanda
9f94cad615 feat: Allow to control whether auto check update 2024-03-11 12:17:46 +08:00
MystiPanda
7778d9f773 style: fix a little 2024-03-10 23:56:04 +08:00
MystiPanda
564bd55147 style: fix styles 2024-03-10 23:47:12 +08:00
MystiPanda
a7ff806522 fix styles 2024-03-10 22:13:25 +08:00
MystiPanda
ac3b074d66 chore: proxy group header height 2024-03-10 21:56:49 +08:00
MystiPanda
da949c2604 chore: adjust proxy group font style 2024-03-10 21:52:40 +08:00
MystiPanda
20a9775dc6 chore: Adjust Profile Style 2024-03-10 21:37:52 +08:00
MystiPanda
8ec19e058f chore: Add Default value 2024-03-10 21:15:22 +08:00
MystiPanda
a5c4549722 style: Adjust icon color 2024-03-10 20:48:13 +08:00
Amnesiash
c7d302aa16
style: Adjust colorful icon (#558)
Co-authored-by: MystiPanda <mystipanda@proton.me>
2024-03-10 20:37:00 +08:00
MystiPanda
77ac565ff3 chore: i18n 2024-03-10 20:33:27 +08:00
MystiPanda
2e6f834a50 chore: Update Icon 2024-03-10 20:14:51 +08:00
MystiPanda
5b044cca9e feat: Add option to control menu icon 2024-03-10 19:54:47 +08:00
MystiPanda
2ab5623809 chore: Adjust styles 2024-03-10 13:24:38 +08:00
MystiPanda
2d07f0d77c Revert "chore: Adjust secondary text style (#545)"
This reverts commit 8ba7f9f70216ac3ae5ff2ac859ec2170737d0cd1.
2024-03-10 13:08:09 +08:00
Amnesiash
8ba7f9f702
chore: Adjust secondary text style (#545) 2024-03-10 12:54:34 +08:00
MystiPanda
460ac7a86b style: Adjust delay fontSize
#544
2024-03-10 12:51:53 +08:00
MystiPanda
f93a1ab3eb docs: update preview 2024-03-10 12:32:08 +08:00
MystiPanda
6b02696aa8 chore: Change Default Font 2024-03-10 12:23:11 +08:00
MystiPanda
25f20d6a85 chore: delete debug output 2024-03-10 11:47:55 +08:00
MystiPanda
8387964bae Release 1.5.6 2024-03-10 11:43:37 +08:00
MystiPanda
926278617f feat: Add default webui
#530
2024-03-10 11:41:22 +08:00
MystiPanda
1933737a0c Adjust styles 2024-03-10 11:21:17 +08:00
MystiPanda
b3e5288bde Adjust styles 2024-03-10 11:12:54 +08:00
wonfen
ed6e966b2f Sytle: UI improvement & Update Readme 2024-03-10 07:00:24 +08:00
MystiPanda
9315fe36b6 fix: fix a little 2024-03-10 00:41:18 +08:00
black23eep
41fbf5ba36
Update layout-traffic.tsx (#528) 2024-03-10 00:35:26 +08:00
MystiPanda
40db481453 chore: update 2024-03-10 00:34:22 +08:00
MystiPanda
1b5e295744 fix: fontSize and some styles 2024-03-10 00:22:22 +08:00
Amnesiash
b42a52f7f6
fix settings.svg (#526) 2024-03-10 00:04:06 +08:00
MystiPanda
8268df84d0 chore: center 2024-03-09 23:38:03 +08:00
Charles
eb6fa5f1f1
tweak(ui): menu icon use svg component (#524) 2024-03-09 23:13:08 +08:00
MystiPanda
025c8856ed fix: img path error 2024-03-09 22:43:53 +08:00
MystiPanda
ed421445e9 Release 1.5.5 2024-03-09 22:02:36 +08:00
Amnesiash
0cda07106b
refactor: Upgrade to the new UI (#521)
Co-authored-by: MystiPanda <mystipanda@proton.me>
2024-03-09 21:37:21 +08:00
wonfen
f335941b62 UI: change paste icon, delete default profile name 2024-03-09 02:34:33 +08:00
Pylogmon
f0719f8bde
feat: Merge Providers (#508) 2024-03-08 11:37:52 +08:00
MystiPanda
27fe28661c
feat: Add animation for provider update 2024-03-02 13:52:48 +08:00
MystiPanda
bb13b12de6
chore: fix style 2024-02-28 18:25:50 +08:00
MystiPanda
1117e28b2e
feat: Try to support touch drag 2024-02-27 23:41:52 +08:00
MystiPanda
0f48873c25
chore: Remove unnecessary hotkey 2024-02-27 11:18:52 +08:00
MystiPanda
faf61b4af3
fix: Image display failed on Linux 2024-02-26 13:31:51 +08:00
Cyenoch
e29ce93d32
Feat: Provide a switch for allowing invalid certificates (#450) 2024-02-25 16:07:06 +08:00
MystiPanda
38ab68492e
chore: change style 2024-02-24 15:39:29 +08:00
MystiPanda
53b1576e5f
Release 1.5.4 2024-02-24 14:00:01 +08:00
MystiPanda
2835e79973
feat: Support Open/Close Dashboard Hotkey
#439
2024-02-24 13:39:30 +08:00
MystiPanda
8e4d7e989b
feat: Show current proxy for group node
#444
2024-02-24 13:09:53 +08:00
MystiPanda
603c6b826c
feat: allow disable group icon 2024-02-24 12:38:17 +08:00
MystiPanda
51bcc77cb3
refactor: Optimize implementation of Custom tray icon 2024-02-24 11:25:22 +08:00
MystiPanda
a30d07b924
feat: Support Custom Tray Icon 2024-02-24 00:52:21 +08:00
MystiPanda
11faa5fe39
Release 1.5.3 2024-02-22 00:23:56 +08:00
MystiPanda
ce8383b26f
feat: add reset button 2024-02-22 00:19:45 +08:00
MystiPanda
bd8f07c90a
fix: Do not set autolaunch at init
#423 #424
2024-02-21 23:50:50 +08:00
MystiPanda
fee077bebd
chore: rm -m arg 2024-02-21 23:38:01 +08:00
MystiPanda
558f4d93ba
chore: change default value of dns hijack 2024-02-21 16:40:47 +08:00
MystiPanda
e77d126349
chore: change default value of strict route 2024-02-21 11:32:51 +08:00
MystiPanda
cd8667d6de
chore: fix placeholder 2024-02-21 11:13:28 +08:00
MystiPanda
8a2d06d010
chore: Add Translation 2024-02-21 11:06:32 +08:00
MystiPanda
92741fc733
feat: Disable system stack when service mode is turned off 2024-02-21 10:52:03 +08:00
MystiPanda
1cff162649
fix: Config data display error
#417
2024-02-21 10:02:28 +08:00
MystiPanda
f59be465ea
Release 1.5.2 2024-02-21 00:04:11 +08:00
MystiPanda
27305317ce
chore: Auto Update config.yml 2024-02-20 23:54:02 +08:00
MystiPanda
8378320e50
feat: Support Tun Config (#416) 2024-02-20 23:27:03 +08:00
MystiPanda
86a69952db
chore: Update patch file 2024-02-20 18:39:36 +08:00
MystiPanda
e212ebfdb9
fix: Allow program run with administrator to start at startup 2024-02-20 18:35:39 +08:00
MystiPanda
f235125d48
chore: add tooltip for tun mode 2024-02-19 18:10:10 +08:00
MystiPanda
8efa815eb9
feat: Support custom delay timeout (#397) 2024-02-18 11:11:22 +08:00
MystiPanda
e54d42576b
build: Try restart windows service after install (#395) 2024-02-18 10:19:54 +08:00
MystiPanda
1e18539862 fix: Merge profile unexpect behavior 2024-02-17 15:58:52 +08:00
MystiPanda
673fdf4721 ci: Update Release Note 2024-02-15 20:05:00 +08:00
MystiPanda
57d6bfba51 ci: change tag 2024-02-15 19:45:37 +08:00
MystiPanda
8fa23aecda chore: update ci script 2024-02-15 19:14:35 +08:00
MystiPanda
f9c10533e8 chore: Change CI Name 2024-02-15 18:45:13 +08:00
MystiPanda
c891c3723e ci: Support alpha package 2024-02-15 18:43:20 +08:00
MystiPanda
a0625ef2e7 chore: remove 32bit package 2024-02-15 18:22:15 +08:00
MystiPanda
b2774abb54 chore: default show proxy detials 2024-02-15 18:17:21 +08:00
wonfen
fa089bbc40 doc: remove 32bit package 2024-02-12 02:25:18 +08:00
MystiPanda
8437d1763f fix: build error 2024-02-11 20:51:00 +08:00
MystiPanda
0532b0f9df Release v1.5.1 2024-02-11 20:32:25 +08:00
MystiPanda
5f8eb853f0 style: clear script 2024-02-11 20:03:14 +08:00
MystiPanda
9125a85382 fix: Custom GLOBAL group display error 2024-02-11 18:27:27 +08:00
MystiPanda
5b3dc44c72 feat: Show proxies count for provider 2024-02-10 13:13:27 +08:00
MystiPanda
ee5147f111 feat: Save window maximize state 2024-02-10 12:51:30 +08:00
MystiPanda
f67137fd5e style: change config name
#350
2024-02-08 10:23:54 +08:00
MystiPanda
b67db4a896 fix: Script profile invalid
#347
2024-02-06 08:55:44 +08:00
MystiPanda
067018828c Release 1.5.0 2024-02-06 00:41:12 +08:00
MystiPanda
e990530ada refactor: Remove clash field filter 2024-02-05 17:28:36 +08:00
wonfen
45f863a72a chore: enable clash field TLS fingerprint 2024-02-04 13:07:25 +08:00
MystiPanda
519febbeb2 fix: Try to fix traffic parse error
#337
2024-02-04 10:24:37 +08:00
wonfen
854b1a4caf chore: update changelog 2024-02-03 16:14:26 +08:00
MystiPanda
08eb95e73a fix: Copy Env Type Select Error 2024-02-02 17:57:56 +08:00
MystiPanda
66f8fbf08c chore: typo 2024-02-02 17:47:28 +08:00
MystiPanda
86a30bbb29 chore: Update Changelog 2024-02-02 17:34:15 +08:00
MystiPanda
966c453c27 fix: prevent_exit 2024-02-02 17:26:31 +08:00
MystiPanda
c7bcaf0193 Release 1.4.11 2024-02-02 16:56:39 +08:00
MystiPanda
0ac91e36a0 fix: exit_app event 2024-02-02 16:32:19 +08:00
MystiPanda
6f1299ce9e chore: fix styles 2024-02-02 16:15:23 +08:00
MystiPanda
83ca29d649 chore: Remove prevent_close 2024-02-02 15:57:03 +08:00
MystiPanda
d0206044dc fix: Fix Nisi Error 2024-02-02 15:53:28 +08:00
ycjcl868
d4623e4175
chore: unused clash core (#284) 2024-01-23 11:22:15 +08:00
MystiPanda
68ef03377d chore: fix style 2024-01-21 13:49:07 +08:00
MystiPanda
d3f9d3d033 revert: some style 2024-01-21 13:49:07 +08:00
wonfen
a6ccd04471 Sytle: UI improvement 2024-01-20 16:05:01 +08:00
Lai Zn
0fd8174e77
fix: Solve the confliction issues on auto updater failure (#273) 2024-01-20 13:03:48 +08:00
MystiPanda
ebc63f479a revert: Support both registry and api for windows sysproxy 2024-01-20 12:16:46 +08:00
MystiPanda
570c39c20a build: Update lock file 2024-01-18 22:34:14 +08:00
MystiPanda
1d57257cf5 Release v1.4.10 2024-01-18 22:26:23 +08:00
MystiPanda
82d7baee0b feat: Add exit button on setting page 2024-01-18 22:19:14 +08:00
MystiPanda
1d91e1f1f7 build: Update Depends 2024-01-18 16:26:38 +08:00
MystiPanda
15e8894614 feat: Support Custom Start Page 2024-01-18 15:37:02 +08:00
Lai Zn
0ae96918e9
feat: Use url path name as fallback subscription name (#255) 2024-01-18 14:36:37 +08:00
MystiPanda
e970880059 feat: Show SubInfo for Proxy Provider
#211
2024-01-18 14:26:57 +08:00
Lai Zn
69ae86aba8
fix: make port change set to system proxy immediately (#256) 2024-01-18 09:37:46 +08:00
MystiPanda
8142e1be49 fix: use nanoid to compatible with old devices 2024-01-18 01:16:39 +08:00
MystiPanda
cbc7612451 feat: Optimizing Provider Support 2024-01-18 01:02:30 +08:00
Kiri
09e6a7b7cc
feat: Add support for loong64 (#246) 2024-01-17 22:30:51 +08:00
Lai Zn
082e35668a
docs: Add guidelines for windows development (#250) 2024-01-17 19:02:39 +08:00
MystiPanda
c9e78c837b fix: Do not use proxy when test on tun mode 2024-01-17 18:08:09 +08:00
MystiPanda
2d171db672 Release v1.4.9 2024-01-17 15:43:15 +08:00
MystiPanda
a8b11abec8 feat: Support Startup Script 2024-01-17 15:06:16 +08:00
MystiPanda
b08333dccd feat: Support proxy group icon 2024-01-17 13:32:56 +08:00
MystiPanda
98bad48971 fix: Fix connection table sort error
#108
2024-01-17 12:54:54 +08:00
MystiPanda
53375bb536 chore: Update I18n 2024-01-17 11:30:19 +08:00
MystiPanda
88798093e1 fix: csp error 2024-01-17 11:08:14 +08:00
MystiPanda
45a28751af feat: Add Test Page 2024-01-17 11:02:17 +08:00
MystiPanda
1670c44464 fix: fix column width 2024-01-16 19:02:38 +08:00
MystiPanda
a286ac85dc Release v1.4.8 2024-01-16 15:36:04 +08:00
MystiPanda
1606adc0ab feat: Support both registry and api for windows sysproxy 2024-01-16 15:11:53 +08:00
MystiPanda
b4ce557d92 fix: Can not use specify update time when create profile 2024-01-16 10:29:04 +08:00
MystiPanda
2ba7fff8d4 refactor: rm theme blur 2024-01-15 17:13:55 +08:00
MystiPanda
98efc93610 Revert Use Tauri Http Api 2024-01-15 10:18:04 +08:00
MystiPanda
2680507eae Revert Use Tauri Websocket 2024-01-15 10:17:00 +08:00
MystiPanda
df72392ad2 fix: Fix connections sort issue and add total traffic info 2024-01-15 00:46:19 +08:00
MystiPanda
a6acb15a00 refactor: Use Tauri Http API 2024-01-14 19:35:03 +08:00
MystiPanda
ba7242a815 refactor: Use Tauri WebSocket 2024-01-14 17:30:18 +08:00
MystiPanda
99740c1324 fix patch error 2024-01-11 14:47:25 +08:00
MystiPanda
c04b20d1fa Release v1.4.7 2024-01-11 13:19:05 +08:00
MystiPanda
e127067878 feat: Disable updater for portable 2024-01-11 12:44:30 +08:00
MystiPanda
6f03b72368 feat: Support hide group
#214
2024-01-11 12:34:05 +08:00
Morris Li
7bd3ee9340
Fix expired Tauri domain (#222) 2024-01-11 10:17:56 +08:00
MystiPanda
c94db606e5 build: Use old sysproxy 2024-01-10 19:24:14 +08:00
MystiPanda
4d2474226b refactor: cargo clippy 2024-01-10 17:36:35 +08:00
MystiPanda
1ffc4f538b refactor: Optimizing the implementation of Linux URL Scheme registration 2024-01-10 16:34:35 +08:00
MystiPanda
6702ac957b fix: resolve scheme error 2024-01-10 15:37:40 +08:00
MystiPanda
ba42b2e77d fix: linux build error 2024-01-10 15:22:08 +08:00
MystiPanda
fba18ca40a feat: Support URL Scheme for MacOS 2024-01-10 14:04:06 +08:00
MystiPanda
3a2a7a1476 feat: Support URL Scheme for Linux 2024-01-10 13:03:34 +08:00
MystiPanda
3c6d6b90bc build: fix macos build script 2024-01-09 22:49:11 +08:00
MystiPanda
47dc9ee304 fix patch error 2024-01-09 22:25:25 +08:00
MystiPanda
0045bf206c Release v1.4.6 2024-01-09 22:17:29 +08:00
MystiPanda
669a1a6953 feat: Support URL Scheme for Windows
#165
2024-01-09 21:57:06 +08:00
MystiPanda
e28452cc7b feat: Optimize control button style 2024-01-09 16:04:56 +08:00
MystiPanda
5ceac03db1 feat: Add pin button 2024-01-09 15:13:59 +08:00
MystiPanda
96215e5950 fix: Fix some compile error 2024-01-09 14:52:43 +08:00
wonfen
7a030b9224 Style: UI improvement & 1.4.6 ready 2024-01-09 13:57:53 +08:00
wonfen
e743478a4d chore: UI adjustment 2024-01-08 19:32:21 +08:00
MystiPanda
bc29c80d44 chore: Use Latest and compatible core 2023-12-23 12:09:19 +08:00
MystiPanda
82b8a474d7 fix: Cargo clippy 2023-12-21 16:49:21 +08:00
MystiPanda
99851b297d fix: Get filename error
#165
2023-12-19 19:52:13 +08:00
MystiPanda
e3a500e12c fix: portable flag 2023-12-15 21:39:34 +08:00
MystiPanda
378666e3cc chore: update service url 2023-12-15 20:38:17 +08:00
MystiPanda
b65ad1ebd7 fix: user-agent version error 2023-12-15 15:18:01 +08:00
MystiPanda
933a821b5f fix: Subinfo parse error 2023-12-15 11:35:10 +08:00
MystiPanda
159337ddbd Release 1.4.5 2023-12-14 17:40:48 +08:00
MystiPanda
2e25a4333a fix: Window control button icon issue
#136
2023-12-14 14:59:55 +08:00
MystiPanda
64fafb0795 chore: Remove unsafe function 2023-12-14 13:56:51 +08:00
MystiPanda
5927e0bb3b fix: icon size 2023-12-14 13:20:01 +08:00
MystiPanda
e21596db83 feat: Update MacOS tray icon 2023-12-14 13:11:46 +08:00
MystiPanda
8a608c3c3e chore: Optimize service path 2023-12-14 13:03:52 +08:00
MystiPanda
76f9db8516 chore: Optimize upgrade process 2023-12-14 11:24:26 +08:00
MystiPanda
90f4809b7c chore: default enable clash field filter 2023-12-14 10:49:58 +08:00
MystiPanda
3ff1af9fd6 chore: Delete unnecessary drag area 2023-12-13 11:09:19 +08:00
MystiPanda
711dd520f7 chore: Change service path 2023-12-13 10:59:07 +08:00
MystiPanda
99503c836a fix: Save wrong window size 2023-12-12 16:42:19 +08:00
MystiPanda
2c8bc51862 Revert "fix: Change PID file path"
This reverts commit d64bdf02de5bb0c34c2165e3dddcb239e6c26034.
2023-12-12 15:59:00 +08:00
MystiPanda
5e7aa15232 fix: Can't switch env type 2023-12-11 10:51:59 +08:00
MystiPanda
d0761869b6 build: fix update issue 2023-12-10 22:24:46 +08:00
MystiPanda
bb99b89228 build: fix patch 2023-12-10 21:40:57 +08:00
MystiPanda
7b88beb0b5 v1.4.4 2023-12-10 21:36:22 +08:00
MystiPanda
82c630bd0e
feat: Support windows aarch64 (#112) 2023-12-10 20:45:27 +08:00
MystiPanda
bb4f11e1b8 feat: Patch for windows aarch64 2023-12-10 19:50:01 +08:00
MystiPanda
3182d20b7c build: Update Depends 2023-12-10 17:14:48 +08:00
MystiPanda
a6f15e2474 chore: Hide script mode for alpha core 2023-12-10 16:31:55 +08:00
MystiPanda
0c3f03680c Support upgrade alpha core 2023-12-10 15:57:10 +08:00
MystiPanda
a66e8dfc9f feat: Support update geodata
#37
2023-12-10 15:22:04 +08:00
zclkkk
556232aac4
chore: Allow user to choose where to install (#110) 2023-12-10 09:50:43 +08:00
MystiPanda
7fcfaadd91 chore: Remove script mode 2023-12-09 17:04:03 +08:00
MystiPanda
18d388e1e2 docs: Update ISSUE_TEMPLATE 2023-12-09 12:00:01 +08:00
MystiPanda
7de6622d74 feat: Support different tray icon for macos 2023-12-09 11:22:02 +08:00
MystiPanda
9af1f90990 feat: Support different tray icon for linux 2023-12-09 11:03:19 +08:00
Pylogmon
15ab43963d
feat: Optimize copy environment variable logic (#106) 2023-12-08 22:16:42 +08:00
MystiPanda
6b7465a4b0 perf: Improves window creation speed 2023-12-08 13:10:35 +08:00
MystiPanda
d64bdf02de fix: Change PID file path
#99
2023-12-08 11:59:40 +08:00
MystiPanda
4a2c94993a docs: Update README 2023-12-07 16:49:59 +08:00
MystiPanda
86c318d86b feat: Add AppImage for x86 linux 2023-12-07 16:38:39 +08:00
MystiPanda
bffc1ad41d ci: fix build script 2023-12-07 16:17:34 +08:00
MystiPanda
2a685c116f chore: Fix build error 2023-12-07 16:02:29 +08:00
MystiPanda
0e271d2924 ci: Fix Linux CI Script 2023-12-07 15:57:53 +08:00
MystiPanda
7127c4d590 ci: Fix Linux Build Script 2023-12-07 15:34:49 +08:00
MystiPanda
a82929996b chore: change default port to 7897 2023-12-07 14:52:14 +08:00
MystiPanda
3f01f52c7b refactor: fix depends 2023-12-07 14:44:44 +08:00
MystiPanda
9c94494622 refactor: Remove unnecessary changes 2023-12-07 13:43:53 +08:00
MystiPanda
c8a508f35c Revert "chore: change default port to 7897"
This reverts commit 4ec73ef1c3e546d36706a034f65781cf0694deed.
2023-12-07 13:32:49 +08:00
wonfen
4ec73ef1c3 chore: change default port to 7897 2023-12-06 03:37:16 +08:00
MystiPanda
3465b79e5b docs: Update README 2023-12-05 17:02:54 +08:00
MystiPanda
726a0a33ae docs: UPDATELOG 2023-12-05 16:47:42 +08:00
MystiPanda
ba05810d80 Release 1.4.3 2023-12-05 16:28:50 +08:00
MystiPanda
10bb53e7de chore: fix appid 2023-12-05 15:41:13 +08:00
MystiPanda
dd8a083546 refactor: Change app_home to standard locations of app_data 2023-12-05 15:39:44 +08:00
MystiPanda
84131a71c9 fix: Stop core before install update 2023-12-05 15:01:15 +08:00
MystiPanda
4909a11896 docs: Update README 2023-12-05 13:33:23 +08:00
MystiPanda
4069357b81 refactor: Remove page animation 2023-12-05 13:30:55 +08:00
MystiPanda
e6e87bcc40 refactor: Change Tun Icon Color 2023-12-05 13:23:54 +08:00
MystiPanda
7ba22045e8 build: Dependency downgrade 2023-12-05 12:55:20 +08:00
Pylogmon
d4040b61c4
refactor: Change Portable Config Path (#66) 2023-12-05 12:52:26 +08:00
Pylogmon
7534f8fc37
refactor: Hide Clash Field Option when Disable Filter (#63) 2023-12-05 08:34:57 +08:00
MystiPanda
7ced009e92
Update README.md 2023-12-04 14:51:46 +08:00
MystiPanda
cc13c71e40 ci: fix updater 2023-12-04 13:51:46 +08:00
MystiPanda
d2f09209a7 chore: Use Nsis 2023-12-04 13:45:28 +08:00
Pylogmon
a241b04d99
fix: Open File (#56) 2023-12-04 12:15:12 +08:00
Pylogmon
4f35d907cb
fix: Get Profile Filename (#54) 2023-12-04 12:15:01 +08:00
MystiPanda
9e50d144a3
chore: change linux meta core to compatible 2023-12-04 11:38:54 +08:00
wonfen
8514bb48c4 chore: change windows meta core to compatible 2023-12-04 06:00:31 +08:00
WhizPanda
3ae633a2a1 fix: alpha core can't display memory 2023-12-03 18:55:38 +08:00
WhizPanda
2799cb9118 style: fix icon size 2023-12-03 18:28:41 +08:00
WhizPanda
d20346b6ac docs: Update README.md 2023-12-03 16:42:49 +08:00
Pylogmon
2f00666a68
style: improve drag icon style (#51) 2023-12-03 16:27:13 +08:00
WhizPanda
80f4570093 ci: Fix Portable Script 2023-12-03 15:36:39 +08:00
wonfen
3f0a2ba48f docs: update readme 2023-12-03 15:25:33 +08:00
WhizPanda
fc90094e8a
feat: Support Both Stable and Alpha Version (#47) 2023-12-03 14:26:03 +08:00
wonfen
20d580ade8 release: 1.4.2, tweak UI, fix emoji on mac 2023-12-03 14:01:53 +08:00
WhizPanda
290a024a9e chore: Adjust style 2023-12-02 23:20:04 +08:00
WhizPanda
64a283c3a6 chore: Replace Repo Name 2023-12-02 23:04:04 +08:00
WhizPanda
3e93f0ecbc build: Update Depends 2023-12-02 22:36:04 +08:00
WhizPanda
b12bcc1c49 style: Improve Style 2023-12-02 16:23:53 +08:00
WhizPanda
05d7313dcc feat: Support New Clash Field
#46
2023-12-02 15:18:54 +08:00
WhizPanda
c0b6e549f0 build: Update Cargo Depends 2023-12-01 15:52:49 +08:00
WhizPanda
31f9bf219e build: Update Depends 2023-12-01 14:49:32 +08:00
WhizPanda
4906ca7059 feat: support random mixed port 2023-12-01 12:56:18 +08:00
WhizPanda
b963a7a0e5
fix: Fix Updater Script 2023-12-01 11:19:49 +08:00
WhizPanda
5d6dadda76
Remove unnecessary conditions 2023-12-01 11:11:20 +08:00
Pylogmon
77f69fd223
feat: Add Windows x86 and Linux armv7 Support (#44)
* feat: Add Windows x86 and Linux armv7 Support

* ci: Remove Linux armv7 Support
2023-12-01 11:03:18 +08:00
Pylogmon
7f5052bc87
feat: Use Latest Meta Core mihomo (#41) 2023-12-01 02:44:18 +08:00
Pylogmon
3009c1f4f6
feat: Support cross-compiling to aarch64 (#40)
#19
2023-11-30 22:46:09 +08:00
Pylogmon
5425872bba
feat: Support Disable Tray Click Event (#38)
#21
2023-11-30 22:45:02 +08:00
Pylogmon
0759e17295
feat: Set different tray icon on tun mode (#33)
好看!
2023-11-30 01:29:11 +08:00
Pylogmon
56a59d25df
feat: Add Download Progress for Updater (#34) 2023-11-30 01:28:46 +08:00
Pylogmon
887f92babe
feat: Support Drag to Reorder the Profile (#29)
* feat: Support Drag to Reorder the Profile

* style: Remove unnecessary styles
2023-11-29 08:54:02 +08:00
wonfen
197f942b3f
Merge pull request #27 from Pylogmon/emoji-font
feat: Embed Emoji fonts
2023-11-28 10:41:35 +08:00
Pylogmon
a5be7a35e9 feat: Embed Emoji fonts 2023-11-28 10:36:32 +08:00
wonfen
e347675265 fix: Adjust font order 2023-11-28 10:03:01 +08:00
wonfen
02a084d571 chore: update preview gif 2023-11-28 08:49:22 +08:00
wonfen
7fbcc23d94 Merge branch 'main' of github.com:wonfen/clash-verge-rev 2023-11-28 07:53:11 +08:00
wonfen
bda87167a3 update clashmeta core, Imporve UI, merge PR, reset icons, fix CI 2023-11-28 07:49:44 +08:00
wonfen
34f53c287e
Merge pull request #24 from Pylogmon/tray
fix: Tray Icon Tooltip is Empty
2023-11-28 01:46:41 +08:00
wonfen
9ab07f37d7
Merge pull request #21 from Pylogmon/tray-event
feat: Config Tray Click Event
2023-11-28 01:46:16 +08:00
Pylogmon
36399b39fb chore: fix style 2023-11-27 20:10:31 +08:00
Pylogmon
1e015287a1 chore: Add Translation 2023-11-27 20:04:47 +08:00
Pylogmon
a590aa8485 fix: Tray Icon Tooltip is Empty 2023-11-27 19:55:42 +08:00
Pylogmon
c0582fde66 chore: Remove Debug Info 2023-11-26 18:49:48 +08:00
Pylogmon
d8d75b4afa feat: Config Tray Click Event 2023-11-26 18:35:21 +08:00
wonfen
9d4942723c fix: portable CI again 2023-11-23 15:01:30 +08:00
wonfen
e5b1ece5c0 chore: change preview gif and fix portable CI 2023-11-23 14:34:11 +08:00
wonfen
1b25bfbf5a fix: CI portable 2023-11-23 13:42:16 +08:00
wonfen
7c64d9f42a
Merge pull request #3 from Kuingsmile/main
fix: Downgrade runas to fix service install bug
2023-11-23 11:11:06 +08:00
wonfen
61f9f4ef58 chore: update clash.meta core to 2023.11.23, change win icons. 2023-11-23 11:10:32 +08:00
Kuingsmile
b8eac56213 fix: Downgrade runas to fix service install bug 2023-11-22 17:17:12 -08:00
wonfen
ab5fb5749b
Merge pull request #2 from Kuingsmile/main
feat: Update DialogContent width in EditorViewer
2023-11-23 07:46:12 +08:00
Kuingsmile
e0fb9a1b25 feat: Update DialogContent width in EditorViewer
component
2023-11-22 06:49:47 -08:00
wonfen
97e717f646
Merge pull request #1 from Kuingsmile/main
feat: add UWP loopback tools
2023-11-22 16:23:38 +08:00
Kuingsmile
caa82ad1e6 feat: add UWP loopback tools 2023-11-22 00:15:41 -08:00
wonfen
7ec251ea6d chore: UI adjustment, add translation, fix CI 2023-11-22 14:52:14 +08:00
wonfen
675b0c3cca chore: update readme & fix updater issue 2023-11-22 07:31:38 +08:00
wonfen
05e54d4b7f chore: remove old updater CI 2023-11-22 07:06:08 +08:00
wonfen
b4527c90e5 Merge remote-tracking branch 'nyanpasu/main' 2023-11-22 06:48:30 +08:00
wonfen
dbc626734d chore: delete clash core, update CI, change profile name, change URL test link 2023-11-22 02:56:47 +08:00
keiko233
3f2ce3cb80 chore: fix typos 2023-11-16 11:31:06 +08:00
keiko233
0820d6d6fb chore: add updater workflow 2023-11-16 10:59:27 +08:00
keiko233
a8c74e39c2 chore: remove un supported platform
* I don't have the relevant equipment to test with
* May support in future
2023-11-16 10:56:03 +08:00
keiko233
d58c29907d chore: no need for second build 2023-11-16 10:41:28 +08:00
keiko233
2322733427 chore: fix missing assets type 2023-11-16 10:37:26 +08:00
keiko233
d76e8fe85a chore: remove un supported platform 2023-11-16 10:30:25 +08:00
keiko233
0c2e4fe34a chore: fix typos 2023-11-16 10:30:01 +08:00
keiko233
30b6c87a49 docs: add preview gif 2023-11-15 15:17:51 +08:00
keiko233
540221467a chore: clean up workflows 2023-11-15 14:37:10 +08:00
keiko233
d44d331a78 Bump Version 1.4.0 2023-11-15 14:06:29 +08:00
keiko233
595554f18a chore: add release build 2023-11-15 13:52:56 +08:00
keiko233
84d3c3f7eb fix: rust lint 2023-11-15 13:49:06 +08:00
keiko233
890f55c9dc chore: test: use pnpm 2023-11-13 14:49:28 +08:00
keiko233
575a14e1f3 feat: minor tweaks 2023-11-12 00:10:23 +08:00
keiko233
91074bebd6 feat: Nyanpasu Misc 2023-11-12 00:09:32 +08:00
keiko233
3459a16b48 chore: switch updater endpoints 2023-11-12 00:08:23 +08:00
keiko233
88c9b6849f fix: valid with unified-delay & tcp-concurrent 2023-11-11 22:34:30 +08:00
keiko233
d87bb25baf chore: delete current release assets 2023-11-11 22:27:28 +08:00
keiko233
34cb796505 feat: add baseContentIn animation 2023-11-11 19:34:03 +08:00
keiko233
1eb34e0662 feat: add route transition 2023-11-11 18:32:11 +08:00
keiko233
01d631033f feat: Material You! 2023-11-11 17:12:57 +08:00
keiko233
84b2c07340 fix: touchpad scrolling causes blank area to appear 2023-11-11 15:03:41 +08:00
keiko233
a86eeb636d chore: drop upload-artifact & use prerelease 2023-11-11 15:00:54 +08:00
keiko233
417a5a8214 chore: fix: typos
* ↑ baka
2023-11-10 11:50:01 +08:00
keiko233
bcf40dde8c fix: typos 2023-11-10 11:35:38 +08:00
keiko233
cad87484c7 fix: download clash core from backup repo 2023-11-10 11:26:05 +08:00
keiko233
b8ad641ed6 chore: add dev workflow 2023-11-10 10:38:41 +08:00
keiko233
ae8197be8b feat: default disable ipv6 2023-11-10 09:10:15 +08:00
keiko233
eafb0274a7 feat: default enable unified-delay & tcp-concurrent with use meta core 2023-11-10 09:08:17 +08:00
keiko233
71a23a4e02 refactor: copy_clash_env 2023-11-09 10:52:52 +08:00
keiko233
26fd90dfa3 feat: support copy CMD & PowerShell proxy env 2023-11-09 09:58:17 +08:00
keiko233
e393ebede2 fix: use meta Country.mmdb 2023-11-09 09:35:41 +08:00
keiko233
2981bb3f19 feat: default use meta core
* :)
2023-11-09 09:34:03 +08:00
keiko233
6e9f05abb1 feat: update Clash Default bypass addrs
*Enabling TUN will cause the local address to go through the proxy
2023-11-09 09:33:38 +08:00
GyDi
9df1115380 chore: fix check 2023-11-03 16:00:34 +08:00
GyDi
f22e360cbb chore: fix check script 2023-11-03 15:52:36 +08:00
MZhao
67769af6f4
feat: new windows tray icons (#899) 2023-11-03 15:01:46 +08:00
Aromia
b1a9a1d6d9
chore: update download links in README.md (#896) 2023-11-03 11:21:20 +08:00
Goooler
cf0606ecb7
chore: bump github actions (#868)
https://github.com/actions/checkout/releases/tag/v4.0.0
https://github.com/actions/setup-node/releases/tag/v4.0.0
2023-11-02 20:14:05 +08:00
neovali
7287edcd6f
chore: add fedora linux install description (#874) 2023-11-02 20:13:24 +08:00
GyDi
e0d26203dd feat: support auto clean log files 2023-11-02 20:12:46 +08:00
GyDi
7e3a85e9da
fix: latency url empty 2023-11-01 23:22:30 +08:00
GyDi
5a0fed9c93 feat: increase the concurrency of latency test 2023-11-01 20:52:38 +08:00
GyDi
1f1e743912
fix: change default port 2023-10-31 14:56:19 +08:00
GyDi
b4301ed0d5
fix: csp 2023-10-31 12:00:57 +08:00
GyDi
b5391560fc
v1.3.8 2023-10-31 01:29:20 +08:00
GyDi
718989cbcf
chore: update log 2023-10-31 01:28:57 +08:00
GyDi
d0aee76962
fix: add default valid key 2023-10-30 17:10:51 +08:00
GyDi
fb08af96bd
fix: page null exception, close #821 2023-10-30 00:53:24 +08:00
GyDi
510a0c5e70
feat: adjust the delay display interval and color, close #836 2023-10-29 23:01:05 +08:00
keiko233
89bdc8ec75 chore: update dependencies 2023-10-22 00:44:01 +08:00
keiko233
ae25ade318 chore: tsconfig: skip Lib Check 2023-10-21 23:53:57 +08:00
keiko233
dd5e46a8a7 feat: theme: change color 2023-10-21 17:30:50 +08:00
keiko233
f7218aaa9e chore: update README.md 2023-10-21 17:02:13 +08:00
keiko233
ee79bcfc44 feat: profiles: import btn with loading state 2023-10-21 16:50:46 +08:00
keiko233
2c2c174874 feat: profile-viewer: handleOk with loading state 2023-10-21 16:47:39 +08:00
keiko233
f57c49ce3a feat: base-dialog: okBtn use LoadingButton 2023-10-21 16:47:10 +08:00
keiko233
06121acfac chore: import MUI Lab 2023-10-21 16:43:30 +08:00
keiko233
2078ce7446 chore: Update dependencies 2023-10-21 16:43:16 +08:00
keiko233
49f41abfdb feat: Nyanpasu Misc 2023-10-20 11:52:40 +08:00
keiko233
70fcfe6d6c feat: Theme support modify --background-color 2023-10-20 11:12:49 +08:00
keiko233
b060b4b9bf feat: settings use Grid layout 2023-10-20 10:05:03 +08:00
keiko233
ee2135bfb3 chore: Use your own update endpoints and public keys 2023-10-19 09:37:31 +08:00
keiko233
7daa322441 chore: readme remove ad 2023-10-18 13:38:58 +08:00
GyDi
74252cb66b chore: fix rust lint 2023-10-18 13:38:03 +08:00
GyDi
5fe2be031f
chore: fix rust lint 2023-10-11 14:55:20 +08:00
GyDi
2ba3aaba47
chore: fix alpha ci 2023-10-11 14:31:44 +08:00
GyDi
ad8903991c
fix: try fix csp 2023-10-11 14:21:56 +08:00
GyDi
3e5624c570
chore: update readme 2023-10-11 00:04:56 +08:00
keiko233
88d3bba300 feat: add Connections Info to ConnectionsPage
*Add Upload Traffic, Download Traffic and Active Connections to ConnectionsPage.
*IConnections uploadTotal and downloadTotal data missing not displayed, add it to ConnectionsPage interface here.
2023-10-10 17:05:31 +08:00
Majokeiko
f5ee6f3537
feat: ClashFieldViewer BaseDialog maxHeight usage percentage (#813)
*The overall interface will be more intuitive when the content is longer.
2023-10-10 14:29:27 +08:00
GyDi
afc77e7adc
chore: update readme 2023-10-10 10:25:57 +08:00
GyDi
024f42fce6
chore: update readme 2023-10-10 10:25:01 +08:00
GyDi
8a5f12b97c
chore: update clash meta 2023-10-08 21:45:12 +08:00
GyDi
954b21cf39
chore: update readme 2023-09-11 10:24:44 +08:00
GyDi
74d095774d
chore: fix updater 2023-09-11 10:16:54 +08:00
GyDi
17a2722e6d
chore: fix updater 2023-09-11 10:12:40 +08:00
GyDi
c843bddbfe
chore: fix clash map, close #736 2023-09-10 19:06:02 +08:00
GyDi
3f22a49755
v1.3.7 2023-09-10 19:02:10 +08:00
GyDi
7af2ffcebf
chore: update log 2023-09-10 19:01:59 +08:00
GyDi
de90c959e0
chore: update auto launch 2023-09-10 18:45:17 +08:00
GyDi
9987dc1eb4
fix: i18n 2023-09-10 15:03:29 +08:00
GyDi
3efd575dd2
feat: add Open Dashboard to the hotkey, close #723 2023-09-10 14:46:03 +08:00
GyDi
f4c7b17a87
feat: add check for updates button, close #766 2023-09-10 14:30:31 +08:00
GyDi
16d80718cb
fix: fix page undefined exception, close #770 2023-09-10 13:45:18 +08:00
GyDi
ad228d53b7
feat: add paste and clear icon 2023-09-09 16:52:00 +08:00
Majokeiko
15ee1e531b
feat: Subscription URL TextField use multiline (#761)
*Subscription link that are too long can make reading difficult, so use multiline TextField.
2023-09-07 16:14:42 +08:00
GyDi
1c8fb3392a
chore: update mmdb 2023-08-28 15:06:13 +08:00
GyDi
8647866a32
fix: set min window size, close #734 2023-08-28 15:00:27 +08:00
GyDi
23351c4f1c
chore: change ubuntu ci version 2023-08-28 14:44:09 +08:00
GyDi
1367c304cf
chore: update clash 2023-08-28 14:22:50 +08:00
GyDi
26d6bcb074
chore: update release link 2023-08-14 11:11:15 +08:00
GyDi
b0d651ece1
chore: update clash meta 2023-08-14 11:09:19 +08:00
GyDi
b6d50ba6a4
fix: rm debug code 2023-08-12 19:16:20 +08:00
GyDi
b3ab6a9166
v1.3.6 2023-08-12 16:12:03 +08:00
GyDi
f39a5ac9c2
chore: update log 2023-08-12 16:11:50 +08:00
GyDi
38a9a9240d
fix: use sudo when pkexec not found 2023-08-12 15:58:37 +08:00
GyDi
241b22a465
chore: update ci 2023-08-12 15:41:26 +08:00
GyDi
741abc0366
feat: show loading when change profile 2023-08-05 22:07:30 +08:00
GyDi
7854775de5
fix: remove div 2023-08-05 21:43:58 +08:00
GyDi
e62eaa6b4b
fix: list key 2023-08-05 21:43:05 +08:00
GyDi
b4cce23ef4
feat: support proxy provider update 2023-08-05 21:38:44 +08:00
GyDi
2bcaf90fc8
feat: add repo link 2023-08-05 19:54:59 +08:00
GyDi
96ffbe2f84
feat: support clash meta memory usage display 2023-08-05 19:40:23 +08:00
GyDi
6f5acee1c3
fix: websocket disconnect when window focus 2023-08-05 17:21:15 +08:00
GyDi
54e491d8bf
feat: supports show connection detail 2023-08-05 16:52:14 +08:00
GyDi
ab6374e278
chore: update geo data to meta, close #707 2023-08-05 13:42:37 +08:00
GyDi
2fda4c9f67
chore: fix faq 2023-08-05 13:41:30 +08:00
GyDi
5138a45b0f
chore: add faq and download link 2023-08-05 13:38:19 +08:00
GyDi
b224d4fa8a
chore: add promotion 2023-08-05 12:57:48 +08:00
whitemirror33
a552e44483
feat: update connection table with wider process column and click to show full detail (#696) 2023-08-04 14:36:28 +08:00
GyDi
0cf3bba118
feat: more trace logs 2023-08-04 14:15:15 +08:00
Andrei Shevchuk
2c48ea3508
feat: Add Russian Language (#697)
* Add Russian Language

* Add Russian support

* Minor update

* Update Russian translation
2023-08-03 11:07:58 +08:00
GyDi
b9b6212b75
fix: try fix undefined error 2023-07-28 09:26:06 +08:00
GyDi
b978aaec21
chore: alpha ci 2023-07-26 17:07:20 +08:00
GyDi
af704681d9
feat: center window when out of monitor 2023-07-24 20:55:26 +08:00
GyDi
1443ddfe6c
chore: fix test ci 2023-07-24 09:59:13 +08:00
GyDi
54457a3e1b
chore: fix test ci 2023-07-24 09:47:05 +08:00
GyDi
bf180e6a2c
chore: test ci 2023-07-24 09:28:54 +08:00
GyDi
864a5820c9
chore: test ci 2023-07-24 09:13:19 +08:00
GyDi
4d3ca49c3f
v1.3.5 2023-07-23 13:31:51 +08:00
GyDi
c49c3cf7f0
chore: update log 2023-07-23 13:31:34 +08:00
GyDi
5d5ab57469
fix: blurry tray icon in Windows 2023-07-23 13:25:54 +08:00
GyDi
31978d8de0
chore: update clash core 2023-07-23 13:11:35 +08:00
GyDi
e8eb68bf24
chore: fix check script 2023-07-23 13:11:17 +08:00
GyDi
9ea08f4fed
chore: update issue templates 2023-07-22 23:04:13 +08:00
GyDi
fe078a5c5b
v1.3.4 2023-07-22 20:38:08 +08:00
GyDi
61933954f3
chore: update log 2023-07-22 20:37:22 +08:00
GyDi
4c243638cb
fix: enable context menu in editable element 2023-07-22 17:21:04 +08:00
GyDi
02ba04b5d8
feat: support copy environment variable 2023-07-22 15:35:32 +08:00
GyDi
4f158a4829
fix: save window size and pos in Windows 2023-07-22 13:13:16 +08:00
GyDi
177a22df59
feat: save window size and position 2023-07-22 10:58:16 +08:00
GyDi
6b0ca2966e
feat: app log level add silent 2023-07-22 09:25:54 +08:00
GyDi
aadfaf7150
feat: overwrite resource file according to file modified 2023-07-22 09:18:54 +08:00
GyDi
b307b9a66b
feat: support app log level settings 2023-07-22 08:53:37 +08:00
Kimiblock Moe
6c1ab6002d
feat: Use polkit to elevate permission instaed of sudo (#678) 2023-07-21 23:05:33 +08:00
GyDi
9638eefc91
chore: update check script 2023-07-11 13:25:55 +08:00
GyDi
9e9c4ad587
fix: optimize traffic graph high CPU usage when hidden 2023-07-10 23:44:09 +08:00
GyDi
ce231431b9
fix: remove fallback group select status, close #659 2023-07-10 23:16:19 +08:00
GyDi
06e1e14e02
chore: update clash 2023-07-10 13:36:17 +08:00
GyDi
416e7884f5
feat: add unified-delay field 2023-06-30 13:58:51 +08:00
GyDi
d579222007
v1.3.3 2023-06-30 09:38:33 +08:00
GyDi
30243c84cd
chore: update log 2023-06-30 09:35:49 +08:00
GyDi
3557a77645
fix: error boundary with key 2023-06-30 09:17:59 +08:00
GyDi
97be28638b
chore: update clash meta 2023-06-30 09:02:26 +08:00
GyDi
aba0826c38
fix: connections is null 2023-06-30 09:02:17 +08:00
GyDi
f032228d0e
fix: font family not works in some interfaces, close #639 2023-06-29 14:21:14 +08:00
GyDi
6cf174c5ed
fix: encodeURIComponent secret 2023-06-29 14:15:57 +08:00
GyDi
c2109d245f
chore: update clash & clash meta 2023-06-08 13:52:40 +08:00
GyDi
6a9745171e
feat: add error boundary to the app root 2023-06-08 13:50:45 +08:00
GyDi
f9a68e8b23
fix: encode controller secret, close #601 2023-06-08 13:48:58 +08:00
GyDi
6e391df5ee
fix: linux not change icon 2023-05-28 18:14:11 +08:00
GyDi
f5edca94d3
fix: try fix blank error 2023-05-28 17:35:00 +08:00
GyDi
60046abec3
fix: close all connections when change mode 2023-05-28 17:07:39 +08:00
GyDi
cafc2060b8 fix: macos not change icon 2023-05-28 16:46:17 +08:00
GyDi
b1f45752cf chore: update deps 2023-05-28 16:45:43 +08:00
GyDi
ed17551170 chore: update clash 2023-05-28 16:44:07 +08:00
w568w
ef5adab638
feat: show tray icon variants in different status (#537) 2023-05-28 10:55:39 +08:00
GyDi
fb653ff99d
fix: error message null 2023-05-19 10:53:11 +08:00
GyDi
78fc47a9c4
chore: update gh proxy 2023-05-19 09:44:31 +08:00
GyDi
2a124cea61
v1.3.2 2023-05-19 00:57:22 +08:00
GyDi
4c7cc563dc
chore: update log 2023-05-19 00:57:10 +08:00
GyDi
6114af4f93
fix: profile data undefined error, close #566 2023-05-18 20:02:46 +08:00
GyDi
8c31629655
chore: update clash core 2023-05-05 20:45:52 +08:00
GyDi
03c8a8edb2
chore: update deps 2023-05-05 20:27:46 +08:00
yettera765
3eeaee154f
fix: import url error (#543)
use rustls instead of depending user's system tls
2023-05-05 12:08:08 +08:00
GyDi
8cf8fa7c80
v1.3.1 2023-04-11 10:04:55 +08:00
GyDi
6b4f6fc71e
chore: update log 2023-04-11 10:04:28 +08:00
Tatius Titus
30c2680b6f
chore: Upgrade to React 18 (#495)
* chore: Upgrade to React 18

* runfix: Add children type to FC components

* chore: Remove @types/react
2023-04-07 12:59:44 +08:00
Mr-Spade
fb7b1800cc
fix: linux DEFAULT_BYPASS (#503) 2023-04-07 12:47:13 +08:00
GyDi
ff573bf377
chore: update deps 2023-04-02 11:20:18 +08:00
GyDi
0a33bb861e
fix: open file with vscode 2023-04-02 11:19:48 +08:00
GyDi
728756289b
chore: update deps 2023-04-02 10:09:14 +08:00
GyDi
56ccd3a0ac
chore: update clash meta 2023-04-02 09:43:32 +08:00
Tatius Titus
66f3f0ba07
fix: Do not render div as a descendant of p (#494) 2023-04-02 09:37:09 +08:00
Srinivas Gowda
af5e0d589e
chore: update clash core version (#476) 2023-03-27 10:59:27 +08:00
GyDi
533dc99e7d
fix: use replace instead 2023-03-17 08:37:45 +08:00
GyDi
fc5ca965ba
fix: escape path space 2023-03-17 08:36:19 +08:00
John Smith
9c4a46bcdb
fix: escape the space in path (#451) 2023-03-17 08:20:35 +08:00
GyDi
52658886e7
fix: add target os linux 2023-03-16 23:57:34 +08:00
GyDi
8174ab7616
chore: fix ci 2023-03-16 23:54:14 +08:00
GyDi
2b6acedae1
fix: appimage path unwrap panic 2023-03-16 23:45:48 +08:00
GyDi
d00fe9c5f4
v1.3.0 2023-03-16 21:33:51 +08:00
GyDi
88aa270728
chore: update log 2023-03-16 21:33:14 +08:00
GyDi
4ae409c7f4
feat: auto restart core after grand permission 2023-03-16 21:32:39 +08:00
GyDi
9a29c9abdd
feat: add restart core button 2023-03-16 20:56:37 +08:00
GyDi
66d93ea037
fix: remove esc key listener in macOS 2023-03-16 20:42:45 +08:00
GyDi
6c0066dbfb
feat: support update all profiles 2023-03-16 20:32:41 +08:00
GyDi
4fde644733
chore: rm file 2023-03-16 20:31:48 +08:00
GyDi
e7841c60df
fix: adjust style 2023-03-16 19:32:59 +08:00
hybo
94f647b24a
chore: evaluate error context lazily (#447) 2023-03-16 17:06:52 +08:00
GyDi
630249d22a
fix: adjust swr option 2023-03-16 17:03:12 +08:00
GyDi
db99b4cb54
fix: infinite retry when websocket error 2023-03-16 17:03:00 +08:00
GyDi
c77db23586
fix: type error 2023-03-16 13:51:46 +08:00
GyDi
daf66bcec4
chore: update deps 2023-03-16 13:42:27 +08:00
GyDi
8caf36349f
chore: fix ci 2023-03-16 13:18:05 +08:00
GyDi
6934de58e5
chore: fix ci 2023-03-16 13:16:30 +08:00
GyDi
54a5007c01
feat: support to grant permission to clash core 2023-03-16 11:16:54 +08:00
GyDi
e25a455698
fix: do not parse log except the clash core 2023-03-16 10:34:28 +08:00
GyDi
ab429dfeb6
feat: support clash fields filter in ui 2023-03-15 08:43:24 +08:00
GyDi
c5289dc0e8
fix: field sort for filter 2023-03-15 08:43:03 +08:00
boatrainlsz
d191877002
chore: update README (#435) 2023-03-07 22:55:38 +08:00
GyDi
4d979160c2
chore: update deps 2023-03-07 00:10:49 +08:00
GyDi
d00e8f6e19
chore: update clash 2023-03-06 23:35:30 +08:00
GyDi
91b77e5237
fix: add meta fields 2023-02-18 00:46:03 +08:00
GyDi
5b8c246d53
chore: update clash 2023-02-18 00:09:40 +08:00
GyDi
b374b9b91c
feat: open dir on the tray 2023-02-17 00:15:21 +08:00
GyDi
403717117e
fix: runtime config user select 2023-02-17 00:00:23 +08:00
GyDi
027295d995
feat: support to disable clash fields filter 2023-02-16 23:52:55 +08:00
GyDi
c9b7eccbc1
fix: app_handle as_ref 2023-02-15 17:25:35 +08:00
GyDi
2b6d9348cd
fix: use crate 2023-02-11 23:31:55 +08:00
GyDi
692f8c8454
fix: appimage auto launch, close #403 2023-02-11 23:19:08 +08:00
inRm3D
6783355c4d
chore: add openssl depend (#395) 2023-02-02 10:54:15 +08:00
GyDi
fb9cca1e99
v1.2.3 2023-02-01 22:11:34 +08:00
GyDi
eb770ede1a
chore: update log 2023-02-01 22:11:06 +08:00
GyDi
2643e853af
chore: aarch script 2023-02-01 21:41:15 +08:00
GyDi
b79456e91b
chore: update clash 2023-01-30 20:50:08 +08:00
GyDi
ac66c086f8
chore: meta ci 2023-01-30 20:40:57 +08:00
GyDi
ebccf401dd
chore: fix ci 2023-01-22 13:31:34 +08:00
GyDi
66494845b7
chore: fix ci 2023-01-19 18:02:08 +08:00
GyDi
e6c36ad602
chore: alpha ci 2023-01-18 23:39:27 +08:00
inRm3D
26379182db
chore: try fix missing libssl3 (#378)
* Update ci.yml

* use package from source
2023-01-18 23:36:18 +08:00
GyDi
bba03d14d4
fix: compatible with UTF8 BOM, close #283 2023-01-17 19:51:02 +08:00
GyDi
23b728a762
feat: adjust macOS window style 2023-01-16 22:57:53 +08:00
GyDi
819c5207d2
fix: use selected proxy after profile changed 2023-01-15 21:33:03 +08:00
GyDi
311358544e
fix: error log 2023-01-15 19:11:51 +08:00
GyDi
4480ecc96d
chore: ci 2023-01-14 22:22:18 +08:00
GyDi
6c5f70a205
v1.2.2 2023-01-14 22:01:28 +08:00
GyDi
99adfb4a9e
chore: update log 2023-01-14 21:56:27 +08:00
GyDi
7909cf4067
fix: adjust fields order 2023-01-14 14:57:55 +08:00
GyDi
780ab20aeb
fix: add meta fields 2023-01-14 14:51:29 +08:00
GyDi
73119bb7c5
chore: ci 2023-01-14 12:20:17 +08:00
GyDi
f20f0f064e
chore: update clash meta 2023-01-14 12:16:09 +08:00
GyDi
1b44ae098c
fix: add os platform value 2023-01-14 12:07:31 +08:00
GyDi
453c230716
feat: recover core after panic, close #353 2023-01-14 11:45:47 +08:00
GyDi
439d885ee1
chore: allow unused 2023-01-13 23:11:48 +08:00
GyDi
43dee3ef76
fix: reconnect traffic websocket 2023-01-13 23:02:45 +08:00
GyDi
c71ba6ff8d
chore: update deps 2023-01-13 21:29:21 +08:00
GyDi
fb7a36eb73
feat: use decorations in Linux, close #354 2023-01-12 00:42:33 +08:00
GyDi
e7f294a065
fix: parse bytes precision, close #334 2023-01-11 14:05:49 +08:00
GyDi
d5037f180e
fix: trigger new profile dialog, close #356 2023-01-11 13:45:16 +08:00
GyDi
e90158809a
fix: parse log cause panic 2023-01-11 13:30:14 +08:00
GyDi
0cb802ed9a
chore: update clash meta 2023-01-09 21:55:03 +08:00
GyDi
d0b47204f4
v1.2.1 2022-12-23 22:44:27 +08:00
GyDi
351cb391e5
chore: update log 2022-12-23 22:44:00 +08:00
GyDi
051be927cd
fix: avoid setting login item repeatedly, close #326 2022-12-23 22:39:27 +08:00
GyDi
8bad2c2113
fix: adjust code 2022-12-15 21:54:48 +08:00
GyDi
2bcf6fb3eb
fix: adjust delay check concurrency 2022-12-15 12:23:57 +08:00
GyDi
d1ba0ed2b2
chore: adjust code 2022-12-15 12:22:20 +08:00
GyDi
6e421e60c5
fix: change default column to auto 2022-12-14 16:56:33 +08:00
GyDi
8385050804
fix: change default app version 2022-12-14 16:15:53 +08:00
GyDi
bfe4f08232
fix: adjust rule ui 2022-12-14 15:59:41 +08:00
GyDi
132f914b0d
fix: adjust log ui 2022-12-14 15:49:05 +08:00
GyDi
97d82b03ab
fix: keep delay data 2022-12-14 15:29:02 +08:00
GyDi
f06fa3f9b7
fix: use list item button 2022-12-14 15:16:49 +08:00
GyDi
6337788a22
fix: proxy item style 2022-12-14 15:15:44 +08:00
GyDi
024db4358b
feat: auto proxy layout column 2022-12-14 15:07:51 +08:00
GyDi
173f35487e
chore: fix ci 2022-12-13 18:13:28 +08:00
GyDi
74cbe82dd1
chore: fix ci 2022-12-13 18:11:43 +08:00
GyDi
a8c30d30a9
chore: fix ci 2022-12-13 18:02:23 +08:00
GyDi
1b7a52d5af
chore: alpha ci 2022-12-13 17:44:46 +08:00
GyDi
e5109789bf
chore: alpha ci 2022-12-13 17:41:53 +08:00
GyDi
4d2b35e09d
feat: support to change proxy layout column 2022-12-13 17:34:39 +08:00
GyDi
5c5177ec57
feat: support to open core dir 2022-12-13 00:44:24 +08:00
GyDi
d93b00cd15
chore: update deps 2022-12-12 00:00:45 +08:00
MoeShin
39ade59174
fix: Virtuoso no work in legacy browsers (#318) 2022-12-08 10:47:42 +08:00
GyDi
0309c815b9
chore: update deps 2022-12-04 20:54:43 +08:00
GyDi
ce613098db
fix: adjust ui 2022-12-04 00:45:39 +08:00
GyDi
ab34044196
feat: profile page ui 2022-11-28 22:29:58 +08:00
GyDi
17f724748f
chore: deps 2022-11-28 22:27:23 +08:00
GyDi
f3a917b5e7
chore: update clash version 2022-11-26 13:25:52 +08:00
GyDi
376011ea08
fix: refresh websocket 2022-11-25 22:22:57 +08:00
GyDi
2ce7624c14
fix: adjust ui 2022-11-24 18:24:34 +08:00
GyDi
c62dddd5b9
feat: save some fields in the runtime config, close #292 2022-11-24 17:52:25 +08:00
GyDi
490ba9f140
chore: alpha ci 2022-11-24 11:14:03 +08:00
GyDi
f76890cc56
fix: parse bytes base 1024 2022-11-24 11:11:31 +08:00
GyDi
e1c8f1fed9
fix: add clash fields 2022-11-24 10:46:21 +08:00
GyDi
6e19a4ab8b
chore: ci 2022-11-24 10:41:03 +08:00
GyDi
b156523a7f
chore: ci 2022-11-24 10:35:22 +08:00
GyDi
d20b745ae5
fix: direct mode hide proxies 2022-11-24 10:35:09 +08:00
GyDi
c51e9e6b2c
feat: add meta feature 2022-11-24 10:26:41 +08:00
GyDi
1a31fa9067
fix: profile can not edit 2022-11-24 10:26:25 +08:00
GyDi
558b8499af
chore: ci 2022-11-23 23:46:32 +08:00
GyDi
986c162988
v1.2.0 2022-11-23 23:15:39 +08:00
GyDi
770d5cd11c
chore: ci 2022-11-23 23:15:20 +08:00
GyDi
446d2ab3af
chore: update log 2022-11-23 23:13:44 +08:00
GyDi
2f9bf7f063
feat: display proxy group type 2022-11-23 18:27:57 +08:00
GyDi
72ff9c0964
chore: rm dead code 2022-11-23 17:45:49 +08:00
GyDi
33b1a11d85
fix: parse logger time 2022-11-23 17:45:43 +08:00
GyDi
06dabf1e4e
fix: adjust service mode ui 2022-11-23 17:45:22 +08:00
GyDi
28d3691e0b
feat: add use clash hook 2022-11-23 17:44:40 +08:00
GyDi
ffa21fbfd2
fix: adjust style 2022-11-23 17:42:01 +08:00
GyDi
db028665fd
fix: check hotkey and optimize hotkey input, close #287 2022-11-23 17:30:19 +08:00
GyDi
6bc83d9f27
fix: mutex dead lock 2022-11-23 16:04:25 +08:00
GyDi
790d832155
fix: adjust item ui 2022-11-23 15:29:42 +08:00
GyDi
f477cecdeb
fix: regenerate config before change core 2022-11-23 09:57:21 +08:00
GyDi
e031389021
fix: close connections when profile change 2022-11-23 00:20:57 +08:00
GyDi
e00f826eb8
fix: lint 2022-11-22 23:02:18 +08:00
GyDi
24f4e8ab99
chore: fix check script 2022-11-22 23:01:04 +08:00
GyDi
1550d528bd
fix: windows service mode 2022-11-22 22:01:34 +08:00
GyDi
40c041031e
fix: init config file 2022-11-22 22:01:19 +08:00
GyDi
3e555ec9f1
chore: fix mmdb url 2022-11-22 21:15:45 +08:00
GyDi
5098f14aab
fix: service mode error and fallback to sidecar 2022-11-22 20:47:21 +08:00
GyDi
a355a9c85e
fix: service mode viewer ui 2022-11-22 20:45:17 +08:00
GyDi
e7db2a8573
chore: update check script 2022-11-22 20:44:44 +08:00
GyDi
9b18bd0b48
fix: create theme error, close #294 2022-11-22 16:01:33 +08:00
GyDi
f95ddd594e
feat: guard the mixed-port and external-controller 2022-11-22 15:45:17 +08:00
GyDi
fe8168784f
feat: adjust builtin script and support meta guard script 2022-11-22 12:00:48 +08:00
MoeShin
4046f143f6
fix: matchMedia().addEventListener #258 (#296) 2022-11-22 09:25:39 +08:00
GyDi
e4e16999c8
chore: alpha release add portable 2022-11-22 00:16:30 +08:00
GyDi
10f3ba4ff4
chore: alpha ci 2022-11-21 23:19:25 +08:00
GyDi
3cd2be5081
fix: check config 2022-11-21 23:11:56 +08:00
GyDi
c9359978f9
fix: show global when no rule groups 2022-11-21 23:06:32 +08:00
GyDi
781c67b31a
fix: service viewer ref 2022-11-21 23:02:48 +08:00
GyDi
020bd129fb
fix: service ref error 2022-11-21 22:33:06 +08:00
GyDi
8086b6d78c
feat: disable script mode when use clash meta 2022-11-21 22:28:57 +08:00
GyDi
48e14b36b8
feat: check config when change core 2022-11-21 22:27:55 +08:00
GyDi
b3c1c56579
fix: group proxies render list is null 2022-11-21 22:10:24 +08:00
GyDi
bd0e932910
feat: support builtin script for enhanced mode 2022-11-21 21:05:00 +08:00
GyDi
525e5f88ae
chore: update ci 2022-11-20 23:17:05 +08:00
GyDi
005eeb0e0b
chore: update ci node version 2022-11-20 23:14:43 +08:00
GyDi
d21bb015e8
fix: pretty bytes 2022-11-20 23:08:30 +08:00
GyDi
7338838b0e
feat: adjust profiles page ui 2022-11-20 22:37:34 +08:00
GyDi
8bb4803ff9
refactor: adjust base components export 2022-11-20 22:03:55 +08:00
GyDi
892b919cf3
refactor: adjust setting dialog component 2022-11-20 21:48:39 +08:00
GyDi
572d81ecef
fix: use verge hook 2022-11-20 20:12:58 +08:00
GyDi
a4ce7a4037
feat: optimize proxy page ui 2022-11-20 19:46:16 +08:00
GyDi
6eafb15cf9
chore: adjust type 2022-11-19 17:22:29 +08:00
GyDi
e19fe5ce1c
fix: adjust notice 2022-11-19 01:24:07 +08:00
GyDi
9d2017e598
feat: add error boundary 2022-11-19 01:22:19 +08:00
GyDi
f33c419ed9
chore: rm polyfill 2022-11-19 01:22:00 +08:00
GyDi
f425fbaf9d
feat: adjust clash log 2022-11-18 22:08:06 +08:00
GyDi
bcc5ec897a
fix: windows issue 2022-11-18 20:15:34 +08:00
GyDi
f5f2fe3472
fix: change dev log level 2022-11-18 18:37:29 +08:00
GyDi
b7c3863882
fix: patch clash config 2022-11-18 18:37:17 +08:00
GyDi
d759f48ee8
fix: cmds params 2022-11-18 18:26:55 +08:00
GyDi
3a37075e71
Merge branch 'refactor' 2022-11-18 18:21:49 +08:00
GyDi
58366c0b87
chore: rm code 2022-11-18 18:19:26 +08:00
GyDi
2667ed13f1
refactor: done 2022-11-18 18:18:41 +08:00
GyDi
34daffbc96
refactor: adjust all path methods and reduce unwrap 2022-11-18 10:26:39 +08:00
GyDi
be81cd72af
fix: adjust singleton detect 2022-11-18 08:24:27 +08:00
GyDi
4ae00714d2
fix: change template 2022-11-18 08:04:26 +08:00
GyDi
f24cbb6692
refactor: rm code 2022-11-17 23:21:13 +08:00
GyDi
5a35c5b928
refactor: fix 2022-11-17 22:53:41 +08:00
GyDi
1880da6351
refactor: rm dead code 2022-11-17 22:52:22 +08:00
GyDi
df93cb103c
refactor: for windows 2022-11-17 20:19:40 +08:00
GyDi
63b474a32c
refactor: wip 2022-11-17 17:07:13 +08:00
GyDi
abdbf158d1
refactor: wip 2022-11-16 01:26:41 +08:00
GyDi
ee68d80d0a
refactor: wip 2022-11-15 01:33:50 +08:00
GyDi
c8e6f3a627
refactor: rm update item block_on 2022-11-14 23:07:51 +08:00
GyDi
dc941575fe
refactor: fix 2022-11-14 22:50:47 +08:00
GyDi
e64103e5f2
fix: copy resource file 2022-11-14 21:11:42 +08:00
GyDi
f0ab03a9fb
chore: tmpl add clash core 2022-11-14 21:10:29 +08:00
GyDi
09965f1cc6
feat: add draft 2022-11-14 19:31:22 +08:00
GyDi
d2852bb34a
refactor: fix 2022-11-14 01:45:58 +08:00
GyDi
b03c52a501
refactor: wip 2022-11-14 01:26:33 +08:00
GyDi
fd6633f536
fix: MediaQueryList addEventListener polyfill 2022-11-13 10:27:26 +08:00
GyDi
320ac81f48
chore: fix ci 2022-11-12 17:07:47 +08:00
GyDi
70bcd2428f
chore: alpha ci 2022-11-12 17:06:26 +08:00
GyDi
71f5ada0a3
chore: lock version 2022-11-12 17:06:18 +08:00
GyDi
aab5141404
chore: fix ci 2022-11-12 16:54:57 +08:00
GyDi
ff6b119f27
chore: alpha ci 2022-11-12 16:47:27 +08:00
GyDi
7ef4b7eeb8
fix: change default tun dns-hijack 2022-11-12 11:48:02 +08:00
GyDi
4668be6e24
chore: format rust code 2022-11-12 11:37:23 +08:00
GyDi
a211fc7c97
fix: something 2022-11-11 22:45:32 +08:00
GyDi
54af0b675d
chore: update deps 2022-11-11 21:28:34 +08:00
GyDi
8c8171e774
feat: change default latency test url 2022-11-11 01:24:18 +08:00
GyDi
0bb1790206
fix: provider proxy sort by delay 2022-11-11 01:21:23 +08:00
GyDi
45fc84d8be
chore: rm dead code 2022-11-10 22:58:46 +08:00
GyDi
f7500f4cad
chore: clash meta compatible and geosite.dat 2022-11-10 22:58:34 +08:00
GyDi
0cfd718d8a
feat: auto close connection when proxy changed 2022-11-10 01:27:05 +08:00
GyDi
5f486d0f51
fix: profile item menu ui dense 2022-11-09 15:53:42 +08:00
GyDi
6e5a2f85a1
fix: disable auto scroll to proxy 2022-11-09 11:44:09 +08:00
GyDi
e66a89208d
feat: support to change external controller 2022-11-06 23:23:26 +08:00
GyDi
7f65c501c6
feat: add sub-rules 2022-11-05 15:50:06 +08:00
GyDi
22c2382765
feat(macOS): support cmd+w and cmd+q 2022-11-04 00:51:46 +08:00
GyDi
38e1a4febf
chore: update clash meta 2022-11-04 00:36:32 +08:00
GyDi
8db554b377
chore: fix ci 2022-11-03 01:34:23 +08:00
GyDi
5f5cc55331
chore: compatible ci 2022-11-03 01:32:16 +08:00
GyDi
2f8b39186f
chore: update ci 2022-11-03 01:15:50 +08:00
GyDi
a3a724e2e6
chore: test ci 2022-11-03 00:51:49 +08:00
GyDi
73235c8699
chore: test ci 2022-11-03 00:48:27 +08:00
GyDi
7e5999e862
chore: add x 2022-11-02 00:57:27 +08:00
GyDi
afa244dcb0
v1.1.2 2022-11-02 00:54:51 +08:00
GyDi
4ea5bb2390
fix: check remote profile 2022-11-02 00:51:25 +08:00
GyDi
e545d552f6
chore: update log 2022-11-02 00:44:45 +08:00
GyDi
56fe7b3596
feat: add version on tray 2022-11-01 23:29:59 +08:00
GyDi
eb28ec866a
feat: add animation 2022-10-29 23:36:10 +08:00
GyDi
4649454282
fix: remove smoother 2022-10-29 20:05:55 +08:00
angrylid
a45dc6efda
feat: add animation to ProfileNew component (#252)
* chore: add .vscode to .gitignore

* feat: add animation to ProfileNew component
2022-10-29 20:02:51 +08:00
GyDi
9e56b9fbb5
fix: icon button color 2022-10-29 19:22:15 +08:00
GyDi
5504994cb9
feat: check remote profile field 2022-10-28 13:00:52 +08:00
GyDi
acff6d0432
fix: init system proxy correctly 2022-10-28 01:33:21 +08:00
GyDi
eea9cb7c5b
fix: open file 2022-10-28 01:26:45 +08:00
GyDi
c0ddddfb1f
fix: reset proxy 2022-10-28 01:06:54 +08:00
GyDi
f7dab3ca56
fix: init config error 2022-10-28 01:02:47 +08:00
GyDi
e11b4038a3
feat: system tray support zh language 2022-10-28 00:40:29 +08:00
GyDi
b635e64803
fix: adjust reset proxy 2022-10-27 21:14:14 +08:00
GyDi
20a194b49a
fix: adjust code 2022-10-27 21:13:27 +08:00
GyDi
33a5fb8837
fix: add https proxy 2022-10-26 17:11:54 +08:00
GyDi
59dae640db
fix: auto scroll into view when sorted proxies changed 2022-10-26 01:24:06 +08:00
GyDi
a6ac75e97b
feat: display delay check result timely 2022-10-26 01:11:02 +08:00
GyDi
cc5b33a8ec
fix: refresh proxies interval, close #235 2022-10-26 01:08:34 +08:00
GyDi
6e1a627b84
fix: style 2022-10-25 23:54:21 +08:00
GyDi
62d4c65e1c
chore: update deps 2022-10-25 23:54:10 +08:00
GyDi
600134a3ac
fix: fetch profile with system proxy, close #249 2022-10-25 23:45:24 +08:00
LooSheng
df14af7337
fix: The profile is replaced when the request fails. (#246) 2022-10-23 17:22:26 +08:00
GyDi
2f740b570d
fix: default dns config 2022-10-22 22:26:40 +08:00
GyDi
294d980b52
fix: kill clash when exit in service mode, close #241 2022-10-22 13:55:06 +08:00
GyDi
c9d9909d74
chore: update mmdb 2022-10-22 13:30:08 +08:00
GyDi
90eeabae7b
feat: update profile with system proxy/clash proxy 2022-10-18 23:19:21 +08:00
GyDi
a32c77c5f1
chore: adjust code 2022-10-17 23:26:25 +08:00
GyDi
910846f2ce
fix: icon button color inherit 2022-10-16 14:40:45 +08:00
GyDi
35d0438261
fix: app version to string 2022-10-16 14:38:57 +08:00
GyDi
515af472ce
fix: break loop when core terminated 2022-10-14 14:46:15 +08:00
GyDi
f062f7f9fe
feat: change global mode ui, close #226 2022-10-13 11:54:52 +08:00
GyDi
f68378041f
feat: default user agent same with app version 2022-10-12 11:28:47 +08:00
GyDi
30ef3057ac
v1.1.1 2022-10-11 23:03:12 +08:00
GyDi
48f3a934c9
chore: update log 2022-10-11 23:02:49 +08:00
GyDi
38d1fde84f
fix: api error handle 2022-10-11 22:51:18 +08:00
GyDi
dd78670a4b
fix: clash meta not load geoip, close #212 2022-10-11 22:24:54 +08:00
GyDi
b8a8190a43
fix: sort proxy during loading, close #221 2022-10-11 22:06:55 +08:00
GyDi
2d0989342f
fix: not create windows when enable slient start 2022-10-11 21:50:00 +08:00
GyDi
15ff9b06a1
fix: root background color 2022-10-11 20:49:03 +08:00
GyDi
41b19f69de
fix: create window correctly 2022-10-11 00:57:34 +08:00
GyDi
f2bd6f1fce
fix: set_activation_policy 2022-10-10 22:15:21 +08:00
GyDi
ec94218a4b
chore: rm aarch64 ci 2022-09-28 18:50:33 +08:00
GyDi
c2e5c7cf38
chore: test ci 2022-09-28 17:26:32 +08:00
GyDi
bac5734527
chore: test ci 2022-09-28 17:12:27 +08:00
GyDi
bef4033d94
chore: fix ci 2022-09-28 16:04:05 +08:00
GyDi
64216cba67
chore: fix test ci 2022-09-28 15:19:50 +08:00
Particle_G
a9d6167a9f
chore: add support for windows arm64, close #216 (#209) 2022-09-28 15:13:24 +08:00
GyDi
6c6b40548f
fix: disable spell check 2022-09-28 14:15:22 +08:00
苏业钦
a916d88e85
chore: add support linux arm64 (#215) 2022-09-28 10:40:41 +08:00
GyDi
ab2f0548a3
chore: clash meta linux use compatible version 2022-09-27 00:16:22 +08:00
GyDi
e30ba07285
feat: optimize config feedback 2022-09-26 20:46:29 +08:00
GyDi
1b336d973d
fix: adjust init launch on dev 2022-09-26 01:35:19 +08:00
GyDi
7b1866737f
v1.1.0 2022-09-26 01:27:56 +08:00
GyDi
eedc4ab648
chore: update log 2022-09-26 01:27:32 +08:00
GyDi
5e429c7a94
fix: ignore disable auto launch error 2022-09-26 01:09:05 +08:00
GyDi
57d23eb043
fix(macos): set auto launch path to application 2022-09-25 23:36:55 +08:00
GyDi
5ebd9be89a
fix: i18n 2022-09-25 01:41:46 +08:00
GyDi
5a743779e2
feat: show connections with table layout 2022-09-25 01:35:21 +08:00
GyDi
0495062110
fix: style 2022-09-24 20:55:40 +08:00
GyDi
d522191f69
fix: save enable log on localstorage 2022-09-24 19:03:14 +08:00
Priestch
bbbdc8b7a6
fix: typo in api.ts (#207) 2022-09-24 18:48:11 +08:00
GyDi
c00ed8aa5a
chore: use ubuntu latest 2022-09-24 16:08:39 +08:00
GyDi
0beaa94068
feat: show loading on proxy group delay check 2022-09-24 15:31:09 +08:00
GyDi
96e76665d6
fix: refresh clash ui await patch 2022-09-24 14:01:28 +08:00
Shun Li
6423a29600
feat: add chains[0] and process to connections display (#205)
* add chains[0] display

* add metadata.process to connections
2022-09-24 13:06:32 +08:00
GyDi
8bddf30dcf
refactor(hotkey): use tauri global shortcut 2022-09-23 15:31:01 +08:00
GyDi
a6b2db182d
feat: adjust connection page ui 2022-09-23 00:08:52 +08:00
GyDi
b9f3f9d859
Merge pull request #197 from FoundTheWOUT/main
Support ordering connection
2022-09-22 22:55:46 +08:00
GyDi
6331447dcd
feat: yaml merge key 2022-09-21 22:15:24 +08:00
GyDi
4213ee660f
feat: toggle log ws 2022-09-20 22:15:28 +08:00
GyDi
3bd9287c5d
chore: update deps 2022-09-20 21:26:38 +08:00
GyDi
b23d3f7c8b
feat: add rule page 2022-09-18 23:19:02 +08:00
GyDi
f8d9e5e027
feat: hotkey viewer 2022-09-18 15:52:53 +08:00
GyDi
8fa7fb3b1f
feat: refresh ui when hotkey clicked 2022-09-18 15:50:03 +08:00
FoundTheWOUT
63d92a0872 Support ordering connection 2022-09-15 15:52:12 +08:00
GyDi
509d83365e
feat: support hotkey (wip) 2022-09-14 01:19:02 +08:00
GyDi
d6ab73c905
fix: remove dead code 2022-09-12 13:42:21 +08:00
GyDi
5a93ba05d5
fix: style 2022-09-12 13:42:13 +08:00
GyDi
2d2fdf0b1e
fix: handle is none 2022-09-12 00:45:19 +08:00
GyDi
cf96622261
fix: unused 2022-09-12 00:02:25 +08:00
GyDi
47c8ccb0e5
refactor: optimize 2022-09-11 20:58:55 +08:00
GyDi
02fdb8778b
fix: style 2022-09-11 18:38:51 +08:00
GyDi
6bed7f0e66
fix: windows logo size 2022-09-11 17:50:58 +08:00
GyDi
7597d335b9
feat: hide window on macos 2022-09-09 16:42:35 +08:00
GyDi
f32c5ba244
fix: do not kill sidecar during updating 2022-09-09 16:33:04 +08:00
GyDi
ab53ab21e2
fix: delay update config 2022-09-09 16:30:27 +08:00
GyDi
acfe5dbb49
fix: reduce logo size 2022-09-09 16:19:13 +08:00
GyDi
f9b91fa189
feat: system proxy setting 2022-09-07 01:51:43 +08:00
GyDi
2462e68ba1
fix: window center 2022-09-06 22:18:06 +08:00
GyDi
019b2a1681
chore: update resource 2022-09-06 15:32:22 +08:00
GyDi
e94a07b677
fix: log level warn value 2022-09-06 14:42:58 +08:00
GyDi
c058c29755
feat: change default singleton port and support to change the port 2022-09-06 00:45:01 +08:00
GyDi
9e7c7ac163
feat: log info 2022-09-05 20:30:39 +08:00
GyDi
fcee41f00d
feat: kill clash by pid 2022-09-05 16:30:29 +08:00
GyDi
ff2c1bf8ed
feat: change clash port in dialog 2022-09-05 02:12:25 +08:00
GyDi
a2cf26e7ed
feat: add proxy item check loading 2022-09-04 23:53:48 +08:00
GyDi
71e6900375
feat: compatible with proxy providers health check 2022-09-04 22:55:54 +08:00
GyDi
3bdc98bd12 v1.0.6 2022-09-03 00:40:50 +08:00
GyDi
68d2a6e951
chore: update log 2022-09-03 00:39:39 +08:00
GyDi
acf47ac947
chore: update deps 2022-09-02 23:06:00 +08:00
GyDi
fda24e5f5a
chore: update deps 2022-09-02 01:35:06 +08:00
GyDi
05eca8e4d8
chore: use ubuntu 18.04 2022-09-02 01:27:06 +08:00
GyDi
b915f3b1a9
feat: add empty ui 2022-09-02 01:09:38 +08:00
GyDi
ab58968f4d
feat: complete i18n 2022-09-02 01:05:45 +08:00
GyDi
820d1e7570
fix: increase delay checker concurrency 2022-09-02 00:41:43 +08:00
GyDi
a120c8cf98
fix: external controller allow lan 2022-09-02 00:24:19 +08:00
GyDi
5a35ea116f
chore: update clash meta version 2022-09-02 00:11:52 +08:00
GyDi
e72ad1f030
fix: remove useless optimizations 2022-08-31 21:44:23 +08:00
GyDi
a17362437a
chore: test ci 2022-08-29 17:26:09 +08:00
GyDi
8643dc43b1
chore: update clash 2022-08-29 11:11:55 +08:00
GyDi
e1c869a358
chore: add test ci os version 2022-08-29 11:02:14 +08:00
GyDi
2f5b8d9abe Merge branch 'main' of github.com:zzzgydi/clash-verge 2022-08-24 22:41:36 +08:00
GyDi
db324f54eb
chore: update auto launch 2022-08-24 22:41:12 +08:00
GyDi
3242efb1a2
fix: reduce unsafe unwrap 2022-08-23 15:19:04 +08:00
FoundTheWOUT
30f9f1a021 fix: timer restore at app launch 2022-08-23 10:35:36 +08:00
GyDi
3f58d05aa7
fix: adjust log text 2022-08-19 17:11:59 +08:00
GyDi
c611a51575
fix: only script profile can display console 2022-08-17 01:45:37 +08:00
GyDi
73458dcd28 v1.0.5 2022-08-16 23:56:29 +08:00
GyDi
23ebeb1cc0
chore: update log 2022-08-16 23:56:04 +08:00
GyDi
a7ba9f1886
fix: fill button title attr 2022-08-16 23:46:33 +08:00
GyDi
d5192e2244
feat: windows portable version do not check update 2022-08-16 01:53:40 +08:00
GyDi
7eb595170f
fix: do not reset system proxy when consistent 2022-08-16 01:27:32 +08:00
GyDi
bd576ca808
fix: adjust web ui item style 2022-08-16 01:08:54 +08:00
GyDi
2f8146b11f
fix: clash field state error 2022-08-16 00:48:06 +08:00
GyDi
7f321c89cb
feat: adjust clash info parsing logs 2022-08-15 20:21:43 +08:00
GyDi
fa65f606b8
fix: badge color error 2022-08-15 20:15:44 +08:00
GyDi
7a3285adaf
fix: web ui port value error 2022-08-15 20:14:33 +08:00
GyDi
8bf78fef10
fix: delay show window 2022-08-15 01:37:26 +08:00
GyDi
78f97ce4df
feat: adjust runtime config 2022-08-15 01:30:37 +08:00
GyDi
66ccbf70f8
feat: support restart app on tray 2022-08-15 01:22:39 +08:00
GyDi
cb48600b40
fix: adjust dialog action button variant 2022-08-15 00:55:35 +08:00
GyDi
33ce235713
feat: optimize profile page 2022-08-14 23:10:19 +08:00
GyDi
f1a68ece01
fix: script code error 2022-08-12 23:41:25 +08:00
GyDi
dd563360af
fix: script exception handle 2022-08-12 11:14:34 +08:00
GyDi
7f6dac4271
feat: refactor 2022-08-12 03:20:55 +08:00
GyDi
178fd8e828
feat: adjust tun mode config 2022-08-11 03:26:08 +08:00
GyDi
1641e02a7d
feat: reimplement enhanced mode 2022-08-11 02:55:10 +08:00
GyDi
cfd04e9bb4
feat: use rquickjs crate 2022-08-10 13:05:48 +08:00
GyDi
38effaf740
feat: reimplement enhanced mode 2022-08-09 21:15:55 +08:00
GyDi
a68eb4a73e
chore: format 2022-08-09 14:33:47 +08:00
GyDi
c02990ef98
fix: change fields 2022-08-09 14:31:59 +08:00
FoundTheWOUT
5aa7d5ffe9
fix: silent start (#150) 2022-08-09 14:14:06 +08:00
GyDi
4942b0fca5
fix: save profile when update 2022-08-08 23:17:22 +08:00
GyDi
aed1bdff5a
fix: list compare wrong 2022-08-08 23:16:28 +08:00
GyDi
929c840006
fix: button color 2022-08-08 23:15:05 +08:00
GyDi
57aef1d3c2
chore: rm code 2022-08-08 22:30:13 +08:00
GyDi
c1734a094c
fix: limit theme mode value 2022-08-08 22:28:44 +08:00
GyDi
99c46685ac
feat: finish clash field control 2022-08-08 22:14:03 +08:00
GyDi
066b08040a
feat: clash field viewer wip 2022-08-08 01:51:30 +08:00
GyDi
35de2334fb fix: add valid clash field 2022-08-07 20:52:50 +08:00
GyDi
5564c966a5
feat: support web ui 2022-08-06 21:56:54 +08:00
GyDi
0891b5e7b7
feat: adjust setting page style 2022-08-06 03:48:03 +08:00
GyDi
f3341f201f
refactor: ts path alias 2022-08-06 02:35:11 +08:00
GyDi
bf0dafabe2
fix: icon style 2022-08-06 01:44:33 +08:00
GyDi
60f6587169
fix: reduce unwrap 2022-07-30 23:32:52 +08:00
GyDi
a9bf32919e
feat: runtime config viewer 2022-07-25 01:20:13 +08:00
GyDi
7633f9f88b
chore: fix updater script 2022-07-18 12:55:59 +08:00
GyDi
9b56233938
v1.0.4 2022-07-17 17:56:07 +08:00
GyDi
65074264b8
chore: update log 2022-07-17 17:52:41 +08:00
GyDi
4f6fceb87f
feat: improve log rule 2022-07-17 17:39:44 +08:00
GyDi
659fdd1d37
fix: import mod 2022-07-17 16:51:54 +08:00
GyDi
8bce2ce040
feat: theme mode support follows system 2022-07-17 16:02:17 +08:00
GyDi
55cc83a5d4
chore: update deps 2022-07-17 14:54:09 +08:00
GyDi
6a51e93ded
refactor: mode manage on tray 2022-07-13 02:26:54 +08:00
GyDi
fcf570e96e
chore: rm code 2022-07-13 01:07:29 +08:00
GyDi
cbc184e953
fix: add tray separator 2022-07-13 01:05:53 +08:00
GyDi
98f9063352
Merge pull request #128 from Limsanity/main
feat: support switch proxy mode
2022-07-13 01:02:14 +08:00
limsanity
c278f1af00 style: resolve formatting problem 2022-07-13 00:54:47 +08:00
limsanity
fbb17a0ba5 feat(system tray): support switch rule/global/direct/script mode in system tray 2022-07-13 00:43:27 +08:00
GyDi
8637a9823e
chore: update deps 2022-07-11 00:41:21 +08:00
GyDi
d717fe7e8c
chore: update clash version 2022-07-08 01:42:14 +08:00
GyDi
5e8dfe7267
chore: update aarch rule 2022-07-07 02:54:20 +08:00
GyDi
aaa4fbcdbd
chore: aarch upload script 2022-07-07 02:53:53 +08:00
GyDi
150f0cf486
fix: instantiate core after init app, close #122 2022-07-06 15:14:33 +08:00
GyDi
711b220a05
chore: update clash version 2022-07-06 00:54:01 +08:00
GyDi
b615c485f7
chore: update deps 2022-07-06 00:49:09 +08:00
GyDi
2f3b6b29ae
fix: rm macOS transition props 2022-07-05 01:24:23 +08:00
GyDi
7aecd83c4a
chore: update deps 2022-07-05 00:52:22 +08:00
GyDi
3b460ab91f
chore: change tray icon 2022-06-22 01:26:25 +08:00
GyDi
661c0eb970 v1.0.3 2022-06-20 02:09:12 +08:00
GyDi
f4a1f1fdc8
chore: update log 2022-06-20 02:06:46 +08:00
GyDi
b5432c3728
chore: update clash version 2022-06-20 01:47:15 +08:00
GyDi
6d0625c409
fix: improve external-controller parse and log 2022-06-20 01:36:56 +08:00
GyDi
2f1ea08b8a
chore: update macos icon 2022-06-18 18:41:53 +08:00
GyDi
a092da1943
fix: show windows on click 2022-06-18 17:28:37 +08:00
GyDi
43ef3cc562
chore: new logo for mac 2022-06-18 17:28:05 +08:00
GyDi
047774475c
chore: update alpha ci 2022-06-17 01:18:19 +08:00
GyDi
91b8504df5
chore: update tauri 2022-06-17 01:16:46 +08:00
GyDi
a4fb2dfcf8
fix: adjust update profile notice error 2022-06-15 02:42:04 +08:00
GyDi
ba16ec02e5
fix: style issue on mac 2022-06-15 02:41:37 +08:00
GyDi
55b7af2623
chore: update version 2022-06-15 01:15:05 +08:00
GyDi
b428eff10e
feat: improve yaml file error log 2022-06-14 01:40:02 +08:00
GyDi
35aee15b6d
chore: update deps 2022-06-14 01:23:58 +08:00
GyDi
6f53c1bfde
Merge pull request #104 from FoundTheWOUT/main
fix: check script run on all OS
2022-06-12 22:25:05 +08:00
FoundTheWOUT
db0230ed75 fix: check script run on all OS 2022-06-05 23:55:41 +08:00
GyDi
7fa3c1e12a
feat: save proxy page state 2022-06-04 18:55:39 +08:00
GyDi
3b5993652f
chore: portable script 2022-06-02 00:56:05 +08:00
GyDi
be4ad8947f
chore: updater script 2022-06-01 10:06:08 +08:00
GyDi
2ead15e78e v1.0.2 2022-06-01 01:26:05 +08:00
GyDi
aa0740ff94
chore: update log 2022-06-01 01:25:39 +08:00
GyDi
6d3f837820
fix: macOS disable transparent 2022-06-01 01:04:46 +08:00
GyDi
359b82c29c
chore: rm some files 2022-06-01 00:49:52 +08:00
GyDi
b54171bc2c
chore: rust cache 2022-06-01 00:47:04 +08:00
GyDi
936b2131e0
chore: adjust ci and script 2022-06-01 00:43:57 +08:00
GyDi
aaef6a9e9c chore: enable meta by default 2022-06-01 00:31:12 +08:00
GyDi
9327006e61
chore: rm file 2022-05-30 00:58:48 +08:00
GyDi
5225c841ae
chore: adjust code 2022-05-30 00:57:31 +08:00
GyDi
8464e319fd
chore: update deps 2022-05-29 23:35:22 +08:00
GyDi
98b8bd90ea
fix: window transparent and can not get hwnd 2022-05-25 19:06:06 +08:00
GyDi
ae94993b09
fix: create main window 2022-05-25 16:45:18 +08:00
GyDi
72f10aaed1
chore: update deps 2022-05-25 16:12:48 +08:00
GyDi
4a74bae8c7
chore: update clash core 2022-05-25 16:08:58 +08:00
ctaoist
5164aec37b
feat: light mode wip (#96)
* 关闭窗口释放UI资源

* windows 还有左键点击事件

* 兼容enhance profile

* bug 修复
2022-05-25 16:06:39 +08:00
GyDi
1581e9b1cd
chore: update clash version 2022-05-18 14:14:37 +08:00
GyDi
536e3ffb11
chore: alpha ci 2022-05-18 14:07:41 +08:00
GyDi
d6103191ba
chore: error text 2022-05-18 09:58:20 +08:00
GyDi
49e37a19a5
chore: ci 2022-05-17 12:35:42 +08:00
GyDi
d02431e260
chore: fix alpha ci 2022-05-17 12:34:30 +08:00
GyDi
f24f6ead92
chore: alpha ci 2022-05-17 11:41:45 +08:00
GyDi
b7bdb7ae50
chore: meta 2022-05-17 02:46:15 +08:00
GyDi
2dcf8ac96f
chore: fix ci 2022-05-17 02:21:58 +08:00
GyDi
5421c94853
chore: test ci 2022-05-17 02:17:02 +08:00
GyDi
10f6bc092a
chore: alpha 2022-05-17 02:11:29 +08:00
GyDi
be9ea4ea8e
feat: clash meta core supports 2022-05-17 01:59:49 +08:00
GyDi
f5c6fa842a
fix: adjust notice 2022-05-17 00:51:37 +08:00
GyDi
e0943ce905
fix: label text 2022-05-16 20:26:13 +08:00
GyDi
61e7df77a7
feat: script mode 2022-05-16 20:18:56 +08:00
GyDi
a5434360bc
chore: test ci 2022-05-16 17:55:14 +08:00
GyDi
ba29c66e3b
chore: update deps 2022-05-16 17:54:21 +08:00
GyDi
b3a72d55ae
feat: clash meta core support (wip) 2022-05-16 01:52:50 +08:00
GyDi
c382ad1cc8
fix: icon path 2022-05-13 12:28:36 +08:00
GyDi
363e28f323
fix: icon issue 2022-05-13 02:46:06 +08:00
GyDi
d695656b8c
fix: notice ui blocking 2022-05-13 02:29:43 +08:00
GyDi
31c6cbc0a2
fix: service mode error 2022-05-13 02:11:03 +08:00
GyDi
b93284bc2f
chore: fix linux build ci 2022-05-11 12:39:41 +08:00
GyDi
99c855b01b
chore: test ci 2022-05-11 12:20:20 +08:00
GyDi
c2eaedc959
chore: test ci 2022-05-11 12:12:55 +08:00
GyDi
a631cd67ec
chore: test ci fix deps 2022-05-11 11:30:19 +08:00
GyDi
66fccd3c68
chore: test ci 2022-05-11 11:22:09 +08:00
GyDi
9a4ebf4daa
chore: test ci 2022-05-11 10:51:28 +08:00
GyDi
91c14211c6
chore: continue on error 2022-05-11 01:26:11 +08:00
GyDi
1ea07c458b
chore: test linux 2022-05-11 00:52:20 +08:00
GyDi
591add6e0c
chore: test ci 2022-05-11 00:31:19 +08:00
GyDi
b99fff66df v1.0.1 2022-05-10 21:40:33 +08:00
GyDi
f54ba05b00
chore: update log 2022-05-10 21:40:07 +08:00
GyDi
6596fb00c7
fix: win11 drag lag 2022-05-09 14:41:26 +08:00
GyDi
df0b5a80dc
chore: change default height 2022-05-09 14:01:46 +08:00
GyDi
8cdbb31dbe
fix: rm unwrap 2022-05-09 14:01:14 +08:00
GyDi
0be4b1222d
feat: reduce gpu usage when hidden 2022-05-07 14:43:52 +08:00
GyDi
18a6bfd73a
feat: interval update from now field 2022-05-07 14:43:08 +08:00
GyDi
5e2271b237
feat: adjust theme 2022-05-06 14:04:39 +08:00
GyDi
798999d490
fix: edit profile info 2022-05-06 12:46:27 +08:00
GyDi
0e68c5e8bc
feat: supports more remote headers close #81 2022-05-06 10:52:59 +08:00
GyDi
9694af82f4
feat: check the remote profile 2022-05-06 01:26:24 +08:00
GyDi
28a4386975
fix: change window default size 2022-05-06 01:15:15 +08:00
GyDi
a238f7beba
chore: update deps 2022-05-06 01:14:13 +08:00
GyDi
75ba16281b
chore: change default user agent 2022-05-06 00:42:20 +08:00
GyDi
ad65a278d4
chore: merge
feat: remove outdated config
2022-04-28 16:28:18 +08:00
tianyoulan
a2320b3f8d feat: fix typo 2022-04-28 15:35:17 +08:00
tianyoulan
ae12853ad0 feat: remove trailing comma 2022-04-28 15:05:10 +08:00
tianyoulan
68adf6dc2f feat: remove outdated config 2022-04-28 15:02:37 +08:00
GyDi
f88989bd4b
fix: change service installer and uninstaller 2022-04-27 15:46:44 +08:00
GyDi
77ef3847ce v1.0.0 2022-04-26 00:50:48 +08:00
GyDi
b8291837fc
chore: update log 2022-04-26 00:49:07 +08:00
GyDi
423a7f951a
fix: adjust connection scroll 2022-04-26 00:37:28 +08:00
GyDi
557f5fe364
fix: adjust something 2022-04-25 20:00:11 +08:00
GyDi
5308970ad8
fix: adjust debounce wait time 2022-04-25 19:39:21 +08:00
GyDi
6b368953f4
feat: windows service mode ui 2022-04-25 16:12:04 +08:00
GyDi
2d0b63c29d
feat: add some commands 2022-04-24 21:03:47 +08:00
GyDi
34e941c8cb
feat: windows service mode 2022-04-24 21:00:17 +08:00
GyDi
76cf007fff
chore: update check script 2022-04-24 15:35:30 +08:00
GyDi
321963be83
wip: windows service mode 2022-04-23 17:26:32 +08:00
GyDi
c733bda6c3
test: windows service 2022-04-21 21:28:44 +08:00
GyDi
e67b50b976
chore: adjust guard log 2022-04-21 19:51:20 +08:00
GyDi
9e3c080909
fix: adjust dns config 2022-04-21 19:50:22 +08:00
GyDi
cb661aaebd
feat: add update interval 2022-04-21 14:26:41 +08:00
GyDi
573571978c
chore: adjust 2022-04-21 14:24:35 +08:00
GyDi
dc492a2a0a
chore: update clash version 2022-04-20 21:02:41 +08:00
GyDi
e47747dd0e
feat: refactor and supports cron tasks 2022-04-20 20:39:27 +08:00
GyDi
4de944b41e
feat: supports cron update profiles 2022-04-20 20:37:16 +08:00
GyDi
5f7a1fa5cd
refactor: verge 2022-04-20 11:17:54 +08:00
GyDi
b8ad328cde
refactor: wip 2022-04-20 01:44:47 +08:00
GyDi
3076fd19c1
refactor: mutex 2022-04-19 14:38:59 +08:00
GyDi
fac437b8c1
fix: traffic graph adapt to different fps 2022-04-19 13:55:26 +08:00
GyDi
697c25015e
refactor: wip 2022-04-19 01:41:20 +08:00
GyDi
d83b404fc3
chore: check script proxy agent supports 2022-04-17 00:37:21 +08:00
GyDi
ab7313cbc4
feat: optimize traffic graph quadratic curve 2022-04-16 22:32:44 +08:00
GyDi
1b8d70322b
feat: optimize the animation of the traffic graph 2022-04-16 17:28:30 +08:00
GyDi
844ffab4ed
fix: optimize clash launch 2022-04-15 01:29:25 +08:00
GyDi
f5d0513d1f
fix: reset after exit 2022-04-14 01:29:33 +08:00
GyDi
557abd4285
fix: adjust code 2022-04-14 01:29:02 +08:00
GyDi
f4f1a0fbc6 v0.0.29 2022-04-13 01:30:08 +08:00
GyDi
74e10dc012
chore: update log 2022-04-13 01:29:48 +08:00
GyDi
359812b7ed
chore: update dep 2022-04-13 01:21:49 +08:00
GyDi
c2449e53c4
chore: rename green to portable 2022-04-13 01:17:40 +08:00
GyDi
1a91249da2
feat: system tray add tun mode 2022-04-13 01:09:51 +08:00
GyDi
b9162f9576
fix: adjust log 2022-04-13 00:49:30 +08:00
GyDi
f726e8a7b3
feat: supports change config dir 2022-04-12 23:09:32 +08:00
GyDi
2f284cfdc9
chore: update clash version 2022-04-12 23:04:19 +08:00
GyDi
b74696adba
feat: add default user agent 2022-04-12 01:05:51 +08:00
GyDi
c8ccba0192
chore: rm console 2022-04-11 02:26:09 +08:00
GyDi
41b0e05f62
feat: connections page supports filter 2022-04-11 02:25:34 +08:00
GyDi
847d5f1b3b
feat: log page supports filter 2022-04-11 01:46:33 +08:00
GyDi
0445f9dfc2
fix: check button hover style 2022-04-10 03:33:17 +08:00
GyDi
3001c780bd
feat: optimize delay checker concurrency strategy 2022-04-10 02:58:48 +08:00
GyDi
68ad5e2320
feat: support sort proxy node and custom test url 2022-04-10 02:09:36 +08:00
GyDi
b5e229b19c
chore: update deps 2022-04-10 01:31:05 +08:00
GyDi
453d798fcf
refactor: proxy head 2022-04-08 01:35:18 +08:00
GyDi
451afdb660 v0.0.28 2022-04-07 01:28:30 +08:00
GyDi
d298bda92c
chore: update log 2022-04-07 01:27:48 +08:00
GyDi
fd99ba6255
feat: handle remote clash config fields 2022-04-07 01:20:44 +08:00
GyDi
6ade0b2b1a
fix: icon button color inherit 2022-04-06 22:52:00 +08:00
GyDi
9902003da9
fix: remove the lonely zero 2022-04-06 22:48:10 +08:00
GyDi
0ff2fcac11
chore: readme 2022-04-06 01:52:20 +08:00
GyDi
e80be8e7b6 v0.0.27 2022-04-06 01:21:33 +08:00
GyDi
fe0ad0f5cb
chore: update log 2022-04-06 01:19:13 +08:00
GyDi
cb8e162f4e
refactor: update profile menu 2022-04-06 01:13:06 +08:00
GyDi
ae8c30fe57
chore: add updater script 2022-04-05 23:24:52 +08:00
GyDi
ab82db9e22
chore: updater json supports arch field 2022-04-05 23:19:54 +08:00
GyDi
cb9d3098de
chore: add ci 2022-04-05 20:21:53 +08:00
GyDi
c927419c99
refactor: enhanced mode ui component 2022-04-03 01:41:48 +08:00
GyDi
c009026961
feat: add text color 2022-04-02 17:18:38 +08:00
GyDi
51cf442fa5
fix: i18n add value 2022-04-02 13:49:48 +08:00
GyDi
954e3553ee
fix: proxy page first render 2022-04-02 01:23:31 +08:00
GyDi
cde17385b4
feat: control final tun config 2022-04-01 23:55:44 +08:00
GyDi
5b9e078061
chore: add debug feature 2022-04-01 23:43:35 +08:00
GyDi
0290d9ddfc
feat: support css injection 2022-04-01 02:08:42 +08:00
GyDi
eab671d102
fix: console warning 2022-04-01 01:16:23 +08:00
GyDi
f9a96ff914
feat: support theme setting 2022-03-31 23:38:00 +08:00
GyDi
3ec2b46d28
feat: add text color 2022-03-31 23:34:36 +08:00
GyDi
aec30b89e0
feat: add theme setting 2022-03-31 23:11:50 +08:00
GyDi
309c33e190
refactor: ui theme 2022-03-30 12:36:39 +08:00
GyDi
9c0276f97b
chore: add api 2022-03-30 01:30:22 +08:00
GyDi
0a3402ff43
fix: icon button title 2022-03-30 01:29:25 +08:00
GyDi
bd82308024
chore: update tauri 2022-03-29 23:05:32 +08:00
GyDi
db3b634e62
fix: macOS transition flickers close #47 2022-03-29 01:39:54 +08:00
GyDi
40bcb22977
chore: update deps 2022-03-29 01:33:14 +08:00
GyDi
4bd94092f1
fix: csp image data 2022-03-28 23:17:11 +08:00
GyDi
cac1ce6895
chore: readme 2022-03-28 01:33:58 +08:00
GyDi
5c3696123a v0.0.26 2022-03-28 01:30:54 +08:00
GyDi
4140fc86ee
chore: update log 2022-03-28 01:18:18 +08:00
GyDi
2ad771e7fd
fix: close dialog after save 2022-03-28 01:09:34 +08:00
GyDi
5a38468144
refactor: optimize enhance mode strategy 2022-03-28 01:07:14 +08:00
GyDi
0a9c81772f
fix: change to deep copy 2022-03-28 00:56:48 +08:00
GyDi
c9649ac501
feat: enhanced mode supports more fields 2022-03-27 20:36:13 +08:00
GyDi
6ea567742b
chore: profile release 2022-03-27 01:38:40 +08:00
GyDi
f31349eaa0
feat: supports edit profile file 2022-03-27 00:58:17 +08:00
GyDi
9d44668d5f
feat: supports silent start 2022-03-26 18:56:16 +08:00
GyDi
a12f58c1c7
feat: use crate open 2022-03-23 23:00:14 +08:00
GyDi
b5283eaaed
fix: window style close #45 2022-03-23 21:43:13 +08:00
GyDi
4b6189af5f
feat: enhance connections display order 2022-03-23 14:02:08 +08:00
GyDi
5d0ffbe453
chore: adjust style 2022-03-23 13:58:57 +08:00
GyDi
502706931e
fix: manage global proxy correctly 2022-03-23 12:49:34 +08:00
GyDi
57c411288f
fix: tauri csp 2022-03-23 01:47:35 +08:00
GyDi
b09b7b11a1
feat: save global selected 2022-03-22 12:38:59 +08:00
GyDi
1a7b3c7294 v0.0.25 2022-03-22 01:51:06 +08:00
GyDi
4678fc7dde
chore: update log 2022-03-22 01:50:24 +08:00
GyDi
9f492fad49
chore: update clash core 2022-03-22 01:50:15 +08:00
GyDi
bd0a959e18
fix: windows style 2022-03-22 01:36:06 +08:00
GyDi
dd605e2610
fix: update state 2022-03-22 01:27:22 +08:00
inRm3D
9910f6b817
chore: readme (#43) 2022-03-21 21:55:45 +08:00
GyDi
991897aff4
chore: tauri feature 2022-03-21 11:40:52 +08:00
GyDi
3cde019208
fix: profile item loading state 2022-03-21 11:40:27 +08:00
GyDi
2f6efbed63
chore: tauri allowList 2022-03-20 13:16:50 +08:00
GyDi
5cff4e299b
chore: update clash version 2022-03-20 12:37:55 +08:00
GyDi
bce33639da v0.0.24 2022-03-20 01:50:39 +08:00
GyDi
366c465cad
chore: update log 2022-03-20 01:50:15 +08:00
GyDi
acc6e05bdc
feat: system tray supports system proxy setting 2022-03-20 01:36:43 +08:00
GyDi
4ce15577cd
feat: prevent context menu on Windows close #22 2022-03-19 19:28:53 +08:00
GyDi
98fa4d5e65
feat: create local profile with selected file 2022-03-19 19:21:55 +08:00
GyDi
7fe94076c7
feat: reduce the impact of the enhanced mode 2022-03-19 16:02:47 +08:00
GyDi
b8b0c8fa63
fix: adjust windows style 2022-03-19 15:35:59 +08:00
GyDi
e585e87bec
feat: parse update log 2022-03-19 15:31:58 +08:00
GyDi
6a4924bb16
chore: update log supports 2022-03-19 14:04:58 +08:00
GyDi
ab0d516d91
chore: updater proxy 2022-03-19 11:14:12 +08:00
GyDi
b756ae39d0
chore: ci support linux 2022-03-19 10:50:44 +08:00
GyDi
c15c38ea8f
chore: readme 2022-03-18 19:02:53 +08:00
GyDi
743963318f
feat: fill i18n 2022-03-18 14:59:23 +08:00
GyDi
ed3fc50858
feat: dayjs i18n 2022-03-18 14:45:24 +08:00
GyDi
5b886fe6be
feat: connections page simply support 2022-03-18 14:43:22 +08:00
GyDi
7074bbc405
feat: add wintun.dll by default 2022-03-18 11:49:00 +08:00
GyDi
ef314c1707
fix: change mixed port error 2022-03-18 11:39:02 +08:00
GyDi
a3e7626dd9
chore: add dev feature 2022-03-18 10:59:35 +08:00
GyDi
5cb5d74eed
chore: rename temp dir 2022-03-18 10:20:24 +08:00
GyDi
6eee10d46d
chore: resolve wintun.dll 2022-03-17 19:29:30 +08:00
GyDi
2d95f2b0d6
fix: auto launch path 2022-03-16 18:44:25 +08:00
GyDi
ec41bb9c70
fix: tun mode config 2022-03-15 14:23:57 +08:00
GyDi
2d1780b1cf
fix: adjsut open cmd error 2022-03-15 12:51:39 +08:00
GyDi
d9ce99887c
chore: fix ci env 2022-03-15 00:00:20 +08:00
GyDi
9b9cc90414 v0.0.23 2022-03-14 01:34:26 +08:00
GyDi
c1eb539a5c
feat: event emit when clash config update 2022-03-13 01:37:41 +08:00
GyDi
e1793f57ef
chore: fix ci 2022-03-13 00:59:42 +08:00
GyDi
dbd09a8743
chore: update tauri action 2022-03-13 00:58:49 +08:00
GyDi
0d189ca617
chore: green version bundle 2022-03-13 00:52:31 +08:00
GyDi
dc9bcc40ee
chore: rm then 2022-03-12 23:58:20 +08:00
GyDi
4991f7ff39
feat: i18n supports 2022-03-12 23:07:45 +08:00
GyDi
a393b8b122
fix: parse external-controller 2022-03-12 21:35:20 +08:00
GyDi
c73b354386
fix: config file case close #18 2022-03-12 21:03:17 +08:00
GyDi
392ecee3ff
chore: merge 2022-03-12 18:45:07 +08:00
ttyS3
bae721c49e
chore: show open app and log dir failed message 2022-03-12 18:04:56 +08:00
GyDi
4e806e21a6
chore: adjust error log 2022-03-12 15:57:16 +08:00
GyDi
ec0fdf83b2
feat: change open command on linux
refactor(logging): refine open dir failed log message, add Linux support
2022-03-12 15:40:23 +08:00
ttyS3
cb94d8414f
feat: add Linux open dir support
refactor(logging): refine open dir failed log message
2022-03-12 03:18:25 +08:00
GyDi
8890051c17
fix: patch item option 2022-03-11 19:56:56 +08:00
GyDi
cf00c9476f
fix: user agent not works 2022-03-11 19:50:51 +08:00
GyDi
b2a24c7abd v0.0.22 2022-03-10 02:27:00 +08:00
GyDi
732a1f4694
chore: rm dead code 2022-03-10 02:25:35 +08:00
GyDi
4c5aa7084e
fix: external-controller 2022-03-10 02:19:06 +08:00
GyDi
fe1fea671c
feat: support more options for remote profile 2022-03-10 02:03:55 +08:00
GyDi
04c754c0ac
chore: reduce icon size on macOS 2022-03-10 01:04:53 +08:00
GyDi
754c22c84e
chore: adjust icon 2022-03-10 00:04:59 +08:00
GyDi
629331870b
chore: add linux link 2022-03-09 20:14:15 +08:00
GyDi
78774315cb
feat: linux system proxy 2022-03-09 19:48:32 +08:00
GyDi
36b9c07928
chore: update deps 2022-03-09 02:36:40 +08:00
GyDi
40a818630d
fix: change proxy bypass on mac 2022-03-09 02:36:03 +08:00
GyDi
568511a4cf
fix: kill sidecars after install still in test 2022-03-09 02:09:51 +08:00
GyDi
109fb39e09
fix: log some error 2022-03-09 02:00:56 +08:00
GyDi
68450d2042
chore: rename productName 2022-03-09 01:53:34 +08:00
GyDi
8a052bbed6
chore: update tauri version 2022-03-09 01:50:37 +08:00
GyDi
3afbb56640
fix: apply_blur parameter 2022-03-08 10:44:41 +08:00
GyDi
c0ad84a491
fix: limit enhanced profile range 2022-03-08 01:45:46 +08:00
GyDi
c72f17605c
chore: update deps 2022-03-08 01:18:20 +08:00
GyDi
42fbee0cdb
chore: add default bypass 2022-03-08 00:39:09 +08:00
GyDi
e9b7ec735f
fix: profile updated field 2022-03-07 01:41:42 +08:00
GyDi
743788135f
fix: profile field check 2022-03-07 01:30:32 +08:00
GyDi
8ea3e6fa26
fix: create dir panic 2022-03-07 01:06:21 +08:00
GyDi
f23c83e681 v0.0.21 2022-03-06 18:36:02 +08:00
GyDi
b615bda17e
chore: default release body 2022-03-06 18:34:38 +08:00
GyDi
f7c7cd1d3c chore: update deps 2022-03-06 18:04:44 +08:00
GyDi
c7e7be4379
fix: only error when selected 2022-03-06 17:06:45 +08:00
GyDi
d63d49f246
feat: enhance profile status 2022-03-06 17:02:29 +08:00
GyDi
dad94edb20
feat: menu item refresh enhanced mode 2022-03-06 15:46:16 +08:00
GyDi
7108d5f3ab
fix: enhanced profile consistency 2022-03-06 15:40:16 +08:00
GyDi
ef47a74920
feat: profile enhanced mode 2022-03-06 14:59:25 +08:00
GyDi
a43dab8057
feat: profile enhanced ui 2022-03-05 22:54:39 +08:00
GyDi
f44039b628
feat: profile item adjust 2022-03-05 19:04:20 +08:00
GyDi
08fa5205b0
fix: simply compatible with proxy providers 2022-03-05 16:18:44 +08:00
GyDi
b91daebd92
fix: component warning 2022-03-05 15:48:39 +08:00
GyDi
9cd6c5c624
chore: update copyright 2022-03-05 01:51:29 +08:00
GyDi
650e017b72
fix: when updater failed 2022-03-04 02:10:27 +08:00
GyDi
18f9d6dec5 fix: log file 2022-03-04 02:08:26 +08:00
GyDi
4df6571ad9
chore: update deps 2022-03-03 20:37:06 +08:00
GyDi
0f5923a10a
chore: enhance wip 2022-03-03 01:58:05 +08:00
GyDi
bcdae1169e
fix: result 2022-03-03 01:56:47 +08:00
GyDi
f260d5df49
feat: enhanced profile (wip) 2022-03-03 01:52:02 +08:00
GyDi
808b861dd1 v0.0.20 2022-03-02 01:59:53 +08:00
GyDi
17f1c487a8
feat: edit profile item 2022-03-02 01:58:16 +08:00
GyDi
8dc2c1a38f
fix: cover profile extra 2022-03-02 01:45:00 +08:00
GyDi
220a494692
chore: adjust log field 2022-03-02 01:13:31 +08:00
GyDi
db6bc10196
chore: rm file 2022-03-02 00:58:07 +08:00
GyDi
1880363aeb
feat: use nanoid 2022-03-02 00:56:05 +08:00
GyDi
19c7b59883
feat: compatible profile config 2022-03-01 11:05:33 +08:00
GyDi
749df89229
refactor: profile config 2022-03-01 08:58:47 +08:00
GyDi
444f2172fa v0.0.19 2022-02-28 01:59:53 +08:00
GyDi
77a77c0ea7
wip: refactor profile 2022-02-28 01:59:13 +08:00
GyDi
dbf380a0d1
refactor: use anyhow to handle error 2022-02-28 01:34:25 +08:00
GyDi
ade34f5217
fix: display menu only on macos 2022-02-27 01:47:56 +08:00
GyDi
e89607799a
fix: proxy global showType 2022-02-27 01:33:22 +08:00
GyDi
d05d8d6a9e
feat: native menu supports 2022-02-27 01:29:57 +08:00
GyDi
b6aa50d3dc
chore: update deps 2022-02-27 01:16:43 +08:00
GyDi
9df361935f
feat: filter proxy and display type 2022-02-27 00:58:14 +08:00
GyDi
98b8a122b6
feat: use lock fn 2022-02-26 17:39:36 +08:00
GyDi
c7232522ee
feat: refactor proxy page 2022-02-26 17:39:08 +08:00
GyDi
5280f1d745
feat: proxy group auto scroll to current 2022-02-26 01:21:39 +08:00
GyDi
b52a081e7b v0.0.18 2022-02-25 02:13:41 +08:00
GyDi
f981a44861
chore: ci 2022-02-25 02:12:55 +08:00
GyDi
d7c5ce0750
feat: clash tun mode supports 2022-02-25 02:09:39 +08:00
GyDi
9ccc66ca1e
feat: use enhanced guard-state 2022-02-25 01:22:33 +08:00
GyDi
8606af3616
feat: guard state supports debounce guard 2022-02-25 01:21:13 +08:00
GyDi
f6e821ba6b
feat: adjust clash version display 2022-02-24 23:04:18 +08:00
GyDi
e8dbcf819b
feat: hide command window 2022-02-24 22:46:12 +08:00
GyDi
bbe2ef4e8e
fix: use full clash config 2022-02-23 23:23:07 +08:00
GyDi
dd15455031
feat: enhance log data 2022-02-23 02:00:45 +08:00
GyDi
12ac7bb338
chore: update readme 2022-02-22 21:54:33 +08:00
GyDi
46ef348f0d v0.0.17 2022-02-22 02:08:31 +08:00
GyDi
1a55cca8af
fix: reconnect websocket when restart clash 2022-02-22 02:05:22 +08:00
GyDi
81ee989f1f
chore: enhance publish ci 2022-02-22 01:56:06 +08:00
GyDi
c9c06f8a3d
fix: wrong exe path 2022-02-21 22:33:37 +08:00
GyDi
72127979c3
chore: use tauri cli 2022-02-21 22:31:00 +08:00
GyDi
1ad3ddef94 v0.0.16 2022-02-21 01:33:11 +08:00
GyDi
97ec5eabf7
feat: change window style 2022-02-20 23:46:13 +08:00
GyDi
e12e3a3f2d
feat: fill verge template 2022-02-20 20:12:55 +08:00
GyDi
4ff625f23b
feat: enable customize guard duration 2022-02-20 20:11:39 +08:00
GyDi
e38dcd85ac
feat: system proxy guard 2022-02-20 18:53:21 +08:00
GyDi
0245baf1b6
feat: enable show or hide traffic graph 2022-02-19 18:14:40 +08:00
GyDi
10b55c043c
fix: patch verge config 2022-02-19 17:32:23 +08:00
GyDi
457655b416
feat: traffic line graph 2022-02-19 17:02:24 +08:00
GyDi
7e4506c860
chore: update deps 2022-02-19 00:34:09 +08:00
GyDi
794d376348
feat: adjust profile item ui 2022-02-19 00:23:47 +08:00
GyDi
c60578f5b5
feat: adjust fetch profile url 2022-02-19 00:09:36 +08:00
GyDi
3a9a392a77
feat: inline config file template 2022-02-18 23:57:13 +08:00
GyDi
a13d4698be
chore: update check script 2022-02-18 23:49:39 +08:00
GyDi
c046a1993e
fix: fetch profile panic 2022-02-17 13:44:26 +08:00
GyDi
f709117cc4
feat: kill sidecars when update app 2022-02-17 02:10:25 +08:00
GyDi
30dd298fca
feat: delete file 2022-02-17 01:58:12 +08:00
GyDi
0ff8bb8090
feat: lock some async functions 2022-02-17 01:42:25 +08:00
GyDi
74bbd3c3a2
chore: tauri updater env 2022-02-16 11:02:00 +08:00
GyDi
2e82eaf59a
chore: add pubkey 2022-02-16 10:59:31 +08:00
GyDi
7f1df1f1bd v0.0.15 2022-02-16 03:22:25 +08:00
GyDi
3c79238a44
feat: support open dir 2022-02-16 03:21:34 +08:00
GyDi
0aa2565df3
fix: spawn command 2022-02-16 02:43:52 +08:00
GyDi
22b11db16e
feat: change allow list 2022-02-16 02:42:56 +08:00
GyDi
d0e678b5e9
feat: support check delay 2022-02-16 02:22:01 +08:00
GyDi
e7bba968b3 fix: import error 2022-02-15 01:36:19 +08:00
GyDi
4934a24293
feat: scroll to proxy item 2022-02-15 01:34:10 +08:00
GyDi
ccb68bcda9
chore: update deps 2022-02-15 00:33:58 +08:00
GyDi
66bf4ba3ad
fix: not open file when new profile 2022-02-15 00:21:34 +08:00
GyDi
78a0cfd052
feat: edit system proxy bypass 2022-02-14 01:26:24 +08:00
GyDi
8548373742
feat: disable user select 2022-02-13 19:52:35 +08:00
GyDi
2dfd725ee0
fix: reset value correctly 2022-02-13 19:40:31 +08:00
GyDi
5b779b4f14
feat: new profile able to edit name and desc 2022-02-13 19:33:24 +08:00
GyDi
fc48aa7155 chore: adjust files 2022-02-13 19:27:24 +08:00
GyDi
6193a842f4
feat: update tauri version 2022-02-13 18:45:03 +08:00
GyDi
eb86b471fe
fix: something 2022-02-12 21:12:39 +08:00
GyDi
2b52584547
fix: menu without fragment 2022-02-10 01:42:52 +08:00
GyDi
6e3cc57f48
feat: display clash core version 2022-02-10 01:35:55 +08:00
GyDi
f2c04621a5
feat: adjust profile item menu 2022-02-10 01:14:57 +08:00
GyDi
3ed6938d4a v0.0.14 2022-02-09 02:11:01 +08:00
GyDi
99fec25ed5
feat: profile item ui 2022-02-09 02:08:27 +08:00
GyDi
73758ad1fd
fix: proxy list error 2022-02-09 02:02:29 +08:00
GyDi
c53fe0ed1f
feat: support new profile 2022-02-07 17:26:05 +08:00
GyDi
6082c2bcac
feat: support open command for viewing 2022-02-07 16:45:20 +08:00
GyDi
069abed784
chore: add item template yaml 2022-02-02 20:56:06 +08:00
GyDi
7d8fa4d78a
fix: something 2022-01-31 23:34:58 +08:00
GyDi
76081f8d89
fix: macos auto launch fail 2022-01-31 23:32:41 +08:00
GyDi
5ef4285558
chore: update deps and app name 2022-01-31 23:27:11 +08:00
GyDi
aa7df4282e
chore: cargo update 2022-01-28 22:02:17 +08:00
GyDi
0ef1d5d0de
chore: update clash version 2022-01-28 22:00:15 +08:00
GyDi
cceb4bb81f v0.0.13 2022-01-25 02:11:00 +08:00
GyDi
f0f45e007d
feat: global proxies use virtual list 2022-01-25 02:08:10 +08:00
GyDi
6a8ffe1642
feat: enable change proxy mode 2022-01-25 01:51:44 +08:00
GyDi
3a73868c10
feat: update styles 2022-01-25 01:48:26 +08:00
GyDi
ab1b5897a6
feat: manage clash mode 2022-01-24 23:13:13 +08:00
GyDi
f94734a5c8 chore: update readme 2022-01-22 23:57:39 +08:00
GyDi
61b86c9584 v0.0.12 2022-01-21 03:09:21 +08:00
GyDi
1ac1d6e903
chore: update ci 2022-01-21 03:08:40 +08:00
GyDi
b6c58f74c0
fix: type error 2022-01-21 03:08:20 +08:00
GyDi
c88e99d87c v0.0.12 2022-01-21 02:59:33 +08:00
GyDi
8d7ab9d05e
refactor: rename profiles & command state 2022-01-21 02:57:15 +08:00
GyDi
47155a4a29
feat: change system porxy when changed port 2022-01-21 02:50:13 +08:00
GyDi
d0b87fd7c3
feat: enable change mixed port 2022-01-21 02:32:23 +08:00
GyDi
d49fd37656
feat: manage clash config 2022-01-21 02:31:44 +08:00
GyDi
0bd29d71be
chore: add ahooks 2022-01-21 02:29:45 +08:00
GyDi
4b5b62c8ae
fix: restart clash should update something 2022-01-21 00:29:33 +08:00
GyDi
65fb2ca2d5
feat: enable update clash info 2022-01-20 23:41:08 +08:00
GyDi
0d5bfc0997
feat: rename edit as view 2022-01-19 23:58:34 +08:00
GyDi
4f02c373c2
chore: adjust ci 2022-01-19 23:55:05 +08:00
GyDi
209a5b1207
fix: script error... 2022-01-19 00:49:23 +08:00
GyDi
95349eacab
fix: tag error 2022-01-19 00:46:43 +08:00
GyDi
82ba604b99
fix: script error 2022-01-19 00:42:37 +08:00
GyDi
46a8dec655
feat: test auto gen update.json ci 2022-01-19 00:37:59 +08:00
GyDi
b5af234524 v0.0.11 2022-01-17 02:53:07 +08:00
GyDi
b5c41750f7
fix: remove cargo test 2022-01-17 02:50:19 +08:00
GyDi
6083824eec v0.0.11 2022-01-17 02:44:08 +08:00
GyDi
40977785c3
feat: adjust setting typography 2022-01-17 02:42:52 +08:00
GyDi
5eddf4f1aa
feat: enable force select profile 2022-01-17 02:28:23 +08:00
GyDi
99a8e25411
feat: support edit profile item 2022-01-17 02:16:17 +08:00
GyDi
08587d8f2f
fix: reduce proxy item height 2022-01-17 02:15:54 +08:00
GyDi
3480d50f61
feat: adjust control ui 2022-01-17 02:15:06 +08:00
GyDi
43af55252d
feat: update profile supports noproxy 2022-01-16 22:57:42 +08:00
GyDi
9c43b31fc0
refactor: something 2022-01-16 18:30:25 +08:00
GyDi
9ec7184aa1
fix: put profile request with no proxy 2022-01-16 18:20:01 +08:00
GyDi
4e2cb30db7
refactor: notice caller 2022-01-16 17:56:43 +08:00
GyDi
9ca83d3291
chore: change ci 2022-01-16 16:03:53 +08:00
GyDi
6b2172d873
fix: ci strategy 2022-01-16 14:30:49 +08:00
GyDi
1a5d9f7dad
chore: enhance ci 2022-01-16 14:27:41 +08:00
GyDi
a8425862f0
feat: rename page 2022-01-16 03:25:50 +08:00
GyDi
a3a3db6abb
refactor: setting page 2022-01-16 03:22:37 +08:00
GyDi
d6c3bc57c0
feat: refactor and adjust ui 2022-01-16 03:11:07 +08:00
GyDi
59c09f90f9
feat: rm some commands 2022-01-16 03:09:36 +08:00
GyDi
d982b83e14
feat: change type 2022-01-15 21:58:13 +08:00
GyDi
cc0e930d34
feat: supports auto launch on macos and windows 2022-01-15 21:55:05 +08:00
GyDi
3c3d77fbea
chore: add auto-launch 2022-01-15 21:00:19 +08:00
GyDi
da7453fdbf v0.0.10 2022-01-13 02:53:29 +08:00
GyDi
5fcd25506e feat: adjust proxy page 2022-01-13 02:51:30 +08:00
GyDi
4979a472de feat: press esc hide the window 2022-01-13 02:11:50 +08:00
GyDi
4e8d4f4591 fix: version update error 2022-01-12 22:19:44 +08:00
GyDi
0f5d2b15e0 v0.0.9 2022-01-12 02:55:07 +08:00
GyDi
7fc9631434 feat: show system proxy info 2022-01-12 02:54:50 +08:00
GyDi
df5953dd7b feat: support blur window 2022-01-12 02:27:29 +08:00
GyDi
8f5b2b4a0e chore: add macos startup todo 2022-01-11 23:14:43 +08:00
GyDi
43c63ffa70 chore: cargo update 2022-01-11 23:13:02 +08:00
GyDi
6779bc7459 v0.0.8 2022-01-11 02:27:04 +08:00
GyDi
664be2d0ba chore: update ci 2022-01-11 02:26:50 +08:00
GyDi
6113898b69 feat: windows support startup 2022-01-11 02:24:43 +08:00
GyDi
79aad6b5c2 feat: window self startup 2022-01-11 02:21:51 +08:00
GyDi
6da7757d36 fix: text 2022-01-10 22:57:21 +08:00
GyDi
dbb3cb8cc8 chore: ignore update json 2022-01-10 22:08:57 +08:00
GyDi
579f36a1dd fix: update profile after restart clash 2022-01-10 22:08:18 +08:00
GyDi
72c2b306cf fix: get proxies multiple times 2022-01-10 21:25:41 +08:00
GyDi
c2673cd396 docs: fix img width 2022-01-10 02:52:12 +08:00
GyDi
8eb152816a docs: update 2022-01-10 02:49:42 +08:00
GyDi
a0bc8a21a5 v0.0.7 2022-01-10 02:17:35 +08:00
GyDi
08e4d72758 feat: use tauri updater 2022-01-10 02:15:38 +08:00
GyDi
66340a27fa feat: support update checker 2022-01-10 02:05:35 +08:00
GyDi
83fe9835b6 v0.0.6 2022-01-09 21:36:43 +08:00
GyDi
4c1a50a3ca chore: ci add macos 2022-01-09 21:34:14 +08:00
GyDi
fe44a7b3bc feat: support macos proxy config 2022-01-09 21:19:35 +08:00
GyDi
e86d192db7 feat: custom window decorations 2022-01-08 22:23:48 +08:00
GyDi
ea8f1c52f9 feat: profiles add menu and delete button 2022-01-08 16:52:18 +08:00
GyDi
a4c1573c45 fix: delete profile item command 2022-01-08 14:21:12 +08:00
GyDi
182bf49ad0 chore: temp 2022-01-08 02:54:37 +08:00
GyDi
13e1ddbccd v0.0.5 2022-01-08 02:12:56 +08:00
GyDi
327b9a1757 chore: enhance ci 2022-01-08 02:12:12 +08:00
GyDi
18c48db7f7 chore: rename script 2022-01-08 01:56:28 +08:00
GyDi
b6543bd87f chore: update publish script 2022-01-08 01:51:24 +08:00
GyDi
9ad8f71d7c refactor: rename 2022-01-08 01:27:25 +08:00
GyDi
e369311fc2 refactor: impl structs methods 2022-01-07 23:29:20 +08:00
GyDi
72ff261fe3 chore: update clash version 2022-01-06 23:40:57 +08:00
GyDi
774c6f7e05 fix: initialize profiles state 2022-01-05 23:30:18 +08:00
GyDi
771af6ae08 chore: fixed tauri rev 2022-01-05 23:27:26 +08:00
GyDi
b3cd207444 feat: delay put profiles and retry 2022-01-05 02:01:32 +08:00
GyDi
03f9fa4bc2 refactor: impl as struct methods 2022-01-05 02:00:59 +08:00
GyDi
e32bfd9aab feat: Window Send and Sync 2022-01-04 21:29:04 +08:00
GyDi
7e47f8f893 chore: update tauri 2022-01-04 21:25:00 +08:00
GyDi
cb816e9653 feat: support restart sidecar tray event 2021-12-31 18:24:50 +08:00
GyDi
6b3e7cbc08 feat: prevent click same 2021-12-31 18:21:35 +08:00
GyDi
db4993ae9b fix: item header bgcolor 2021-12-31 18:19:53 +08:00
GyDi
4dc3cf6c6b feat: scroller stable 2021-12-31 18:19:17 +08:00
GyDi
2b84bbf3a8 feat: compatible with macos(wip) 2021-12-29 18:49:38 +08:00
GyDi
26ef4c9961 chore: change tauri to git repo 2021-12-29 18:47:29 +08:00
GyDi
4f56c38599 fix: null type error 2021-12-29 01:01:22 +08:00
GyDi
240f4dcfb1 chore: dev support macos 2021-12-29 01:01:09 +08:00
GyDi
ac6abd81c9 v0.0.4 2021-12-28 01:48:25 +08:00
GyDi
14bda4f3a5 feat: record selected proxy 2021-12-28 01:47:43 +08:00
GyDi
61b9670b45 feat: display version 2021-12-28 01:35:58 +08:00
GyDi
01e8db317e chore: save lock file 2021-12-28 00:14:15 +08:00
GyDi
92fc09493e chore: post version script 2021-12-27 23:07:56 +08:00
GyDi
d927209db7 v0.0.3 2021-12-27 23:06:46 +08:00
GyDi
e94007b21f v0.0.3 2021-12-27 23:06:45 +08:00
GyDi
18750f275a
chore: update version 2021-12-27 10:21:49 +08:00
GyDi
d686a853f4
chore: update version 2021-12-27 10:21:10 +08:00
351 changed files with 60076 additions and 4679 deletions

5
.cargo/config.toml Normal file
View File

@ -0,0 +1,5 @@
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

View File

@ -5,3 +5,9 @@ charset = utf-8
end_of_line = lf
indent_size = 2
insert_final_newline = true
[*.rs]
charset = utf-8
end_of_line = lf
indent_size = 4
insert_final_newline = true

63
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,63 @@
name: 问题反馈 / Bug report
title: "[BUG] "
description: 反馈你遇到的问题 / Report the issue you are experiencing
labels: ["bug"]
type: "Bug"
body:
- type: markdown
attributes:
value: |
## 在提交问题之前,请确认以下事项:
1. 请 **确保** 您已经查阅了 [Clash Verge Rev 官方文档](https://clash-verge-rev.github.io/guide/term.html) 以及 [常见问题](https://clash-verge-rev.github.io/faq/windows.html)
2. 请 **确保** [已有的问题](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue) 中没有人提交过相似issue否则请在已有的issue下进行讨论
3. 请 **务必** 给issue填写一个简洁明了的标题以便他人快速检索
4. 请 **务必** 先下载 [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) 版本测试,确保问题依然存在
5. 请 **务必** 按照模板规范详细描述问题否则issue将会被关闭
## Before submitting the issue, please make sure of the following checklist:
1. Please make sure you have read the [Clash Verge Rev official documentation](https://clash-verge-rev.github.io/guide/term.html) and [FAQ](https://clash-verge-rev.github.io/faq/windows.html)
2. Please make sure there is no similar issue in the [existing issues](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue), otherwise please discuss under the existing issue
3. Please be sure to fill in a concise and clear title for the issue so that others can quickly search
4. Please be sure to download the [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) version for testing to ensure that the problem still exists
5. Please describe the problem in detail according to the template specification, otherwise the issue will be closed
- type: textarea
id: description
attributes:
label: 问题描述 / Describe the bug
description: 详细清晰地描述你遇到的问题,并配合截图 / Describe the problem you encountered in detail and clearly, and provide screenshots
validations:
required: true
- type: textarea
attributes:
label: 软件版本 / Verge Version
description: 请提供Verge的具体版本如果是alpha版本请注明下载时间(精确到小时分钟) / Please provide the specific version of Verge. If it is an alpha version, please indicate the download time (accurate to hours and minutes)
validations:
required: true
- type: textarea
attributes:
label: 复现步骤 / To Reproduce
description: 请提供复现问题的步骤 / Steps to reproduce the behavior
validations:
required: true
- type: dropdown
attributes:
label: 操作系统 / OS
options:
- Windows
- Linux
- MacOS
validations:
required: true
- type: input
attributes:
label: 操作系统版本 / OS Version
description: 请提供你的操作系统版本Linux请额外提供桌面环境及窗口系统 / Please provide your OS version, for Linux, please also provide the desktop environment and window system
validations:
required: true
- type: textarea
attributes:
label: 日志 / Log
description: 请提供完整或相关部分的Debug日志请在“软件左侧菜单”->“设置”->“日志等级”调整到debugVerge错误请把“杂项设置”->“app日志等级”调整到debug/trace并重启Verge生效。日志文件在“软件左侧菜单”->“设置”->“日志目录”下) / Please provide a complete or relevant part of the Debug log (please adjust the "Log level" to debug in "Software left menu" -> "Settings" -> "Log level". If there is a Verge error, please adjust "Miscellaneous settings" -> "app log level" to trace, and restart Verge to take effect. The log file is under "Software left menu" -> "Settings" -> "Log directory")
validations:
required: true

4
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,4 @@
contact_links:
- name: 讨论交流 / Communication
url: https://t.me/clash_verge_rev
about: 在 Telegram 群组中与其他用户讨论交流 / Communicate with other users in the Telegram group

View File

@ -0,0 +1,47 @@
name: 功能请求 / Feature request
title: "[Feature] "
description: 提出你的功能请求 / Propose your feature request
labels: ["enhancement"]
type: "Feature"
body:
- type: markdown
attributes:
value: |
## 在提交问题之前,请确认以下事项:
1. 请 **确保** 您已经查阅了 [Clash Verge Rev 官方文档](https://clash-verge-rev.github.io/guide/term.html) 确认软件不存在类似的功能
2. 请 **确保** [已有的问题](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue) 中没有人提交过相似issue否则请在已有的issue下进行讨论
3. 请 **务必** 给issue填写一个简洁明了的标题以便他人快速检索
4. 请 **务必** 先下载 [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) 版本测试,确保该功能还未实现
5. 请 **务必** 按照模板规范详细描述问题否则issue将会被关闭
## Before submitting the issue, please make sure of the following checklist:
1. Please make sure you have read the [Clash Verge Rev official documentation](https://clash-verge-rev.github.io/guide/term.html) to confirm that the software does not have similar functions
2. Please make sure there is no similar issue in the [existing issues](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue), otherwise please discuss under the existing issue
3. Please be sure to fill in a concise and clear title for the issue so that others can quickly search
4. Please be sure to download the [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) version for testing to ensure that the function has not been implemented
5. Please describe the problem in detail according to the template specification, otherwise the issue will be closed
- type: textarea
id: description
attributes:
label: 功能描述 / Feature description
description: 详细清晰地描述你的功能请求 / A clear and concise description of what the feature is
validations:
required: true
- type: textarea
attributes:
label: 使用场景 / Use case
description: 请描述你的功能请求的使用场景 / Please describe the use case of your feature request
validations:
required: true
- type: checkboxes
id: os-labels
attributes:
label: 适用系统 / Target OS
description: 请选择该功能适用的操作系统(至少选择一个) / Please select the operating system(s) for this feature request (select at least one)
options:
- label: windows
- label: macos
- label: linux
validations:
required: true

454
.github/workflows/alpha.yml vendored Normal file
View File

@ -0,0 +1,454 @@
name: Alpha Build
on:
workflow_dispatch:
schedule:
# UTC+8 00:00 (UTC 16:00 previous day) and UTC+8 12:00 (UTC 04:00)
- cron: "0 16,4 * * *"
permissions: write-all
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
concurrency:
# only allow per workflow per commit (and not pr) to run at a time
group: "${{ github.workflow }} - ${{ github.head_ref || github.ref }}"
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
check_commit:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check if version changed
id: check
run: |
# For manual workflow_dispatch, always run
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "should_run=true" >> $GITHUB_OUTPUT
exit 0
fi
# Store current version from package.json
CURRENT_VERSION=$(cat package.json | jq -r '.version')
echo "Current version: $CURRENT_VERSION"
# Get the previous commit's package.json version
git checkout HEAD~1 package.json
PREVIOUS_VERSION=$(cat package.json | jq -r '.version')
echo "Previous version: $PREVIOUS_VERSION"
# Reset back to current commit
git checkout HEAD package.json
# Check if version changed
if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
echo "Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
echo "should_run=true" >> $GITHUB_OUTPUT
else
echo "Version unchanged: $CURRENT_VERSION"
echo "should_run=false" >> $GITHUB_OUTPUT
fi
delete_old_release:
needs: check_commit
if: ${{ needs.check_commit.outputs.should_run == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Delete Old Alpha Release
uses: dev-drprasad/delete-tag-and-release@v1.1
with:
tag_name: alpha
delete_release: true
repo: ${{ github.repository }}
github_token: ${{ secrets.GITHUB_TOKEN }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
alpha:
needs: delete_old_release
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: windows-latest
target: aarch64-pc-windows-msvc
- os: macos-latest
target: aarch64-apple-darwin
- os: macos-latest
target: x86_64-apple-darwin
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
cache-on-failure: true
- name: Install dependencies (ubuntu only)
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tagName: alpha
releaseName: "Clash Verge Rev Alpha"
releaseBody: "More new features are now supported."
releaseDraft: false
prerelease: true
tauriScript: pnpm
args: --target ${{ matrix.target }}
alpha-for-linux-arm:
needs: delete_old_release
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
arch: arm64
- os: ubuntu-22.04
target: armv7-unknown-linux-gnueabihf
arch: armhf
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: "Setup for linux"
run: |-
sudo ls -lR /etc/apt/
cat > /tmp/sources.list << EOF
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-security main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main multiverse universe restricted
EOF
sudo mv /etc/apt/sources.list /etc/apt/sources.list.default
sudo mv /tmp/sources.list /etc/apt/sources.list
sudo dpkg --add-architecture ${{ matrix.arch }}
sudo apt update
sudo apt install -y \
libwebkit2gtk-4.1-dev:${{ matrix.arch }} \
libayatana-appindicator3-dev:${{ matrix.arch }} \
libssl-dev:${{ matrix.arch }} \
patchelf:${{ matrix.arch }} \
librsvg2-dev:${{ matrix.arch }}
- name: "Install aarch64 tools"
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt install -y \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu
- name: "Install armv7 tools"
if: matrix.target == 'armv7-unknown-linux-gnueabihf'
run: |
sudo apt install -y \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf
- name: Build for Linux
run: |
export PKG_CONFIG_ALLOW_CROSS=1
if [ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]; then
export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/:$PKG_CONFIG_PATH
export PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/
elif [ "${{ matrix.target }}" == "armv7-unknown-linux-gnueabihf" ]; then
export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/:$PKG_CONFIG_PATH
export PKG_CONFIG_SYSROOT_DIR=/usr/arm-linux-gnueabihf/
fi
pnpm build --target ${{ matrix.target }}
env:
NODE_OPTIONS: "--max_old_space_size=4096"
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
- name: Get Version
run: |
sudo apt-get update
sudo apt-get install jq
echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
- name: Upload Release
uses: softprops/action-gh-release@v2
with:
tag_name: alpha
name: "Clash Verge Rev Alpha"
body: "More new features are now supported."
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
files: |
src-tauri/target/${{ matrix.target }}/release/bundle/deb/*.deb
src-tauri/target/${{ matrix.target }}/release/bundle/rpm/*.rpm
alpha-for-fixed-webview2:
needs: delete_old_release
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
arch: x64
- os: windows-latest
target: aarch64-pc-windows-msvc
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
cache-on-failure: true
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: Download WebView2 Runtime
run: |
invoke-webrequest -uri https://github.com/westinyang/WebView2RuntimeArchive/releases/download/109.0.1518.78/Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -outfile Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab
Expand .\Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -F:* ./src-tauri
Remove-Item .\src-tauri\tauri.windows.conf.json
Rename-Item .\src-tauri\webview2.${{ matrix.arch }}.json tauri.windows.conf.json
- name: Tauri build
id: build
uses: tauri-apps/tauri-action@v0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tauriScript: pnpm
args: --target ${{ matrix.target }}
- name: Rename
run: |
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*-setup.exe"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.exe$", "_fixed_webview2-setup.exe"
Rename-Item $file.FullName $newName
}
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*.nsis.zip"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.nsis\.zip$", "_fixed_webview2-setup.nsis.zip"
Rename-Item $file.FullName $newName
}
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*-setup.exe.sig"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.exe\.sig$", "_fixed_webview2-setup.exe.sig"
Rename-Item $file.FullName $newName
}
- name: Upload Release
uses: softprops/action-gh-release@v2
with:
tag_name: alpha
name: "Clash Verge Rev Alpha"
body: "More new features are now supported."
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
files: src-tauri/target/${{ matrix.target }}/release/bundle/nsis/*setup*
- name: Portable Bundle
run: pnpm portable-fixed-webview2 ${{ matrix.target }} --alpha
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update_tag:
name: Update tag
runs-on: ubuntu-latest
needs: [delete_old_release, alpha, alpha-for-linux-arm, alpha-for-fixed-webview2]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Fetch Alpha update logs
id: fetch_alpha_logs
run: |
# Check if UPDATELOG.md exists
if [ -f "UPDATELOG.md" ]; then
# Extract the section starting with ## and containing -alpha until the next ## or end of file
ALPHA_LOGS=$(awk '/^## .*-alpha/{flag=1; print; next} /^## /{flag=0} flag' UPDATELOG.md)
if [ -n "$ALPHA_LOGS" ]; then
echo "Found alpha update logs"
echo "ALPHA_LOGS<<EOF" >> $GITHUB_ENV
echo "$ALPHA_LOGS" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
else
echo "No alpha sections found in UPDATELOG.md"
fi
else
echo "UPDATELOG.md file not found"
fi
shell: bash
- name: Set Env
run: |
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
shell: bash
- run: |
# 检查 ALPHA_LOGS 是否存在,如果不存在则使用默认消息
if [ -z "$ALPHA_LOGS" ]; then
echo "No alpha logs found, using default message"
ALPHA_LOGS="More new features are now supported. Check for detailed changelog soon."
else
echo "Using found alpha logs"
fi
# 生成 release.txt 文件
cat > release.txt << EOF
$ALPHA_LOGS
## 我应该下载哪个版本?
### MacOS
- MacOS intel芯片: x64.dmg
- MacOS apple M芯片: aarch64.dmg
### Linux
- Linux 64位: amd64.deb/amd64.rpm
- Linux arm64 architecture: arm64.deb/aarch64.rpm
- Linux armv7架构: armhf.deb/armhfp.rpm
### Windows (不再支持Win7)
#### 正常版本(推荐)
- 64位: x64-setup.exe
- arm64架构: arm64-setup.exe
#### 便携版问题很多不再提供
#### 内置Webview2版(体积较大仅在企业版系统或无法安装webview2时使用)
- 64位: x64_fixed_webview2-setup.exe
- arm64架构: arm64_fixed_webview2-setup.exe
### FAQ
- [常见问题](https://clash-verge-rev.github.io/faq/windows.html)
### 稳定机场VPN推荐
- [狗狗加速](https://verge.dginv.click/#/register?code=oaxsAGo6)
Created at ${{ env.BUILDTIME }}.
EOF
- name: Upload Release
uses: softprops/action-gh-release@v2
with:
tag_name: alpha
name: "Clash Verge Rev Alpha"
body_path: release.txt
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
generate_release_notes: true

94
.github/workflows/dev.yml vendored Normal file
View File

@ -0,0 +1,94 @@
name: Development Test
on:
workflow_dispatch:
permissions: write-all
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
concurrency:
# only allow per workflow per commit (and not pr) to run at a time
group: "${{ github.workflow }} - ${{ github.head_ref || github.ref }}"
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
dev:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
bundle: nsis
- os: macos-latest
target: aarch64-apple-darwin
bundle: dmg
- os: macos-latest
target: x86_64-apple-darwin
bundle: dmg
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
cache-on-failure: true
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "20"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tauriScript: pnpm
args: --target ${{ matrix.target }} -b ${{ matrix.bundle }}
- name: Upload Artifacts
if: matrix.os == 'macos-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: src-tauri/target/${{ matrix.target }}/release/bundle/dmg/*.dmg
if-no-files-found: error
- name: Upload Artifacts
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: src-tauri/target/${{ matrix.target }}/release/bundle/nsis/*.exe
if-no-files-found: error

View File

@ -1,55 +1,374 @@
name: Release Project
name: Release Build
on:
push:
tags:
- v*
workflow_dispatch:
permissions: write-all
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
concurrency:
# only allow per workflow per commit (and not pr) to run at a time
group: "${{ github.workflow }} - ${{ github.head_ref || github.ref }}"
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
build-tauri:
release:
strategy:
fail-fast: false
matrix:
platform: [windows-latest]
runs-on: ${{ matrix.platform }}
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: windows-latest
target: aarch64-pc-windows-msvc
- os: macos-latest
target: aarch64-apple-darwin
- os: macos-latest
target: x86_64-apple-darwin
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: setup node
uses: actions/setup-node@v1
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
node-version: 14
- name: install Rust stable
uses: actions-rs/toolchain@v1
workspaces: src-tauri
cache-all-crates: true
cache-on-failure: true
- name: Install dependencies (ubuntu only)
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf
- name: Install Node
uses: actions/setup-node@v4
with:
toolchain: stable
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- uses: actions/cache@v2
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
src-tauri/target/
src-tauri/WixTools/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: install app dependencies and build it
run: yarn && yarn run predev
- uses: tauri-apps/tauri-action@v0
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tagName: v__VERSION__
releaseName: "Clash Verge v__VERSION__"
releaseBody: "This is a release."
releaseDraft: true
prerelease: false
releaseName: "Clash Verge Rev v__VERSION__"
releaseBody: "More new features are now supported."
tauriScript: pnpm
args: --target ${{ matrix.target }}
release-for-linux-arm:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
arch: arm64
- os: ubuntu-22.04
target: armv7-unknown-linux-gnueabihf
arch: armhf
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: "Setup for linux"
run: |-
sudo ls -lR /etc/apt/
cat > /tmp/sources.list << EOF
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-security main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-updates main multiverse universe restricted
deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu jammy-backports main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main multiverse universe restricted
deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main multiverse universe restricted
EOF
sudo mv /etc/apt/sources.list /etc/apt/sources.list.default
sudo mv /tmp/sources.list /etc/apt/sources.list
sudo dpkg --add-architecture ${{ matrix.arch }}
sudo apt update
sudo apt install -y \
libwebkit2gtk-4.1-dev:${{ matrix.arch }} \
libayatana-appindicator3-dev:${{ matrix.arch }} \
libssl-dev:${{ matrix.arch }} \
patchelf:${{ matrix.arch }} \
librsvg2-dev:${{ matrix.arch }}
- name: "Install aarch64 tools"
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt install -y \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu
- name: "Install armv7 tools"
if: matrix.target == 'armv7-unknown-linux-gnueabihf'
run: |
sudo apt install -y \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf
- name: Build for Linux
run: |
export PKG_CONFIG_ALLOW_CROSS=1
if [ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]; then
export PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/:$PKG_CONFIG_PATH
export PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/
elif [ "${{ matrix.target }}" == "armv7-unknown-linux-gnueabihf" ]; then
export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig/:$PKG_CONFIG_PATH
export PKG_CONFIG_SYSROOT_DIR=/usr/arm-linux-gnueabihf/
fi
pnpm build --target ${{ matrix.target }}
env:
NODE_OPTIONS: "--max_old_space_size=4096"
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
- name: Get Version
run: |
sudo apt-get update
sudo apt-get install jq
echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV
echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV
- name: Upload Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{env.VERSION}}
name: "Clash Verge Rev v${{env.VERSION}}"
body: "More new features are now supported."
token: ${{ secrets.GITHUB_TOKEN }}
files: |
src-tauri/target/${{ matrix.target }}/release/bundle/deb/*.deb
src-tauri/target/${{ matrix.target }}/release/bundle/rpm/*.rpm
release-for-fixed-webview2:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
arch: x64
- os: windows-latest
target: aarch64-pc-windows-msvc
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
cache-all-crates: true
cache-on-failure: true
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install and check
run: |
pnpm i
pnpm check ${{ matrix.target }}
- name: Download WebView2 Runtime
run: |
invoke-webrequest -uri https://github.com/westinyang/WebView2RuntimeArchive/releases/download/109.0.1518.78/Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -outfile Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab
Expand .\Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -F:* ./src-tauri
Remove-Item .\src-tauri\tauri.windows.conf.json
Rename-Item .\src-tauri\webview2.${{ matrix.arch }}.json tauri.windows.conf.json
- name: Tauri build
id: build
uses: tauri-apps/tauri-action@v0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tauriScript: pnpm
args: --target ${{ matrix.target }}
- name: Rename
run: |
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*-setup.exe"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.exe$", "_fixed_webview2-setup.exe"
Rename-Item $file.FullName $newName
}
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*.nsis.zip"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.nsis\.zip$", "_fixed_webview2-setup.nsis.zip"
Rename-Item $file.FullName $newName
}
$files = Get-ChildItem ".\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\*-setup.exe.sig"
foreach ($file in $files) {
$newName = $file.Name -replace "-setup\.exe\.sig$", "_fixed_webview2-setup.exe.sig"
Rename-Item $file.FullName $newName
}
- name: Upload Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{steps.build.outputs.appVersion}}
name: "Clash Verge Rev v${{steps.build.outputs.appVersion}}"
body: "More new features are now supported."
token: ${{ secrets.GITHUB_TOKEN }}
files: src-tauri/target/${{ matrix.target }}/release/bundle/nsis/*setup*
- name: Portable Bundle
run: pnpm portable-fixed-webview2 ${{ matrix.target }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-update:
runs-on: ubuntu-latest
needs: [release, release-for-linux-arm]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install
run: pnpm i
- name: Release updater file
run: pnpm updater
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-update-for-fixed-webview2:
runs-on: ubuntu-latest
needs: [release-for-fixed-webview2]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install
run: pnpm i
- name: Release updater file
run: pnpm updater-fixed-webview2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
submit-to-winget:
runs-on: ubuntu-latest
needs: [release-update]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get Version
run: |
sudo apt-get update
sudo apt-get install jq
echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV
- name: Submit to Winget
uses: vedantmgoyal9/winget-releaser@main
with:
identifier: ClashVergeRev.ClashVergeRev
version: ${{env.VERSION}}
release-tag: v${{env.VERSION}}
installers-regex: '_(arm64|x64|x86)-setup\.exe$'
token: ${{ secrets.WINGET_TOKEN }}

52
.github/workflows/updater.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: Updater CI
on: workflow_dispatch
permissions: write-all
jobs:
release-update:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install
run: pnpm i
- name: Release updater file
run: pnpm updater
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-update-for-fixed-webview2:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "22"
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
- name: Pnpm install
run: pnpm i
- name: Release updater file
run: pnpm updater-fixed-webview2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

8
.gitignore vendored
View File

@ -1,7 +1,11 @@
node_modules
.pnpm-store
.DS_Store
dist
dist-ssr
*.local
package-lock.json
yarn.lock
update.json
scripts/_env.sh
.vscode
.tool-versions
.idea

18
.husky/pre-commit Normal file → Executable file
View File

@ -1,4 +1,16 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
#!/bin/bash
yarn pretty-quick --staged
#pnpm pretty-quick --staged
# 运行 clippy fmt
#cargo fmt --manifest-path ./src-tauri/Cargo.toml
# if [ $? -ne 0 ]; then
# echo "rustfmt failed to format the code. Please fix the issues and try again."
# exit 1
# fi
#git add .
# 允许提交
exit 0

13
.husky/pre-push Normal file
View File

@ -0,0 +1,13 @@
#!/bin/bash
# 运行 clippy
#cargo clippy --manifest-path ./src-tauri/Cargo.toml --fix
# 如果 clippy 失败,阻止 push
#if [ $? -ne 0 ]; then
# echo "Clippy found issues in sub_crate. Please fix them before pushing."
# exit 1
#fi
# 允许 push
exit 0

1
.tool-versions Normal file
View File

@ -0,0 +1 @@
nodejs 21.7.1

106
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,106 @@
# CONTRIBUTING
Thank you for your interest in contributing to Clash Verge Rev! This document provides guidelines and instructions to help you set up your development environment and start contributing.
## Development Setup
Before you start contributing to the project, you need to set up your development environment. Here are the steps you need to follow:
### Prerequisites
1. **Install Rust and Node.js**: Our project requires both Rust and Node.js. Please follow the instructions provided [here](https://tauri.app/v1/guides/getting-started/prerequisites) to install them on your system.
### Setup for Windows Users
If you're a Windows user, you may need to perform some additional steps:
- Make sure to add Rust and Node.js to your system's PATH. This is usually done during the installation process, but you can verify and manually add them if necessary.
- The gnu `patch` tool should be installed
When you setup `Rust` environment, Only use toolchain with `Windows MSVC` , to change settings follow command:
```shell
rustup target add x86_64-pc-windows-msvc
rustup set default-host x86_64-pc-windows-msvc
```
### Install Node.js Package
After installing Rust and Node.js, install the necessary Node.js and Node Package Manager:
```shell
npm install pnpm -g
```
### Install Dependencies
```shell
pnpm install
```
### Download the Mihomo Core Binary
You have two options for downloading the clash binary:
- Automatically download it via the provided script:
```shell
pnpm run check
# Use '--force' to force update to the latest version
# pnpm run check --force
```
- Manually download it from the [Mihomo release](https://github.com/MetaCubeX/mihomo/releases). After downloading, rename the binary according to the [Tauri configuration](https://tauri.app/v1/api/config#bundleconfig.externalbin).
### Run the Development Server
To run the development server, use the following command:
```shell
pnpm dev
# If an app instance already exists, use a different command
pnpm dev:diff
```
### Build the Project
To build this project:
```shell
pnpm build
```
For a faster build, use the following command
```shell
pnpm build:fast
```
This uses Rust's fast-release profile which significantly reduces compilation time by disabling optimization and LTO. The resulting binary will be larger and less performant than the standard build, but it's useful for testing changes quickly.
The `Artifacts` will display in the `log` in the Terminal.
### Build clean
To clean rust build:
```shell
pnpm clean
```
### Portable Version (Windows Only)
To package portable version after the build:
```shell
pnpm portable
```
## Contributing Your Changes
Once you have made your changes:
1. Fork the repository.
2. Create a new branch for your feature or bug fix.
3. Commit your changes with clear and concise commit messages.
4. Push your branch to your fork and submit a pull request to our repository.
We appreciate your contributions and look forward to your active participation in our project!

106
README.md
View File

@ -1,59 +1,91 @@
<h1 align="center">
<img src="./src/assets/image/logo.png" alt="Clash" width="128" />
<img src="./src-tauri/icons/icon.png" alt="Clash" width="128" />
<br>
Clash Verge
Continuation of <a href="https://github.com/zzzgydi/clash-verge">Clash Verge</a>
<br>
</h1>
<h3 align="center">
A <a href="https://github.com/Dreamacro/clash">Clash</a> GUI based on <a href="https://github.com/tauri-apps/tauri">tauri</a>.
A Clash Meta GUI based on <a href="https://github.com/tauri-apps/tauri">Tauri</a>.
</h3>
## Preview
| Dark | Light |
| -------------------------------- | --------------------------------- |
| ![预览](./docs/preview_dark.png) | ![预览](./docs/preview_light.png) |
## Install
请到发布页面下载对应的安装包:[Release page](https://github.com/clash-verge-rev/clash-verge-rev/releases)<br>
Go to the [release page](https://github.com/clash-verge-rev/clash-verge-rev/releases) to download the corresponding installation package<br>
Supports Windows (x64/x86), Linux (x64/arm64) and macOS 10.15+ (intel/apple).
### 安装说明和常见问题,请到[文档页](https://clash-verge-rev.github.io/)查看:[Doc](https://clash-verge-rev.github.io/)
---
### TG 频道: [@clash_verge_rev](https://t.me/clash_verge_re)
## Promotion
[狗狗加速 —— 技术流机场 Doggygo VPN](https://verge.dginv.click/#/register?code=oaxsAGo6)
- 高性能海外机场,免费试用,优惠套餐,解锁流媒体,全球首家支持 Hysteria 协议。
- 使用 Clash Verge 专属邀请链接注册送 3 天,每天 1G 流量免费试用:[点此注册](https://verge.dginv.click/#/register?code=oaxsAGo6)
- Clash Verge 专属 8 折优惠码: verge20 (仅有 500 份)
- 优惠套餐每月仅需 15.8 元160G 流量,年付 8 折
- 海外团队,无跑路风险,高达 50% 返佣
- 集群负载均衡设计,高速专线(兼容老客户端)极低延迟无视晚高峰4K 秒开
- 全球首家 Hysteria 协议机场,现已上线更快的 `Hysteria2` 协议(Clash Verge 客户端最佳搭配)
- 解锁流媒体及 ChatGPT
- 官网:[https://狗狗加速.com](https://verge.dginv.click/#/register?code=oaxsAGo6)
## Features
Now it's no different from the others, even fewer. (WIP)
- 基于性能强劲的 Rust 和 Tauri 2 框架
- 内置[Clash.Meta(mihomo)](https://github.com/MetaCubeX/mihomo)内核,并支持切换 `Alpha` 版本内核。
- 简洁美观的用户界面,支持自定义主题颜色、代理组/托盘图标以及 `CSS Injection`
- 配置文件管理和增强Merge 和 Script配置文件语法提示。
- 系统代理和守卫、`TUN(虚拟网卡)` 模式。
- 可视化节点和规则编辑
- WebDav 配置备份和同步
### FAQ
Refer to [Doc FAQ Page](https://clash-verge-rev.github.io/faq/windows.html)
### Donation
[捐助Clash Verge Rev的开发](https://github.com/sponsors/clash-verge-rev)
## Development
You should install Rust and Nodejs. Then install tauri cli and packages.
See [CONTRIBUTING.md](./CONTRIBUTING.md) for more details.
To run the development server, execute the following commands after all prerequisites for **Tauri** are installed:
```shell
cargo install tauri-cli --git https://github.com/tauri-apps/tauri
yarn install
pnpm i
pnpm run check
pnpm dev
```
Then download the clash binary... Or you can download it from [clash premium release](https://github.com/Dreamacro/clash/releases/tag/premium) and rename it according to [tauri config](https://tauri.studio/en/docs/api/config#tauri.bundle.externalBin).
```shell
yarn run predev
```
Then run
```shell
yarn dev
```
## Todos
> This keng is a little big...
## Screenshots
<div align="center">
<img src="./docs/demo1.png" alt="demo1" width="42%" />
<img src="./docs/demo2.png" alt="demo2" width="42%" />
</div>
## Disclaimer
This is a learning project for Rust practice.
## Contributions
PR welcome!
Issue and PR welcome!
## Acknowledgement
Clash Verge rev was based on or inspired by these projects and so on:
- [zzzgydi/clash-verge](https://github.com/zzzgydi/clash-verge): A Clash GUI based on tauri. Supports Windows, macOS and Linux.
- [tauri-apps/tauri](https://github.com/tauri-apps/tauri): Build smaller, faster, and more secure desktop applications with a web frontend.
- [Dreamacro/clash](https://github.com/Dreamacro/clash): A rule-based tunnel in Go.
- [MetaCubeX/mihomo](https://github.com/MetaCubeX/mihomo): A rule-based tunnel in Go.
- [Fndroid/clash_for_windows_pkg](https://github.com/Fndroid/clash_for_windows_pkg): A Windows/macOS GUI based on Clash.
- [vitejs/vite](https://github.com/vitejs/vite): Next generation frontend tooling. It's fast!
## License
GPL-3.0 License
GPL-3.0 License. See [License here](./LICENSE) for details.

1483
UPDATELOG.md Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

BIN
docs/preview_dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
docs/preview_light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@ -1,49 +1,111 @@
{
"name": "clash-verge",
"version": "0.0.1",
"license": "GPL-3.0",
"version": "2.2.1-alpha",
"license": "GPL-3.0-only",
"scripts": {
"dev": "cargo tauri dev",
"build": "cargo tauri build",
"dev": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev",
"dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev",
"build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build",
"build:fast": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build -- --profile fast-release",
"tauri": "tauri",
"web:dev": "vite",
"web:build": "tsc && vite build",
"web:build": "tsc --noEmit && vite build",
"web:serve": "vite preview",
"predev": "node scripts/pre-dev.mjs",
"prepare": "husky install"
"check": "node scripts/check.mjs",
"updater": "node scripts/updater.mjs",
"updater-fixed-webview2": "node scripts/updater-fixed-webview2.mjs",
"portable": "node scripts/portable.mjs",
"portable-fixed-webview2": "node scripts/portable-fixed-webview2.mjs",
"fix-alpha-version": "node scripts/alpha_version.mjs",
"prepare": "husky",
"clean": "cd ./src-tauri && cargo clean && cd -"
},
"dependencies": {
"@emotion/react": "^11.7.0",
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.2.1",
"@mui/material": "^5.2.3",
"@tauri-apps/api": "^1.0.0-beta.8",
"axios": "^0.24.0",
"dayjs": "^1.10.7",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-router-dom": "^6.0.2",
"react-virtuoso": "^2.3.1",
"recoil": "^0.5.2",
"swr": "^1.1.2-beta.0"
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@juggle/resize-observer": "^3.4.0",
"@mui/icons-material": "^6.4.8",
"@mui/lab": "6.0.0-beta.25",
"@mui/material": "^6.4.8",
"@mui/x-data-grid": "^7.28.0",
"@tauri-apps/api": "2.2.0",
"@tauri-apps/plugin-clipboard-manager": "^2.2.2",
"@tauri-apps/plugin-dialog": "^2.2.0",
"@tauri-apps/plugin-fs": "^2.2.0",
"@tauri-apps/plugin-global-shortcut": "^2.2.0",
"@tauri-apps/plugin-notification": "^2.2.2",
"@tauri-apps/plugin-process": "^2.2.0",
"@tauri-apps/plugin-shell": "2.2.0",
"@tauri-apps/plugin-updater": "2.3.0",
"@types/d3-shape": "^3.1.7",
"@types/json-schema": "^7.0.15",
"ahooks": "^3.8.4",
"axios": "^1.8.3",
"cli-color": "^2.0.4",
"d3-shape": "^3.2.0",
"dayjs": "1.11.13",
"foxact": "^0.2.44",
"glob": "^11.0.1",
"i18next": "^24.2.3",
"js-base64": "^3.7.7",
"js-yaml": "^4.1.0",
"lodash-es": "^4.17.21",
"monaco-editor": "^0.52.2",
"monaco-yaml": "^5.3.1",
"nanoid": "^5.1.5",
"peggy": "^4.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.1.2",
"react-hook-form": "^7.54.2",
"react-i18next": "^13.5.0",
"react-markdown": "^9.1.0",
"react-monaco-editor": "^0.56.2",
"react-router-dom": "^6.30.0",
"react-transition-group": "^4.4.5",
"react-virtuoso": "^4.12.5",
"recharts": "^2.15.1",
"sockette": "^2.0.6",
"swr": "^2.3.3",
"tar": "^7.4.3",
"types-pac": "^1.0.3",
"zustand": "^5.0.3"
},
"devDependencies": {
"@tauri-apps/cli": "^1.0.0-beta.10",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@vitejs/plugin-react": "^1.1.1",
"adm-zip": "^0.5.9",
"fs-extra": "^10.0.0",
"husky": "^7.0.0",
"node-fetch": "^3.1.0",
"pretty-quick": "^3.1.3",
"sass": "^1.44.0",
"typescript": "^4.5.2",
"vite": "^2.7.1"
"@actions/github": "^6.0.0",
"@tauri-apps/cli": "2.2.7",
"@types/js-cookie": "^3.0.6",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@types/react-transition-group": "^4.4.12",
"@vitejs/plugin-legacy": "^6.0.2",
"@vitejs/plugin-react": "^4.3.4",
"adm-zip": "^0.5.16",
"cross-env": "^7.0.3",
"https-proxy-agent": "^7.0.6",
"husky": "^9.1.7",
"meta-json-schema": "^1.19.3",
"node-fetch": "^3.3.2",
"prettier": "^3.5.3",
"pretty-quick": "^4.1.1",
"sass": "^1.86.0",
"terser": "^5.39.0",
"typescript": "^5.8.2",
"vite": "^6.2.2",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-svgr": "^4.3.0"
},
"prettier": {
"tabWidth": 2,
"semi": true,
"singleQuote": false,
"endOfLine": "lf"
}
},
"type": "module",
"packageManager": "pnpm@9.13.2"
}

6288
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

56
scripts/alpha_version.mjs Normal file
View File

@ -0,0 +1,56 @@
import { exec } from "child_process";
import { promisify } from "util";
import fs from "fs/promises";
import path from "path";
/**
* 为Alpha版本重命名版本号
*/
const execPromise = promisify(exec);
/**
* 标准输出HEAD hash
*/
async function getLatestCommitHash() {
try {
const { stdout } = await execPromise("git rev-parse HEAD");
const commitHash = stdout.trim();
// 格式化只截取前7位字符
const formathash = commitHash.substring(0, 7);
console.log(`Found the latest commit hash code: ${commitHash}`);
return formathash;
} catch (error) {
console.error("pnpm run fix-alpha-version ERROR", error);
}
}
/**
* @param string 传入格式化后的hash
* 将新的版本号写入文件 package.json
*/
async function updatePackageVersion(newVersion) {
// 获取内容根目录
const _dirname = process.cwd();
const packageJsonPath = path.join(_dirname, "package.json");
try {
// 读取文件
const data = await fs.readFile(packageJsonPath, "utf8");
const packageJson = JSON.parse(data);
// 获取键值替换
let result = packageJson.version.replace("alpha", newVersion);
console.log("[INFO]: Current version is: ", result);
packageJson.version = result;
// 写入版本号
await fs.writeFile(
packageJsonPath,
JSON.stringify(packageJson, null, 2),
"utf8",
);
console.log(`[INFO]: Alpha version update to: ${newVersion}`);
} catch (error) {
console.error("pnpm run fix-alpha-version ERROR", error);
}
}
const newVersion = await getLatestCommitHash();
updatePackageVersion(newVersion).catch(console.error);

567
scripts/check.mjs Normal file
View File

@ -0,0 +1,567 @@
import fs from "fs";
import fsp from "fs/promises";
import zlib from "zlib";
import { extract } from "tar";
import path from "path";
import AdmZip from "adm-zip";
import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";
import { execSync } from "child_process";
import { log_info, log_debug, log_error, log_success } from "./utils.mjs";
import { glob } from "glob";
const cwd = process.cwd();
const TEMP_DIR = path.join(cwd, "node_modules/.verge");
const FORCE = process.argv.includes("--force");
const PLATFORM_MAP = {
"x86_64-pc-windows-msvc": "win32",
"i686-pc-windows-msvc": "win32",
"aarch64-pc-windows-msvc": "win32",
"x86_64-apple-darwin": "darwin",
"aarch64-apple-darwin": "darwin",
"x86_64-unknown-linux-gnu": "linux",
"i686-unknown-linux-gnu": "linux",
"aarch64-unknown-linux-gnu": "linux",
"armv7-unknown-linux-gnueabihf": "linux",
"riscv64gc-unknown-linux-gnu": "linux",
"loongarch64-unknown-linux-gnu": "linux",
};
const ARCH_MAP = {
"x86_64-pc-windows-msvc": "x64",
"i686-pc-windows-msvc": "ia32",
"aarch64-pc-windows-msvc": "arm64",
"x86_64-apple-darwin": "x64",
"aarch64-apple-darwin": "arm64",
"x86_64-unknown-linux-gnu": "x64",
"i686-unknown-linux-gnu": "ia32",
"aarch64-unknown-linux-gnu": "arm64",
"armv7-unknown-linux-gnueabihf": "arm",
"riscv64gc-unknown-linux-gnu": "riscv64",
"loongarch64-unknown-linux-gnu": "loong64",
};
const arg1 = process.argv.slice(2)[0];
const arg2 = process.argv.slice(2)[1];
const target = arg1 === "--force" ? arg2 : arg1;
const { platform, arch } = target
? { platform: PLATFORM_MAP[target], arch: ARCH_MAP[target] }
: process;
const SIDECAR_HOST = target
? target
: execSync("rustc -vV")
.toString()
.match(/(?<=host: ).+(?=\s*)/g)[0];
/* ======= clash meta alpha======= */
const META_ALPHA_VERSION_URL =
"https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha/version.txt";
const META_ALPHA_URL_PREFIX = `https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha`;
let META_ALPHA_VERSION;
const META_ALPHA_MAP = {
"win32-x64": "mihomo-windows-amd64-compatible",
"win32-ia32": "mihomo-windows-386",
"win32-arm64": "mihomo-windows-arm64",
"darwin-x64": "mihomo-darwin-amd64-compatible",
"darwin-arm64": "mihomo-darwin-arm64",
"linux-x64": "mihomo-linux-amd64-compatible",
"linux-ia32": "mihomo-linux-386",
"linux-arm64": "mihomo-linux-arm64",
"linux-arm": "mihomo-linux-armv7",
"linux-riscv64": "mihomo-linux-riscv64",
"linux-loong64": "mihomo-linux-loong64",
};
// Fetch the latest alpha release version from the version.txt file
async function getLatestAlphaVersion() {
const options = {};
const httpProxy =
process.env.HTTP_PROXY ||
process.env.http_proxy ||
process.env.HTTPS_PROXY ||
process.env.https_proxy;
if (httpProxy) {
options.agent = new HttpsProxyAgent(httpProxy);
}
try {
const response = await fetch(META_ALPHA_VERSION_URL, {
...options,
method: "GET",
});
let v = await response.text();
META_ALPHA_VERSION = v.trim(); // Trim to remove extra whitespaces
log_info(`Latest alpha version: ${META_ALPHA_VERSION}`);
} catch (error) {
log_error("Error fetching latest alpha version:", error.message);
process.exit(1);
}
}
/* ======= clash meta stable ======= */
const META_VERSION_URL =
"https://github.com/MetaCubeX/mihomo/releases/latest/download/version.txt";
const META_URL_PREFIX = `https://github.com/MetaCubeX/mihomo/releases/download`;
let META_VERSION;
const META_MAP = {
"win32-x64": "mihomo-windows-amd64-compatible",
"win32-ia32": "mihomo-windows-386",
"win32-arm64": "mihomo-windows-arm64",
"darwin-x64": "mihomo-darwin-amd64-compatible",
"darwin-arm64": "mihomo-darwin-arm64",
"linux-x64": "mihomo-linux-amd64-compatible",
"linux-ia32": "mihomo-linux-386",
"linux-arm64": "mihomo-linux-arm64",
"linux-arm": "mihomo-linux-armv7",
"linux-riscv64": "mihomo-linux-riscv64",
"linux-loong64": "mihomo-linux-loong64",
};
// Fetch the latest release version from the version.txt file
async function getLatestReleaseVersion() {
const options = {};
const httpProxy =
process.env.HTTP_PROXY ||
process.env.http_proxy ||
process.env.HTTPS_PROXY ||
process.env.https_proxy;
if (httpProxy) {
options.agent = new HttpsProxyAgent(httpProxy);
}
try {
const response = await fetch(META_VERSION_URL, {
...options,
method: "GET",
});
let v = await response.text();
META_VERSION = v.trim(); // Trim to remove extra whitespaces
log_info(`Latest release version: ${META_VERSION}`);
} catch (error) {
log_error("Error fetching latest release version:", error.message);
process.exit(1);
}
}
/*
* check available
*/
if (!META_MAP[`${platform}-${arch}`]) {
throw new Error(
`clash meta alpha unsupported platform "${platform}-${arch}"`,
);
}
if (!META_ALPHA_MAP[`${platform}-${arch}`]) {
throw new Error(
`clash meta alpha unsupported platform "${platform}-${arch}"`,
);
}
/**
* core info
*/
function clashMetaAlpha() {
const name = META_ALPHA_MAP[`${platform}-${arch}`];
const isWin = platform === "win32";
const urlExt = isWin ? "zip" : "gz";
const downloadURL = `${META_ALPHA_URL_PREFIX}/${name}-${META_ALPHA_VERSION}.${urlExt}`;
const exeFile = `${name}${isWin ? ".exe" : ""}`;
const zipFile = `${name}-${META_ALPHA_VERSION}.${urlExt}`;
return {
name: "verge-mihomo-alpha",
targetFile: `verge-mihomo-alpha-${SIDECAR_HOST}${isWin ? ".exe" : ""}`,
exeFile,
zipFile,
downloadURL,
};
}
function clashMeta() {
const name = META_MAP[`${platform}-${arch}`];
const isWin = platform === "win32";
const urlExt = isWin ? "zip" : "gz";
const downloadURL = `${META_URL_PREFIX}/${META_VERSION}/${name}-${META_VERSION}.${urlExt}`;
const exeFile = `${name}${isWin ? ".exe" : ""}`;
const zipFile = `${name}-${META_VERSION}.${urlExt}`;
return {
name: "verge-mihomo",
targetFile: `verge-mihomo-${SIDECAR_HOST}${isWin ? ".exe" : ""}`,
exeFile,
zipFile,
downloadURL,
};
}
/**
* download sidecar and rename
*/
async function resolveSidecar(binInfo) {
const { name, targetFile, zipFile, exeFile, downloadURL } = binInfo;
const sidecarDir = path.join(cwd, "src-tauri", "sidecar");
const sidecarPath = path.join(sidecarDir, targetFile);
await fsp.mkdir(sidecarDir, { recursive: true });
if (!FORCE && fs.existsSync(sidecarPath)) return;
const tempDir = path.join(TEMP_DIR, name);
const tempZip = path.join(tempDir, zipFile);
const tempExe = path.join(tempDir, exeFile);
await fsp.mkdir(tempDir, { recursive: true });
try {
if (!fs.existsSync(tempZip)) {
await downloadFile(downloadURL, tempZip);
}
if (zipFile.endsWith(".zip")) {
const zip = new AdmZip(tempZip);
zip.getEntries().forEach((entry) => {
log_debug(`"${name}" entry name`, entry.entryName);
});
zip.extractAllTo(tempDir, true);
await fsp.rename(tempExe, sidecarPath);
log_success(`unzip finished: "${name}"`);
} else if (zipFile.endsWith(".tgz")) {
// tgz
await fsp.mkdir(tempDir, { recursive: true });
await extract({
cwd: tempDir,
file: tempZip,
//strip: 1, // 可能需要根据实际的 .tgz 文件结构调整
});
const files = await fsp.readdir(tempDir);
log_debug(`"${name}" files in tempDir:`, files);
const extractedFile = files.find((file) => file.startsWith("虚空终端-"));
if (extractedFile) {
const extractedFilePath = path.join(tempDir, extractedFile);
await fsp.rename(extractedFilePath, sidecarPath);
log_success(`"${name}" file renamed to "${sidecarPath}"`);
execSync(`chmod 755 ${sidecarPath}`);
log_success(`chmod binary finished: "${name}"`);
} else {
throw new Error(`Expected file not found in ${tempDir}`);
}
} else {
// gz
const readStream = fs.createReadStream(tempZip);
const writeStream = fs.createWriteStream(sidecarPath);
await new Promise((resolve, reject) => {
const onError = (error) => {
log_error(`"${name}" gz failed:`, error.message);
reject(error);
};
readStream
.pipe(zlib.createGunzip().on("error", onError))
.pipe(writeStream)
.on("finish", () => {
execSync(`chmod 755 ${sidecarPath}`);
log_success(`chmod binary finished: "${name}"`);
resolve();
})
.on("error", onError);
});
}
} catch (err) {
// 需要删除文件
await fsp.rm(sidecarPath, { recursive: true, force: true });
throw err;
} finally {
// delete temp dir
await fsp.rm(tempDir, { recursive: true, force: true });
}
}
const resolveSetDnsScript = () =>
resolveResource({
file: "set_dns.sh",
localPath: path.join(cwd, "scripts/set_dns.sh"),
});
const resolveUnSetDnsScript = () =>
resolveResource({
file: "unset_dns.sh",
localPath: path.join(cwd, "scripts/unset_dns.sh"),
});
/**
* download the file to the resources dir
*/
async function resolveResource(binInfo) {
const { file, downloadURL, localPath } = binInfo;
const resDir = path.join(cwd, "src-tauri/resources");
const targetPath = path.join(resDir, file);
if (!FORCE && fs.existsSync(targetPath)) return;
if (downloadURL) {
await fsp.mkdir(resDir, { recursive: true });
await downloadFile(downloadURL, targetPath);
}
if (localPath) {
await fs.copyFile(localPath, targetPath, (err) => {
if (err) {
console.error("Error copying file:", err);
} else {
console.log("File was copied successfully");
}
});
log_debug(`copy file finished: "${localPath}"`);
}
log_success(`${file} finished`);
}
/**
* download file and save to `path`
*/ async function downloadFile(url, path) {
const options = {};
const httpProxy =
process.env.HTTP_PROXY ||
process.env.http_proxy ||
process.env.HTTPS_PROXY ||
process.env.https_proxy;
if (httpProxy) {
options.agent = new HttpsProxyAgent(httpProxy);
}
const response = await fetch(url, {
...options,
method: "GET",
headers: { "Content-Type": "application/octet-stream" },
});
const buffer = await response.arrayBuffer();
await fsp.writeFile(path, new Uint8Array(buffer));
log_success(`download finished: ${url}`);
}
// SimpleSC.dll
const resolvePlugin = async () => {
const url =
"https://nsis.sourceforge.io/mediawiki/images/e/ef/NSIS_Simple_Service_Plugin_Unicode_1.30.zip";
const tempDir = path.join(TEMP_DIR, "SimpleSC");
const tempZip = path.join(
tempDir,
"NSIS_Simple_Service_Plugin_Unicode_1.30.zip",
);
const tempDll = path.join(tempDir, "SimpleSC.dll");
const pluginDir = path.join(process.env.APPDATA, "Local/NSIS");
const pluginPath = path.join(pluginDir, "SimpleSC.dll");
await fsp.mkdir(pluginDir, { recursive: true });
await fsp.mkdir(tempDir, { recursive: true });
if (!FORCE && fs.existsSync(pluginPath)) return;
try {
if (!fs.existsSync(tempZip)) {
await downloadFile(url, tempZip);
}
const zip = new AdmZip(tempZip);
zip.getEntries().forEach((entry) => {
log_debug(`"SimpleSC" entry name`, entry.entryName);
});
zip.extractAllTo(tempDir, true);
await fsp.cp(tempDll, pluginPath, { recursive: true, force: true });
log_success(`unzip finished: "SimpleSC"`);
} finally {
await fsp.rm(tempDir, { recursive: true, force: true });
}
};
// service chmod
const resolveServicePermission = async () => {
const serviceExecutables = [
"clash-verge-service*",
"install-service*",
"uninstall-service*",
];
const resDir = path.join(cwd, "src-tauri/resources");
for (let f of serviceExecutables) {
// 使用glob模块来处理通配符
const files = glob.sync(path.join(resDir, f));
for (let filePath of files) {
if (fs.existsSync(filePath)) {
execSync(`chmod 755 ${filePath}`);
log_success(`chmod finished: "${filePath}"`);
}
}
}
};
// 在 resolveResource 函数后添加新函数
async function resolveLocales() {
const srcLocalesDir = path.join(cwd, "src/locales");
const targetLocalesDir = path.join(cwd, "src-tauri/resources/locales");
try {
// 确保目标目录存在
await fsp.mkdir(targetLocalesDir, { recursive: true });
// 读取所有语言文件
const files = await fsp.readdir(srcLocalesDir);
// 复制每个文件
for (const file of files) {
const srcPath = path.join(srcLocalesDir, file);
const targetPath = path.join(targetLocalesDir, file);
await fsp.copyFile(srcPath, targetPath);
log_success(`Copied locale file: ${file}`);
}
log_success("All locale files copied successfully");
} catch (err) {
log_error("Error copying locale files:", err.message);
throw err;
}
}
/**
* main
*/
const SERVICE_URL = `https://github.com/clash-verge-rev/clash-verge-service/releases/download/${SIDECAR_HOST}`;
const resolveService = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "clash-verge-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/clash-verge-service${ext}`,
});
};
const resolveInstall = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "install-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/install-service${ext}`,
});
};
const resolveUninstall = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "uninstall-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/uninstall-service${ext}`,
});
};
const resolveMmdb = () =>
resolveResource({
file: "Country.mmdb",
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb`,
});
const resolveGeosite = () =>
resolveResource({
file: "geosite.dat",
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat`,
});
const resolveGeoIP = () =>
resolveResource({
file: "geoip.dat",
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat`,
});
const resolveEnableLoopback = () =>
resolveResource({
file: "enableLoopback.exe",
downloadURL: `https://github.com/Kuingsmile/uwp-tool/releases/download/latest/enableLoopback.exe`,
});
const resolveWinSysproxy = () =>
resolveResource({
file: "sysproxy.exe",
downloadURL: `https://github.com/clash-verge-rev/sysproxy/releases/download/${arch}/sysproxy.exe`,
});
const tasks = [
// { name: "clash", func: resolveClash, retry: 5 },
{
name: "verge-mihomo-alpha",
func: () =>
getLatestAlphaVersion().then(() => resolveSidecar(clashMetaAlpha())),
retry: 5,
},
{
name: "verge-mihomo",
func: () =>
getLatestReleaseVersion().then(() => resolveSidecar(clashMeta())),
retry: 5,
},
{ name: "plugin", func: resolvePlugin, retry: 5, winOnly: true },
{ name: "service", func: resolveService, retry: 5 },
{ name: "install", func: resolveInstall, retry: 5 },
{ name: "uninstall", func: resolveUninstall, retry: 5 },
{ name: "mmdb", func: resolveMmdb, retry: 5 },
{ name: "geosite", func: resolveGeosite, retry: 5 },
{ name: "geoip", func: resolveGeoIP, retry: 5 },
{
name: "enableLoopback",
func: resolveEnableLoopback,
retry: 5,
winOnly: true,
},
{
name: "service_chmod",
func: resolveServicePermission,
retry: 5,
unixOnly: platform === "linux" || platform === "darwin",
},
{
name: "windows-sysproxy",
func: resolveWinSysproxy,
retry: 5,
winOnly: true,
},
{
name: "set_dns_script",
func: resolveSetDnsScript,
retry: 5,
macosOnly: true,
},
{
name: "unset_dns_script",
func: resolveUnSetDnsScript,
retry: 5,
macosOnly: true,
},
{
name: "locales",
func: resolveLocales,
retry: 2,
},
];
async function runTask() {
const task = tasks.shift();
if (!task) return;
if (task.unixOnly && platform === "win32") return runTask();
if (task.winOnly && platform !== "win32") return runTask();
if (task.macosOnly && platform !== "darwin") return runTask();
if (task.linuxOnly && platform !== "linux") return runTask();
for (let i = 0; i < task.retry; i++) {
try {
await task.func();
break;
} catch (err) {
log_error(`task::${task.name} try ${i} ==`, err.message);
if (i === task.retry - 1) throw err;
}
}
return runTask();
}
runTask();

View File

@ -0,0 +1,103 @@
import fs from "fs";
import fsp from "fs/promises";
import path from "path";
import AdmZip from "adm-zip";
import { createRequire } from "module";
import { getOctokit, context } from "@actions/github";
const target = process.argv.slice(2)[0];
const alpha = process.argv.slice(2)[1];
const ARCH_MAP = {
"x86_64-pc-windows-msvc": "x64",
"i686-pc-windows-msvc": "x86",
"aarch64-pc-windows-msvc": "arm64",
};
const PROCESS_MAP = {
x64: "x64",
ia32: "x86",
arm64: "arm64",
};
const arch = target ? ARCH_MAP[target] : PROCESS_MAP[process.arch];
/// Script for ci
/// 打包绿色版/便携版 (only Windows)
async function resolvePortable() {
if (process.platform !== "win32") return;
const releaseDir = target
? `./src-tauri/target/${target}/release`
: `./src-tauri/target/release`;
const configDir = path.join(releaseDir, ".config");
if (!fs.existsSync(releaseDir)) {
throw new Error("could not found the release dir");
}
await fsp.mkdir(configDir, { recursive: true });
if (!fs.existsSync(path.join(configDir, "PORTABLE"))) {
await fsp.writeFile(path.join(configDir, "PORTABLE"), "");
}
const zip = new AdmZip();
zip.addLocalFile(path.join(releaseDir, "Clash Verge.exe"));
zip.addLocalFile(path.join(releaseDir, "verge-mihomo.exe"));
zip.addLocalFile(path.join(releaseDir, "verge-mihomo-alpha.exe"));
zip.addLocalFolder(path.join(releaseDir, "resources"), "resources");
zip.addLocalFolder(
path.join(
releaseDir,
`Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${arch}`,
),
`Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${arch}`,
);
zip.addLocalFolder(configDir, ".config");
const require = createRequire(import.meta.url);
const packageJson = require("../package.json");
const { version } = packageJson;
const zipFile = `Clash.Verge_${version}_${arch}_fixed_webview2_portable.zip`;
zip.writeZip(zipFile);
console.log("[INFO]: create portable zip successfully");
// push release assets
if (process.env.GITHUB_TOKEN === undefined) {
throw new Error("GITHUB_TOKEN is required");
}
const options = { owner: context.repo.owner, repo: context.repo.repo };
const github = getOctokit(process.env.GITHUB_TOKEN);
const tag = alpha ? "alpha" : process.env.TAG_NAME || `v${version}`;
console.log("[INFO]: upload to ", tag);
const { data: release } = await github.rest.repos.getReleaseByTag({
...options,
tag,
});
let assets = release.assets.filter((x) => {
return x.name === zipFile;
});
if (assets.length > 0) {
let id = assets[0].id;
await github.rest.repos.deleteReleaseAsset({
...options,
asset_id: id,
});
}
console.log(release.name);
await github.rest.repos.uploadReleaseAsset({
...options,
release_id: release.id,
name: zipFile,
data: zip.toBuffer(),
});
}
resolvePortable().catch(console.error);

52
scripts/portable.mjs Normal file
View File

@ -0,0 +1,52 @@
import fs from "fs";
import path from "path";
import AdmZip from "adm-zip";
import { createRequire } from "module";
import fsp from "fs/promises";
const target = process.argv.slice(2)[0];
const ARCH_MAP = {
"x86_64-pc-windows-msvc": "x64",
"aarch64-pc-windows-msvc": "arm64",
};
const PROCESS_MAP = {
x64: "x64",
arm64: "arm64",
};
const arch = target ? ARCH_MAP[target] : PROCESS_MAP[process.arch];
/// Script for ci
/// 打包绿色版/便携版 (only Windows)
async function resolvePortable() {
if (process.platform !== "win32") return;
const releaseDir = target
? `./src-tauri/target/${target}/release`
: `./src-tauri/target/release`;
const configDir = path.join(releaseDir, ".config");
if (!fs.existsSync(releaseDir)) {
throw new Error("could not found the release dir");
}
await fsp.mkdir(configDir, { recursive: true });
if (!fs.existsSync(path.join(configDir, "PORTABLE"))) {
await fsp.writeFile(path.join(configDir, "PORTABLE"), "");
}
const zip = new AdmZip();
zip.addLocalFile(path.join(releaseDir, "clash-verge.exe"));
zip.addLocalFile(path.join(releaseDir, "verge-mihomo.exe"));
zip.addLocalFile(path.join(releaseDir, "verge-mihomo-alpha.exe"));
zip.addLocalFolder(path.join(releaseDir, "resources"), "resources");
zip.addLocalFolder(configDir, ".config");
const require = createRequire(import.meta.url);
const packageJson = require("../package.json");
const { version } = packageJson;
const zipFile = `Clash.Verge_${version}_${arch}_portable.zip`;
zip.writeZip(zipFile);
console.log("[INFO]: create portable zip successfully");
}
resolvePortable().catch(console.error);

View File

@ -1,104 +0,0 @@
import fs from "fs-extra";
import path from "path";
import AdmZip from "adm-zip";
import fetch from "node-fetch";
import { execSync } from "child_process";
const cwd = process.cwd();
const CLASH_URL_PREFIX =
"https://github.com/Dreamacro/clash/releases/download/premium/";
const CLASH_LATEST_DATE = "2021.12.07";
/**
* get the correct clash release infomation
*/
function resolveClash() {
const { platform, arch } = process;
let name = "";
// todo
if (platform === "win32" && arch === "x64") {
name = `clash-windows-386`;
}
if (!name) {
throw new Error("todo");
}
const isWin = platform === "win32";
const zip = isWin ? "zip" : "gz";
const url = `${CLASH_URL_PREFIX}${name}-${CLASH_LATEST_DATE}.${zip}`;
const exefile = `${name}${isWin ? ".exe" : ""}`;
const zipfile = `${name}.${zip}`;
return { url, zip, exefile, zipfile };
}
/**
* get the sidecar bin
*/
async function resolveSidecar() {
const sidecarDir = path.join(cwd, "src-tauri", "sidecar");
const host = execSync("rustc -vV | grep host").toString().slice(6).trim();
const ext = process.platform === "win32" ? ".exe" : "";
const sidecarFile = `clash-${host}${ext}`;
const sidecarPath = path.join(sidecarDir, sidecarFile);
if (!(await fs.pathExists(sidecarDir))) await fs.mkdir(sidecarDir);
if (await fs.pathExists(sidecarPath)) return;
// download sidecar
const binInfo = resolveClash();
const tempDir = path.join(cwd, "pre-dev-temp");
const tempZip = path.join(tempDir, binInfo.zipfile);
const tempExe = path.join(tempDir, binInfo.exefile);
if (!(await fs.pathExists(tempDir))) await fs.mkdir(tempDir);
if (!(await fs.pathExists(tempZip))) await downloadFile(binInfo.url, tempZip);
// Todo: support gz
const zip = new AdmZip(tempZip);
zip.getEntries().forEach((entry) => {
console.log("[INFO]: entry name", entry.entryName);
});
zip.extractAllTo(tempDir, true);
// save as sidecar
await fs.rename(tempExe, sidecarPath);
// delete temp dir
await fs.remove(tempDir);
}
/**
* get the Country.mmdb (not required)
*/
async function resolveMmdb() {
const url =
"https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb";
const resPath = path.join(cwd, "src-tauri", "resources", "Country.mmdb");
if (await fs.pathExists(resPath)) return;
await downloadFile(url, resPath);
}
/**
* download file and save to `path`
*/
async function downloadFile(url, path) {
console.log(`[INFO]: downloading from "${url}"`);
const response = await fetch(url, {
method: "GET",
headers: { "Content-Type": "application/octet-stream" },
});
const buffer = await response.arrayBuffer();
await fs.writeFile(path, new Uint8Array(buffer));
}
/// main
resolveSidecar();
resolveMmdb();

66
scripts/set_dns.sh Normal file
View File

@ -0,0 +1,66 @@
#!/bin/bash
# 验证IPv4地址格式
function is_valid_ipv4() {
local ip=$1
local IFS='.'
local -a octets
[[ ! $ip =~ ^([0-9]+\.){3}[0-9]+$ ]] && return 1
read -r -a octets <<<"$ip"
[ "${#octets[@]}" -ne 4 ] && return 1
for octet in "${octets[@]}"; do
if ! [[ "$octet" =~ ^[0-9]+$ ]] || ((octet < 0 || octet > 255)); then
return 1
fi
done
return 0
}
# 验证IPv6地址格式
function is_valid_ipv6() {
local ip=$1
if [[ ! $ip =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]] &&
[[ ! $ip =~ ^(([0-9a-fA-F]{0,4}:){0,7}:|(:[0-9a-fA-F]{0,4}:){0,6}:[0-9a-fA-F]{0,4})$ ]]; then
return 1
fi
return 0
}
# 验证IP地址是否为有效的IPv4或IPv6
function is_valid_ip() {
is_valid_ipv4 "$1" || is_valid_ipv6 "$1"
}
# 检查参数
[ $# -lt 1 ] && echo "Usage: $0 <IP address>" && exit 1
! is_valid_ip "$1" && echo "$1 is not a valid IP address." && exit 1
# 获取网络接口和硬件端口
nic=$(route -n get default | grep "interface" | awk '{print $2}')
hardware_port=$(networksetup -listallhardwareports | awk -v dev="$nic" '
/Hardware Port:/{port=$0; gsub("Hardware Port: ", "", port)}
/Device: /{if ($2 == dev) {print port; exit}}
')
# 获取当前DNS设置
original_dns=$(networksetup -getdnsservers "$hardware_port")
# 检查当前DNS设置是否有效
is_valid_dns=false
for ip in $original_dns; do
ip=$(echo "$ip" | tr -d '[:space:]')
if [ -n "$ip" ] && (is_valid_ipv4 "$ip" || is_valid_ipv6 "$ip"); then
is_valid_dns=true
break
fi
done
# 更新DNS设置
if [ "$is_valid_dns" = false ]; then
echo "empty" >.original_dns.txt
else
echo "$original_dns" >.original_dns.txt
fi
networksetup -setdnsservers "$hardware_port" "$1"

20
scripts/unset_dns.sh Normal file
View File

@ -0,0 +1,20 @@
#!/bin/bash
nic=$(route -n get default | grep "interface" | awk '{print $2}')
hardware_port=$(networksetup -listallhardwareports | awk -v dev="$nic" '
/Hardware Port:/{
port=$0; gsub("Hardware Port: ", "", port)
}
/Device: /{
if ($2 == dev) {
print port;
exit
}
}
')
if [ -f .original_dns.txt ]; then
original_dns=$(cat .original_dns.txt)
networksetup -setdnsservers "$hardware_port" $original_dns
rm -rf .original_dns.txt
fi

45
scripts/updatelog.mjs Normal file
View File

@ -0,0 +1,45 @@
import fs from "fs";
import fsp from "fs/promises";
import path from "path";
const UPDATE_LOG = "UPDATELOG.md";
// parse the UPDATELOG.md
export async function resolveUpdateLog(tag) {
const cwd = process.cwd();
const reTitle = /^## v[\d\.]+/;
const reEnd = /^---/;
const file = path.join(cwd, UPDATE_LOG);
if (!fs.existsSync(file)) {
throw new Error("could not found UPDATELOG.md");
}
const data = await fsp.readFile(file, "utf-8");
const map = {};
let p = "";
data.split("\n").forEach((line) => {
if (reTitle.test(line)) {
p = line.slice(3).trim();
if (!map[p]) {
map[p] = [];
} else {
throw new Error(`Tag ${p} dup`);
}
} else if (reEnd.test(line)) {
p = "";
} else if (p) {
map[p].push(line);
}
});
if (!map[tag]) {
throw new Error(`could not found "${tag}" in UPDATELOG.md`);
}
return map[tag].join("\n").trim();
}

View File

@ -0,0 +1,157 @@
import fetch from "node-fetch";
import { getOctokit, context } from "@actions/github";
import { resolveUpdateLog } from "./updatelog.mjs";
const UPDATE_TAG_NAME = "updater";
const UPDATE_JSON_FILE = "update-fixed-webview2.json";
const UPDATE_JSON_PROXY = "update-fixed-webview2-proxy.json";
/// generate update.json
/// upload to update tag's release asset
async function resolveUpdater() {
if (process.env.GITHUB_TOKEN === undefined) {
throw new Error("GITHUB_TOKEN is required");
}
const options = { owner: context.repo.owner, repo: context.repo.repo };
const github = getOctokit(process.env.GITHUB_TOKEN);
const { data: tags } = await github.rest.repos.listTags({
...options,
per_page: 10,
page: 1,
});
// get the latest publish tag
const tag = tags.find((t) => t.name.startsWith("v"));
console.log(tag);
console.log();
const { data: latestRelease } = await github.rest.repos.getReleaseByTag({
...options,
tag: tag.name,
});
const updateData = {
name: tag.name,
notes: await resolveUpdateLog(tag.name), // use updatelog.md
pub_date: new Date().toISOString(),
platforms: {
"windows-x86_64": { signature: "", url: "" },
"windows-aarch64": { signature: "", url: "" },
"windows-x86": { signature: "", url: "" },
"windows-i686": { signature: "", url: "" },
},
};
const promises = latestRelease.assets.map(async (asset) => {
const { name, browser_download_url } = asset;
// win64 url
if (name.endsWith("x64_fixed_webview2-setup.nsis.zip")) {
updateData.platforms["windows-x86_64"].url = browser_download_url;
}
// win64 signature
if (name.endsWith("x64_fixed_webview2-setup.nsis.zip.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["windows-x86_64"].signature = sig;
}
// win32 url
if (name.endsWith("x86_fixed_webview2-setup.nsis.zip")) {
updateData.platforms["windows-x86"].url = browser_download_url;
updateData.platforms["windows-i686"].url = browser_download_url;
}
// win32 signature
if (name.endsWith("x86_fixed_webview2-setup.nsis.zip.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["windows-x86"].signature = sig;
updateData.platforms["windows-i686"].signature = sig;
}
// win arm url
if (name.endsWith("arm64_fixed_webview2-setup.nsis.zip")) {
updateData.platforms["windows-aarch64"].url = browser_download_url;
}
// win arm signature
if (name.endsWith("arm64_fixed_webview2-setup.nsis.zip.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["windows-aarch64"].signature = sig;
}
});
await Promise.allSettled(promises);
console.log(updateData);
// maybe should test the signature as well
// delete the null field
Object.entries(updateData.platforms).forEach(([key, value]) => {
if (!value.url) {
console.log(`[Error]: failed to parse release for "${key}"`);
delete updateData.platforms[key];
}
});
// 生成一个代理github的更新文件
// 使用 https://hub.fastgit.xyz/ 做github资源的加速
const updateDataNew = JSON.parse(JSON.stringify(updateData));
Object.entries(updateDataNew.platforms).forEach(([key, value]) => {
if (value.url) {
updateDataNew.platforms[key].url =
"https://download.clashverge.dev/" + value.url;
} else {
console.log(`[Error]: updateDataNew.platforms.${key} is null`);
}
});
// update the update.json
const { data: updateRelease } = await github.rest.repos.getReleaseByTag({
...options,
tag: UPDATE_TAG_NAME,
});
// delete the old assets
for (let asset of updateRelease.assets) {
if (asset.name === UPDATE_JSON_FILE) {
await github.rest.repos.deleteReleaseAsset({
...options,
asset_id: asset.id,
});
}
if (asset.name === UPDATE_JSON_PROXY) {
await github.rest.repos
.deleteReleaseAsset({ ...options, asset_id: asset.id })
.catch(console.error); // do not break the pipeline
}
}
// upload new assets
await github.rest.repos.uploadReleaseAsset({
...options,
release_id: updateRelease.id,
name: UPDATE_JSON_FILE,
data: JSON.stringify(updateData, null, 2),
});
await github.rest.repos.uploadReleaseAsset({
...options,
release_id: updateRelease.id,
name: UPDATE_JSON_PROXY,
data: JSON.stringify(updateDataNew, null, 2),
});
}
// get the signature file content
async function getSignature(url) {
const response = await fetch(url, {
method: "GET",
headers: { "Content-Type": "application/octet-stream" },
});
return response.text();
}
resolveUpdater().catch(console.error);

312
scripts/updater.mjs Normal file
View File

@ -0,0 +1,312 @@
import fetch from "node-fetch";
import { getOctokit, context } from "@actions/github";
import { resolveUpdateLog } from "./updatelog.mjs";
// Add stable update JSON filenames
const UPDATE_TAG_NAME = "updater";
const UPDATE_JSON_FILE = "update.json";
const UPDATE_JSON_PROXY = "update-proxy.json";
// Add alpha update JSON filenames
const ALPHA_TAG_NAME = "updater-alpha";
const ALPHA_UPDATE_JSON_FILE = "update-alpha.json";
const ALPHA_UPDATE_JSON_PROXY = "update-alpha-proxy.json";
/// generate update.json
/// upload to update tag's release asset
async function resolveUpdater() {
if (process.env.GITHUB_TOKEN === undefined) {
throw new Error("GITHUB_TOKEN is required");
}
const options = { owner: context.repo.owner, repo: context.repo.repo };
const github = getOctokit(process.env.GITHUB_TOKEN);
// Fetch all tags using pagination
let allTags = [];
let page = 1;
const perPage = 100;
while (true) {
const { data: pageTags } = await github.rest.repos.listTags({
...options,
per_page: perPage,
page: page,
});
allTags = allTags.concat(pageTags);
// Break if we received fewer tags than requested (last page)
if (pageTags.length < perPage) {
break;
}
page++;
}
const tags = allTags;
console.log(`Retrieved ${tags.length} tags in total`);
// More flexible tag detection with regex patterns
const stableTagRegex = /^v\d+\.\d+\.\d+$/; // Matches vX.Y.Z format
// const preReleaseRegex = /^v\d+\.\d+\.\d+-(alpha|beta|rc|pre)/i; // Matches vX.Y.Z-alpha/beta/rc format
const preReleaseRegex = /^(alpha|beta|rc|pre)$/i; // Matches exact alpha/beta/rc/pre tags
// Get the latest stable tag and pre-release tag
const stableTag = tags.find((t) => stableTagRegex.test(t.name));
const preReleaseTag = tags.find((t) => preReleaseRegex.test(t.name));
console.log("All tags:", tags.map((t) => t.name).join(", "));
console.log("Stable tag:", stableTag ? stableTag.name : "None found");
console.log(
"Pre-release tag:",
preReleaseTag ? preReleaseTag.name : "None found",
);
console.log();
// Process stable release
if (stableTag) {
await processRelease(github, options, stableTag, false);
}
// Process pre-release if found
if (preReleaseTag) {
await processRelease(github, options, preReleaseTag, true);
}
}
// Process a release (stable or alpha) and generate update files
async function processRelease(github, options, tag, isAlpha) {
if (!tag) return;
const { data: release } = await github.rest.repos.getReleaseByTag({
...options,
tag: tag.name,
});
const updateData = {
name: tag.name,
notes: await resolveUpdateLog(tag.name).catch(
() => "No changelog available",
),
pub_date: new Date().toISOString(),
platforms: {
win64: { signature: "", url: "" }, // compatible with older formats
linux: { signature: "", url: "" }, // compatible with older formats
darwin: { signature: "", url: "" }, // compatible with older formats
"darwin-aarch64": { signature: "", url: "" },
"darwin-intel": { signature: "", url: "" },
"darwin-x86_64": { signature: "", url: "" },
"linux-x86_64": { signature: "", url: "" },
"linux-x86": { signature: "", url: "" },
"linux-i686": { signature: "", url: "" },
"linux-aarch64": { signature: "", url: "" },
"linux-armv7": { signature: "", url: "" },
"windows-x86_64": { signature: "", url: "" },
"windows-aarch64": { signature: "", url: "" },
"windows-x86": { signature: "", url: "" },
"windows-i686": { signature: "", url: "" },
},
};
const promises = release.assets.map(async (asset) => {
const { name, browser_download_url } = asset;
// Process all the platform URL and signature data
// win64 url
if (name.endsWith("x64-setup.exe")) {
updateData.platforms.win64.url = browser_download_url;
updateData.platforms["windows-x86_64"].url = browser_download_url;
}
// win64 signature
if (name.endsWith("x64-setup.exe.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms.win64.signature = sig;
updateData.platforms["windows-x86_64"].signature = sig;
}
// win32 url
if (name.endsWith("x86-setup.exe")) {
updateData.platforms["windows-x86"].url = browser_download_url;
updateData.platforms["windows-i686"].url = browser_download_url;
}
// win32 signature
if (name.endsWith("x86-setup.exe.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["windows-x86"].signature = sig;
updateData.platforms["windows-i686"].signature = sig;
}
// win arm url
if (name.endsWith("arm64-setup.exe")) {
updateData.platforms["windows-aarch64"].url = browser_download_url;
}
// win arm signature
if (name.endsWith("arm64-setup.exe.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["windows-aarch64"].signature = sig;
}
// darwin url (intel)
if (name.endsWith(".app.tar.gz") && !name.includes("aarch")) {
updateData.platforms.darwin.url = browser_download_url;
updateData.platforms["darwin-intel"].url = browser_download_url;
updateData.platforms["darwin-x86_64"].url = browser_download_url;
}
// darwin signature (intel)
if (name.endsWith(".app.tar.gz.sig") && !name.includes("aarch")) {
const sig = await getSignature(browser_download_url);
updateData.platforms.darwin.signature = sig;
updateData.platforms["darwin-intel"].signature = sig;
updateData.platforms["darwin-x86_64"].signature = sig;
}
// darwin url (aarch)
if (name.endsWith("aarch64.app.tar.gz")) {
updateData.platforms["darwin-aarch64"].url = browser_download_url;
// 使linux可以检查更新
updateData.platforms.linux.url = browser_download_url;
updateData.platforms["linux-x86_64"].url = browser_download_url;
updateData.platforms["linux-x86"].url = browser_download_url;
updateData.platforms["linux-i686"].url = browser_download_url;
updateData.platforms["linux-aarch64"].url = browser_download_url;
updateData.platforms["linux-armv7"].url = browser_download_url;
}
// darwin signature (aarch)
if (name.endsWith("aarch64.app.tar.gz.sig")) {
const sig = await getSignature(browser_download_url);
updateData.platforms["darwin-aarch64"].signature = sig;
updateData.platforms.linux.signature = sig;
updateData.platforms["linux-x86_64"].signature = sig;
updateData.platforms["linux-x86"].url = browser_download_url;
updateData.platforms["linux-i686"].url = browser_download_url;
updateData.platforms["linux-aarch64"].signature = sig;
updateData.platforms["linux-armv7"].signature = sig;
}
});
await Promise.allSettled(promises);
console.log(updateData);
// maybe should test the signature as well
// delete the null field
Object.entries(updateData.platforms).forEach(([key, value]) => {
if (!value.url) {
console.log(`[Error]: failed to parse release for "${key}"`);
delete updateData.platforms[key];
}
});
// Generate a proxy update file for accelerated GitHub resources
const updateDataNew = JSON.parse(JSON.stringify(updateData));
Object.entries(updateDataNew.platforms).forEach(([key, value]) => {
if (value.url) {
updateDataNew.platforms[key].url =
"https://download.clashverge.dev/" + value.url;
} else {
console.log(`[Error]: updateDataNew.platforms.${key} is null`);
}
});
// Get the appropriate updater release based on isAlpha flag
const releaseTag = isAlpha ? ALPHA_TAG_NAME : UPDATE_TAG_NAME;
console.log(
`Processing ${isAlpha ? "alpha" : "stable"} release:`,
releaseTag,
);
try {
let updateRelease;
try {
// Try to get the existing release
const response = await github.rest.repos.getReleaseByTag({
...options,
tag: releaseTag,
});
updateRelease = response.data;
console.log(
`Found existing ${releaseTag} release with ID: ${updateRelease.id}`,
);
} catch (error) {
// If release doesn't exist, create it
if (error.status === 404) {
console.log(
`Release with tag ${releaseTag} not found, creating new release...`,
);
const createResponse = await github.rest.repos.createRelease({
...options,
tag_name: releaseTag,
name: isAlpha
? "Auto-update Alpha Channel"
: "Auto-update Stable Channel",
body: `This release contains the update information for ${isAlpha ? "alpha" : "stable"} channel.`,
prerelease: isAlpha,
});
updateRelease = createResponse.data;
console.log(
`Created new ${releaseTag} release with ID: ${updateRelease.id}`,
);
} else {
// If it's another error, throw it
throw error;
}
}
// File names based on release type
const jsonFile = isAlpha ? ALPHA_UPDATE_JSON_FILE : UPDATE_JSON_FILE;
const proxyFile = isAlpha ? ALPHA_UPDATE_JSON_PROXY : UPDATE_JSON_PROXY;
// Delete existing assets with these names
for (let asset of updateRelease.assets) {
if (asset.name === jsonFile) {
await github.rest.repos.deleteReleaseAsset({
...options,
asset_id: asset.id,
});
}
if (asset.name === proxyFile) {
await github.rest.repos
.deleteReleaseAsset({ ...options, asset_id: asset.id })
.catch(console.error); // do not break the pipeline
}
}
// Upload new assets
await github.rest.repos.uploadReleaseAsset({
...options,
release_id: updateRelease.id,
name: jsonFile,
data: JSON.stringify(updateData, null, 2),
});
await github.rest.repos.uploadReleaseAsset({
...options,
release_id: updateRelease.id,
name: proxyFile,
data: JSON.stringify(updateDataNew, null, 2),
});
console.log(
`Successfully uploaded ${isAlpha ? "alpha" : "stable"} update files to ${releaseTag}`,
);
} catch (error) {
console.error(
`Failed to process ${isAlpha ? "alpha" : "stable"} release:`,
error.message,
);
}
}
// get the signature file content
async function getSignature(url) {
const response = await fetch(url, {
method: "GET",
headers: { "Content-Type": "application/octet-stream" },
});
return response.text();
}
resolveUpdater().catch(console.error);

11
scripts/utils.mjs Normal file
View File

@ -0,0 +1,11 @@
import clc from "cli-color";
export const log_success = (msg, ...optionalParams) =>
console.log(clc.green(msg), ...optionalParams);
export const log_error = (msg, ...optionalParams) =>
console.log(clc.red(msg), ...optionalParams);
export const log_info = (msg, ...optionalParams) =>
console.log(clc.bgBlue(msg), ...optionalParams);
var debugMsg = clc.xterm(245);
export const log_debug = (msg, ...optionalParams) =>
console.log(debugMsg(msg), ...optionalParams);

1
src-tauri/.clippy.toml Normal file
View File

@ -0,0 +1 @@
avoid-breaking-exported-api = true

View File

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

8845
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

138
src-tauri/Cargo.toml Normal file → Executable file
View File

@ -1,34 +1,136 @@
[package]
name = "app"
version = "0.1.0"
name = "clash-verge"
version = "2.2.1-alpha"
description = "clash verge"
authors = ["zzzgydi"]
license = "GPL-3.0"
repository = ""
default-run = "app"
authors = ["zzzgydi", "wonfen", "MystiPanda"]
license = "GPL-3.0-only"
repository = "https://github.com/clash-verge-rev/clash-verge-rev.git"
default-run = "clash-verge"
edition = "2021"
build = "build.rs"
[package.metadata.bundle]
identifier = "io.github.clash-verge-rev.clash-verge-rev"
[build-dependencies]
tauri-build = { version = "1.0.0-beta.4" }
tauri-build = { version = "2.0.6", features = [] }
[dependencies]
dirs = "4.0.0"
chrono = "0.4.19"
serde_json = "1.0"
serde_yaml = "0.8"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-beta.8", features = ["api-all", "system-tray"] }
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
log = "0.4.14"
log4rs = "1.0.0"
warp = "0.3"
anyhow = "1.0.97"
dirs = "6.0"
open = "5.1"
log = "0.4"
dunce = "1.0"
log4rs = "1"
nanoid = "0.4"
chrono = "0.4.40"
sysinfo = "0.33.1"
boa_engine = "0.20.0"
serde_json = "1.0"
serde_yaml = "0.9"
once_cell = "1.20.3"
port_scanner = "0.1.5"
delay_timer = "0.11.6"
parking_lot = "0.12"
percent-encoding = "2.3.1"
window-shadows = { version = "0.2.2" }
tokio = { version = "1.43", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls", "cookies"] }
regex = "1.10.5"
sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", rev = "3d748b5" }
image = "0.25.5"
imageproc = "0.25.0"
rusttype = "0.9"
tauri = { version = "2.3.1", features = [
"protocol-asset",
"devtools",
"tray-icon",
"image-ico",
"image-png",
] }
network-interface = { version = "2.0.0", features = ["serde"] }
tauri-plugin-shell = "2.2.0"
tauri-plugin-dialog = "2.2.0"
tauri-plugin-fs = "2.2.0"
tauri-plugin-notification = "2.2.1"
tauri-plugin-process = "2.2.0"
tauri-plugin-clipboard-manager = "2.2.1"
tauri-plugin-deep-link = "2.2.0"
tauri-plugin-devtools = "2.0.0-rc"
url = "2.5.4"
zip = "2.2.3"
reqwest_dav = "0.1.14"
aes-gcm = { version = "0.10.3", features = ["std"] }
base64 = "0.22.1"
getrandom = "0.3.1"
tokio-tungstenite = "0.26.2"
futures = "0.3"
sys-locale = "0.3.1"
async-trait = "0.1.87"
mihomo_api = { path = "src_crates/crate_mihomo_api" }
ab_glyph = "0.2.29"
tungstenite = "0.26.2"
[target.'cfg(windows)'.dependencies]
winreg = { version = "0.10", features = ["transactions"] }
runas = "=1.2.0"
deelevate = "0.2.0"
winreg = "0.55.0"
url = "2.5.4"
[target.'cfg(target_os = "linux")'.dependencies]
users = "0.11.0"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-autostart = "2.2.0"
tauri-plugin-global-shortcut = "2.2.0"
tauri-plugin-updater = "2.5.1"
tauri-plugin-window-state = "2.2.1"
#openssl
[features]
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]
verge-dev = []
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s"
strip = true
[profile.dev]
incremental = true
[profile.fast-release]
inherits = "release" # 继承 release 的配置
panic = "abort" # 与 release 相同
codegen-units = 256 # 增加编译单元,提升编译速度
lto = false # 禁用 LTO提升编译速度
opt-level = 0 # 禁用优化,大幅提升编译速度
debug = true # 保留调试信息
strip = false # 不剥离符号,保留调试信息
[profile.fast-dev]
inherits = "dev" # 继承 dev 的配置
codegen-units = 256 # 增加编译单元,提升编译速度
opt-level = 0 # 禁用优化,进一步提升编译速度
incremental = true # 启用增量编译
debug = true # 保留调试信息
strip = false # 不剥离符号,保留调试信息
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[dev-dependencies]
env_logger = "0.11.0"
mockito = "1.7.0"
tempfile = "3.17.1"
[workspace]
members = [
"src_crates/crate_mihomo_api",]

BIN
src-tauri/assets/fonts/SF-Pro.ttf Executable file

Binary file not shown.

View File

@ -0,0 +1,21 @@
{
"identifier": "desktop-capability",
"platforms": ["macOS", "windows", "linux"],
"webviews": ["main"],
"windows": ["main"],
"permissions": [
"global-shortcut:default",
"updater:default",
"dialog:default",
"dialog:allow-ask",
"dialog:allow-message",
"updater:default",
"updater:allow-check",
"updater:allow-download-and-install",
"process:allow-restart",
"deep-link:default",
"window-state:default",
"window-state:default",
"autostart:default"
]
}

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,10 @@
[Desktop Entry]
Categories={{{categories}}}
Comment={{{comment}}}
Exec={{{exec}}} %u
StartupWMClass={{{exec}}}
Icon={{{icon}}}
Name={{{name}}}
Terminal=false
Type=Application
MimeType=x-scheme-handler/clash;

View File

@ -0,0 +1,4 @@
#!/bin/bash
chmod +x /usr/bin/install-service
chmod +x /usr/bin/uninstall-service
chmod +x /usr/bin/clash-verge-service

View File

@ -0,0 +1,2 @@
#!/bin/bash
/usr/bin/uninstall-service

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.application-groups</key>
<array>
<string>io.github.clash-verge-rev.clash-verge-rev</string>
</array>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
# Default Config For Clash Core
mixed-port: 7890
log-level: info
allow-lan: false
external-controller: 127.0.0.1:9090
secret: ""

View File

@ -1,3 +0,0 @@
# Profiles Config for Clash Verge
current: 0

View File

@ -1,6 +0,0 @@
# Defaulf Config For Clash Verge
theme_mode: light
enable_self_startup: false
enable_system_proxy: false
system_proxy_bypass: localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>

View File

@ -1,6 +1,6 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
tab_spaces = 4
newline_style = "Auto"
use_small_heuristics = "Default"
reorder_imports = true

205
src-tauri/src/cmd/app.rs Normal file
View File

@ -0,0 +1,205 @@
use super::CmdResult;
use crate::{feat, utils::dirs, wrap_err};
use tauri::Manager;
/// 打开应用程序所在目录
#[tauri::command]
pub fn open_app_dir() -> CmdResult<()> {
let app_dir = wrap_err!(dirs::app_home_dir())?;
wrap_err!(open::that(app_dir))
}
/// 打开核心所在目录
#[tauri::command]
pub fn open_core_dir() -> CmdResult<()> {
let core_dir = wrap_err!(tauri::utils::platform::current_exe())?;
let core_dir = core_dir.parent().ok_or("failed to get core dir")?;
wrap_err!(open::that(core_dir))
}
/// 打开日志目录
#[tauri::command]
pub fn open_logs_dir() -> CmdResult<()> {
let log_dir = wrap_err!(dirs::app_logs_dir())?;
wrap_err!(open::that(log_dir))
}
/// 打开网页链接
#[tauri::command]
pub fn open_web_url(url: String) -> CmdResult<()> {
wrap_err!(open::that(url))
}
/// 打开/关闭开发者工具
#[tauri::command]
pub fn open_devtools(app_handle: tauri::AppHandle) {
if let Some(window) = app_handle.get_webview_window("main") {
if !window.is_devtools_open() {
window.open_devtools();
} else {
window.close_devtools();
}
}
}
/// 退出应用
#[tauri::command]
pub fn exit_app() {
feat::quit(Some(0));
}
/// 重启应用
#[tauri::command]
pub async fn restart_app() -> CmdResult<()> {
feat::restart_app();
Ok(())
}
/// 获取便携版标识
#[tauri::command]
pub fn get_portable_flag() -> CmdResult<bool> {
Ok(*dirs::PORTABLE_FLAG.get().unwrap_or(&false))
}
/// 获取应用目录
#[tauri::command]
pub fn get_app_dir() -> CmdResult<String> {
let app_home_dir = wrap_err!(dirs::app_home_dir())?
.to_string_lossy()
.to_string();
Ok(app_home_dir)
}
/// 获取当前自启动状态
#[tauri::command]
pub fn get_auto_launch_status() -> CmdResult<bool> {
use crate::core::sysopt::Sysopt;
wrap_err!(Sysopt::global().get_launch_status())
}
/// 下载图标缓存
#[tauri::command]
pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String> {
let icon_cache_dir = wrap_err!(dirs::app_home_dir())?.join("icons").join("cache");
let icon_path = icon_cache_dir.join(&name);
// 如果文件已存在,直接返回路径
if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string());
}
// 确保缓存目录存在
if !icon_cache_dir.exists() {
let _ = std::fs::create_dir_all(&icon_cache_dir);
}
// 使用临时文件名来下载
let temp_path = icon_cache_dir.join(format!("{}.downloading", &name));
// 下载文件到临时位置
let response = wrap_err!(reqwest::get(&url).await)?;
// 检查内容类型是否为图片
let content_type = response
.headers()
.get(reqwest::header::CONTENT_TYPE)
.and_then(|v| v.to_str().ok())
.unwrap_or("");
let is_image = content_type.starts_with("image/");
// 获取响应内容
let content = wrap_err!(response.bytes().await)?;
// 检查内容是否为HTML (针对CDN错误页面)
let is_html = content.len() > 15
&& (content.starts_with(b"<!DOCTYPE html")
|| content.starts_with(b"<html")
|| content.starts_with(b"<?xml"));
// 只有当内容确实是图片时才保存
if is_image && !is_html {
{
let mut file = match std::fs::File::create(&temp_path) {
Ok(file) => file,
Err(_) => {
if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string());
} else {
return Err("Failed to create temporary file".into());
}
}
};
wrap_err!(std::io::copy(&mut content.as_ref(), &mut file))?;
}
// 再次检查目标文件是否已存在,避免重命名覆盖其他线程已完成的文件
if !icon_path.exists() {
match std::fs::rename(&temp_path, &icon_path) {
Ok(_) => {}
Err(_) => {
let _ = std::fs::remove_file(&temp_path);
if icon_path.exists() {
return Ok(icon_path.to_string_lossy().to_string());
}
}
}
} else {
let _ = std::fs::remove_file(&temp_path);
}
Ok(icon_path.to_string_lossy().to_string())
} else {
let _ = std::fs::remove_file(&temp_path);
Err(format!("下载的内容不是有效图片: {}", url))
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct IconInfo {
name: String,
previous_t: String,
current_t: String,
}
/// 复制图标文件
#[tauri::command]
pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
use std::{fs, path::Path};
let file_path = Path::new(&path);
let icon_dir = wrap_err!(dirs::app_home_dir())?.join("icons");
if !icon_dir.exists() {
let _ = fs::create_dir_all(&icon_dir);
}
let ext = match file_path.extension() {
Some(e) => e.to_string_lossy().to_string(),
None => "ico".to_string(),
};
let dest_path = icon_dir.join(format!(
"{0}-{1}.{ext}",
icon_info.name, icon_info.current_t
));
if file_path.exists() {
if icon_info.previous_t.trim() != "" {
fs::remove_file(
icon_dir.join(format!("{0}-{1}.png", icon_info.name, icon_info.previous_t)),
)
.unwrap_or_default();
fs::remove_file(
icon_dir.join(format!("{0}-{1}.ico", icon_info.name, icon_info.previous_t)),
)
.unwrap_or_default();
}
match fs::copy(file_path, &dest_path) {
Ok(_) => Ok(dest_path.to_string_lossy().to_string()),
Err(err) => Err(err.to_string()),
}
} else {
Err("file not found".to_string())
}
}

223
src-tauri/src/cmd/clash.rs Normal file
View File

@ -0,0 +1,223 @@
use super::CmdResult;
use crate::{config::*, core::*, feat, module::mihomo::MihomoManager, wrap_err};
use serde_yaml::Mapping;
/// 复制Clash环境变量
#[tauri::command]
pub fn copy_clash_env() -> CmdResult {
feat::copy_clash_env();
Ok(())
}
/// 获取Clash信息
#[tauri::command]
pub fn get_clash_info() -> CmdResult<ClashInfo> {
Ok(Config::clash().latest().get_client_info())
}
/// 修改Clash配置
#[tauri::command]
pub async fn patch_clash_config(payload: Mapping) -> CmdResult {
wrap_err!(feat::patch_clash(payload).await)
}
/// 修改Clash模式
#[tauri::command]
pub async fn patch_clash_mode(payload: String) -> CmdResult {
feat::change_clash_mode(payload);
Ok(())
}
/// 切换Clash核心
#[tauri::command]
pub async fn change_clash_core(clash_core: String) -> CmdResult<Option<String>> {
log::info!(target: "app", "changing core to {clash_core}");
match CoreManager::global()
.change_core(Some(clash_core.clone()))
.await
{
Ok(_) => {
log::info!(target: "app", "core changed to {clash_core}");
handle::Handle::notice_message("config_core::change_success", &clash_core);
handle::Handle::refresh_clash();
Ok(None)
}
Err(err) => {
let error_msg = err.to_string();
log::error!(target: "app", "failed to change core: {error_msg}");
handle::Handle::notice_message("config_core::change_error", &error_msg);
Ok(Some(error_msg))
}
}
}
/// 重启核心
#[tauri::command]
pub async fn restart_core() -> CmdResult {
wrap_err!(CoreManager::global().restart_core().await)
}
/// 获取代理延迟
#[tauri::command]
pub async fn clash_api_get_proxy_delay(
name: String,
url: Option<String>,
timeout: i32,
) -> CmdResult<serde_json::Value> {
MihomoManager::global()
.test_proxy_delay(&name, url, timeout)
.await
}
/// 测试URL延迟
#[tauri::command]
pub async fn test_delay(url: String) -> CmdResult<u32> {
Ok(feat::test_delay(url).await.unwrap_or(10000u32))
}
/// 保存DNS配置到单独文件
#[tauri::command]
pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
use crate::utils::dirs;
use serde_yaml;
use std::fs;
// 获取DNS配置文件路径
let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())?
.join("dns_config.yaml");
// 保存DNS配置到文件
let yaml_str = serde_yaml::to_string(&dns_config).map_err(|e| e.to_string())?;
fs::write(&dns_path, yaml_str).map_err(|e| e.to_string())?;
log::info!(target: "app", "DNS config saved to {:?}", dns_path);
Ok(())
}
/// 应用或撤销DNS配置
#[tauri::command]
pub fn apply_dns_config(apply: bool) -> CmdResult {
use crate::{
config::Config,
core::{handle, CoreManager},
utils::dirs,
};
use tauri::async_runtime;
// 使用spawn来处理异步操作
async_runtime::spawn(async move {
if apply {
// 读取DNS配置文件
let dns_path = match dirs::app_home_dir() {
Ok(path) => path.join("dns_config.yaml"),
Err(e) => {
log::error!(target: "app", "Failed to get home dir: {}", e);
return;
}
};
if !dns_path.exists() {
log::warn!(target: "app", "DNS config file not found");
return;
}
let dns_yaml = match std::fs::read_to_string(&dns_path) {
Ok(content) => content,
Err(e) => {
log::error!(target: "app", "Failed to read DNS config: {}", e);
return;
}
};
// 解析DNS配置并创建patch
let patch_config = match serde_yaml::from_str::<serde_yaml::Mapping>(&dns_yaml) {
Ok(config) => {
let mut patch = serde_yaml::Mapping::new();
patch.insert("dns".into(), config.into());
patch
}
Err(e) => {
log::error!(target: "app", "Failed to parse DNS config: {}", e);
return;
}
};
log::info!(target: "app", "Applying DNS config from file");
// 重新生成配置确保DNS配置被正确应用
// 这里不调用patch_clash以避免将DNS配置写入config.yaml
Config::runtime()
.latest()
.patch_config(patch_config.clone());
// 首先重新生成配置
if let Err(err) = Config::generate().await {
log::error!(target: "app", "Failed to regenerate config with DNS: {}", err);
return;
}
// 然后应用新配置
if let Err(err) = CoreManager::global().update_config().await {
log::error!(target: "app", "Failed to apply config with DNS: {}", err);
} else {
log::info!(target: "app", "DNS config successfully applied");
handle::Handle::refresh_clash();
}
} else {
// 当关闭DNS设置时不需要对配置进行任何修改
// 直接重新生成配置让enhance函数自动跳过DNS配置的加载
log::info!(target: "app", "DNS settings disabled, regenerating config");
// 重新生成配置
if let Err(err) = Config::generate().await {
log::error!(target: "app", "Failed to regenerate config: {}", err);
return;
}
// 应用新配置
match CoreManager::global().update_config().await {
Ok(_) => {
log::info!(target: "app", "Config regenerated successfully");
handle::Handle::refresh_clash();
}
Err(err) => {
log::error!(target: "app", "Failed to apply regenerated config: {}", err);
}
}
}
});
Ok(())
}
/// 检查DNS配置文件是否存在
#[tauri::command]
pub fn check_dns_config_exists() -> CmdResult<bool> {
use crate::utils::dirs;
let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())?
.join("dns_config.yaml");
Ok(dns_path.exists())
}
/// 获取DNS配置文件内容
#[tauri::command]
pub async fn get_dns_config_content() -> CmdResult<String> {
use crate::utils::dirs;
use std::fs;
let dns_path = dirs::app_home_dir()
.map_err(|e| e.to_string())?
.join("dns_config.yaml");
if !dns_path.exists() {
return Err("DNS config file not found".into());
}
let content = fs::read_to_string(&dns_path).map_err(|e| e.to_string())?;
Ok(content)
}

View File

@ -0,0 +1,9 @@
use crate::module::lightweight;
use super::CmdResult;
#[tauri::command]
pub async fn entry_lightweight_mode() -> CmdResult {
lightweight::entry_lightweight_mode();
Ok(())
}

File diff suppressed because it is too large Load Diff

36
src-tauri/src/cmd/mod.rs Normal file
View File

@ -0,0 +1,36 @@
use anyhow::Result;
// Common result type used by command functions
pub type CmdResult<T = ()> = Result<T, String>;
// Command modules
pub mod app;
pub mod clash;
pub mod media_unlock_checker;
pub mod network;
pub mod profile;
pub mod proxy;
pub mod runtime;
pub mod save_profile;
pub mod system;
pub mod uwp;
pub mod validate;
pub mod verge;
pub mod webdav;
pub mod lighteweight;
// Re-export all command functions for backwards compatibility
pub use app::*;
pub use clash::*;
pub use media_unlock_checker::*;
pub use network::*;
pub use profile::*;
pub use proxy::*;
pub use runtime::*;
pub use save_profile::*;
pub use system::*;
pub use uwp::*;
pub use validate::*;
pub use verge::*;
pub use webdav::*;
pub use lighteweight::*;

View File

@ -0,0 +1,63 @@
use super::CmdResult;
use crate::wrap_err;
use network_interface::NetworkInterface;
use serde_yaml::Mapping;
use sysproxy::{Autoproxy, Sysproxy};
/// get the system proxy
#[tauri::command]
pub fn get_sys_proxy() -> CmdResult<Mapping> {
let current = wrap_err!(Sysproxy::get_system_proxy())?;
let mut map = Mapping::new();
map.insert("enable".into(), current.enable.into());
map.insert(
"server".into(),
format!("{}:{}", current.host, current.port).into(),
);
map.insert("bypass".into(), current.bypass.into());
Ok(map)
}
/// get the system proxy
#[tauri::command]
pub fn get_auto_proxy() -> CmdResult<Mapping> {
let current = wrap_err!(Autoproxy::get_auto_proxy())?;
let mut map = Mapping::new();
map.insert("enable".into(), current.enable.into());
map.insert("url".into(), current.url.into());
Ok(map)
}
/// 获取网络接口列表
#[tauri::command]
pub fn get_network_interfaces() -> Vec<String> {
use sysinfo::Networks;
let mut result = Vec::new();
let networks = Networks::new_with_refreshed_list();
for (interface_name, _) in &networks {
result.push(interface_name.clone());
}
result
}
/// 获取网络接口详细信息
#[tauri::command]
pub fn get_network_interfaces_info() -> CmdResult<Vec<NetworkInterface>> {
use network_interface::{NetworkInterface, NetworkInterfaceConfig};
let names = get_network_interfaces();
let interfaces = wrap_err!(NetworkInterface::show())?;
let mut result = Vec::new();
for interface in interfaces {
if names.contains(&interface.name) {
result.push(interface);
}
}
Ok(result)
}

View File

@ -0,0 +1,177 @@
use super::CmdResult;
use crate::{
config::*,
core::*,
feat, log_err, ret_err,
utils::{dirs, help},
wrap_err,
};
/// 获取配置文件列表
#[tauri::command]
pub fn get_profiles() -> CmdResult<IProfiles> {
let _ = tray::Tray::global().update_menu();
Ok(Config::profiles().data().clone())
}
/// 增强配置文件
#[tauri::command]
pub async fn enhance_profiles() -> CmdResult {
match CoreManager::global().update_config().await {
Ok((true, _)) => {
println!("[enhance_profiles] 配置更新成功");
log_err!(tray::Tray::global().update_tooltip());
handle::Handle::refresh_clash();
Ok(())
}
Ok((false, error_msg)) => {
println!("[enhance_profiles] 配置验证失败: {}", error_msg);
handle::Handle::notice_message("config_validate::error", &error_msg);
Ok(())
}
Err(e) => {
println!("[enhance_profiles] 更新过程发生错误: {}", e);
handle::Handle::notice_message("config_validate::process_terminated", e.to_string());
Ok(())
}
}
}
/// 导入配置文件
#[tauri::command]
pub async fn import_profile(url: String, option: Option<PrfOption>) -> CmdResult {
let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?;
wrap_err!(Config::profiles().data().append_item(item))
}
/// 重新排序配置文件
#[tauri::command]
pub async fn reorder_profile(active_id: String, over_id: String) -> CmdResult {
wrap_err!(Config::profiles().data().reorder(active_id, over_id))
}
/// 创建配置文件
#[tauri::command]
pub async fn create_profile(item: PrfItem, file_data: Option<String>) -> CmdResult {
let item = wrap_err!(PrfItem::from(item, file_data).await)?;
wrap_err!(Config::profiles().data().append_item(item))
}
/// 更新配置文件
#[tauri::command]
pub async fn update_profile(index: String, option: Option<PrfOption>) -> CmdResult {
wrap_err!(feat::update_profile(index, option).await)
}
/// 删除配置文件
#[tauri::command]
pub async fn delete_profile(index: String) -> CmdResult {
let should_update = wrap_err!({ Config::profiles().data().delete_item(index) })?;
if should_update {
wrap_err!(CoreManager::global().update_config().await)?;
handle::Handle::refresh_clash();
}
Ok(())
}
/// 修改profiles的配置
#[tauri::command]
pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
println!("[cmd配置patch] 开始修改配置文件");
// 保存当前配置,以便在验证失败时恢复
let current_profile = Config::profiles().latest().current.clone();
println!("[cmd配置patch] 当前配置: {:?}", current_profile);
// 更新profiles配置
println!("[cmd配置patch] 正在更新配置草稿");
wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
// 更新配置并进行验证
match CoreManager::global().update_config().await {
Ok((true, _)) => {
println!("[cmd配置patch] 配置更新成功");
handle::Handle::refresh_clash();
let _ = tray::Tray::global().update_tooltip();
Config::profiles().apply();
wrap_err!(Config::profiles().data().save_file())?;
Ok(true)
}
Ok((false, error_msg)) => {
println!("[cmd配置patch] 配置验证失败: {}", error_msg);
Config::profiles().discard();
// 如果验证失败,恢复到之前的配置
if let Some(prev_profile) = current_profile {
println!("[cmd配置patch] 尝试恢复到之前的配置: {}", prev_profile);
let restore_profiles = IProfiles {
current: Some(prev_profile),
items: None,
};
// 静默恢复,不触发验证
wrap_err!({ Config::profiles().draft().patch_config(restore_profiles) })?;
Config::profiles().apply();
wrap_err!(Config::profiles().data().save_file())?;
println!("[cmd配置patch] 成功恢复到之前的配置");
}
// 发送验证错误通知
handle::Handle::notice_message("config_validate::error", &error_msg);
Ok(false)
}
Err(e) => {
println!("[cmd配置patch] 更新过程发生错误: {}", e);
Config::profiles().discard();
handle::Handle::notice_message("config_validate::boot_error", e.to_string());
Ok(false)
}
}
}
/// 根据profile name修改profiles
#[tauri::command]
pub async fn patch_profiles_config_by_profile_index(
_app_handle: tauri::AppHandle,
profile_index: String,
) -> CmdResult<bool> {
let profiles = IProfiles {
current: Some(profile_index),
items: None,
};
patch_profiles_config(profiles).await
}
/// 修改某个profile item的
#[tauri::command]
pub fn patch_profile(index: String, profile: PrfItem) -> CmdResult {
wrap_err!(Config::profiles().data().patch_item(index, profile))?;
Ok(())
}
/// 查看配置文件
#[tauri::command]
pub fn view_profile(app_handle: tauri::AppHandle, index: String) -> CmdResult {
let file = {
wrap_err!(Config::profiles().latest().get_item(&index))?
.file
.clone()
.ok_or("the file field is null")
}?;
let path = wrap_err!(dirs::app_profiles_dir())?.join(file);
if !path.exists() {
ret_err!("the file not found");
}
wrap_err!(help::open_file(app_handle, path))
}
/// 读取配置文件内容
#[tauri::command]
pub fn read_profile_file(index: String) -> CmdResult<String> {
let profiles = Config::profiles();
let profiles = profiles.latest();
let item = wrap_err!(profiles.get_item(&index))?;
let data = wrap_err!(item.read_file())?;
Ok(data)
}

View File

@ -0,0 +1,24 @@
use super::CmdResult;
use crate::module::mihomo::MihomoManager;
#[tauri::command]
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
let mannager = MihomoManager::global();
let proxies = mannager
.refresh_proxies()
.await
.map(|_| mannager.get_proxies())
.or_else(|_| Ok(mannager.get_proxies()));
proxies
}
#[tauri::command]
pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
let mannager = MihomoManager::global();
let providers = mannager
.refresh_providers_proxies()
.await
.map(|_| mannager.get_providers_proxies())
.or_else(|_| Ok(mannager.get_providers_proxies()));
providers
}

View File

@ -0,0 +1,36 @@
use super::CmdResult;
use crate::{config::*, wrap_err};
use anyhow::Context;
use serde_yaml::Mapping;
use std::collections::HashMap;
/// 获取运行时配置
#[tauri::command]
pub fn get_runtime_config() -> CmdResult<Option<Mapping>> {
Ok(Config::runtime().latest().config.clone())
}
/// 获取运行时YAML配置
#[tauri::command]
pub fn get_runtime_yaml() -> CmdResult<String> {
let runtime = Config::runtime();
let runtime = runtime.latest();
let config = runtime.config.as_ref();
wrap_err!(config
.ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
.and_then(
|config| serde_yaml::to_string(config).context("failed to convert config to yaml")
))
}
/// 获取运行时存在的键
#[tauri::command]
pub fn get_runtime_exists() -> CmdResult<Vec<String>> {
Ok(Config::runtime().latest().exists_keys.clone())
}
/// 获取运行时日志
#[tauri::command]
pub fn get_runtime_logs() -> CmdResult<HashMap<String, Vec<(String, String)>>> {
Ok(Config::runtime().latest().chain_logs.clone())
}

View File

@ -0,0 +1,116 @@
use super::CmdResult;
use crate::{config::*, core::*, utils::dirs, wrap_err};
use std::fs;
/// 保存profiles的配置
#[tauri::command]
pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdResult {
if file_data.is_none() {
return Ok(());
}
// 在异步操作前完成所有文件操作
let (file_path, original_content, is_merge_file) = {
let profiles = Config::profiles();
let profiles_guard = profiles.latest();
let item = wrap_err!(profiles_guard.get_item(&index))?;
// 确定是否为merge类型文件
let is_merge = item.itype.as_ref().is_some_and(|t| t == "merge");
let content = wrap_err!(item.read_file())?;
let path = item.file.clone().ok_or("file field is null")?;
let profiles_dir = wrap_err!(dirs::app_profiles_dir())?;
(profiles_dir.join(path), content, is_merge)
};
// 保存新的配置文件
wrap_err!(fs::write(&file_path, file_data.clone().unwrap()))?;
let file_path_str = file_path.to_string_lossy().to_string();
println!(
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
file_path_str, is_merge_file
);
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
if is_merge_file {
println!("[cmd配置save] 检测到merge文件只进行语法验证");
match CoreManager::global()
.validate_config_file(&file_path_str, Some(true))
.await
{
Ok((true, _)) => {
println!("[cmd配置save] merge文件语法验证通过");
// 成功后尝试更新整体配置
if let Err(e) = CoreManager::global().update_config().await {
println!("[cmd配置save] 更新整体配置时发生错误: {}", e);
log::warn!(target: "app", "更新整体配置时发生错误: {}", e);
}
return Ok(());
}
Ok((false, error_msg)) => {
println!("[cmd配置save] merge文件语法验证失败: {}", error_msg);
// 恢复原始配置文件
wrap_err!(fs::write(&file_path, original_content))?;
// 发送合并文件专用错误通知
let result = (false, error_msg.clone());
crate::cmd::validate::handle_yaml_validation_notice(&result, "合并配置文件");
return Ok(());
}
Err(e) => {
println!("[cmd配置save] 验证过程发生错误: {}", e);
// 恢复原始配置文件
wrap_err!(fs::write(&file_path, original_content))?;
return Err(e.to_string());
}
}
}
// 非merge文件使用完整验证流程
match CoreManager::global()
.validate_config_file(&file_path_str, None)
.await
{
Ok((true, _)) => {
println!("[cmd配置save] 验证成功");
Ok(())
}
Ok((false, error_msg)) => {
println!("[cmd配置save] 验证失败: {}", error_msg);
// 恢复原始配置文件
wrap_err!(fs::write(&file_path, original_content))?;
// 智能判断错误类型
let is_script_error = file_path_str.ends_with(".js")
|| error_msg.contains("Script syntax error")
|| error_msg.contains("Script must contain a main function")
|| error_msg.contains("Failed to read script file");
if error_msg.contains("YAML syntax error")
|| error_msg.contains("Failed to read file:")
|| (!file_path_str.ends_with(".js") && !is_script_error)
{
// 普通YAML错误使用YAML通知处理
println!("[cmd配置save] YAML配置文件验证失败发送通知");
let result = (false, error_msg.clone());
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML配置文件");
} else if is_script_error {
// 脚本错误使用专门的通知处理
println!("[cmd配置save] 脚本文件验证失败,发送通知");
let result = (false, error_msg.clone());
crate::cmd::validate::handle_script_validation_notice(&result, "脚本文件");
} else {
// 普通配置错误使用一般通知
println!("[cmd配置save] 其他类型验证失败,发送一般通知");
handle::Handle::notice_message("config_validate::error", &error_msg);
}
Ok(())
}
Err(e) => {
println!("[cmd配置save] 验证过程发生错误: {}", e);
// 恢复原始配置文件
wrap_err!(fs::write(&file_path, original_content))?;
Err(e.to_string())
}
}
}

View File

@ -0,0 +1,71 @@
use super::CmdResult;
use crate::{
core::{self, handle, service, CoreManager},
module::sysinfo::PlatformSpecification,
wrap_err,
};
use once_cell::sync::Lazy;
use std::{
sync::atomic::{AtomicI64, Ordering},
time::{SystemTime, UNIX_EPOCH},
};
use tauri_plugin_clipboard_manager::ClipboardExt;
// 存储应用启动时间的全局变量
static APP_START_TIME: Lazy<AtomicI64> = Lazy::new(|| {
// 获取当前系统时间,转换为毫秒级时间戳
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as i64;
AtomicI64::new(now)
});
#[tauri::command]
pub async fn export_diagnostic_info() -> CmdResult<()> {
let sysinfo = PlatformSpecification::new();
let info = format!("{:?}", sysinfo);
let app_handle = handle::Handle::global().app_handle().unwrap();
let cliboard = app_handle.clipboard();
if cliboard.write_text(info).is_err() {
log::error!(target: "app", "Failed to write to clipboard");
}
Ok(())
}
#[tauri::command]
pub async fn get_system_info() -> CmdResult<String> {
let sysinfo = PlatformSpecification::new();
let info = format!("{:?}", sysinfo);
Ok(info)
}
/// 获取当前内核运行模式
#[tauri::command]
pub async fn get_running_mode() -> Result<String, String> {
match CoreManager::global().get_running_mode().await {
core::RunningMode::Service => Ok("service".to_string()),
core::RunningMode::Sidecar => Ok("sidecar".to_string()),
core::RunningMode::NotRunning => Ok("not_running".to_string()),
}
}
/// 安装/重装系统服务
#[tauri::command]
pub async fn install_service() -> CmdResult {
wrap_err!(service::reinstall_service().await)
}
/// 获取应用的运行时间(毫秒)
#[tauri::command]
pub fn get_app_uptime() -> CmdResult<i64> {
let start_time = APP_START_TIME.load(Ordering::Relaxed);
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as i64;
Ok(now - start_time)
}

28
src-tauri/src/cmd/uwp.rs Normal file
View File

@ -0,0 +1,28 @@
use super::CmdResult;
/// Platform-specific implementation for UWP functionality
#[cfg(windows)]
mod platform {
use super::CmdResult;
use crate::{core::win_uwp, wrap_err};
pub async fn invoke_uwp_tool() -> CmdResult {
wrap_err!(win_uwp::invoke_uwptools().await)
}
}
/// Stub implementation for non-Windows platforms
#[cfg(not(windows))]
mod platform {
use super::CmdResult;
pub async fn invoke_uwp_tool() -> CmdResult {
Ok(())
}
}
/// Command exposed to Tauri
#[tauri::command]
pub async fn invoke_uwp_tool() -> CmdResult {
platform::invoke_uwp_tool().await
}

View File

@ -0,0 +1,104 @@
use super::CmdResult;
use crate::core::*;
/// 发送脚本验证通知消息
#[tauri::command]
pub async fn script_validate_notice(status: String, msg: String) -> CmdResult {
handle::Handle::notice_message(&status, &msg);
Ok(())
}
/// 处理脚本验证相关的所有消息通知
/// 统一通知接口,保持消息类型一致性
pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str) {
if !result.0 {
let error_msg = &result.1;
// 根据错误消息内容判断错误类型
let status = if error_msg.starts_with("File not found:") {
"config_validate::file_not_found"
} else if error_msg.starts_with("Failed to read script file:") {
"config_validate::script_error"
} else if error_msg.starts_with("Script syntax error:") {
"config_validate::script_syntax_error"
} else if error_msg == "Script must contain a main function" {
"config_validate::script_missing_main"
} else {
// 如果是其他类型错误,作为一般脚本错误处理
"config_validate::script_error"
};
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
handle::Handle::notice_message(status, error_msg);
}
}
/// 验证指定脚本文件
#[tauri::command]
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
log::info!(target: "app", "验证脚本文件: {}", file_path);
match CoreManager::global()
.validate_config_file(&file_path, None)
.await
{
Ok(result) => {
handle_script_validation_notice(&result, "脚本文件");
Ok(result.0) // 返回验证结果布尔值
}
Err(e) => {
let error_msg = e.to_string();
log::error!(target: "app", "验证脚本文件过程发生错误: {}", error_msg);
handle::Handle::notice_message("config_validate::process_terminated", &error_msg);
Ok(false)
}
}
}
/// 处理YAML验证相关的所有消息通知
/// 统一通知接口,保持消息类型一致性
pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
if !result.0 {
let error_msg = &result.1;
println!("[通知] 处理{}验证错误: {}", file_type, error_msg);
// 检查是否为merge文件
let is_merge_file = file_type.contains("合并");
// 根据错误消息内容判断错误类型
let status = if error_msg.starts_with("File not found:") {
"config_validate::file_not_found"
} else if error_msg.starts_with("Failed to read file:") {
"config_validate::yaml_read_error"
} else if error_msg.starts_with("YAML syntax error:") {
if is_merge_file {
"config_validate::merge_syntax_error"
} else {
"config_validate::yaml_syntax_error"
}
} else if error_msg.contains("mapping values are not allowed") {
if is_merge_file {
"config_validate::merge_mapping_error"
} else {
"config_validate::yaml_mapping_error"
}
} else if error_msg.contains("did not find expected key") {
if is_merge_file {
"config_validate::merge_key_error"
} else {
"config_validate::yaml_key_error"
}
} else {
// 如果是其他类型错误,根据文件类型作为一般错误处理
if is_merge_file {
"config_validate::merge_error"
} else {
"config_validate::yaml_error"
}
};
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
println!("[通知] 发送通知: status={}, msg={}", status, error_msg);
handle::Handle::notice_message(status, error_msg);
}
}

View File

@ -0,0 +1,16 @@
use super::CmdResult;
use crate::{config::*, feat, wrap_err};
/// 获取Verge配置
#[tauri::command]
pub fn get_verge_config() -> CmdResult<IVergeResponse> {
let verge = Config::verge();
let verge_data = verge.data().clone();
Ok(IVergeResponse::from(verge_data))
}
/// 修改Verge配置
#[tauri::command]
pub async fn patch_verge_config(payload: IVerge) -> CmdResult {
wrap_err!(feat::patch_verge(payload, false).await)
}

View File

@ -0,0 +1,46 @@
use super::CmdResult;
use crate::{config::*, core, feat, wrap_err};
use reqwest_dav::list_cmd::ListFile;
/// 保存 WebDAV 配置
#[tauri::command]
pub async fn save_webdav_config(url: String, username: String, password: String) -> CmdResult<()> {
let patch = IVerge {
webdav_url: Some(url),
webdav_username: Some(username),
webdav_password: Some(password),
..IVerge::default()
};
Config::verge().draft().patch_config(patch.clone());
Config::verge().apply();
Config::verge()
.data()
.save_file()
.map_err(|err| err.to_string())?;
core::backup::WebDavClient::global().reset();
Ok(())
}
/// 创建 WebDAV 备份并上传
#[tauri::command]
pub async fn create_webdav_backup() -> CmdResult<()> {
wrap_err!(feat::create_backup_and_upload_webdav().await)
}
/// 列出 WebDAV 上的备份文件
#[tauri::command]
pub async fn list_webdav_backup() -> CmdResult<Vec<ListFile>> {
wrap_err!(feat::list_wevdav_backup().await)
}
/// 删除 WebDAV 上的备份文件
#[tauri::command]
pub async fn delete_webdav_backup(filename: String) -> CmdResult<()> {
wrap_err!(feat::delete_webdav_backup(filename).await)
}
/// 从 WebDAV 恢复备份文件
#[tauri::command]
pub async fn restore_webdav_backup(filename: String) -> CmdResult<()> {
wrap_err!(feat::restore_webdav_backup(filename).await)
}

View File

@ -1,2 +0,0 @@
pub mod profile;
pub mod some;

View File

@ -1,190 +0,0 @@
use crate::{
config::{ProfileItem, ProfilesConfig},
events::state::{ClashInfoState, ProfileLock},
utils::{
app_home_dir,
clash::put_clash_profile,
config::{read_profiles, save_profiles},
fetch::fetch_profile,
},
};
use std::fs::File;
use std::io::Write;
use std::time::{SystemTime, UNIX_EPOCH};
use tauri::State;
/// Import the profile from url
/// and save to `profiles.yaml`
#[tauri::command]
pub async fn import_profile(url: String, lock: State<'_, ProfileLock>) -> Result<(), String> {
let result = match fetch_profile(&url).await {
Some(r) => r,
None => {
log::error!("failed to fetch profile from `{}`", url);
return Err(format!("failed to fetch profile from `{}`", url));
}
};
// get lock
if lock.0.lock().is_err() {
return Err(format!("can not get file lock"));
}
// save the profile file
let path = app_home_dir().join("profiles").join(&result.file);
let file_data = result.data.as_bytes();
File::create(path).unwrap().write(file_data).unwrap();
// update `profiles.yaml`
let mut profiles = read_profiles();
let mut items = profiles.items.unwrap_or(vec![]);
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
items.push(ProfileItem {
name: Some(result.name),
file: Some(result.file),
mode: Some(format!("rule")),
url: Some(url),
selected: Some(vec![]),
extra: Some(result.extra),
updated: Some(now as usize),
});
profiles.items = Some(items);
save_profiles(&profiles)
}
/// Update the profile
/// and save to `profiles.yaml`
/// http request firstly
/// then acquire the lock of `profiles.yaml`
#[tauri::command]
pub async fn update_profile(index: usize, lock: State<'_, ProfileLock>) -> Result<(), String> {
// get lock
if lock.0.lock().is_err() {
return Err(format!("can not get file lock"));
}
// update `profiles.yaml`
let mut profiles = read_profiles();
let mut items = profiles.items.unwrap_or(vec![]);
if index >= items.len() {
return Err(format!("the index out of bound"));
}
let url = match &items[index].url {
Some(u) => u,
None => return Err(format!("invalid url")),
};
let result = match fetch_profile(&url).await {
Some(r) => r,
None => {
log::error!("failed to fetch profile from `{}`", url);
return Err(format!("failed to fetch profile from `{}`", url));
}
};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as usize;
// update file
let file_path = &items[index].file.as_ref().unwrap();
let file_path = app_home_dir().join("profiles").join(file_path);
let file_data = result.data.as_bytes();
File::create(file_path).unwrap().write(file_data).unwrap();
items[index].name = Some(result.name);
items[index].extra = Some(result.extra);
items[index].updated = Some(now);
profiles.items = Some(items);
save_profiles(&profiles)
}
/// get all profiles from `profiles.yaml`
/// do not acquire the lock of ProfileLock
#[tauri::command]
pub fn get_profiles() -> Result<ProfilesConfig, String> {
Ok(read_profiles())
}
/// patch the profile config
#[tauri::command]
pub fn set_profiles(
index: usize,
profile: ProfileItem,
lock: State<'_, ProfileLock>,
) -> Result<(), String> {
// get lock
if lock.0.lock().is_err() {
return Err(format!("can not get file lock"));
}
let mut profiles = read_profiles();
let mut items = profiles.items.unwrap_or(vec![]);
if index >= items.len() {
return Err(format!("the index out of bound"));
}
if profile.name.is_some() {
items[index].name = profile.name;
}
if profile.file.is_some() {
items[index].file = profile.file;
}
if profile.mode.is_some() {
items[index].mode = profile.mode;
}
if profile.url.is_some() {
items[index].url = profile.url;
}
if profile.selected.is_some() {
items[index].selected = profile.selected;
}
if profile.extra.is_some() {
items[index].extra = profile.extra;
}
profiles.items = Some(items);
save_profiles(&profiles)
}
/// change the current profile
#[tauri::command]
pub async fn put_profiles(
current: usize,
lock: State<'_, ProfileLock>,
clash_info: State<'_, ClashInfoState>,
) -> Result<(), String> {
if lock.0.lock().is_err() {
return Err(format!("can not get file lock"));
}
let clash_info = match clash_info.0.lock() {
Ok(arc) => arc.clone(),
_ => return Err(format!("can not get clash info")),
};
let mut profiles = read_profiles();
let items_len = match &profiles.items {
Some(list) => list.len(),
None => 0,
};
if current >= items_len {
return Err(format!("the index out of bound"));
}
profiles.current = Some(current);
match save_profiles(&profiles) {
Ok(_) => put_clash_profile(&clash_info).await,
Err(err) => Err(err),
}
}

View File

@ -1,154 +0,0 @@
use crate::{
config::VergeConfig,
events::{
emit::ClashInfoPayload,
state::{ClashInfoState, VergeConfLock},
},
utils::{
clash::run_clash_bin,
config::{read_clash, save_clash, save_verge},
sysopt::{get_proxy_config, set_proxy_config, SysProxyConfig, DEFAULT_BYPASS},
},
};
use serde_yaml::Mapping;
use tauri::{api::process::kill_children, AppHandle, State};
/// restart the sidecar
#[tauri::command]
pub fn restart_sidecar(app_handle: AppHandle, clash_info: State<'_, ClashInfoState>) {
kill_children();
let payload = run_clash_bin(&app_handle);
if let Ok(mut arc) = clash_info.0.lock() {
*arc = payload;
}
}
/// get the clash core info from the state
/// the caller can also get the infomation by clash's api
#[tauri::command]
pub fn get_clash_info(clash_info: State<'_, ClashInfoState>) -> Result<ClashInfoPayload, String> {
match clash_info.0.lock() {
Ok(arc) => Ok(arc.clone()),
Err(_) => Err(format!("can not get clash info")),
}
}
/// update the clash core config
/// after putting the change to the clash core
/// then we should save the latest config
#[tauri::command]
pub fn patch_clash_config(payload: Mapping) -> Result<(), String> {
let mut config = read_clash();
for (key, value) in payload.iter() {
if config.contains_key(key) {
config[key] = value.clone();
} else {
config.insert(key.clone(), value.clone());
}
}
save_clash(&config)
}
/// set the system proxy
/// Tips: only support windows now
#[tauri::command]
pub fn set_sys_proxy(
enable: bool,
clash_info: State<'_, ClashInfoState>,
verge_lock: State<'_, VergeConfLock>,
) -> Result<(), String> {
let clash_info = match clash_info.0.lock() {
Ok(arc) => arc.clone(),
_ => return Err(format!("can not get clash info")),
};
let verge_info = match verge_lock.0.lock() {
Ok(arc) => arc.clone(),
_ => return Err(format!("can not get verge info")),
};
let port = match clash_info.controller {
Some(ctrl) => ctrl.port,
None => None,
};
if port.is_none() {
return Err(format!("can not get clash core's port"));
}
let config = if enable {
let server = format!("127.0.0.1:{}", port.unwrap());
let bypass = verge_info
.system_proxy_bypass
.unwrap_or(String::from(DEFAULT_BYPASS));
SysProxyConfig {
enable,
server,
bypass,
}
} else {
SysProxyConfig {
enable,
server: String::from(""),
bypass: String::from(""),
}
};
match set_proxy_config(&config) {
Ok(_) => Ok(()),
Err(_) => Err(format!("can not set proxy")),
}
}
/// get the system proxy
/// Tips: only support windows now
#[tauri::command]
pub fn get_sys_proxy() -> Result<SysProxyConfig, String> {
match get_proxy_config() {
Ok(value) => Ok(value),
Err(err) => Err(err.to_string()),
}
}
/// get the verge config
#[tauri::command]
pub fn get_verge_config(verge_lock: State<'_, VergeConfLock>) -> Result<VergeConfig, String> {
match verge_lock.0.lock() {
Ok(arc) => Ok(arc.clone()),
Err(_) => Err(format!("can not get the lock")),
}
}
/// patch the verge config
/// this command only save the config and not responsible for other things
#[tauri::command]
pub async fn patch_verge_config(
payload: VergeConfig,
verge_lock: State<'_, VergeConfLock>,
) -> Result<(), String> {
let mut verge = match verge_lock.0.lock() {
Ok(v) => v,
Err(_) => return Err(format!("can not get the lock")),
};
if payload.theme_mode.is_some() {
verge.theme_mode = payload.theme_mode;
}
// todo
if payload.enable_self_startup.is_some() {
verge.enable_self_startup = payload.enable_self_startup;
}
// todo
if payload.enable_system_proxy.is_some() {
verge.enable_system_proxy = payload.enable_system_proxy;
}
if payload.system_proxy_bypass.is_some() {
verge.system_proxy_bypass = payload.system_proxy_bypass;
}
save_verge(&verge)
}

View File

@ -1,30 +1,367 @@
use crate::utils::{dirs, help};
use anyhow::Result;
use serde::{Deserialize, Serialize};
use serde_yaml::{Mapping, Value};
use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
str::FromStr,
};
/// ### `config.yaml` schema
/// here should contain all configuration options.
/// See: https://github.com/Dreamacro/clash/wiki/configuration for details
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ClashConfig {
pub port: Option<u32>,
#[derive(Default, Debug, Clone)]
pub struct IClashTemp(pub Mapping);
/// alias to `mixed-port`
pub mixed_port: Option<u32>,
/// alias to `allow-lan`
pub allow_lan: Option<bool>,
/// alias to `external-controller`
pub external_ctrl: Option<String>,
pub secret: Option<String>,
impl IClashTemp {
pub fn new() -> Self {
let template = Self::template();
match dirs::clash_path().and_then(|path| help::read_mapping(&path)) {
Ok(mut map) => {
template.0.keys().for_each(|key| {
if !map.contains_key(key) {
map.insert(key.clone(), template.0.get(key).unwrap().clone());
}
});
Self(Self::guard(map))
}
Err(err) => {
log::error!(target: "app", "{err}");
template
}
}
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ClashController {
pub fn template() -> Self {
let mut map = Mapping::new();
let mut tun = Mapping::new();
tun.insert("enable".into(), false.into());
tun.insert("stack".into(), "gvisor".into());
tun.insert("auto-route".into(), true.into());
tun.insert("strict-route".into(), false.into());
tun.insert("auto-detect-interface".into(), true.into());
tun.insert("dns-hijack".into(), vec!["any:53"].into());
#[cfg(not(target_os = "windows"))]
map.insert("redir-port".into(), 7895.into());
#[cfg(target_os = "linux")]
map.insert("tproxy-port".into(), 7896.into());
map.insert("mixed-port".into(), 7897.into());
map.insert("socks-port".into(), 7898.into());
map.insert("port".into(), 7899.into());
map.insert("log-level".into(), "info".into());
map.insert("allow-lan".into(), false.into());
map.insert("mode".into(), "rule".into());
map.insert("external-controller".into(), "127.0.0.1:9097".into());
let mut cors_map = Mapping::new();
cors_map.insert("allow-private-network".into(), true.into());
cors_map.insert("allow-origins".into(), vec!["*"].into());
map.insert("secret".into(), "".into());
map.insert("tun".into(), tun.into());
map.insert("external-controller-cors".into(), cors_map.into());
map.insert("unified-delay".into(), true.into());
Self(map)
}
fn guard(mut config: Mapping) -> Mapping {
#[cfg(not(target_os = "windows"))]
let redir_port = Self::guard_redir_port(&config);
#[cfg(target_os = "linux")]
let tproxy_port = Self::guard_tproxy_port(&config);
let mixed_port = Self::guard_mixed_port(&config);
let socks_port = Self::guard_socks_port(&config);
let port = Self::guard_port(&config);
let ctrl = Self::guard_server_ctrl(&config);
#[cfg(not(target_os = "windows"))]
config.insert("redir-port".into(), redir_port.into());
#[cfg(target_os = "linux")]
config.insert("tproxy-port".into(), tproxy_port.into());
config.insert("mixed-port".into(), mixed_port.into());
config.insert("socks-port".into(), socks_port.into());
config.insert("port".into(), port.into());
config.insert("external-controller".into(), ctrl.into());
config
}
pub fn patch_config(&mut self, patch: Mapping) {
for (key, value) in patch.into_iter() {
self.0.insert(key, value);
}
}
pub fn save_config(&self) -> Result<()> {
help::save_yaml(
&dirs::clash_path()?,
&self.0,
Some("# Generated by Clash Verge"),
)
}
pub fn get_mixed_port(&self) -> u16 {
Self::guard_mixed_port(&self.0)
}
#[allow(unused)]
pub fn get_socks_port(&self) -> u16 {
Self::guard_socks_port(&self.0)
}
#[allow(unused)]
pub fn get_port(&self) -> u16 {
Self::guard_port(&self.0)
}
pub fn get_client_info(&self) -> ClashInfo {
let config = &self.0;
ClashInfo {
mixed_port: Self::guard_mixed_port(config),
socks_port: Self::guard_socks_port(config),
port: Self::guard_port(config),
server: Self::guard_client_ctrl(config),
secret: config.get("secret").and_then(|value| match value {
Value::String(val_str) => Some(val_str.clone()),
Value::Bool(val_bool) => Some(val_bool.to_string()),
Value::Number(val_num) => Some(val_num.to_string()),
_ => None,
}),
}
}
#[cfg(not(target_os = "windows"))]
pub fn guard_redir_port(config: &Mapping) -> u16 {
let mut port = config
.get("redir-port")
.and_then(|value| match value {
Value::String(val_str) => val_str.parse().ok(),
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
_ => None,
})
.unwrap_or(7895);
if port == 0 {
port = 7895;
}
port
}
#[cfg(target_os = "linux")]
pub fn guard_tproxy_port(config: &Mapping) -> u16 {
let mut port = config
.get("tproxy-port")
.and_then(|value| match value {
Value::String(val_str) => val_str.parse().ok(),
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
_ => None,
})
.unwrap_or(7896);
if port == 0 {
port = 7896;
}
port
}
pub fn guard_mixed_port(config: &Mapping) -> u16 {
let raw_value = config.get("mixed-port");
let mut port = raw_value
.and_then(|value| match value {
Value::String(val_str) => val_str.parse().ok(),
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
_ => None,
})
.unwrap_or(7897);
if port == 0 {
port = 7897;
}
port
}
pub fn guard_socks_port(config: &Mapping) -> u16 {
let mut port = config
.get("socks-port")
.and_then(|value| match value {
Value::String(val_str) => val_str.parse().ok(),
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
_ => None,
})
.unwrap_or(7898);
if port == 0 {
port = 7898;
}
port
}
pub fn guard_port(config: &Mapping) -> u16 {
let mut port = config
.get("port")
.and_then(|value| match value {
Value::String(val_str) => val_str.parse().ok(),
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
_ => None,
})
.unwrap_or(7899);
if port == 0 {
port = 7899;
}
port
}
pub fn guard_server_ctrl(config: &Mapping) -> String {
config
.get("external-controller")
.and_then(|value| match value.as_str() {
Some(val_str) => {
let val_str = val_str.trim();
let val = match val_str.starts_with(':') {
true => format!("127.0.0.1{val_str}"),
false => val_str.to_owned(),
};
SocketAddr::from_str(val.as_str())
.ok()
.map(|s| s.to_string())
}
None => None,
})
.unwrap_or("127.0.0.1:9097".into())
}
pub fn guard_client_ctrl(config: &Mapping) -> String {
let value = Self::guard_server_ctrl(config);
match SocketAddr::from_str(value.as_str()) {
Ok(mut socket) => {
if socket.ip().is_unspecified() {
socket.set_ip(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
}
socket.to_string()
}
Err(_) => "127.0.0.1:9097".into(),
}
}
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ClashInfo {
/// clash core port
pub port: Option<String>,
pub mixed_port: u16,
pub socks_port: u16,
pub port: u16,
/// same as `external-controller`
pub server: Option<String>,
pub server: String,
/// clash secret
pub secret: Option<String>,
}
#[test]
fn test_clash_info() {
fn get_case<T: Into<Value>, D: Into<Value>>(mp: T, ec: D) -> ClashInfo {
let mut map = Mapping::new();
map.insert("mixed-port".into(), mp.into());
map.insert("external-controller".into(), ec.into());
IClashTemp(IClashTemp::guard(map)).get_client_info()
}
fn get_result<S: Into<String>>(port: u16, server: S) -> ClashInfo {
ClashInfo {
mixed_port: port,
socks_port: 7898,
port: 7899,
server: server.into(),
secret: None,
}
}
assert_eq!(
IClashTemp(IClashTemp::guard(Mapping::new())).get_client_info(),
get_result(7897, "127.0.0.1:9097")
);
assert_eq!(get_case("", ""), get_result(7897, "127.0.0.1:9097"));
assert_eq!(get_case(65537, ""), get_result(1, "127.0.0.1:9097"));
assert_eq!(
get_case(8888, "127.0.0.1:8888"),
get_result(8888, "127.0.0.1:8888")
);
assert_eq!(
get_case(8888, " :98888 "),
get_result(8888, "127.0.0.1:9097")
);
assert_eq!(
get_case(8888, "0.0.0.0:8080 "),
get_result(8888, "127.0.0.1:8080")
);
assert_eq!(
get_case(8888, "0.0.0.0:8080"),
get_result(8888, "127.0.0.1:8080")
);
assert_eq!(
get_case(8888, "[::]:8080"),
get_result(8888, "127.0.0.1:8080")
);
assert_eq!(
get_case(8888, "192.168.1.1:8080"),
get_result(8888, "192.168.1.1:8080")
);
assert_eq!(
get_case(8888, "192.168.1.1:80800"),
get_result(8888, "127.0.0.1:9097")
);
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct IClash {
pub mixed_port: Option<u16>,
pub allow_lan: Option<bool>,
pub log_level: Option<String>,
pub ipv6: Option<bool>,
pub mode: Option<String>,
pub external_controller: Option<String>,
pub secret: Option<String>,
pub dns: Option<IClashDNS>,
pub tun: Option<IClashTUN>,
pub interface_name: Option<String>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct IClashTUN {
pub enable: Option<bool>,
pub stack: Option<String>,
pub auto_route: Option<bool>,
pub auto_detect_interface: Option<bool>,
pub dns_hijack: Option<Vec<String>>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct IClashDNS {
pub enable: Option<bool>,
pub listen: Option<String>,
pub default_nameserver: Option<Vec<String>>,
pub enhanced_mode: Option<String>,
pub fake_ip_range: Option<String>,
pub use_hosts: Option<bool>,
pub fake_ip_filter: Option<Vec<String>>,
pub nameserver: Option<Vec<String>>,
pub fallback: Option<Vec<String>>,
pub fallback_filter: Option<IClashFallbackFilter>,
pub nameserver_policy: Option<Vec<String>>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct IClashFallbackFilter {
pub geoip: Option<bool>,
pub geoip_code: Option<String>,
pub ipcidr: Option<Vec<String>>,
pub domain: Option<Vec<String>>,
}

View File

@ -0,0 +1,159 @@
use super::{Draft, IClashTemp, IProfiles, IRuntime, IVerge};
use crate::{
config::PrfItem,
core::{handle, CoreManager},
enhance,
utils::{dirs, help},
};
use anyhow::{anyhow, Result};
use once_cell::sync::OnceCell;
use std::path::PathBuf;
use tokio::time::{sleep, Duration};
pub const RUNTIME_CONFIG: &str = "clash-verge.yaml";
pub const CHECK_CONFIG: &str = "clash-verge-check.yaml";
pub struct Config {
clash_config: Draft<IClashTemp>,
verge_config: Draft<IVerge>,
profiles_config: Draft<IProfiles>,
runtime_config: Draft<IRuntime>,
}
impl Config {
pub fn global() -> &'static Config {
static CONFIG: OnceCell<Config> = OnceCell::new();
CONFIG.get_or_init(|| Config {
clash_config: Draft::from(IClashTemp::new()),
verge_config: Draft::from(IVerge::new()),
profiles_config: Draft::from(IProfiles::new()),
runtime_config: Draft::from(IRuntime::new()),
})
}
pub fn clash() -> Draft<IClashTemp> {
Self::global().clash_config.clone()
}
pub fn verge() -> Draft<IVerge> {
Self::global().verge_config.clone()
}
pub fn profiles() -> Draft<IProfiles> {
Self::global().profiles_config.clone()
}
pub fn runtime() -> Draft<IRuntime> {
Self::global().runtime_config.clone()
}
/// 初始化订阅
pub async fn init_config() -> Result<()> {
if Self::profiles()
.data()
.get_item(&"Merge".to_string())
.is_err()
{
let merge_item = PrfItem::from_merge(Some("Merge".to_string()))?;
Self::profiles().data().append_item(merge_item.clone())?;
}
if Self::profiles()
.data()
.get_item(&"Script".to_string())
.is_err()
{
let script_item = PrfItem::from_script(Some("Script".to_string()))?;
Self::profiles().data().append_item(script_item.clone())?;
}
// 生成运行时配置
crate::log_err!(Self::generate().await);
// 生成运行时配置文件并验证
let config_result = Self::generate_file(ConfigType::Run);
let validation_result = if config_result.is_ok() {
// 验证配置文件
println!("[首次启动] 开始验证配置");
match CoreManager::global().validate_config().await {
Ok((is_valid, error_msg)) => {
if !is_valid {
println!(
"[首次启动] 配置验证失败,使用默认最小配置启动: {}",
error_msg
);
CoreManager::global()
.use_default_config("config_validate::boot_error", &error_msg)
.await?;
Some(("config_validate::boot_error", error_msg))
} else {
println!("[首次启动] 配置验证成功");
Some(("config_validate::success", String::new()))
}
}
Err(err) => {
println!("[首次启动] 验证进程执行失败: {}", err);
CoreManager::global()
.use_default_config("config_validate::process_terminated", "")
.await?;
Some(("config_validate::process_terminated", String::new()))
}
}
} else {
println!("[首次启动] 生成配置文件失败,使用默认配置");
CoreManager::global()
.use_default_config("config_validate::error", "")
.await?;
Some(("config_validate::error", String::new()))
};
// 在单独的任务中发送通知
if let Some((msg_type, msg_content)) = validation_result {
tauri::async_runtime::spawn(async move {
sleep(Duration::from_secs(2)).await;
handle::Handle::notice_message(msg_type, &msg_content);
});
}
Ok(())
}
/// 将订阅丢到对应的文件中
pub fn generate_file(typ: ConfigType) -> Result<PathBuf> {
let path = match typ {
ConfigType::Run => dirs::app_home_dir()?.join(RUNTIME_CONFIG),
ConfigType::Check => dirs::app_home_dir()?.join(CHECK_CONFIG),
};
let runtime = Config::runtime();
let runtime = runtime.latest();
let config = runtime
.config
.as_ref()
.ok_or(anyhow!("failed to get runtime config"))?;
help::save_yaml(&path, &config, Some("# Generated by Clash Verge"))?;
Ok(path)
}
/// 生成订阅存好
pub async fn generate() -> Result<()> {
let (config, exists_keys, logs) = enhance::enhance().await;
*Config::runtime().draft() = IRuntime {
config: Some(config),
exists_keys,
chain_logs: logs,
};
Ok(())
}
}
#[derive(Debug)]
pub enum ConfigType {
Run,
Check,
}

View File

@ -0,0 +1,127 @@
use super::{IClashTemp, IProfiles, IRuntime, IVerge};
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct Draft<T: Clone + ToOwned> {
inner: Arc<Mutex<(T, Option<T>)>>,
}
macro_rules! draft_define {
($id: ident) => {
impl Draft<$id> {
#[allow(unused)]
pub fn data(&self) -> MappedMutexGuard<$id> {
MutexGuard::map(self.inner.lock(), |guard| &mut guard.0)
}
pub fn latest(&self) -> MappedMutexGuard<$id> {
MutexGuard::map(self.inner.lock(), |inner| {
if inner.1.is_none() {
&mut inner.0
} else {
inner.1.as_mut().unwrap()
}
})
}
pub fn draft(&self) -> MappedMutexGuard<$id> {
MutexGuard::map(self.inner.lock(), |inner| {
if inner.1.is_none() {
inner.1 = Some(inner.0.clone());
}
inner.1.as_mut().unwrap()
})
}
pub fn apply(&self) -> Option<$id> {
let mut inner = self.inner.lock();
match inner.1.take() {
Some(draft) => {
let old_value = inner.0.to_owned();
inner.0 = draft.to_owned();
Some(old_value)
}
None => None,
}
}
pub fn discard(&self) -> Option<$id> {
let mut inner = self.inner.lock();
inner.1.take()
}
}
impl From<$id> for Draft<$id> {
fn from(data: $id) -> Self {
Draft {
inner: Arc::new(Mutex::new((data, None))),
}
}
}
};
}
// draft_define!(IClash);
draft_define!(IClashTemp);
draft_define!(IProfiles);
draft_define!(IRuntime);
draft_define!(IVerge);
#[test]
fn test_draft() {
let verge = IVerge {
enable_auto_launch: Some(true),
enable_tun_mode: Some(false),
..IVerge::default()
};
let draft = Draft::from(verge);
assert_eq!(draft.data().enable_auto_launch, Some(true));
assert_eq!(draft.data().enable_tun_mode, Some(false));
assert_eq!(draft.draft().enable_auto_launch, Some(true));
assert_eq!(draft.draft().enable_tun_mode, Some(false));
let mut d = draft.draft();
d.enable_auto_launch = Some(false);
d.enable_tun_mode = Some(true);
drop(d);
assert_eq!(draft.data().enable_auto_launch, Some(true));
assert_eq!(draft.data().enable_tun_mode, Some(false));
assert_eq!(draft.draft().enable_auto_launch, Some(false));
assert_eq!(draft.draft().enable_tun_mode, Some(true));
assert_eq!(draft.latest().enable_auto_launch, Some(false));
assert_eq!(draft.latest().enable_tun_mode, Some(true));
assert!(draft.apply().is_some());
assert!(draft.apply().is_none());
assert_eq!(draft.data().enable_auto_launch, Some(false));
assert_eq!(draft.data().enable_tun_mode, Some(true));
assert_eq!(draft.draft().enable_auto_launch, Some(false));
assert_eq!(draft.draft().enable_tun_mode, Some(true));
let mut d = draft.draft();
d.enable_auto_launch = Some(true);
drop(d);
assert_eq!(draft.data().enable_auto_launch, Some(false));
assert_eq!(draft.draft().enable_auto_launch, Some(true));
assert!(draft.discard().is_some());
assert_eq!(draft.data().enable_auto_launch, Some(false));
assert!(draft.discard().is_none());
assert_eq!(draft.draft().enable_auto_launch, Some(false));
}

View File

@ -0,0 +1,95 @@
use crate::utils::dirs::get_encryption_key;
use aes_gcm::{
aead::{Aead, KeyInit},
Aes256Gcm, Key,
};
use base64::{engine::general_purpose::STANDARD, Engine};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
const NONCE_LENGTH: usize = 12;
/// Encrypt data
pub fn encrypt_data(data: &str) -> Result<String, Box<dyn std::error::Error>> {
let encryption_key = get_encryption_key()?;
let key = Key::<Aes256Gcm>::from_slice(&encryption_key);
let cipher = Aes256Gcm::new(key);
// Generate random nonce
let mut nonce = vec![0u8; NONCE_LENGTH];
getrandom::fill(&mut nonce)?;
// Encrypt data
let ciphertext = cipher
.encrypt(nonce.as_slice().into(), data.as_bytes())
.map_err(|e| format!("Encryption failed: {}", e))?;
// Concatenate nonce and ciphertext and encode them in base64
let mut combined = nonce;
combined.extend(ciphertext);
Ok(STANDARD.encode(combined))
}
/// Decrypt data
pub fn decrypt_data(encrypted: &str) -> Result<String, Box<dyn std::error::Error>> {
let encryption_key = get_encryption_key()?;
let key = Key::<Aes256Gcm>::from_slice(&encryption_key);
let cipher = Aes256Gcm::new(key);
// Decode from base64
let data = STANDARD.decode(encrypted)?;
if data.len() < NONCE_LENGTH {
return Err("Invalid encrypted data".into());
}
// Separate nonce and ciphertext
let (nonce, ciphertext) = data.split_at(NONCE_LENGTH);
// Decrypt data
let plaintext = cipher
.decrypt(nonce.into(), ciphertext)
.map_err(|e| format!("Decryption failed: {}", e))?;
String::from_utf8(plaintext).map_err(|e| e.into())
}
/// Serialize encrypted function
pub fn serialize_encrypted<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: Serialize,
S: Serializer,
{
// 如果序列化失败,返回 None
let json = match serde_json::to_string(value) {
Ok(j) => j,
Err(_) => return serializer.serialize_none(),
};
// 如果加密失败,返回 None
match encrypt_data(&json) {
Ok(encrypted) => serializer.serialize_str(&encrypted),
Err(_) => serializer.serialize_none(),
}
}
/// Deserialize decrypted function
pub fn deserialize_encrypted<'a, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: for<'de> Deserialize<'de> + Default,
D: Deserializer<'a>,
{
// 如果反序列化字符串失败,返回默认值
let encrypted = match String::deserialize(deserializer) {
Ok(s) => s,
Err(_) => return Ok(T::default()),
};
// 如果解密失败,返回默认值
let decrypted_string = match decrypt_data(&encrypted) {
Ok(data) => data,
Err(_) => return Ok(T::default()),
};
// 如果 JSON 解析失败,返回默认值
match serde_json::from_str(&decrypted_string) {
Ok(value) => Ok(value),
Err(_) => Ok(T::default()),
}
}

View File

@ -1,7 +1,18 @@
mod clash;
#[allow(clippy::module_inception)]
mod config;
mod draft;
mod encrypt;
mod prfitem;
mod profiles;
mod runtime;
mod verge;
pub use self::clash::*;
pub use self::profiles::*;
pub use self::verge::*;
pub use self::{
clash::*, config::*, draft::*, encrypt::*, prfitem::*, profiles::*, runtime::*, verge::*,
};
pub const DEFAULT_PAC: &str = r#"function FindProxyForURL(url, host) {
return "PROXY 127.0.0.1:%mixed-port%; SOCKS5 127.0.0.1:%mixed-port%; DIRECT;";
}
"#;

View File

@ -0,0 +1,564 @@
use crate::utils::{dirs, help, resolve::VERSION, tmpl};
use anyhow::{bail, Context, Result};
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::fs;
use sysproxy::Sysproxy;
use super::Config;
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct PrfItem {
pub uid: Option<String>,
/// profile item type
/// enum value: remote | local | script | merge
#[serde(rename = "type")]
pub itype: Option<String>,
/// profile name
pub name: Option<String>,
/// profile file
pub file: Option<String>,
/// profile description
#[serde(skip_serializing_if = "Option::is_none")]
pub desc: Option<String>,
/// source url
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
/// selected information
#[serde(skip_serializing_if = "Option::is_none")]
pub selected: Option<Vec<PrfSelected>>,
/// subscription user info
#[serde(skip_serializing_if = "Option::is_none")]
pub extra: Option<PrfExtra>,
/// updated time
pub updated: Option<usize>,
/// some options of the item
#[serde(skip_serializing_if = "Option::is_none")]
pub option: Option<PrfOption>,
/// profile web page url
#[serde(skip_serializing_if = "Option::is_none")]
pub home: Option<String>,
/// the file data
#[serde(skip)]
pub file_data: Option<String>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct PrfSelected {
pub name: Option<String>,
pub now: Option<String>,
}
#[derive(Default, Debug, Clone, Copy, Deserialize, Serialize)]
pub struct PrfExtra {
pub upload: u64,
pub download: u64,
pub total: u64,
pub expire: u64,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct PrfOption {
/// for `remote` profile's http request
/// see issue #13
#[serde(skip_serializing_if = "Option::is_none")]
pub user_agent: Option<String>,
/// for `remote` profile
/// use system proxy
#[serde(skip_serializing_if = "Option::is_none")]
pub with_proxy: Option<bool>,
/// for `remote` profile
/// use self proxy
#[serde(skip_serializing_if = "Option::is_none")]
pub self_proxy: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub update_interval: Option<u64>,
/// for `remote` profile
/// disable certificate validation
/// default is `false`
#[serde(skip_serializing_if = "Option::is_none")]
pub danger_accept_invalid_certs: Option<bool>,
pub merge: Option<String>,
pub script: Option<String>,
pub rules: Option<String>,
pub proxies: Option<String>,
pub groups: Option<String>,
}
impl PrfOption {
pub fn merge(one: Option<Self>, other: Option<Self>) -> Option<Self> {
match (one, other) {
(Some(mut a), Some(b)) => {
a.user_agent = b.user_agent.or(a.user_agent);
a.with_proxy = b.with_proxy.or(a.with_proxy);
a.self_proxy = b.self_proxy.or(a.self_proxy);
a.danger_accept_invalid_certs = b
.danger_accept_invalid_certs
.or(a.danger_accept_invalid_certs);
a.update_interval = b.update_interval.or(a.update_interval);
a.merge = b.merge.or(a.merge);
a.script = b.script.or(a.script);
a.rules = b.rules.or(a.rules);
a.proxies = b.proxies.or(a.proxies);
a.groups = b.groups.or(a.groups);
Some(a)
}
t => t.0.or(t.1),
}
}
}
impl PrfItem {
/// From partial item
/// must contain `itype`
pub async fn from(item: PrfItem, file_data: Option<String>) -> Result<PrfItem> {
if item.itype.is_none() {
bail!("type should not be null");
}
match item.itype.unwrap().as_str() {
"remote" => {
if item.url.is_none() {
bail!("url should not be null");
}
let url = item.url.as_ref().unwrap().as_str();
let name = item.name;
let desc = item.desc;
PrfItem::from_url(url, name, desc, item.option).await
}
"local" => {
let name = item.name.unwrap_or("Local File".into());
let desc = item.desc.unwrap_or("".into());
PrfItem::from_local(name, desc, file_data, item.option)
}
typ => bail!("invalid profile item type \"{typ}\""),
}
}
/// ## Local type
/// create a new item from name/desc
pub fn from_local(
name: String,
desc: String,
file_data: Option<String>,
option: Option<PrfOption>,
) -> Result<PrfItem> {
let uid = help::get_uid("L");
let file = format!("{uid}.yaml");
let opt_ref = option.as_ref();
let update_interval = opt_ref.and_then(|o| o.update_interval);
let mut merge = opt_ref.and_then(|o| o.merge.clone());
let mut script = opt_ref.and_then(|o| o.script.clone());
let mut rules = opt_ref.and_then(|o| o.rules.clone());
let mut proxies = opt_ref.and_then(|o| o.proxies.clone());
let mut groups = opt_ref.and_then(|o| o.groups.clone());
if merge.is_none() {
let merge_item = PrfItem::from_merge(None)?;
Config::profiles().data().append_item(merge_item.clone())?;
merge = merge_item.uid;
}
if script.is_none() {
let script_item = PrfItem::from_script(None)?;
Config::profiles().data().append_item(script_item.clone())?;
script = script_item.uid;
}
if rules.is_none() {
let rules_item = PrfItem::from_rules()?;
Config::profiles().data().append_item(rules_item.clone())?;
rules = rules_item.uid;
}
if proxies.is_none() {
let proxies_item = PrfItem::from_proxies()?;
Config::profiles()
.data()
.append_item(proxies_item.clone())?;
proxies = proxies_item.uid;
}
if groups.is_none() {
let groups_item = PrfItem::from_groups()?;
Config::profiles().data().append_item(groups_item.clone())?;
groups = groups_item.uid;
}
Ok(PrfItem {
uid: Some(uid),
itype: Some("local".into()),
name: Some(name),
desc: Some(desc),
file: Some(file),
url: None,
selected: None,
extra: None,
option: Some(PrfOption {
update_interval,
merge,
script,
rules,
proxies,
groups,
..PrfOption::default()
}),
home: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(file_data.unwrap_or(tmpl::ITEM_LOCAL.into())),
})
}
/// ## Remote type
/// create a new item from url
pub async fn from_url(
url: &str,
name: Option<String>,
desc: Option<String>,
option: Option<PrfOption>,
) -> Result<PrfItem> {
let opt_ref = option.as_ref();
let with_proxy = opt_ref.is_some_and(|o| o.with_proxy.unwrap_or(false));
let self_proxy = opt_ref.is_some_and(|o| o.self_proxy.unwrap_or(false));
let accept_invalid_certs =
opt_ref.is_some_and(|o| o.danger_accept_invalid_certs.unwrap_or(false));
let user_agent = opt_ref.and_then(|o| o.user_agent.clone());
let update_interval = opt_ref.and_then(|o| o.update_interval);
let mut merge = opt_ref.and_then(|o| o.merge.clone());
let mut script = opt_ref.and_then(|o| o.script.clone());
let mut rules = opt_ref.and_then(|o| o.rules.clone());
let mut proxies = opt_ref.and_then(|o| o.proxies.clone());
let mut groups = opt_ref.and_then(|o| o.groups.clone());
let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy();
// 使用软件自己的代理
if self_proxy {
let port = Config::verge()
.latest()
.verge_mixed_port
.unwrap_or(Config::clash().data().get_mixed_port());
let proxy_scheme = format!("http://127.0.0.1:{port}");
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
builder = builder.proxy(proxy);
}
if let Ok(proxy) = reqwest::Proxy::https(&proxy_scheme) {
builder = builder.proxy(proxy);
}
if let Ok(proxy) = reqwest::Proxy::all(&proxy_scheme) {
builder = builder.proxy(proxy);
}
}
// 使用系统代理
else if with_proxy {
if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() {
let proxy_scheme = format!("http://{}:{}", p.host, p.port);
if let Ok(proxy) = reqwest::Proxy::http(&proxy_scheme) {
builder = builder.proxy(proxy);
}
if let Ok(proxy) = reqwest::Proxy::https(&proxy_scheme) {
builder = builder.proxy(proxy);
}
if let Ok(proxy) = reqwest::Proxy::all(&proxy_scheme) {
builder = builder.proxy(proxy);
}
}
}
let version = match VERSION.get() {
Some(v) => format!("clash-verge/v{}", v),
None => "clash-verge/unknown".to_string(),
};
builder = builder.danger_accept_invalid_certs(accept_invalid_certs);
builder = builder.user_agent(user_agent.unwrap_or(version));
let resp = builder.build()?.get(url).send().await?;
let status_code = resp.status();
if !StatusCode::is_success(&status_code) {
bail!("failed to fetch remote profile with status {status_code}")
}
let header = resp.headers();
// parse the Subscription UserInfo
let extra = match header.get("Subscription-Userinfo") {
Some(value) => {
let sub_info = value.to_str().unwrap_or("");
Some(PrfExtra {
upload: help::parse_str(sub_info, "upload").unwrap_or(0),
download: help::parse_str(sub_info, "download").unwrap_or(0),
total: help::parse_str(sub_info, "total").unwrap_or(0),
expire: help::parse_str(sub_info, "expire").unwrap_or(0),
})
}
None => None,
};
// parse the Content-Disposition
let filename = match header.get("Content-Disposition") {
Some(value) => {
let filename = format!("{value:?}");
let filename = filename.trim_matches('"');
match help::parse_str::<String>(filename, "filename*") {
Some(filename) => {
let iter = percent_encoding::percent_decode(filename.as_bytes());
let filename = iter.decode_utf8().unwrap_or_default();
filename.split("''").last().map(|s| s.to_string())
}
None => match help::parse_str::<String>(filename, "filename") {
Some(filename) => {
let filename = filename.trim_matches('"');
Some(filename.to_string())
}
None => None,
},
}
}
None => Some(
crate::utils::help::get_last_part_and_decode(url).unwrap_or("Remote File".into()),
),
};
let update_interval = match update_interval {
Some(val) => Some(val),
None => match header.get("profile-update-interval") {
Some(value) => match value.to_str().unwrap_or("").parse::<u64>() {
Ok(val) => Some(val * 60), // hour -> min
Err(_) => None,
},
None => None,
},
};
let home = match header.get("profile-web-page-url") {
Some(value) => {
let str_value = value.to_str().unwrap_or("");
Some(str_value.to_string())
}
None => None,
};
let uid = help::get_uid("R");
let file = format!("{uid}.yaml");
let name = name.unwrap_or(filename.unwrap_or("Remote File".into()));
let data = resp.text_with_charset("utf-8").await?;
// process the charset "UTF-8 with BOM"
let data = data.trim_start_matches('\u{feff}');
// check the data whether the valid yaml format
let yaml = serde_yaml::from_str::<Mapping>(data)
.context("the remote profile data is invalid yaml")?;
if !yaml.contains_key("proxies") && !yaml.contains_key("proxy-providers") {
bail!("profile does not contain `proxies` or `proxy-providers`");
}
if merge.is_none() {
let merge_item = PrfItem::from_merge(None)?;
Config::profiles().data().append_item(merge_item.clone())?;
merge = merge_item.uid;
}
if script.is_none() {
let script_item = PrfItem::from_script(None)?;
Config::profiles().data().append_item(script_item.clone())?;
script = script_item.uid;
}
if rules.is_none() {
let rules_item = PrfItem::from_rules()?;
Config::profiles().data().append_item(rules_item.clone())?;
rules = rules_item.uid;
}
if proxies.is_none() {
let proxies_item = PrfItem::from_proxies()?;
Config::profiles()
.data()
.append_item(proxies_item.clone())?;
proxies = proxies_item.uid;
}
if groups.is_none() {
let groups_item = PrfItem::from_groups()?;
Config::profiles().data().append_item(groups_item.clone())?;
groups = groups_item.uid;
}
Ok(PrfItem {
uid: Some(uid),
itype: Some("remote".into()),
name: Some(name),
desc,
file: Some(file),
url: Some(url.into()),
selected: None,
extra,
option: Some(PrfOption {
update_interval,
merge,
script,
rules,
proxies,
groups,
..PrfOption::default()
}),
home,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(data.into()),
})
}
/// ## Merge type (enhance)
/// create the enhanced item by using `merge` rule
pub fn from_merge(uid: Option<String>) -> Result<PrfItem> {
let mut id = help::get_uid("m");
let mut template = tmpl::ITEM_MERGE_EMPTY.into();
if let Some(uid) = uid {
id = uid;
template = tmpl::ITEM_MERGE.into();
}
let file = format!("{id}.yaml");
Ok(PrfItem {
uid: Some(id),
itype: Some("merge".into()),
name: None,
desc: None,
file: Some(file),
url: None,
selected: None,
extra: None,
option: None,
home: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(template),
})
}
/// ## Script type (enhance)
/// create the enhanced item by using javascript quick.js
pub fn from_script(uid: Option<String>) -> Result<PrfItem> {
let mut id = help::get_uid("s");
if let Some(uid) = uid {
id = uid;
}
let file = format!("{id}.js"); // js ext
Ok(PrfItem {
uid: Some(id),
itype: Some("script".into()),
name: None,
desc: None,
file: Some(file),
url: None,
home: None,
selected: None,
extra: None,
option: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(tmpl::ITEM_SCRIPT.into()),
})
}
/// ## Rules type (enhance)
pub fn from_rules() -> Result<PrfItem> {
let uid = help::get_uid("r");
let file = format!("{uid}.yaml"); // yaml ext
Ok(PrfItem {
uid: Some(uid),
itype: Some("rules".into()),
name: None,
desc: None,
file: Some(file),
url: None,
home: None,
selected: None,
extra: None,
option: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(tmpl::ITEM_RULES.into()),
})
}
/// ## Proxies type (enhance)
pub fn from_proxies() -> Result<PrfItem> {
let uid = help::get_uid("p");
let file = format!("{uid}.yaml"); // yaml ext
Ok(PrfItem {
uid: Some(uid),
itype: Some("proxies".into()),
name: None,
desc: None,
file: Some(file),
url: None,
home: None,
selected: None,
extra: None,
option: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(tmpl::ITEM_PROXIES.into()),
})
}
/// ## Groups type (enhance)
pub fn from_groups() -> Result<PrfItem> {
let uid = help::get_uid("g");
let file = format!("{uid}.yaml"); // yaml ext
Ok(PrfItem {
uid: Some(uid),
itype: Some("groups".into()),
name: None,
desc: None,
file: Some(file),
url: None,
home: None,
selected: None,
extra: None,
option: None,
updated: Some(chrono::Local::now().timestamp() as usize),
file_data: Some(tmpl::ITEM_GROUPS.into()),
})
}
/// get the file data
pub fn read_file(&self) -> Result<String> {
if self.file.is_none() {
bail!("could not find the file");
}
let file = self.file.clone().unwrap();
let path = dirs::app_profiles_dir()?.join(file);
fs::read_to_string(path).context("failed to read the file")
}
/// save the file data
pub fn save_file(&self, data: String) -> Result<()> {
if self.file.is_none() {
bail!("could not find the file");
}
let file = self.file.clone().unwrap();
let path = dirs::app_profiles_dir()?.join(file);
fs::write(path, data.as_bytes()).context("failed to save the file")
}
}

View File

@ -1,52 +1,488 @@
use super::{prfitem::PrfItem, PrfOption};
use crate::utils::{dirs, help};
use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::{fs, io::Write};
/// Define the `profiles.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ProfilesConfig {
/// current profile's name
pub current: Option<usize>,
pub struct IProfiles {
/// same as PrfConfig.current
pub current: Option<String>,
/// profile list
pub items: Option<Vec<ProfileItem>>,
pub items: Option<Vec<PrfItem>>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ProfileItem {
/// profile name
pub name: Option<String>,
/// profile file
pub file: Option<String>,
/// current mode
pub mode: Option<String>,
/// source url
pub url: Option<String>,
/// selected infomation
pub selected: Option<Vec<ProfileSelected>>,
/// user info
pub extra: Option<ProfileExtra>,
/// updated time
pub updated: Option<usize>,
macro_rules! patch {
($lv: expr, $rv: expr, $key: tt) => {
if ($rv.$key).is_some() {
$lv.$key = $rv.$key;
}
};
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ProfileSelected {
pub name: Option<String>,
pub now: Option<String>,
impl IProfiles {
pub fn new() -> Self {
match dirs::profiles_path().and_then(|path| help::read_yaml::<Self>(&path)) {
Ok(mut profiles) => {
if profiles.items.is_none() {
profiles.items = Some(vec![]);
}
// compatible with the old old old version
if let Some(items) = profiles.items.as_mut() {
for item in items.iter_mut() {
if item.uid.is_none() {
item.uid = Some(help::get_uid("d"));
}
}
}
profiles
}
Err(err) => {
log::error!(target: "app", "{err}");
Self::template()
}
}
}
#[derive(Default, Debug, Clone, Copy, Deserialize, Serialize)]
pub struct ProfileExtra {
pub upload: usize,
pub download: usize,
pub total: usize,
pub expire: usize,
pub fn template() -> Self {
Self {
items: Some(vec![]),
..Self::default()
}
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
/// the result from url
pub struct ProfileResponse {
pub name: String,
pub file: String,
pub data: String,
pub extra: ProfileExtra,
pub fn save_file(&self) -> Result<()> {
help::save_yaml(
&dirs::profiles_path()?,
self,
Some("# Profiles Config for Clash Verge"),
)
}
/// 只修改currentvalid和chain
pub fn patch_config(&mut self, patch: IProfiles) -> Result<()> {
if self.items.is_none() {
self.items = Some(vec![]);
}
if let Some(current) = patch.current {
let items = self.items.as_ref().unwrap();
let some_uid = Some(current);
if items.iter().any(|e| e.uid == some_uid) {
self.current = some_uid;
}
}
Ok(())
}
pub fn get_current(&self) -> Option<String> {
self.current.clone()
}
/// get items ref
pub fn get_items(&self) -> Option<&Vec<PrfItem>> {
self.items.as_ref()
}
/// find the item by the uid
pub fn get_item(&self, uid: &String) -> Result<&PrfItem> {
if let Some(items) = self.items.as_ref() {
let some_uid = Some(uid.clone());
for each in items.iter() {
if each.uid == some_uid {
return Ok(each);
}
}
}
bail!("failed to get the profile item \"uid:{uid}\"");
}
/// append new item
/// if the file_data is some
/// then should save the data to file
pub fn append_item(&mut self, mut item: PrfItem) -> Result<()> {
if item.uid.is_none() {
bail!("the uid should not be null");
}
let uid = item.uid.clone();
// save the file data
// move the field value after save
if let Some(file_data) = item.file_data.take() {
if item.file.is_none() {
bail!("the file should not be null");
}
let file = item.file.clone().unwrap();
let path = dirs::app_profiles_dir()?.join(&file);
fs::File::create(path)
.with_context(|| format!("failed to create file \"{}\"", file))?
.write(file_data.as_bytes())
.with_context(|| format!("failed to write to file \"{}\"", file))?;
}
if self.current.is_none()
&& (item.itype == Some("remote".to_string()) || item.itype == Some("local".to_string()))
{
self.current = uid;
}
if self.items.is_none() {
self.items = Some(vec![]);
}
if let Some(items) = self.items.as_mut() {
items.push(item)
}
self.save_file()
}
/// reorder items
pub fn reorder(&mut self, active_id: String, over_id: String) -> Result<()> {
let mut items = self.items.take().unwrap_or_default();
let mut old_index = None;
let mut new_index = None;
for (i, _) in items.iter().enumerate() {
if items[i].uid == Some(active_id.clone()) {
old_index = Some(i);
}
if items[i].uid == Some(over_id.clone()) {
new_index = Some(i);
}
}
if old_index.is_none() || new_index.is_none() {
return Ok(());
}
let item = items.remove(old_index.unwrap());
items.insert(new_index.unwrap(), item);
self.items = Some(items);
self.save_file()
}
/// update the item value
pub fn patch_item(&mut self, uid: String, item: PrfItem) -> Result<()> {
let mut items = self.items.take().unwrap_or_default();
for each in items.iter_mut() {
if each.uid == Some(uid.clone()) {
patch!(each, item, itype);
patch!(each, item, name);
patch!(each, item, desc);
patch!(each, item, file);
patch!(each, item, url);
patch!(each, item, selected);
patch!(each, item, extra);
patch!(each, item, updated);
patch!(each, item, option);
self.items = Some(items);
return self.save_file();
}
}
self.items = Some(items);
bail!("failed to find the profile item \"uid:{uid}\"")
}
/// be used to update the remote item
/// only patch `updated` `extra` `file_data`
pub fn update_item(&mut self, uid: String, mut item: PrfItem) -> Result<()> {
if self.items.is_none() {
self.items = Some(vec![]);
}
// find the item
let _ = self.get_item(&uid)?;
if let Some(items) = self.items.as_mut() {
let some_uid = Some(uid.clone());
for each in items.iter_mut() {
if each.uid == some_uid {
each.extra = item.extra;
each.updated = item.updated;
each.home = item.home;
each.option = PrfOption::merge(each.option.clone(), item.option);
// save the file data
// move the field value after save
if let Some(file_data) = item.file_data.take() {
let file = each.file.take();
let file =
file.unwrap_or(item.file.take().unwrap_or(format!("{}.yaml", &uid)));
// the file must exists
each.file = Some(file.clone());
let path = dirs::app_profiles_dir()?.join(&file);
fs::File::create(path)
.with_context(|| format!("failed to create file \"{}\"", file))?
.write(file_data.as_bytes())
.with_context(|| format!("failed to write to file \"{}\"", file))?;
}
break;
}
}
}
self.save_file()
}
/// delete item
/// if delete the current then return true
pub fn delete_item(&mut self, uid: String) -> Result<bool> {
let current = self.current.as_ref().unwrap_or(&uid);
let current = current.clone();
let item = self.get_item(&uid)?;
let merge_uid = item.option.as_ref().and_then(|e| e.merge.clone());
let script_uid = item.option.as_ref().and_then(|e| e.script.clone());
let rules_uid = item.option.as_ref().and_then(|e| e.rules.clone());
let proxies_uid = item.option.as_ref().and_then(|e| e.proxies.clone());
let groups_uid = item.option.as_ref().and_then(|e| e.groups.clone());
let mut items = self.items.take().unwrap_or_default();
let mut index = None;
let mut merge_index = None;
let mut script_index = None;
let mut rules_index = None;
let mut proxies_index = None;
let mut groups_index = None;
// get the index
for (i, _) in items.iter().enumerate() {
if items[i].uid == Some(uid.clone()) {
index = Some(i);
break;
}
}
if let Some(index) = index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// get the merge index
for (i, _) in items.iter().enumerate() {
if items[i].uid == merge_uid {
merge_index = Some(i);
break;
}
}
if let Some(index) = merge_index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// get the script index
for (i, _) in items.iter().enumerate() {
if items[i].uid == script_uid {
script_index = Some(i);
break;
}
}
if let Some(index) = script_index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// get the rules index
for (i, _) in items.iter().enumerate() {
if items[i].uid == rules_uid {
rules_index = Some(i);
break;
}
}
if let Some(index) = rules_index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// get the proxies index
for (i, _) in items.iter().enumerate() {
if items[i].uid == proxies_uid {
proxies_index = Some(i);
break;
}
}
if let Some(index) = proxies_index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// get the groups index
for (i, _) in items.iter().enumerate() {
if items[i].uid == groups_uid {
groups_index = Some(i);
break;
}
}
if let Some(index) = groups_index {
if let Some(file) = items.remove(index).file {
let _ = dirs::app_profiles_dir().map(|path| {
let path = path.join(file);
if path.exists() {
let _ = fs::remove_file(path);
}
});
}
}
// delete the original uid
if current == uid {
self.current = None;
for item in items.iter() {
if item.itype == Some("remote".to_string())
|| item.itype == Some("local".to_string())
{
self.current = item.uid.clone();
break;
}
}
}
self.items = Some(items);
self.save_file()?;
Ok(current == uid)
}
/// 获取current指向的订阅内容
pub fn current_mapping(&self) -> Result<Mapping> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let file_path = match item.file.as_ref() {
Some(file) => dirs::app_profiles_dir()?.join(file),
None => bail!("failed to get the file field"),
};
return help::read_mapping(&file_path);
}
bail!("failed to find the current profile \"uid:{current}\"");
}
_ => Ok(Mapping::new()),
}
}
/// 获取current指向的订阅的merge
pub fn current_merge(&self) -> Option<String> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let merge = item.option.as_ref().and_then(|e| e.merge.clone());
return merge;
}
None
}
_ => None,
}
}
/// 获取current指向的订阅的script
pub fn current_script(&self) -> Option<String> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let script = item.option.as_ref().and_then(|e| e.script.clone());
return script;
}
None
}
_ => None,
}
}
/// 获取current指向的订阅的rules
pub fn current_rules(&self) -> Option<String> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let rules = item.option.as_ref().and_then(|e| e.rules.clone());
return rules;
}
None
}
_ => None,
}
}
/// 获取current指向的订阅的proxies
pub fn current_proxies(&self) -> Option<String> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let proxies = item.option.as_ref().and_then(|e| e.proxies.clone());
return proxies;
}
None
}
_ => None,
}
}
/// 获取current指向的订阅的groups
pub fn current_groups(&self) -> Option<String> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let groups = item.option.as_ref().and_then(|e| e.groups.clone());
return groups;
}
None
}
_ => None,
}
}
/// 判断profile是否是current指向的
pub fn is_current_profile_index(&self, index: String) -> bool {
self.current == Some(index)
}
/// 获取所有的profiles(uid名称)
pub fn all_profile_uid_and_name(&self) -> Option<Vec<(String, String)>> {
self.items.as_ref().map(|items| {
items
.iter()
.filter_map(|e| {
if let (Some(uid), Some(name)) = (e.uid.clone(), e.name.clone()) {
Some((uid, name))
} else {
None
}
})
.collect()
})
}
}

View File

@ -0,0 +1,49 @@
use crate::enhance::field::use_keys;
use serde::{Deserialize, Serialize};
use serde_yaml::{Mapping, Value};
use std::collections::HashMap;
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IRuntime {
pub config: Option<Mapping>,
// 记录在订阅中包括merge和script生成的出现过的keys
// 这些keys不一定都生效
pub exists_keys: Vec<String>,
pub chain_logs: HashMap<String, Vec<(String, String)>>,
}
impl IRuntime {
pub fn new() -> Self {
Self::default()
}
// 这里只更改 allow-lan | ipv6 | log-level | tun
pub fn patch_config(&mut self, patch: Mapping) {
if let Some(config) = self.config.as_mut() {
["allow-lan", "ipv6", "log-level", "unified-delay"]
.into_iter()
.for_each(|key| {
if let Some(value) = patch.get(key).to_owned() {
config.insert(key.into(), value.clone());
}
});
let patch_tun = patch.get("tun");
if patch_tun.is_some() {
let tun = config.get("tun");
let mut tun = tun.map_or(Mapping::new(), |val| {
val.as_mapping().cloned().unwrap_or(Mapping::new())
});
let patch_tun = patch_tun.map_or(Mapping::new(), |val| {
val.as_mapping().cloned().unwrap_or(Mapping::new())
});
use_keys(&patch_tun).into_iter().for_each(|key| {
if let Some(value) = patch_tun.get(&key).to_owned() {
tun.insert(key.into(), value.clone());
}
});
config.insert("tun".into(), Value::from(tun));
}
}
}
}

View File

@ -1,17 +1,548 @@
use crate::{
config::{deserialize_encrypted, serialize_encrypted, DEFAULT_PAC},
utils::{dirs, help, i18n},
};
use anyhow::Result;
use log::LevelFilter;
use serde::{Deserialize, Serialize};
/// ### `verge.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct VergeConfig {
/// `light` or `dark`
pub struct IVerge {
/// app log level
/// silent | error | warn | info | debug | trace
pub app_log_level: Option<String>,
// i18n
pub language: Option<String>,
/// `light` or `dark` or `system`
pub theme_mode: Option<String>,
/// tray click event
pub tray_event: Option<String>,
/// copy env type
pub env_type: Option<String>,
/// start page
pub start_page: Option<String>,
/// startup script path
pub startup_script: Option<String>,
/// enable traffic graph default is true
pub traffic_graph: Option<bool>,
/// show memory info (only for Clash Meta)
pub enable_memory_usage: Option<bool>,
/// enable group icon
pub enable_group_icon: Option<bool>,
/// common tray icon
pub common_tray_icon: Option<bool>,
/// tray icon
#[cfg(target_os = "macos")]
pub tray_icon: Option<String>,
/// menu icon
pub menu_icon: Option<String>,
/// sysproxy tray icon
pub sysproxy_tray_icon: Option<bool>,
/// tun tray icon
pub tun_tray_icon: Option<bool>,
/// clash tun mode
pub enable_tun_mode: Option<bool>,
/// can the app auto startup
pub enable_self_startup: Option<bool>,
pub enable_auto_launch: Option<bool>,
/// not show the window on launch
pub enable_silent_start: Option<bool>,
/// set system proxy
pub enable_system_proxy: Option<bool>,
/// enable proxy guard
pub enable_proxy_guard: Option<bool>,
/// enable dns settings - this controls whether dns_config.yaml is applied
pub enable_dns_settings: Option<bool>,
/// always use default bypass
pub use_default_bypass: Option<bool>,
/// set system proxy bypass
pub system_proxy_bypass: Option<String>,
/// proxy guard duration
pub proxy_guard_duration: Option<u64>,
/// use pac mode
pub proxy_auto_config: Option<bool>,
/// pac script content
pub pac_file_content: Option<String>,
/// theme setting
pub theme_setting: Option<IVergeTheme>,
/// web ui list
pub web_ui_list: Option<Vec<String>>,
/// clash core path
#[serde(skip_serializing_if = "Option::is_none")]
pub clash_core: Option<String>,
/// hotkey map
/// format: {func},{key}
pub hotkeys: Option<Vec<String>>,
/// enable global hotkey
pub enable_global_hotkey: Option<bool>,
/// 首页卡片设置
/// 控制首页各个卡片的显示和隐藏
pub home_cards: Option<serde_json::Value>,
/// 切换代理时自动关闭连接
pub auto_close_connection: Option<bool>,
/// 是否自动检查更新
pub auto_check_update: Option<bool>,
/// 默认的延迟测试连接
pub default_latency_test: Option<String>,
/// 默认的延迟测试超时时间
pub default_latency_timeout: Option<i32>,
/// 是否使用内部的脚本支持,默认为真
pub enable_builtin_enhanced: Option<bool>,
/// proxy 页面布局 列数
pub proxy_layout_column: Option<i32>,
/// 测试站列表
pub test_list: Option<Vec<IVergeTestItem>>,
/// 日志清理
/// 0: 不清理; 1: 7天; 2: 30天; 3: 90天
pub auto_log_clean: Option<i32>,
/// 是否启用随机端口
pub enable_random_port: Option<bool>,
/// verge 的各种 port 用于覆盖 clash 的各种 port
#[cfg(not(target_os = "windows"))]
pub verge_redir_port: Option<u16>,
#[cfg(not(target_os = "windows"))]
pub verge_redir_enabled: Option<bool>,
#[cfg(target_os = "linux")]
pub verge_tproxy_port: Option<u16>,
#[cfg(target_os = "linux")]
pub verge_tproxy_enabled: Option<bool>,
pub verge_mixed_port: Option<u16>,
pub verge_socks_port: Option<u16>,
pub verge_socks_enabled: Option<bool>,
pub verge_port: Option<u16>,
pub verge_http_enabled: Option<bool>,
/// WebDAV 配置 (加密存储)
#[serde(
serialize_with = "serialize_encrypted",
deserialize_with = "deserialize_encrypted",
skip_serializing_if = "Option::is_none",
default
)]
pub webdav_url: Option<String>,
/// WebDAV 用户名 (加密存储)
#[serde(
serialize_with = "serialize_encrypted",
deserialize_with = "deserialize_encrypted",
skip_serializing_if = "Option::is_none",
default
)]
pub webdav_username: Option<String>,
/// WebDAV 密码 (加密存储)
#[serde(
serialize_with = "serialize_encrypted",
deserialize_with = "deserialize_encrypted",
skip_serializing_if = "Option::is_none",
default
)]
pub webdav_password: Option<String>,
pub enable_tray_speed: Option<bool>,
/// 自动进入轻量模式
pub enable_auto_light_weight_mode: Option<bool>,
/// 自动进入轻量模式的延迟(分钟)
pub auto_light_weight_minutes: Option<u64>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IVergeTestItem {
pub uid: Option<String>,
pub name: Option<String>,
pub icon: Option<String>,
pub url: Option<String>,
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IVergeTheme {
pub primary_color: Option<String>,
pub secondary_color: Option<String>,
pub primary_text: Option<String>,
pub secondary_text: Option<String>,
pub info_color: Option<String>,
pub error_color: Option<String>,
pub warning_color: Option<String>,
pub success_color: Option<String>,
pub font_family: Option<String>,
pub css_injection: Option<String>,
}
impl IVerge {
fn get_system_language() -> String {
let sys_lang = sys_locale::get_locale()
.unwrap_or_else(|| String::from("en"))
.to_lowercase();
let lang_code = sys_lang.split(['_', '-']).next().unwrap_or("en");
let supported_languages = i18n::get_supported_languages();
if supported_languages.contains(&lang_code.to_string()) {
lang_code.to_string()
} else {
String::from("en")
}
}
pub fn new() -> Self {
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
Ok(config) => config,
Err(err) => {
log::error!(target: "app", "{err}");
Self::template()
}
}
}
pub fn template() -> Self {
Self {
clash_core: Some("verge-mihomo".into()),
language: Some(Self::get_system_language()),
theme_mode: Some("system".into()),
#[cfg(not(target_os = "windows"))]
env_type: Some("bash".into()),
#[cfg(target_os = "windows")]
env_type: Some("powershell".into()),
start_page: Some("/home".into()),
traffic_graph: Some(true),
enable_memory_usage: Some(true),
enable_group_icon: Some(true),
#[cfg(target_os = "macos")]
tray_icon: Some("monochrome".into()),
menu_icon: Some("monochrome".into()),
common_tray_icon: Some(false),
sysproxy_tray_icon: Some(false),
tun_tray_icon: Some(false),
enable_auto_launch: Some(false),
enable_silent_start: Some(false),
enable_system_proxy: Some(false),
proxy_auto_config: Some(false),
pac_file_content: Some(DEFAULT_PAC.into()),
enable_random_port: Some(false),
#[cfg(not(target_os = "windows"))]
verge_redir_port: Some(7895),
#[cfg(not(target_os = "windows"))]
verge_redir_enabled: Some(false),
#[cfg(target_os = "linux")]
verge_tproxy_port: Some(7896),
#[cfg(target_os = "linux")]
verge_tproxy_enabled: Some(false),
verge_mixed_port: Some(7897),
verge_socks_port: Some(7898),
verge_socks_enabled: Some(false),
verge_port: Some(7899),
verge_http_enabled: Some(false),
enable_proxy_guard: Some(false),
use_default_bypass: Some(true),
proxy_guard_duration: Some(30),
auto_close_connection: Some(true),
auto_check_update: Some(true),
enable_builtin_enhanced: Some(true),
auto_log_clean: Some(3),
webdav_url: None,
webdav_username: None,
webdav_password: None,
enable_tray_speed: Some(true),
enable_global_hotkey: Some(true),
enable_auto_light_weight_mode: Some(false),
auto_light_weight_minutes: Some(10),
enable_dns_settings: Some(true),
home_cards: None,
..Self::default()
}
}
/// Save IVerge App Config
pub fn save_file(&self) -> Result<()> {
help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Verge Config"))
}
/// patch verge config
/// only save to file
pub fn patch_config(&mut self, patch: IVerge) {
macro_rules! patch {
($key: tt) => {
if patch.$key.is_some() {
self.$key = patch.$key;
}
};
}
patch!(app_log_level);
patch!(language);
patch!(theme_mode);
patch!(tray_event);
patch!(env_type);
patch!(start_page);
patch!(startup_script);
patch!(traffic_graph);
patch!(enable_memory_usage);
patch!(enable_group_icon);
#[cfg(target_os = "macos")]
patch!(tray_icon);
patch!(menu_icon);
patch!(common_tray_icon);
patch!(sysproxy_tray_icon);
patch!(tun_tray_icon);
patch!(enable_tun_mode);
patch!(enable_auto_launch);
patch!(enable_silent_start);
patch!(enable_random_port);
#[cfg(not(target_os = "windows"))]
patch!(verge_redir_port);
#[cfg(not(target_os = "windows"))]
patch!(verge_redir_enabled);
#[cfg(target_os = "linux")]
patch!(verge_tproxy_port);
#[cfg(target_os = "linux")]
patch!(verge_tproxy_enabled);
patch!(verge_mixed_port);
patch!(verge_socks_port);
patch!(verge_socks_enabled);
patch!(verge_port);
patch!(verge_http_enabled);
patch!(enable_system_proxy);
patch!(enable_proxy_guard);
patch!(use_default_bypass);
patch!(system_proxy_bypass);
patch!(proxy_guard_duration);
patch!(proxy_auto_config);
patch!(pac_file_content);
patch!(theme_setting);
patch!(web_ui_list);
patch!(clash_core);
patch!(hotkeys);
patch!(enable_global_hotkey);
patch!(auto_close_connection);
patch!(auto_check_update);
patch!(default_latency_test);
patch!(default_latency_timeout);
patch!(enable_builtin_enhanced);
patch!(proxy_layout_column);
patch!(test_list);
patch!(auto_log_clean);
patch!(webdav_url);
patch!(webdav_username);
patch!(webdav_password);
patch!(enable_tray_speed);
patch!(enable_auto_light_weight_mode);
patch!(auto_light_weight_minutes);
patch!(enable_dns_settings);
patch!(home_cards);
}
/// 在初始化前尝试拿到单例端口的值
pub fn get_singleton_port() -> u16 {
#[cfg(not(feature = "verge-dev"))]
const SERVER_PORT: u16 = 33331;
#[cfg(feature = "verge-dev")]
const SERVER_PORT: u16 = 11233;
SERVER_PORT
}
/// 获取日志等级
pub fn get_log_level(&self) -> LevelFilter {
if let Some(level) = self.app_log_level.as_ref() {
match level.to_lowercase().as_str() {
"silent" => LevelFilter::Off,
"error" => LevelFilter::Error,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
_ => LevelFilter::Info,
}
} else {
LevelFilter::Info
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct IVergeResponse {
pub app_log_level: Option<String>,
pub language: Option<String>,
pub theme_mode: Option<String>,
pub tray_event: Option<String>,
pub env_type: Option<String>,
pub start_page: Option<String>,
pub startup_script: Option<String>,
pub traffic_graph: Option<bool>,
pub enable_memory_usage: Option<bool>,
pub enable_group_icon: Option<bool>,
pub common_tray_icon: Option<bool>,
#[cfg(target_os = "macos")]
pub tray_icon: Option<String>,
pub menu_icon: Option<String>,
pub sysproxy_tray_icon: Option<bool>,
pub tun_tray_icon: Option<bool>,
pub enable_tun_mode: Option<bool>,
pub enable_auto_launch: Option<bool>,
pub enable_silent_start: Option<bool>,
pub enable_system_proxy: Option<bool>,
pub enable_proxy_guard: Option<bool>,
pub enable_global_hotkey: Option<bool>,
pub use_default_bypass: Option<bool>,
pub system_proxy_bypass: Option<String>,
pub proxy_guard_duration: Option<u64>,
pub proxy_auto_config: Option<bool>,
pub pac_file_content: Option<String>,
pub theme_setting: Option<IVergeTheme>,
pub web_ui_list: Option<Vec<String>>,
pub clash_core: Option<String>,
pub hotkeys: Option<Vec<String>>,
pub auto_close_connection: Option<bool>,
pub auto_check_update: Option<bool>,
pub default_latency_test: Option<String>,
pub default_latency_timeout: Option<i32>,
pub enable_builtin_enhanced: Option<bool>,
pub proxy_layout_column: Option<i32>,
pub test_list: Option<Vec<IVergeTestItem>>,
pub auto_log_clean: Option<i32>,
pub enable_random_port: Option<bool>,
#[cfg(not(target_os = "windows"))]
pub verge_redir_port: Option<u16>,
#[cfg(not(target_os = "windows"))]
pub verge_redir_enabled: Option<bool>,
#[cfg(target_os = "linux")]
pub verge_tproxy_port: Option<u16>,
#[cfg(target_os = "linux")]
pub verge_tproxy_enabled: Option<bool>,
pub verge_mixed_port: Option<u16>,
pub verge_socks_port: Option<u16>,
pub verge_socks_enabled: Option<bool>,
pub verge_port: Option<u16>,
pub verge_http_enabled: Option<bool>,
pub webdav_url: Option<String>,
pub webdav_username: Option<String>,
pub webdav_password: Option<String>,
pub enable_tray_speed: Option<bool>,
pub enable_auto_light_weight_mode: Option<bool>,
pub auto_light_weight_minutes: Option<u64>,
pub enable_dns_settings: Option<bool>,
pub home_cards: Option<serde_json::Value>,
}
impl From<IVerge> for IVergeResponse {
fn from(verge: IVerge) -> Self {
Self {
app_log_level: verge.app_log_level,
language: verge.language,
theme_mode: verge.theme_mode,
tray_event: verge.tray_event,
env_type: verge.env_type,
start_page: verge.start_page,
startup_script: verge.startup_script,
traffic_graph: verge.traffic_graph,
enable_memory_usage: verge.enable_memory_usage,
enable_group_icon: verge.enable_group_icon,
common_tray_icon: verge.common_tray_icon,
#[cfg(target_os = "macos")]
tray_icon: verge.tray_icon,
menu_icon: verge.menu_icon,
sysproxy_tray_icon: verge.sysproxy_tray_icon,
tun_tray_icon: verge.tun_tray_icon,
enable_tun_mode: verge.enable_tun_mode,
enable_auto_launch: verge.enable_auto_launch,
enable_silent_start: verge.enable_silent_start,
enable_system_proxy: verge.enable_system_proxy,
enable_proxy_guard: verge.enable_proxy_guard,
enable_global_hotkey: verge.enable_global_hotkey,
use_default_bypass: verge.use_default_bypass,
system_proxy_bypass: verge.system_proxy_bypass,
proxy_guard_duration: verge.proxy_guard_duration,
proxy_auto_config: verge.proxy_auto_config,
pac_file_content: verge.pac_file_content,
theme_setting: verge.theme_setting,
web_ui_list: verge.web_ui_list,
clash_core: verge.clash_core,
hotkeys: verge.hotkeys,
auto_close_connection: verge.auto_close_connection,
auto_check_update: verge.auto_check_update,
default_latency_test: verge.default_latency_test,
default_latency_timeout: verge.default_latency_timeout,
enable_builtin_enhanced: verge.enable_builtin_enhanced,
proxy_layout_column: verge.proxy_layout_column,
test_list: verge.test_list,
auto_log_clean: verge.auto_log_clean,
enable_random_port: verge.enable_random_port,
#[cfg(not(target_os = "windows"))]
verge_redir_port: verge.verge_redir_port,
#[cfg(not(target_os = "windows"))]
verge_redir_enabled: verge.verge_redir_enabled,
#[cfg(target_os = "linux")]
verge_tproxy_port: verge.verge_tproxy_port,
#[cfg(target_os = "linux")]
verge_tproxy_enabled: verge.verge_tproxy_enabled,
verge_mixed_port: verge.verge_mixed_port,
verge_socks_port: verge.verge_socks_port,
verge_socks_enabled: verge.verge_socks_enabled,
verge_port: verge.verge_port,
verge_http_enabled: verge.verge_http_enabled,
webdav_url: verge.webdav_url,
webdav_username: verge.webdav_username,
webdav_password: verge.webdav_password,
enable_tray_speed: verge.enable_tray_speed,
enable_auto_light_weight_mode: verge.enable_auto_light_weight_mode,
auto_light_weight_minutes: verge.auto_light_weight_minutes,
enable_dns_settings: verge.enable_dns_settings,
home_cards: verge.home_cards,
}
}
}

Some files were not shown because too many files have changed in this diff Show More