46 lines
1.4 KiB
Dart
46 lines
1.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
/// Locks once the app returns after being in the background for at least
|
|
/// [gracePeriod], so a quick trip to the image picker or installer doesn't.
|
|
class AppLifecycleLockObserver extends WidgetsBindingObserver {
|
|
final VoidCallback onLock;
|
|
final VoidCallback? onBackground;
|
|
final VoidCallback? onForeground;
|
|
final bool Function()? shouldLock;
|
|
final Duration gracePeriod;
|
|
final DateTime Function() _clock;
|
|
|
|
DateTime? _backgroundedAt;
|
|
|
|
AppLifecycleLockObserver({
|
|
required this.onLock,
|
|
this.onBackground,
|
|
this.onForeground,
|
|
this.shouldLock,
|
|
this.gracePeriod = const Duration(seconds: 30),
|
|
DateTime Function()? clock,
|
|
}) : _clock = clock ?? DateTime.now;
|
|
|
|
@override
|
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
|
switch (state) {
|
|
case AppLifecycleState.inactive:
|
|
break;
|
|
case AppLifecycleState.hidden:
|
|
case AppLifecycleState.paused:
|
|
case AppLifecycleState.detached:
|
|
if (_backgroundedAt != null) return;
|
|
_backgroundedAt = _clock();
|
|
onBackground?.call();
|
|
case AppLifecycleState.resumed:
|
|
final backgroundedAt = _backgroundedAt;
|
|
if (backgroundedAt == null) return;
|
|
_backgroundedAt = null;
|
|
|
|
final away = _clock().difference(backgroundedAt);
|
|
if (away >= gracePeriod && (shouldLock?.call() ?? true)) onLock();
|
|
onForeground?.call();
|
|
}
|
|
}
|
|
}
|