You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			115 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			115 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 | 
						|
import 'package:matrix/matrix.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
 | 
						|
import 'package:fluffychat/config/setting_keys.dart';
 | 
						|
import 'package:fluffychat/widgets/lock_screen.dart';
 | 
						|
 | 
						|
class AppLockWidget extends StatefulWidget {
 | 
						|
  const AppLockWidget({
 | 
						|
    required this.child,
 | 
						|
    required this.pincode,
 | 
						|
    required this.clients,
 | 
						|
    super.key,
 | 
						|
  });
 | 
						|
 | 
						|
  final List<Client> clients;
 | 
						|
  final String? pincode;
 | 
						|
  final Widget child;
 | 
						|
 | 
						|
  @override
 | 
						|
  State<AppLockWidget> createState() => AppLock();
 | 
						|
}
 | 
						|
 | 
						|
class AppLock extends State<AppLockWidget> with WidgetsBindingObserver {
 | 
						|
  String? _pincode;
 | 
						|
  bool _isLocked = false;
 | 
						|
  bool _paused = false;
 | 
						|
  bool get isActive =>
 | 
						|
      _pincode != null &&
 | 
						|
      int.tryParse(_pincode!) != null &&
 | 
						|
      _pincode!.length == 4 &&
 | 
						|
      !_paused;
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    _pincode = widget.pincode;
 | 
						|
    _isLocked = isActive;
 | 
						|
    super.initState();
 | 
						|
    WidgetsBinding.instance.addObserver(this);
 | 
						|
    WidgetsBinding.instance.addPostFrameCallback(_checkLoggedIn);
 | 
						|
  }
 | 
						|
 | 
						|
  void _checkLoggedIn(_) async {
 | 
						|
    if (widget.clients.any((client) => client.isLogged())) return;
 | 
						|
 | 
						|
    await changePincode(null);
 | 
						|
    setState(() {
 | 
						|
      _isLocked = false;
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void didChangeAppLifecycleState(AppLifecycleState state) {
 | 
						|
    if (isActive &&
 | 
						|
        state == AppLifecycleState.hidden &&
 | 
						|
        !_isLocked &&
 | 
						|
        isActive) {
 | 
						|
      showLockScreen();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  bool get isLocked => _isLocked;
 | 
						|
 | 
						|
  Future<void> changePincode(String? pincode) async {
 | 
						|
    await const FlutterSecureStorage().write(
 | 
						|
      key: SettingKeys.appLockKey,
 | 
						|
      value: pincode,
 | 
						|
    );
 | 
						|
    _pincode = pincode;
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  bool unlock(String pincode) {
 | 
						|
    final isCorrect = pincode == _pincode;
 | 
						|
    if (isCorrect) {
 | 
						|
      setState(() {
 | 
						|
        _isLocked = false;
 | 
						|
      });
 | 
						|
    }
 | 
						|
    return isCorrect;
 | 
						|
  }
 | 
						|
 | 
						|
  void showLockScreen() => setState(() {
 | 
						|
        _isLocked = true;
 | 
						|
      });
 | 
						|
 | 
						|
  Future<T> pauseWhile<T>(Future<T> future) async {
 | 
						|
    _paused = true;
 | 
						|
    try {
 | 
						|
      return await future;
 | 
						|
    } finally {
 | 
						|
      _paused = false;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  static AppLock of(BuildContext context) => Provider.of<AppLock>(
 | 
						|
        context,
 | 
						|
        listen: false,
 | 
						|
      );
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) => Provider<AppLock>(
 | 
						|
        create: (_) => this,
 | 
						|
        child: Stack(
 | 
						|
          fit: StackFit.expand,
 | 
						|
          children: [
 | 
						|
            widget.child,
 | 
						|
            if (isLocked) const LockScreen(),
 | 
						|
          ],
 | 
						|
        ),
 | 
						|
      );
 | 
						|
}
 |