194 lines
5.8 KiB
Dart

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<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _needsUpdate = false;
String? _newVersion;
InStoreAppVersionCheckerResult? _updateResult;
final InStoreAppVersionChecker _checker = InStoreAppVersionChecker(
androidStore: AndroidStore.googlePlayStore,
);
@override
void initState() {
super.initState();
_checkVersion();
}
/// -------------------------
/// Version Check
/// -------------------------
Future<void> _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<String> _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<AppNotifier>(
builder: (_, notifier, __) {
return FutureBuilder<String>(
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(),
);
},
);
},
);
},
);
}
}