You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_QLine/lib/services/connectivity_service.dart

183 lines
5.7 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:universal_html/html.dart' as html;
import 'dart:developer' as dev;
import 'package:js/js.dart';
@JS('startIPDetection')
external void startIPDetectionJS();
@JS('deviceIPResult')
external String? get deviceIPResultJS;
@JS('deviceIPDetecting')
external bool? get deviceIPDetectingJS;
abstract class ConnectivityService {
void subscribeToConnectivityChange({
required Function() onInternetDisConnected,
required Function() onInternetConnected,
});
Future<String> getCurrentScreenIP();
}
class ConnectivityServiceImp implements ConnectivityService {
Connectivity connectivityInstance;
ConnectivityServiceImp({required this.connectivityInstance});
@override
subscribeToConnectivityChange({
required Function() onInternetDisConnected,
required Function() onInternetConnected,
}) {
connectivityInstance.onConnectivityChanged.listen((List<ConnectivityResult> event) async {
switch (event.first) {
case ConnectivityResult.wifi:
case ConnectivityResult.ethernet:
onInternetConnected();
break;
case ConnectivityResult.none:
onInternetDisConnected();
break;
case ConnectivityResult.mobile:
case ConnectivityResult.bluetooth:
case ConnectivityResult.vpn:
case ConnectivityResult.other:
break;
}
});
}
@override
Future<String> getCurrentScreenIP() async {
// Web: Auto-detect IP or get from URL/localStorage
if (kIsWeb) {
dev.log('🌐 Web platform - attempting to get device IP...');
// Priority 1: Check URL query parameter: ?ip=12.4.5.1
final uri = Uri.base;
if (uri.queryParameters.containsKey('ip')) {
final ip = uri.queryParameters['ip']!;
dev.log('✅ IP from URL parameter: $ip');
try {
html.window.localStorage['device_ip'] = ip;
dev.log('💾 Saved IP to localStorage: $ip');
} catch (e) {
dev.log('❌ Failed to save IP to localStorage: $e');
}
return ip;
}
// Priority 2: Check localStorage FIRST (before auto-detect to avoid delay)
String? storedIp;
try {
storedIp = html.window.localStorage['device_ip'];
dev.log('🔍 Checking localStorage for saved IP...');
dev.log(' localStorage[device_ip] = $storedIp');
dev.log(' storedIp type: ${storedIp.runtimeType}');
dev.log(' storedIp == null: ${storedIp == null}');
dev.log(' storedIp.isEmpty: ${storedIp?.isEmpty}');
dev.log(' storedIp == "null": ${storedIp == 'null'}');
} catch (e) {
dev.log('❌ Error accessing localStorage: $e');
storedIp = null;
}
if (storedIp != null && storedIp.isNotEmpty && storedIp != 'null') {
dev.log('✅ IP from localStorage: $storedIp');
return storedIp;
} else {
dev.log('⚠️ localStorage check failed - storedIp: "$storedIp"');
}
// Priority 3: Try to auto-detect IP using WebRTC (only if not in localStorage)
dev.log('📡 No stored IP found, attempting auto-detection...');
try {
final detectedIP = await _autoDetectIP();
if (detectedIP != null && detectedIP.isNotEmpty) {
dev.log('✅ IP auto-detected from device: $detectedIP');
try {
html.window.localStorage['device_ip'] = detectedIP;
dev.log('💾 Saved auto-detected IP to localStorage');
} catch (e) {
dev.log('❌ Failed to save auto-detected IP to localStorage: $e');
}
return detectedIP;
}
} catch (e) {
dev.log('⚠️ Auto-detection failed: $e');
}
// No IP found
dev.log('⚠️ No IP address detected');
dev.log('📌 Add to URL: ${uri.origin}/?ip=YOUR_DEVICE_IP');
return '';
}
// Android Native: Get actual IP from network interface
dev.log('📱 Android native - getting IP from network interface...');
const eth = "eth0";
const wlan = "wlan0";
String currentDeviceIp = "";
try {
final ips = await NetworkInterface.list(type: InternetAddressType.IPv4);
for (var interface in ips) {
if (interface.name == eth) {
for (var address in interface.addresses) {
currentDeviceIp = address.address;
dev.log('✅ IP from ethernet (eth0): $currentDeviceIp');
}
}
if (interface.name == wlan) {
for (var address in interface.addresses) {
currentDeviceIp = address.address;
dev.log('✅ IP from WiFi (wlan0): $currentDeviceIp');
}
}
}
} catch (e) {
dev.log('❌ Failed to get network interface IP: $e');
}
return currentDeviceIp;
}
/// Auto-detect device IP using WebRTC (works on web browsers)
Future<String?> _autoDetectIP() async {
try {
// Start IP detection in JavaScript
startIPDetectionJS();
// Poll for result
final stopwatch = Stopwatch()..start();
while (stopwatch.elapsed.inSeconds < 5) {
await Future.delayed(const Duration(milliseconds: 100));
// Check if still detecting
final isDetecting = deviceIPDetectingJS;
if (isDetecting == false || isDetecting == null) {
// Detection completed
final result = deviceIPResultJS;
if (result != null && result != 'TIMEOUT' && result != 'ERROR') {
return result;
}
break;
}
}
dev.log('⏱️ IP detection timeout or failed');
return null;
} catch (e) {
dev.log('❌ Auto-detection error: $e');
return null;
}
}
}