In materialApp I am using the upgrader to in home attribute to show a upgraderAlert to show that there is a app Update pending and need to update the app (I want to make it forcefully upgrade).
here is the code of my material app where it goes to a splash screen after it (if i do not use upgrader and use the original work flow).
import 'dart:io';
import 'package:big_daddy_live_line_new/core/core.dart';
import 'package:big_daddy_live_line_new/main.dart';
import 'package:big_daddy_live_line_new/resources/src/theme/bloc/theme_bloc.dart';
import 'package:big_daddy_live_line_new/resources/src/theme/theme.dart';
import 'package:big_daddy_live_line_new/src/app/route/routes.dart';
import 'package:big_daddy_live_line_new/src/l10n/l10n.dart';
import 'package:big_daddy_live_line_new/src/ui/splash/splash_screen.dart';
import 'package:big_daddy_live_line_new/updates_checker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:upgrader/upgrader.dart';
import '../di/dependency.dart';
import 'localization/localization_cubit.dart';
export 'bloc_observer.dart';
export 'localization/localization_cubit.dart';
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp>
with SingletonsMixin, WidgetsBindingObserver {
late final AppRouteGenerator _routeGenerator = AppRouteGenerator();
late final routeObserver = this<RouteObserver>();
bool willDisplay = false;
late String route;
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
init();
}
void init() async {
await Upgrader.clearSavedSettings();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
String get initialRoute {
return UpdateChecker.routeName;
// return SplashScreen.routeName;
}
@override
Widget build(BuildContext context) {
final localizationState =
BlocProvider.of<LocalizationCubit>(context, listen: true).state;
final themeState = BlocProvider.of<ThemeBloc>(context, listen: true).state;
return MaterialApp(
onGenerateTitle: (context) => context.l10n.appName,
navigatorKey: navigatorKey,
navigatorObservers: [routeObserver],
debugShowCheckedModeBanner: false,
themeMode: themeState.themeMode,
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
onGenerateRoute: _routeGenerator,
// initialRoute: initialRoute,
locale: localizationState.locale,
supportedLocales: localizationState.supportedLocales,
localizationsDelegates: const [
AppLocalization.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: UpgradeAlert(
upgrader: Upgrader(
durationUntilAlertAgain: Duration(seconds: 5),
canDismissDialog: false,
shouldPopScope: () {
if (Platform.isAndroid) {
Future.delayed(const Duration(milliseconds: 1000), () {
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
});
} else if (Platform.isIOS) {
Future.delayed(const Duration(milliseconds: 1000), () {
exit(0);
});
}
return true;
},
),
navigatorKey: navigatorKey,
),
);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
}
super.didChangeAppLifecycleState(state);
}
}
When using the initialRoute property of the material app the splash screen gets loaded under the UpgradeAlert.
Where the splash screen is running on a timer and after the timer runs out it loads the next screen based on the conditions.
onLoaded: (composition) {
_controller
..duration = composition.duration
..forward().whenComplete(
// () async {
// context.navigator.pushReplacementNamed(
// UpdateChecker.routeName);
// }
() async {
if (box.read('sportSelected') != null) {
if (box.read('sportSelected') ==
"Cricket") {
context.navigator.pushReplacementNamed(
HomeScreen.routeName);
setState(() {
loadNextScreen = false;
});
} else if (box.read('sportSelected') ==
"Football") {
context.navigator.pushReplacementNamed(
HomeScreenFootball.routeName);
setState(() {
loadNextScreen = false;
});
} else {
context.navigator.pushReplacementNamed(
SportSelectionScreen.routeName);
setState(() {
loadNextScreen = false;
});
}
} else {
context.navigator.pushReplacementNamed(
SportSelectionScreen.routeName);
setState(() {
loadNextScreen = false;
});
}
},
);
},
After the timer runs out on splashscreen the upgradeAlert widget also gets removed with removed due to pushreplacementNamed of navigator. But the splashscreen need to be poped after being loaded.
can Anyone please let me know how to make it work or any solution on implementing the upgraderAlert without triggering the splashscreen if upgraderAlert shows a dialougebox.
I have tried applying condition in loading of either the splash screen or upgraderAleart screen with different scaffold if the currentAppVersion and PlayStoreAppVersion are different but not able to fetch PlayStoreAppVersion to make the comparison.
I have also tried making a condition in the material app for initial route to either load splashscreen or a blank scaffold if upgrader.willDisplay is true but is provide only null as a return.
I don't know how to route using the upgradeAlert.navigatorKey as the example in the docs is not explaing how to use it without using goRouter or any other example. Also in the example if the upgrader do not show a dialouge box the second screen is still loaded how to switch to the screen1 is not shown. link: https://pub.dev/packages/upgrader/install ||| https://github.com/larryaasen/upgrader/blob/master/example/lib/main-gorouter.dart