Closed iKK001 closed 11 months ago
I finally found a solution.
The reason for not-recognition of the userInteraction in my Flutter Web app is as follows:
I had the SessionTimeoutManager
Widget too deep down the Widget tree ! And therefore the userInteractions where not recognized.
The reason I had it one level too deep down was the following:
If you wrap the SessionTimeoutManager
arround MaterialApp
(as stated in your example on the main page of your github repo), then you will get the error (at the timeoutEvent callback location) that the context cannot use Navigator ! Therefore if one wants to listen to userInteraction-timeoutEvents (and doing a Navigator.pushNamed(...) on it), then you must hand the sessionConfig
as a parameter down the widget-tree to the location where the context can fulfill a Navigator action !
See the working example here !
class MyApp extends StatelessWidget {
const MyApp({super.key});
final sessionConfig = SessionConfig(
invalidateSessionForAppLostFocus:
const Duration(seconds: constants.AUTO_LOGOUT_TIMER_DURATION),
invalidateSessionForUserInactivity:
const Duration(seconds: constants.AUTO_LOGOUT_TIMER_DURATION),
);
@override
Widget build(BuildContext context) {
return SessionTimeoutManager(
sessionConfig: sessionConfig,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MainPage(sessionConfig: sessionConfig), // GIVE IT AS A PARAMETER DOWN THE WIDGET-TREE HERE...
routes: {
'/': (context) => const FirstScreen(),
'/auth': (context) => const AuthScreen(),
},
),
);
}
}
class MainPage extends StatelessWidget {
final SessionConfig sessionConfig;
const MainPage({
super.key,
required this.sessionConfig,
});
@override
Widget build(BuildContext context) {
sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
Navigator.pushNamed(context, '/logout');
} else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
Navigator.pushNamed(context, '/logout');
}
});
return MyApp();
}
}
I find the example code shown in your main github and dart-package site very much misleading.
As a suggestion, you should explain that Navigator.of(context).pushNamed("/auth");
will not work with your example shown. And that you need to send down the sessionConfig
down the widget-tree to an appropriate location where the context will allow Naviagor to work.
Moreover, it is important that SessionTimeoutManager
is placed above MaterialApp
if routing is used.
And an even better solution is to use the following :
final navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => navigatorKey.currentState!;
This allows to make navigation without the context (i.e. when SessionTimeoutManager
is wrapping MaterialApp then you cannot use context for Navigator.pushNamed(...). Therefore the NavigatorState mechano !
sessionConfig.stream.listen((SessionTimeoutState timeoutEvent) {
if (timeoutEvent == SessionTimeoutState.userInactivityTimeout) {
_navigator.pushNamed('/logout');
} else if (timeoutEvent == SessionTimeoutState.appFocusTimeout) {
_navigator.pushNamed('/logout');
}
});
Thanks for your input. I will update the readme accordingly
Using Flutter channel stable, 3.13.5 / Chrome - develop for the web :
I know people had asked about this before. But the solution provided did not help.
I am working on Flutter WEB where this library simply does not work for USER-INTERACTION timeoutEvents. The Web-Application delivers timeoutEvent's no matter how much I interact with my Flutter Web appliction.
(and I know that this library cannot deliver
appFocusTimeout
for Web - but I am talking aboutuserInactivityTimeout
that does not seem to work either for flutter Web.)What does "userIneraction" mean exactly ?
I would like to prevent logout with this library for any of the following userInteractions:
Here is my code:
What is wrong still ?