Skip to content

Commit f969433

Browse files
therealalephclaude
andauthored
v1.1.0: unified Connect button, proxy mode, app splitting, Persian UI, MIPS build (#41)
Major feature release across Android + desktop. Six items the user asked for, verified end-to-end on the emulator. Android ------- * Unified Connect/Disconnect button. Single large button swaps between green "Connect" (when the service is down) and red "Disconnect" (when it's up). Tracks the real service state via a new process-wide `VpnState` singleton flipped from the service's startEverything() / teardown() — not optimistic, the button only reports what the service actually did. * Connection mode dropdown (issue #37). Two options: VPN (TUN) — routes every app — and Proxy only — user configures per-app via Wi-Fi proxy to 127.0.0.1:8080 (HTTP) / :1081 (SOCKS5). PROXY_ONLY skips VpnService.prepare() entirely (no OS VPN grant prompt) and the service just keeps the foreground listeners up. Default is VPN_TUN so existing behaviour is preserved for users who upgrade without looking at the dropdown. * App splitting. In VPN_TUN mode you can pick All / Only selected / All except selected, with a picker dialog that lists installed user-visible apps (LazyColumn with search, "show system apps" toggle, multi-select checkboxes). ONLY calls `Builder.addAllowedApplication()` for each chosen package; EXCEPT calls `addDisallowedApplication()` additive to the mandatory self-exclude. Requires QUERY_ALL_PACKAGES — added to the manifest along with a `<queries>` launcher-intent filter so the picker rows can render app labels, not just package strings. * Persian/English UI toggle with RTL. Top-bar TextButton cycles AUTO → FA → EN → AUTO. Persian strings live in `res/values-fa/strings.xml`; English in `res/values/strings.xml`. `AppCompatDelegate.setApplicationLocales()` is used as the persistence layer (plus `AppLocalesMetadataHolderService` meta and `locales_config.xml` for the per-app-language OS entry on API 33+). MainActivity overrides `attachBaseContext` to wrap the context with the right locale at the earliest possible moment — otherwise a saved preference wouldn't apply until the SECOND process after toggling. RTL swaps automatically because Persian is script="Arab" in Android's locale database. * Collapsible How-to-use card. The big instruction block that used to dominate the bottom of the screen now lives inside a CollapsibleSection that starts expanded for a fresh install (empty deployment URLs / auth_key) and collapsed otherwise. * Update check auto-fires on first composition, silent-on-up-to-date, snackbar-only-if-available. Still surfaces via the version badge tap for manual checks. * MhrvVpnService teardown guard was kept from v1.0.2 — `AtomicBoolean` makes the second caller a no-op, which is the SIGSEGV fix for "tap Stop, app closes" from before. Stress-tested under rapid Connect/Disconnect cycles. Desktop ------- * Fix: Advanced section silently resetting on every Save. `ConfigWire` was missing `fetch_ips_from_api` / `max_ips_to_scan` / `scan_batch_size` / `google_ip_validation` — every persist dropped them, every reload fell back to the serde defaults, user saw their Advanced toggles reset. Added the fields to the wire struct (issue surfaced by the user as "Advanced resets after reopening the app"). * Windows renderer fallback (issue #28). `eframe` is now built with BOTH `glow` (OpenGL 2+) and `wgpu` (DX12/Vulkan/Metal); runtime defaults to glow for compat but honours `MHRV_RENDERER=wgpu` for boxes that crash with "egui_glow requires opengl 2.0+" — old Windows hardware, RDP sessions, VMs without GPU acceleration. `run.bat` auto-retries the UI with `MHRV_RENDERER=wgpu` if the first launch exits non-zero, so users don't need to know about the flag. CI -- * Added OpenWRT mipsel-softfloat build target (issue #26). MT7621 routers specifically need soft-float because the CPU has no FPU; a hard-float binary segfaults on first fp op. Built via `messense/rust-musl-cross:mipsel-musl-softfloat` docker image + nightly Rust with `-Z build-std` (mipsel is Rust tier 3 since 1.72, no pre-built std). Marked `continue-on-error: true` — the tier-3 target occasionally regresses and we'd rather ship the rest of the release than block on MT7621 support. Signature / versioning ---------------------- * versionCode 110, versionName 1.1.0; Cargo bumped to 1.1.0. * Release APK signed with the committed `release.jks` (same as v1.0.2), so v1.0.2 → v1.1.0 upgrades install in-place without the uninstall-first dance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4100c36 commit f969433

20 files changed

Lines changed: 1624 additions & 144 deletions

File tree

.github/workflows/release.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,24 @@ jobs:
4444
- target: aarch64-unknown-linux-musl
4545
os: ubuntu-latest
4646
name: mhrv-rs-linux-musl-arm64
47+
# OpenWRT MT7621 (soft-float mipsel 32-bit). Dozens of cheap
48+
# home routers run this chipset and they *specifically* need
49+
# the soft-float variant — MT7621 has no hardware FPU and a
50+
# hard-float binary segfaults on the first fp op. Tier-3 in
51+
# Rust since 1.72; we build it via messense's musl-cross
52+
# docker image which still has a mipsel-softfloat toolchain.
53+
# `continue-on-error: true` so a regression here doesn't block
54+
# the rest of the release. Issue #26.
55+
- target: mipsel-unknown-linux-musl
56+
os: ubuntu-latest
57+
name: mhrv-rs-openwrt-mipsel-softfloat
58+
mipsel_softfloat: true
4759

4860
runs-on: ${{ matrix.os }}
61+
# mipsel-softfloat is best-effort: the Rust tier-3 target occasionally
62+
# regresses. Letting it fail keeps the main release going so
63+
# desktop/Android users aren't blocked by MT7621 router support.
64+
continue-on-error: ${{ matrix.mipsel_softfloat == true }}
4965

5066
steps:
5167
- uses: actions/checkout@v4
@@ -125,6 +141,23 @@ jobs:
125141
cargo build --release --target aarch64-unknown-linux-musl --bin mhrv-rs
126142
sudo chown -R "$(id -u):$(id -g)" target
127143
144+
# OpenWRT MT7621 / mipsel-softfloat. The messense image tag
145+
# `mipsel-musl-softfloat` ships a toolchain that emits soft-float
146+
# insn exclusively — matches the MT7621's FPU-less reality.
147+
# Requires Rust nightly + -Z build-std because mipsel is tier 3
148+
# in the stable channel, which means no pre-built std.
149+
- name: Build CLI (mipsel-softfloat via docker)
150+
if: matrix.target == 'mipsel-unknown-linux-musl' && matrix.mipsel_softfloat == true
151+
run: |
152+
docker run --rm -v "$PWD":/src -w /src \
153+
messense/rust-musl-cross:mipsel-musl-softfloat \
154+
sh -c "rustup toolchain install nightly --profile minimal --component rust-src && \
155+
cargo +nightly build --release \
156+
-Z build-std=std,panic_abort \
157+
--target mipsel-unknown-linux-musl \
158+
--bin mhrv-rs"
159+
sudo chown -R "$(id -u):$(id -g)" target
160+
128161
# UI build: we try to build the UI binary on every platform. If it fails
129162
# on cross-compile for linux-arm64 (missing arm64 system libs cross),
130163
# we still ship the CLI. We also skip the UI on musl targets (OpenWRT etc.

0 commit comments

Comments
 (0)