feat(app): add secure routing and runtime resilience
Add explicit TUN and SOCKS5 connection modes, app routing controls, authenticated per-session local SOCKS5, Android network monitoring, persistent haptics, resilient session recovery, notification hardening and client-side Hivemind cleanup. Keep the hosted flutter_vless_android 1.1.5 runtime as the base and apply the Android compatibility/security patches at build time instead of restoring the unstable vendored runtime.
This commit is contained in:
1 parent
371db8da9f
commit
8ead3ff249
30 files changed
+3959
-484
No files matched your search
@@ -0,0 +1,65 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:revoltvpn/logic/haptic_settings.dart';
|
||||
|
||||
/// Gives short touch taps the same haptic feedback across the app.
|
||||
/// Scroll gestures are ignored by checking travel distance and touch duration.
|
||||
class AppHapticSurface extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
||||
const AppHapticSurface({super.key, required this.child});
|
||||
|
||||
@override
|
||||
State<AppHapticSurface> createState() => _AppHapticSurfaceState();
|
||||
}
|
||||
|
||||
class _PointerStart {
|
||||
final Offset position;
|
||||
final DateTime time;
|
||||
|
||||
const _PointerStart(this.position, this.time);
|
||||
}
|
||||
|
||||
class _AppHapticSurfaceState extends State<AppHapticSurface> {
|
||||
static const double _maxTapTravel = 18;
|
||||
static const Duration _maxTapDuration = Duration(milliseconds: 700);
|
||||
|
||||
final Map<int, _PointerStart> _starts = <int, _PointerStart>{};
|
||||
|
||||
bool _supportsHaptics(PointerDeviceKind kind) {
|
||||
return kind == PointerDeviceKind.touch ||
|
||||
kind == PointerDeviceKind.stylus ||
|
||||
kind == PointerDeviceKind.invertedStylus;
|
||||
}
|
||||
|
||||
void _onDown(PointerDownEvent event) {
|
||||
if (!_supportsHaptics(event.kind)) return;
|
||||
_starts[event.pointer] = _PointerStart(event.position, DateTime.now());
|
||||
}
|
||||
|
||||
void _onCancel(PointerCancelEvent event) {
|
||||
_starts.remove(event.pointer);
|
||||
}
|
||||
|
||||
void _onUp(PointerUpEvent event) {
|
||||
final start = _starts.remove(event.pointer);
|
||||
if (start == null || !_supportsHaptics(event.kind)) return;
|
||||
|
||||
final travelled = (event.position - start.position).distance;
|
||||
final elapsed = DateTime.now().difference(start.time);
|
||||
if (travelled <= _maxTapTravel && elapsed <= _maxTapDuration) {
|
||||
HapticSettings.tap();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Listener(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onPointerDown: _onDown,
|
||||
onPointerUp: _onUp,
|
||||
onPointerCancel: _onCancel,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user