From 7c86d0c5c26db81efa4cf90c46ee0d4b64f0f156 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Mon, 1 Dec 2025 15:04:59 +0530 Subject: [PATCH] Refactor connectivity handling in MainWrapper and enhance offline experience in MyApp --- lib/main.dart | 58 +++++++++++++++++----------------- lib/view/my_app.dart | 75 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 34 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 9ca62c0..a14567a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,6 @@ import 'package:on_field_work/helpers/services/app_initializer.dart'; import 'package:on_field_work/view/my_app.dart'; import 'package:on_field_work/helpers/theme/app_notifier.dart'; import 'package:on_field_work/helpers/services/app_logger.dart'; -import 'package:on_field_work/view/layouts/offline_screen.dart'; import 'package:on_field_work/helpers/services/storage/local_storage.dart'; Future main() async { @@ -55,38 +54,37 @@ Widget _buildErrorApp() => const MaterialApp( ), ); -class MainWrapper extends StatefulWidget { +class MainWrapper extends StatelessWidget { const MainWrapper({super.key}); - @override - State createState() => _MainWrapperState(); -} - -class _MainWrapperState extends State { - List _connectivityStatus = [ConnectivityResult.none]; - final Connectivity _connectivity = Connectivity(); - - @override - void initState() { - super.initState(); - _initializeConnectivity(); - _connectivity.onConnectivityChanged.listen((results) { - setState(() => _connectivityStatus = results); - }); - } - - Future _initializeConnectivity() async { - final result = await _connectivity.checkConnectivity(); - setState(() => _connectivityStatus = result); - } - @override Widget build(BuildContext context) { - final bool isOffline = - _connectivityStatus.contains(ConnectivityResult.none); - return isOffline - ? const MaterialApp( - debugShowCheckedModeBanner: false, home: OfflineScreen()) - : const MyApp(); + // 1. Use FutureBuilder to check the current connectivity status ONCE. + return FutureBuilder>( + future: Connectivity().checkConnectivity(), + builder: (context, initialSnapshot) { + // If the initial check is still running, display a standard loading screen. + if (!initialSnapshot.hasData) { + return const MaterialApp( + home: Center(child: CircularProgressIndicator()), + ); + } + + // 2. Once the initial status is known, use StreamBuilder for real-time updates. + return StreamBuilder>( + stream: Connectivity().onConnectivityChanged, + // 💡 CRITICAL: Use the actual result from the FutureBuilder as the initial data. + initialData: initialSnapshot.data!, + builder: (context, streamSnapshot) { + final List results = + streamSnapshot.data ?? [ConnectivityResult.none]; + final bool isOffline = results.contains(ConnectivityResult.none); + + // Pass the accurate connectivity status down to MyApp. + return MyApp(isOffline: isOffline); + }, + ); + }, + ); } } diff --git a/lib/view/my_app.dart b/lib/view/my_app.dart index 068843e..76c1796 100644 --- a/lib/view/my_app.dart +++ b/lib/view/my_app.dart @@ -14,7 +14,9 @@ import 'package:on_field_work/helpers/theme/app_notifier.dart'; import 'package:on_field_work/routes.dart'; class MyApp extends StatelessWidget { - const MyApp({super.key}); + final bool isOffline; + + const MyApp({super.key, required this.isOffline}); Future _getInitialRoute() async { try { @@ -40,6 +42,62 @@ class MyApp extends StatelessWidget { } } + // ✨ REVISED: Helper Widget to show a full-screen, well-designed offline status + Widget _buildConnectivityOverlay(BuildContext context) { + // If not offline, return an empty widget. + if (!isOffline) return const SizedBox.shrink(); + + // Otherwise, return a full-screen overlay. + return Directionality( + textDirection: AppTheme.textDirection, + child: Scaffold( + backgroundColor: + Colors.grey.shade100, // Light background for the offline state + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.cloud_off, + color: Colors.red.shade700, // Prominent color + size: 100, + ), + const SizedBox(height: 24), + const Text( + "You Are Offline", + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + ), + const SizedBox(height: 8), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 40.0), + child: Text( + "Please check your internet connection and try again.", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + color: Colors.black54, + ), + ), + ), + const SizedBox(height: 32), + // Optional: Add a button for the user to potentially refresh/retry + // ElevatedButton( + // onPressed: () { + // // Add logic to re-check connectivity or navigate (if possible) + // }, + // child: const Text("RETRY"), + // ), + ], + ), + ), + ), + ); + } + @override Widget build(BuildContext context) { return Consumer( @@ -71,9 +129,18 @@ class MyApp extends StatelessWidget { getPages: getPageRoute(), builder: (context, child) { NavigationService.registerContext(context); - return Directionality( - textDirection: AppTheme.textDirection, - child: child ?? const SizedBox(), + + // 💡 REVISED: Use a Stack to place the offline overlay ON TOP of the app content. + // This allows the full-screen view to cover everything, including the main app content. + return Stack( + children: [ + Directionality( + textDirection: AppTheme.textDirection, + child: child ?? const SizedBox(), + ), + // 2. The full-screen connectivity overlay, only visible when offline + _buildConnectivityOverlay(context), + ], ); }, localizationsDelegates: [