import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; abstract final class HapticSettings { HapticSettings._(); static const String _prefKey = 'haptic_feedback_enabled'; static const MethodChannel _channel = MethodChannel('com.revoltvpn.app/haptics'); static bool _enabled = false; static bool _initialized = false; static bool get enabled => _enabled; static Future initialize() async { if (_initialized) return; try { final prefs = await SharedPreferences.getInstance(); _enabled = prefs.getBool(_prefKey) ?? false; } catch (e) { debugPrint('[Haptics] Failed to load preference: $e'); _enabled = false; } finally { _initialized = true; } } static Future setEnabled(bool value) async { final previous = _enabled; _enabled = value; _initialized = true; try { final prefs = await SharedPreferences.getInstance(); final saved = await prefs.setBool(_prefKey, value); if (!saved) throw StateError('Could not save haptic setting'); } catch (e) { _enabled = previous; debugPrint('[Haptics] Failed to save preference: $e'); rethrow; } } /// Confirmation haptic for a successful connect/disconnect. Best-effort: a /// vibration failure must never block or fail the VPN action. static void success() => unawaited(_impact()); static Future _impact() async { if (!_initialized) await initialize(); if (!_enabled || kIsWeb) return; if (defaultTargetPlatform == TargetPlatform.android) { try { final handled = await _channel.invokeMethod( 'impact', {'kind': 'success'}, ) ?? false; if (handled) return; } catch (e) { debugPrint('[Haptics] Native vibration unavailable: $e'); } } await HapticFeedback.mediumImpact(); } }