import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; import 'package:flutter_in_store_app_version_checker/flutter_in_store_app_version_checker.dart'; import 'package:on_field_work/helpers/services/app_logger.dart'; import 'package:on_field_work/helpers/services/localizations/language.dart'; import 'package:on_field_work/helpers/services/navigation_services.dart'; import 'package:on_field_work/helpers/services/storage/local_storage.dart'; import 'package:on_field_work/helpers/theme/app_theme.dart'; import 'package:on_field_work/helpers/theme/theme_customizer.dart'; import 'package:on_field_work/helpers/theme/app_notifier.dart'; import 'package:on_field_work/routes.dart'; import 'package:on_field_work/view/mandatory_update_screen.dart'; class MyApp extends StatefulWidget { final bool isOffline; const MyApp({super.key, required this.isOffline}); @override State createState() => _MyAppState(); } class _MyAppState extends State { bool _needsUpdate = false; String? _newVersion; InStoreAppVersionCheckerResult? _updateResult; final InStoreAppVersionChecker _checker = InStoreAppVersionChecker( androidStore: AndroidStore.googlePlayStore, ); @override void initState() { super.initState(); _checkVersion(); } /// ------------------------- /// Version Check /// ------------------------- Future _checkVersion() async { try { final result = await _checker.checkUpdate(); _updateResult = result; logSafe("Version Check initiated..."); logSafe("Current App Version: ${_checker.currentVersion}"); logSafe("Result canUpdate: ${result.canUpdate}"); logSafe("Result newVersion: ${result.newVersion}"); logSafe("Result appURL: ${result.appURL}"); if (result.canUpdate) { setState(() { _needsUpdate = true; _newVersion = result.newVersion ?? ""; }); logSafe("New version available → $_newVersion"); } if (result.errorMessage != null) { logSafe("VersionChecker Error: ${result.errorMessage}"); } } catch (e, stack) { logSafe( "Version check exception", error: e, stackTrace: stack, level: LogLevel.error, ); } } /// ------------------------- /// Initial Route Logic /// ------------------------- Future _getInitialRoute() async { try { final token = LocalStorage.getJwtToken(); if (token == null || token.isEmpty) { return "/auth/login-option"; } if (LocalStorage.getIsMpin()) { await LocalStorage.setBool("mpin_verified", false); return "/auth/mpin-auth"; } return "/dashboard"; } catch (e, stack) { logSafe( "Initial route ERROR", error: e, stackTrace: stack, level: LogLevel.error, ); return "/auth/login-option"; } } /// ------------------------- /// Offline Overlay (Blocking) /// ------------------------- Widget _buildOfflineOverlay() { return Directionality( textDirection: AppTheme.textDirection, child: Scaffold( backgroundColor: Colors.grey.shade200, body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.cloud_off, size: 100, color: Colors.red.shade600), const SizedBox(height: 20), const Text( "You Are Offline", style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), const Padding( padding: EdgeInsets.symmetric(horizontal: 32), child: Text( "Please check your internet connection and try again.", textAlign: TextAlign.center, style: TextStyle(fontSize: 16, color: Colors.black54), ), ), ], ), ), ), ); } /// ------------------------- /// Build /// ------------------------- @override Widget build(BuildContext context) { if (_needsUpdate && !widget.isOffline) { // 4. USE THE NEW WIDGET HERE return MandatoryUpdateScreen( newVersion: _newVersion ?? "", updateResult: _updateResult, ); } if (widget.isOffline) { return _buildOfflineOverlay(); } return Consumer( builder: (_, notifier, __) { return FutureBuilder( future: _getInitialRoute(), builder: (context, snapshot) { if (!snapshot.hasData) { return const MaterialApp( home: Center(child: CircularProgressIndicator()), ); } return GetMaterialApp( debugShowCheckedModeBanner: false, theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, themeMode: ThemeCustomizer.instance.theme, navigatorKey: NavigationService.navigatorKey, initialRoute: snapshot.data!, getPages: getPageRoute(), supportedLocales: Language.getLocales(), localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], builder: (context, child) { NavigationService.registerContext(context); return Directionality( textDirection: AppTheme.textDirection, child: child ?? const SizedBox(), ); }, ); }, ); }, ); } }