import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; import '../types/abstracts.dart'; import '../types/credential.dart'; import '../types/screen_arguments.dart'; import '../widgets/tappable_text_list.dart'; class Home extends StatefulWidget { const Home({Key key}) : super(key: key); @override State createState() => _HomeState(); } class _HomeState extends State with WidgetsBindingObserver { CredentialsRepo _client; ConfigRepo _config; Future> _metadatas; bool _stateIsPaused = false; Timer _pausedStateTimer; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void didChangeDependencies() { super.didChangeDependencies(); _config = Provider.of(context); _client = Provider.of(context); _metadatas = _client.getAllMetadata('').toList(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { _stateIsPaused = state == AppLifecycleState.paused; if (_stateIsPaused) { _pausedStateTimer = _newPausedStateTimer(); return; } if (_pausedStateTimer != null) _pausedStateTimer.cancel(); } @override Widget build(BuildContext context) { return CupertinoPageScaffold( child: FutureBuilder>( future: _metadatas, builder: ( BuildContext context, AsyncSnapshot> snapshot, ) => (snapshot.connectionState == ConnectionState.done) ? TappableTextList( tappableText: _buildTappableText(context, snapshot.data)) : Center(child: CupertinoActivityIndicator()), ), navigationBar: CupertinoNavigationBar( leading: GestureDetector( child: Align( child: Text('Lock', style: TextStyle(color: CupertinoColors.destructiveRed)), alignment: Alignment(-0.9, 0)), onTap: _makeLockOnTapHandler(context), ), trailing: GestureDetector( child: Icon(CupertinoIcons.gear), onTap: _makeConfigOnTapHandler(context), ), ), ); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); if (_pausedStateTimer != null) _pausedStateTimer.cancel(); super.dispose(); } Timer _newPausedStateTimer() { const checkPeriod = 30; return Timer(Duration(seconds: checkPeriod), () { Navigator.of(context) .pushNamedAndRemoveUntil('/', ModalRoute.withName('/home')); }); } Map _buildTappableText( BuildContext context, List metadatas, ) { final Map> metaMap = {}; metadatas.sort((a, b) => a.id.compareTo(b.id)); for (var metadata in metadatas) { final source = metadata.sourceHost; if (metaMap[source] == null) { metaMap[source] = [metadata]; } else { metaMap[source].add(metadata); } } final handleOnTap = (List metadatas) => () async => Navigator.of(context).pushNamed('/credentials', arguments: metadatas); final Map tappableText = {}; metaMap.forEach((String key, List value) => tappableText[key] = handleOnTap(value)); return tappableText; } GestureTapCallback _makeLockOnTapHandler(BuildContext context) { return () => Navigator.of(context).pushReplacementNamed('/'); } GestureTapCallback _makeConfigOnTapHandler(BuildContext context) { return () async => Navigator.of(context).pushNamed('/config', arguments: ConfigScreenArguments( connectionConfig: await _config.connectionConfig, privateKey: await _config.privateKey)); } }