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 getCurrentScreenIP(); } class ConnectivityServiceImp implements ConnectivityService { Connectivity connectivityInstance; ConnectivityServiceImp({required this.connectivityInstance}); @override subscribeToConnectivityChange({ required Function() onInternetDisConnected, required Function() onInternetConnected, }) { connectivityInstance.onConnectivityChanged.listen((List 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 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 _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; } } }