* Fix reordered list behavior and persistence
Use remove-and-insert semantics for every reorderable collection and persist the resulting order instead of swapping endpoints.
Resolve routing rules and proxy-chain members by stable keys, make proxy rows draggable, and serialize profile-order writes per group so rapid drag updates cannot be persisted out of order.
* Signal touch reorder activation with haptic feedback
Emit one gesture-threshold pulse when a long press makes an item draggable. Reuse the same handle across every reorderable list and rely on the platform touch-feedback setting.
* fix: reset stuck start lock on system Always-on VPN restart
When Android restarts CoreVpnService for Always-on VPN (via VpnService.SERVICE_INTERFACE
or null intent), a stuck isStartingLock from a killed process prevents tryLockStart() from
succeeding, causing an immediate return without setupVpnService().
Fix: Reset stuck start lock via unlockStart() on system-initiated VPN start/restart,
allowing setupVpnService() to establish the TUN interface. If setup fails during system
start, return START_STICKY to keep the service alive for OS reconnection.
Also accept LOCKED_BOOT_COMPLETED and MY_PACKAGE_REPLACED in BootReceiver.
* Update BootReceiver.kt
* Update CoreVpnService.kt
---------
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
- Refactor subscription synchronization and testing from static object to a dedicated foreground service.
- Implement SubscriptionUpdateService with accurate lifecycle management using AtomicInteger (runningTasks).
- Enforce serial execution of subscription updates via Semaphore(1) to ensure data integrity and bandwidth control.
- Fix NetworkOnMainThreadException by switching service execution to Dispatchers.IO.
- Decouple update logic from Main UI components for better modularity.
- Prevent rapid rescheduling loops by updating 'lastUpdated' timestamp at the start of the task.
- Simplify messaging by supporting multiple subscription IDs in a single SubscriptionUpdateMessage.
* Fix snackbar positioned low when virtual navigation
* Fix checkupdate page not display updating information
* Fix first snackbar short in consecutive message
* fix snackbar the RESUMED show timing
Refactored MainActivity and its Compose UI components to use a single
onAction: (MainAction) -> Unit callback. This significantly simplifies
component signatures and centralizes interaction logic.
- Updated MainContract.kt to include all UI-triggered actions.
- Modified MainScreen and sub-components (TopBar, BottomBar, Drawer, etc.)
to use the unified onAction dispatcher.
- Implemented a centralized action handler in MainActivity to dispatch
between ViewModel and Activity-specific tasks.
- Removed redundant ImportConfigViaSub action.
- Moved QR code generation state into MainUiState for MVI consistency.
This change reduces parameter drilling and improves maintainability of
the main interface.
Improve settings UX consistency across Compose screens: disabled setting text now uses proper muted alpha for title/description, domain strategy and geo source pickers now use shared `SettingsListItem` instead of custom click/dialog state, routing rule row UI was extracted into a reusable composable, and several settings toggles were un-gated so they can be changed outside VPN-only conditions.
Move manual subscription updates to WorkManager-based background jobs and simplify scheduler logic by handling auto-update checks in `scheduleOne`. Add post-update server testing support with optional invalid-node cleanup and sorting, plus MMKV/AngConfig helpers to remove multiple servers and reorder subscription servers by test delay. Update the subscriptions UI flow and zh-TW strings to reflect background execution and new auto-test options.
- Implement BaseViewModel to centralize loading state and UI event handling.
- Migrate all ViewModels (Main, Backup, Logcat, etc.) to inherit from BaseViewModel.
- Convert MainViewModel from AndroidViewModel to standard ViewModel using global app context.
- Standardize UI events using ViewModelEvent/BaseViewModelEvent sealed interfaces.
- Simplify loading logic with launchLoading helper and direct toast notifications.
- Cleanup redundant loading/toast boilerplate code across the application.
- Update LogcatActivity to observe the unified isLoading state.
- Create BaseViewModel to encapsulate common UI state (isLoading) and logic (toasts, finishing activity).
- Implement ViewModelEvent and BaseViewModelEvent for standardized UI communication via SideEffects.
- Move core business logic (I/O, Zip, WebDAV) from BackupActivity to BackupViewModel.
- Standardize code naming conventions and update documentation to English.
- Improve Activity purity by delegating state management and background tasks to the ViewModel.