1

I am trying to detect the activity of user like Mouse Moving or Typing in Text field or Clicking on screen anywhere. Using Timer Function I can achieve to logout from the Portal if there is no activity for 15 minutes but this functionality is only working when user set idle the window pane. For example: In Browser user open two tabs and on first tab user using the portal and suddenly working on the another tab of same window pane then this feature is not working (it's pause the time) but if user using two different applications then this feature is working.

So need help how to make this functionality better.

Flutter Web Only...

I tried simple Timer Function of Flutter. I am trying to logout the user from the portal after some time if there is no activity.

il_boga
  • 1,305
  • 1
  • 13
  • 21

1 Answers1

1

I am sure I developed this code from some other question here on SO, but I can't find it.
Anyway, I have a similar function in a webapp of mine: it detects mouse clicks and the likes (not mouse movement!), and logs out the user if the timer runs out. As far as I know, it doesn't have any problem with different tabs.
This is the class that acts as timer:

class SessionTimer {
  late Timer timer;
  BuildContext context;
  Function onLogout;
  int minutes;
  SessionTimer({required this.context, required this.onLogout, required this.minutes});

  void startTimer() {
    timer = Timer.periodic(Duration(minutes: minutes), (_) {
      timedOut();
    });
  }

  void userActivityDetected([_]) {
    //print('detected');
    if (timer.isActive) {
      timer.cancel();
      //print('restarted');
      startTimer();
    }
    return;
  }

  Future<void> timedOut() async {
    timer.cancel();
    await showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => WillPopScope(
          onWillPop: () async {
            return false;
          },
          child: PointerInterceptor(
              child: AlertDialog(
            title: Text('settingsAutoLogout'.tr()),
            content: Text('logoutForced'.tr()),
            actions: <Widget>[
              TextButton(onPressed: () => onLogout(), child: const Icon(Icons.check)),
            ],
          ))),
    );
  }
}

This is the HomePage state that has the session timer:

class HomePageState extends State<HomePage> {
  SessionTimer? _sessionTimer;

  @override
  void initState() {
    super.initState();
    var cfg = Config();
    cfg.init(MyApp.database).then((success) {
      _sessionTimer = SessionTimer(context: context, onLogout: () => _logout(false), minutes: cfg.autoLogout);
      _sessionTimer!.startTimer();
    });
  }
  //rest of the State class...

This is the GestureDetector at the top of the widget tree (after the user has logged in, of course):

return GestureDetector(
        onTap: _sessionTimer?.userActivityDetected,
        onPanDown: _sessionTimer?.userActivityDetected,
        onScaleStart: _sessionTimer?.userActivityDetected,
        child: //rest of the widget tree...

Hope this helps.

il_boga
  • 1,305
  • 1
  • 13
  • 21