From caf35fe19f66b72be30b0824ead55b4544c157bb Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 28 Jan 2021 15:10:09 +0100 Subject: [PATCH] Migrate all widget to stateless with provider fine --- lib/main.dart | 60 +++-- lib/models/generateWallets.dart | 42 ++-- lib/models/history.dart | 13 -- lib/models/myWallets.dart | 74 ++++-- lib/models/walletOptions.dart | 211 +++++++++++++++++ lib/ui/historyScreen.dart | 1 - lib/ui/home.dart | 5 +- lib/ui/myWallets/changePin.dart | 80 ++----- lib/ui/myWallets/confirmWalletStorage.dart | 59 +++-- lib/ui/myWallets/generateWalletsScreen.dart | 28 +-- lib/ui/myWallets/walletOptions.dart | 246 +++----------------- lib/ui/myWallets/walletsHome.dart | 39 +--- lib/ui/settingsScreen.dart | 73 +----- 13 files changed, 430 insertions(+), 501 deletions(-) create mode 100644 lib/models/walletOptions.dart diff --git a/lib/main.dart b/lib/main.dart index 41677f1..211f6e1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'package:gecko/models/generateWallets.dart'; import 'package:gecko/models/history.dart'; import 'package:gecko/models/home.dart'; import 'package:gecko/models/myWallets.dart'; +import 'package:gecko/models/walletOptions.dart'; import 'package:gecko/ui/home.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -93,39 +94,32 @@ class Gecko extends StatelessWidget { ); DubpRust.setup(); - return - // MultiProvider( - // providers: [ - // Provider(create: (context) => HistoryProvider()), - // Provider(create: (context) => MyWalletsProvider()), - // ], - // child: - MaterialApp( - title: 'Ğecko', - theme: ThemeData( - primaryColor: Color(0xffFFD58D), - accentColor: Colors.grey[850], - textTheme: TextTheme( - bodyText1: TextStyle(), - bodyText2: TextStyle(), - ).apply( - bodyColor: Color(0xff855F2D), - // displayColor: Colors.blue, + return MultiProvider( + providers: [ + // Provider(create: (context) => HistoryProvider()), + // Provider(create: (context) => MyWalletsProvider()), + ChangeNotifierProvider(create: (_) => HomeProvider()), + ChangeNotifierProvider(create: (_) => HistoryProvider('')), + ChangeNotifierProvider(create: (_) => MyWalletsProvider()), + ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()), + ChangeNotifierProvider(create: (_) => WalletOptionsProvider()) + ], + child: GraphQLProvider( + client: _client, + child: MaterialApp( + title: 'Ğecko', + theme: ThemeData( + primaryColor: Color(0xffFFD58D), + accentColor: Colors.grey[850], + textTheme: TextTheme( + bodyText1: TextStyle(), + bodyText2: TextStyle(), + ).apply( + bodyColor: Color(0xff855F2D), + // displayColor: Colors.blue, + ), ), - ), - home: MultiProvider( - providers: [ - // Provider(create: (context) => HistoryProvider()), - // Provider(create: (context) => MyWalletsProvider()), - ChangeNotifierProvider(create: (_) => HomeProvider()), - ChangeNotifierProvider(create: (_) => HistoryProvider('')), - ChangeNotifierProvider(create: (_) => MyWalletsProvider()), - ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()) - ], - child: GraphQLProvider( - client: _client, - child: HomeScreen(), - ), - )); + home: HomeScreen(), + ))); } } diff --git a/lib/models/generateWallets.dart b/lib/models/generateWallets.dart index aa2f3a0..e57977b 100644 --- a/lib/models/generateWallets.dart +++ b/lib/models/generateWallets.dart @@ -8,21 +8,23 @@ import 'package:path_provider/path_provider.dart'; import 'package:sentry_flutter/sentry_flutter.dart' as sentry; class GenerateWalletsProvider with ChangeNotifier { - NewWallet generatedWallet; + GenerateWalletsProvider(); + // NewWallet generatedWallet; + NewWallet actualWallet; + FocusNode walletNameFocus = FocusNode(); Color askedWordColor = Colors.black; bool isAskedWordValid = false; int nbrWord; String generatedMnemonic; - bool walletIsGenerated = false; - NewWallet actualWallet; + bool walletIsGenerated = true; TextEditingController mnemonicController = TextEditingController(); TextEditingController pubkey = TextEditingController(); TextEditingController pin = TextEditingController(); - Future storeWallet(_name, _pubkey, BuildContext context) async { + Future storeWallet(NewWallet wallet, _name, BuildContext context) async { final appPath = await _localPath; final Directory walletNameDirectory = Directory('$appPath/wallets/$_name'); final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); @@ -34,10 +36,11 @@ class GenerateWalletsProvider with ChangeNotifier { } walletNameDirectory.createSync(); - walletFile.writeAsString('${generatedWallet.dewif}'); + walletFile.writeAsString('${wallet.dewif}'); Navigator.pop(context, true); - Navigator.pop(context, _pubkey.text); + Navigator.pop(context, wallet.publicKey); + // notifyListeners(); return _name; } @@ -48,7 +51,7 @@ class GenerateWalletsProvider with ChangeNotifier { } void checkAskedWord(String value, String _mnemo) { - nbrWord = getRandomInt(); + // nbrWord = getRandomInt(); final runesAsked = _mnemo.split(' ')[nbrWord].runes; List runesAskedUnaccent = []; @@ -71,10 +74,11 @@ class GenerateWalletsProvider with ChangeNotifier { isAskedWordValid = true; askedWordColor = Colors.green[600]; walletNameFocus.nextFocus(); + notifyListeners(); } else { isAskedWordValid = false; } - notifyListeners(); + // notifyListeners(); } String removeDiacritics(String str) { @@ -118,6 +122,8 @@ class GenerateWalletsProvider with ChangeNotifier { child: Text("J'ai compris"), onPressed: () { Navigator.of(context).pop(); + askedWordColor = Colors.green[500]; + isAskedWordValid = true; }, ), ], @@ -128,10 +134,10 @@ class GenerateWalletsProvider with ChangeNotifier { Future generateMnemonic() async { try { - this.generatedMnemonic = - await DubpRust.genMnemonic(language: Language.french); + generatedMnemonic = await DubpRust.genMnemonic(language: Language.french); this.actualWallet = await generateWallet(this.generatedMnemonic); - this.walletIsGenerated = true; + walletIsGenerated = true; + // notifyListeners(); } catch (e, stack) { print(e); if (kReleaseMode) { @@ -142,7 +148,7 @@ class GenerateWalletsProvider with ChangeNotifier { } } // await checkIfWalletExist(); - return this.generatedMnemonic; + return generatedMnemonic; } Future generateWallet(generatedMnemonic) async { @@ -162,11 +168,11 @@ class GenerateWalletsProvider with ChangeNotifier { } mnemonicController.text = generatedMnemonic; - pubkey.text = actualWallet.publicKey; - pin.text = actualWallet.pin; - notifyListeners(); + pubkey.text = this.actualWallet.publicKey; + pin.text = this.actualWallet.pin; + // notifyListeners(); - return actualWallet; + return this.actualWallet; } Future changePinCode() async { @@ -175,7 +181,7 @@ class GenerateWalletsProvider with ChangeNotifier { oldPin: this.actualWallet.pin, ); - pin.text = actualWallet.pin; - notifyListeners(); + pin.text = this.actualWallet.pin; + // notifyListeners(); } } diff --git a/lib/models/history.dart b/lib/models/history.dart index f336123..e93c588 100644 --- a/lib/models/history.dart +++ b/lib/models/history.dart @@ -10,9 +10,6 @@ class HistoryProvider with ChangeNotifier { final TextEditingController _outputPubkey = new TextEditingController(); // String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug - // FetchMoreOptions opts; - // ScrollController scrollController = new ScrollController(); - Future scan() async { await Permission.camera.request(); String barcode; @@ -28,7 +25,6 @@ class HistoryProvider with ChangeNotifier { } return 'false'; } - // this._outputPubkey.text = ""; if (barcode != null) { this._outputPubkey.text = barcode; isPubkey(barcode); @@ -59,13 +55,4 @@ class HistoryProvider with ChangeNotifier { return ''; } - - // scrollListener() { - // if (scrollController.offset >= scrollController.position.maxScrollExtent && - // !scrollController.position.outOfRange) { - // print('On est en bas !!'); - // // fetchMore(opts); - // notifyListeners(); - // } - // } } diff --git a/lib/models/myWallets.dart b/lib/models/myWallets.dart index 224eb7b..f6d31f9 100644 --- a/lib/models/myWallets.dart +++ b/lib/models/myWallets.dart @@ -3,9 +3,9 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import 'package:gecko/globals.dart'; +import 'package:provider/provider.dart'; class MyWalletsProvider with ChangeNotifier { - // Directory appPath; List listWallets = []; bool checkIfWalletExist() { @@ -24,28 +24,14 @@ class MyWalletsProvider with ChangeNotifier { List contents = walletsFolder.listSync(); if (contents.length == 0) { print('No wallets detected'); - notifyListeners(); return false; } else { print('Some wallets have been detected:'); for (var _wallets in contents) { print(_wallets); } - notifyListeners(); return true; } - - // final bool isExist = - // File('${walletsFolder.path}/$name/wallet.dewif').existsSync(); - // print(this.appPath.path); - // print('Wallet existe ? : ' + isExist.toString()); - // print('Is wallet generated ? : ' + walletIsGenerated.toString()); - // if (isExist) { - // print('Un wallet existe !'); - // return true; - // } else { - // return false; - // } } Future importWallet() async {} @@ -63,8 +49,62 @@ class MyWalletsProvider with ChangeNotifier { print(_name); listWallets.add(_name); }); - notifyListeners(); - return listWallets; } + + Future deleteAllWallet(context) async { + try { + print('DELETE THAT ?: $walletsDirectory'); + + final bool _answer = await _confirmDeletingAllWallets(context); + + if (_answer) { + walletsDirectory.deleteSync(recursive: true); + walletsDirectory.createSync(); + Navigator.pop(context); + } + return 0; + } catch (e) { + return 1; + } + } + + Future _confirmDeletingAllWallets(context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + MyWalletsProvider _myWalletProvider = + Provider.of(context); + return AlertDialog( + title: Text( + 'Êtes-vous sûr de vouloir supprimer tous vos portefeuilles ?'), + content: SingleChildScrollView(child: Text('')), + actions: [ + TextButton( + child: Text("Non"), + onPressed: () { + Navigator.pop(context, false); + }, + ), + TextButton( + child: Text("Oui"), + onPressed: () { + WidgetsBinding.instance.addPostFrameCallback((_) { + _myWalletProvider.listWallets = + _myWalletProvider.getAllWalletsNames(); + _myWalletProvider.rebuildWidget(); + }); + Navigator.pop(context, true); + }, + ), + ], + ); + }, + ); + } + + void rebuildWidget() { + notifyListeners(); + } } diff --git a/lib/models/walletOptions.dart b/lib/models/walletOptions.dart new file mode 100644 index 0000000..d37bb5d --- /dev/null +++ b/lib/models/walletOptions.dart @@ -0,0 +1,211 @@ +import 'dart:io'; +import 'package:dubp/dubp.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'dart:async'; +import 'package:sentry/sentry.dart' as sentry; +import 'package:gecko/globals.dart'; + +class WalletOptionsProvider with ChangeNotifier { + TextEditingController pubkey = new TextEditingController(); + TextEditingController _newWalletName = new TextEditingController(); + bool isWalletUnlock = false; + bool ischangedPin = false; + TextEditingController newPin = new TextEditingController(); + + Future get badWallet => null; + + Future _getPubkeyFromDewif(_dewif, _pin) async { + String _pubkey; + RegExp regExp = new RegExp( + r'^[A-Z0-9]+$', + caseSensitive: false, + multiLine: false, + ); + + if (regExp.hasMatch(_pin) == true && _pin.length == 6) { + print("Le format du code PIN est correct."); + } else { + print('Format de code PIN invalide'); + return 'false'; + } + try { + _pubkey = await DubpRust.getDewifPublicKey(dewif: _dewif, pin: _pin); + this.pubkey.text = _pubkey; + notifyListeners(); + + return _pubkey; + } catch (e, stack) { + print('Bad PIN code !'); + print(e); + if (kReleaseMode) { + await sentry.Sentry.captureException( + e, + stackTrace: stack, + ); + } + notifyListeners(); + + return 'false'; + } + } + + Future readLocalWallet(String _name, String _pin) async { + print('NOM: ' + _name); + try { + File _walletFile = File('${walletsDirectory.path}/$_name/wallet.dewif'); + String _localDewif = await _walletFile.readAsString(); + String _localPubkey; + + if ((_localPubkey = await _getPubkeyFromDewif(_localDewif, _pin)) != + 'false') { + this.pubkey.text = _localPubkey; + isWalletUnlock = true; + notifyListeners(); + + return _localDewif; + } else { + throw 'Bad pubkey'; + } + } catch (e) { + print('ERROR READING FILE: $e'); + this.pubkey.clear(); + return 'bad'; + } + } + + Future _renameWallet(_walletName, _newName) async { + final _walletFile = Directory('${walletsDirectory.path}/$_walletName'); + + try { + _walletFile.rename('${walletsDirectory.path}/$_newName'); + } catch (e) { + print('ERREUR lors du renommage du wallet: $e'); + } + } + + Future renameWalletAlerte(context, _walletName) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: Text('Choisissez un nouveau nom pour ce portefeuille'), + content: SingleChildScrollView( + child: ListBody( + children: [ + TextField( + controller: this._newWalletName, + maxLines: 1, + textAlign: TextAlign.center, + decoration: InputDecoration(), + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold)), + ], + ), + ), + actions: [ + TextButton( + child: Text("Valider"), + onPressed: () { + WidgetsBinding.instance.addPostFrameCallback((_) { + _renameWallet(_walletName, this._newWalletName.text); + }); + notifyListeners(); + Navigator.pop(context, true); + }, + ), + ], + ); + }, + ); + } + + Future deleteWallet(context, _name) async { + try { + final _walletFile = Directory('${walletsDirectory.path}/$_name'); + print('DELETE THAT ?: $_walletFile'); + + final bool _answer = await _confirmDeletingWallet(context, _name); + + if (_answer) { + _walletFile.deleteSync(recursive: true); + isWalletUnlock = false; + Navigator.pop(context); + } + return 0; + } catch (e) { + return 1; + } + } + + Future _confirmDeletingWallet(context, _walletName) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: Text( + 'Êtes-vous sûr de vouloir supprimer le portefeuille "$_walletName" ?'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text( + 'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'), + ], + ), + ), + actions: [ + TextButton( + child: Text("Non"), + onPressed: () { + Navigator.pop(context, false); + }, + ), + TextButton( + child: Text("Oui"), + onPressed: () { + Navigator.pop(context, true); + }, + ), + ], + ); + }, + ); + } + + Future changePin(_name, _oldPin) async { + try { + final _walletFile = Directory('${walletsDirectory.path}/$_name'); + final _dewif = + File(_walletFile.path + '/wallet.dewif').readAsLinesSync()[0]; + + NewWallet newWalletFile = await DubpRust.changeDewifPin( + dewif: _dewif, + oldPin: _oldPin, + ); + + newPin.text = newWalletFile.pin; + ischangedPin = true; + // notifyListeners(); + return newWalletFile; + } catch (e) { + print('Impossible de changer le code PIN.'); + return badWallet; + } + } + + Future storeWallet(context, _name, _newWalletFile) async { + final Directory walletNameDirectory = + Directory('${walletsDirectory.path}/$_name'); + final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); + + walletFile.writeAsString('${_newWalletFile.dewif}'); + + Navigator.pop(context); + + return _name; + } +} diff --git a/lib/ui/historyScreen.dart b/lib/ui/historyScreen.dart index d8875bb..0ce9435 100644 --- a/lib/ui/historyScreen.dart +++ b/lib/ui/historyScreen.dart @@ -25,7 +25,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier { _historyProvider = Provider.of(context); this._outputPubkey.text = _historyProvider.pubkey; print('Build pubkey : ' + _historyProvider.pubkey); - // scrollController.addListener(scrollListener); return Scaffold( floatingActionButton: Container( height: 80.0, diff --git a/lib/ui/home.dart b/lib/ui/home.dart index 1a8b83f..d09538f 100644 --- a/lib/ui/home.dart +++ b/lib/ui/home.dart @@ -9,8 +9,6 @@ import 'package:provider/provider.dart'; // ignore: must_be_immutable class HomeScreen extends StatelessWidget { - // HomeProvider _homeProvider = HomeProvider(); - var currentTab = [HistoryScreen(), WalletsHome()]; @override @@ -89,8 +87,7 @@ class HomeScreen extends StatelessWidget { currentIndex: _homeProvider.currentIndex, items: [ BottomNavigationBarItem( - icon: new Icon(Icons - .format_list_bulleted), //Icons.person_add_alt_1_rounded //Icons.lock + icon: new Icon(Icons.format_list_bulleted), label: 'Accueil', ), BottomNavigationBarItem( diff --git a/lib/ui/myWallets/changePin.dart b/lib/ui/myWallets/changePin.dart index 455b812..a3535fd 100644 --- a/lib/ui/myWallets/changePin.dart +++ b/lib/ui/myWallets/changePin.dart @@ -1,42 +1,33 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:dubp/dubp.dart'; +import 'package:gecko/models/walletOptions.dart'; import 'dart:io'; import 'dart:async'; import 'package:path_provider/path_provider.dart'; +import 'package:provider/provider.dart'; -class ChangePinScreen extends StatefulWidget { - const ChangePinScreen( +// ignore: must_be_immutable +class ChangePinScreen extends StatelessWidget with ChangeNotifier { + ChangePinScreen( {Key keyMyWallets, @required this.walletName, @required this.oldPin}) : super(key: keyMyWallets); - final String walletName; final oldPin; - @override - ChangePinScreenState createState() => ChangePinScreenState(); -} - -class ChangePinScreenState extends State { Directory appPath; - TextEditingController _newPin = new TextEditingController(); - bool ischangedPin = false; - NewWallet newWalletFile; - - Future get badWallet => null; - - void initState() { - super.initState(); - changePin(widget.walletName, widget.oldPin); - } + NewWallet _newWalletFile; @override Widget build(BuildContext context) { + WalletOptionsProvider _walletOptions = + Provider.of(context); + _walletOptions.changePin(walletName, oldPin); return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( title: SizedBox( height: 22, - child: Text(widget.walletName), + child: Text(walletName), )), body: Center( child: SafeArea( @@ -57,7 +48,7 @@ class ChangePinScreenState extends State { children: [ TextField( enabled: true, - controller: this._newPin, + controller: _walletOptions.newPin, maxLines: 1, textAlign: TextAlign.center, decoration: InputDecoration(), @@ -68,8 +59,9 @@ class ChangePinScreenState extends State { IconButton( icon: Icon(Icons.replay), color: Color(0xffD28928), - onPressed: () { - changePin(widget.walletName, widget.oldPin); + onPressed: () async { + _newWalletFile = + await _walletOptions.changePin(walletName, oldPin); }, ), ], @@ -85,50 +77,10 @@ class ChangePinScreenState extends State { primary: Colors.green[400], //Color(0xffFFD68E), // background onPrimary: Colors.black, // foreground ), - onPressed: (ischangedPin) - ? () => storeWallet(widget.walletName) - : null, + onPressed: () => _walletOptions.storeWallet( + context, walletName, _newWalletFile), child: Text('Confirmer', style: TextStyle(fontSize: 28))), ) ])))); } - - Future changePin(_name, _oldPin) async { - try { - final appPath = await _localPath; - final _walletFile = Directory('$appPath/wallets/$_name'); - final _dewif = - File(_walletFile.path + '/wallet.dewif').readAsLinesSync()[0]; - - newWalletFile = await DubpRust.changeDewifPin( - dewif: _dewif, - oldPin: _oldPin, - ); - - _newPin.text = newWalletFile.pin; - ischangedPin = true; - setState(() {}); - return newWalletFile; - } catch (e) { - print('Impossible de changer le code PIN.'); - return badWallet; - } - } - - Future storeWallet(_name) async { - final appPath = await _localPath; - final Directory walletNameDirectory = Directory('$appPath/wallets/$_name'); - final walletFile = File('${walletNameDirectory.path}/wallet.dewif'); - - walletFile.writeAsString('${this.newWalletFile.dewif}'); - - Navigator.pop(context); - - return _name; - } - - Future get _localPath async { - final directory = await getApplicationDocumentsDirectory(); - return directory.path; - } } diff --git a/lib/ui/myWallets/confirmWalletStorage.dart b/lib/ui/myWallets/confirmWalletStorage.dart index 64c59a2..09d448f 100644 --- a/lib/ui/myWallets/confirmWalletStorage.dart +++ b/lib/ui/myWallets/confirmWalletStorage.dart @@ -1,6 +1,8 @@ +import 'package:dubp/dubp.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/models/generateWallets.dart'; +import 'package:gecko/models/myWallets.dart'; import 'package:provider/provider.dart'; // ignore: must_be_immutable @@ -8,37 +10,42 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier { ConfirmStoreWallet({ Key validationKey, @required this.generatedMnemonic, - @required generatedWallet, + @required this.generatedWallet, }) : super(key: validationKey); String generatedMnemonic; + NewWallet generatedWallet; - // @override - // void dispose() { - // _wordFocus.dispose(); - // _walletNameFocus.dispose(); - // super.dispose(); - // } - - TextEditingController _mnemonicController = new TextEditingController(); - TextEditingController _pubkey = new TextEditingController(); - TextEditingController _inputRestoreWord = new TextEditingController(); - TextEditingController walletName = new TextEditingController(); + TextEditingController _mnemonicController = TextEditingController(); + TextEditingController _pubkey = TextEditingController(); + TextEditingController _inputRestoreWord = TextEditingController(); + TextEditingController walletName = TextEditingController(); FocusNode _wordFocus = FocusNode(); @override Widget build(BuildContext context) { - var _generateWalletProvider = Provider.of(context); + GenerateWalletsProvider _generateWalletProvider = + Provider.of(context); + MyWalletsProvider _myWalletProvider = + Provider.of(context); + print("JE BUILD !!!"); this._mnemonicController.text = generatedMnemonic; - this._pubkey.text = _generateWalletProvider.generatedWallet.publicKey; + this._pubkey.text = generatedWallet.publicKey; return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back, color: Colors.black), + onPressed: () { + Navigator.of(context).pop(); + _generateWalletProvider.isAskedWordValid = false; + _generateWalletProvider.askedWordColor = Colors.black; + }), title: SizedBox( - height: 22, - child: Text('Confirmez ce portefeuille'), - )), + height: 22, + child: Text('Confirmez ce portefeuille'), + )), body: Center( child: Column(children: [ SizedBox(height: 15), @@ -97,12 +104,10 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier { ), TextFormField( focusNode: _generateWalletProvider.walletNameFocus, - // autofocus: true, inputFormatters: [ FilteringTextInputFormatter.allow( RegExp('[A-Za-z|0-9|\\-|_| ]')), ], - // enabled: isAskedWordValid, controller: this.walletName, textInputAction: TextInputAction.next, onChanged: (v) { @@ -130,8 +135,20 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier { ), onPressed: (_generateWalletProvider.isAskedWordValid && this.walletName.text != '') - ? () => _generateWalletProvider.storeWallet( - walletName.text, _pubkey.text, context) + ? () { + _generateWalletProvider.storeWallet( + generatedWallet, walletName.text, context); + _generateWalletProvider.isAskedWordValid = + false; + _generateWalletProvider.askedWordColor = + Colors.black; + WidgetsBinding.instance + .addPostFrameCallback((_) { + _myWalletProvider.listWallets = + _myWalletProvider.getAllWalletsNames(); + _myWalletProvider.rebuildWidget(); + }); + } : null, child: Text('Confirmer', style: TextStyle(fontSize: 28))), diff --git a/lib/ui/myWallets/generateWalletsScreen.dart b/lib/ui/myWallets/generateWalletsScreen.dart index 5cdd130..d33734f 100644 --- a/lib/ui/myWallets/generateWalletsScreen.dart +++ b/lib/ui/myWallets/generateWalletsScreen.dart @@ -7,8 +7,6 @@ import 'package:super_tooltip/super_tooltip.dart'; // ignore: must_be_immutable class GenerateWalletsScreen extends StatelessWidget { SuperTooltip tooltip; - // final formKey = GlobalKey(); - bool hasError = false; String validPin = 'NO PIN'; String currentText = ""; @@ -16,8 +14,11 @@ class GenerateWalletsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - var _generateWalletProvider = Provider.of(context); + GenerateWalletsProvider _generateWalletProvider = + Provider.of(context); _generateWalletProvider.generateMnemonic(); + print('IS GENERATED ? : ' + + _generateWalletProvider.walletIsGenerated.toString()); return Scaffold( appBar: AppBar( title: SizedBox( @@ -31,10 +32,6 @@ class GenerateWalletsScreen extends StatelessWidget { child: FloatingActionButton( heroTag: "buttonGenerateWallet", onPressed: () => _generateWalletProvider.generateMnemonic(), - // print(resultScan); - // if (resultScan != 'false') { - // onTabTapped(0); - // } child: Container( height: 40.0, width: 40.0, @@ -128,7 +125,6 @@ class GenerateWalletsScreen extends StatelessWidget { ), ), SizedBox(height: 20), - // Expanded(child: Align(alignment: Alignment.bottomCenter)), new ElevatedButton( style: ElevatedButton.styleFrom( primary: Color(0xffFFD68E), // background @@ -136,28 +132,18 @@ class GenerateWalletsScreen extends StatelessWidget { ), onPressed: _generateWalletProvider.walletIsGenerated ? () { + _generateWalletProvider.nbrWord = + _generateWalletProvider.getRandomInt(); Navigator.push( context, MaterialPageRoute(builder: (context) { return ConfirmStoreWallet( - // validationKey: _keyValidWallets, generatedMnemonic: _generateWalletProvider.generatedMnemonic, generatedWallet: _generateWalletProvider.actualWallet); }), - ) - // .then((value) => setState(() { - // if (value != null) { - // _pin.clear(); - // _mnemonicController.clear(); - // _pubkey.clear(); - // this.generatedMnemonic = null; - // this.actualWallet = null; - // this.walletIsGenerated = false; - // } - // })) - ; + ); } : null, child: Text('Enregistrer ce portefeuille', diff --git a/lib/ui/myWallets/walletOptions.dart b/lib/ui/myWallets/walletOptions.dart index 1f7d234..2ad5a5b 100644 --- a/lib/ui/myWallets/walletOptions.dart +++ b/lib/ui/myWallets/walletOptions.dart @@ -1,57 +1,54 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:dubp/dubp.dart'; +import 'package:gecko/models/walletOptions.dart'; import 'package:gecko/ui/myWallets/changePin.dart'; import 'dart:io'; import 'dart:async'; -import 'package:path_provider/path_provider.dart'; import 'package:pin_code_fields/pin_code_fields.dart'; -import 'package:sentry/sentry.dart' as sentry; +import 'package:provider/provider.dart'; -class WalletOptions extends StatefulWidget { - const WalletOptions({Key keyMyWallets, @required this.walletName}) +// ignore: must_be_immutable +class WalletOptions extends StatelessWidget with ChangeNotifier { + WalletOptions({Key keyMyWallets, @required this.walletName}) : super(key: keyMyWallets); + String walletName; - final String walletName; - @override - WalletOptionsState createState() => WalletOptionsState(); -} - -class WalletOptionsState extends State { StreamController errorController; Directory appPath; - TextEditingController _pubkey = new TextEditingController(); TextEditingController _enterPin = new TextEditingController(); - TextEditingController _newWalletName = new TextEditingController(); final formKey = GlobalKey(); bool hasError = false; String validPin = 'NO PIN'; var pinColor = Color(0xffF9F9F1); - bool isWalletUnlock = false; var walletPin = ''; Future get badWallet => null; - void initState() { - super.initState(); - errorController = StreamController(); - isWalletUnlock = false; - } - @override Widget build(BuildContext context) { + WalletOptionsProvider _walletOptions = + Provider.of(context); + errorController = StreamController(); + // _walletOptions.isWalletUnlock = false; return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back, color: Colors.black), + onPressed: () { + Navigator.of(context).pop(); + _walletOptions.isWalletUnlock = false; + }), title: SizedBox( - height: 22, - child: Text(widget.walletName), - )), + height: 22, + child: Text(walletName), + )), body: Center( child: SafeArea( child: Column(children: [ Visibility( - visible: isWalletUnlock, + visible: _walletOptions.isWalletUnlock, child: Expanded( child: Column(children: [ SizedBox(height: 15), @@ -64,7 +61,7 @@ class WalletOptionsState extends State { ), SizedBox(height: 15), Text( - this._pubkey.text, + _walletOptions.pubkey.text, style: TextStyle( fontSize: 14.0, color: Colors.black, @@ -83,9 +80,10 @@ class WalletOptionsState extends State { 0xffFFD68E), //Color(0xffFFD68E), // background onPrimary: Colors.black, // foreground ), - onPressed: () => - _renameWalletAlerte().then((_) { - setState(() {}); + onPressed: () => _walletOptions + .renameWalletAlerte(context, walletName) + .then((_) { + notifyListeners(); }), child: Text('Renommer ce portefeuille', style: TextStyle(fontSize: 20)))))), @@ -106,7 +104,7 @@ class WalletOptionsState extends State { context, MaterialPageRoute(builder: (context) { return ChangePinScreen( - walletName: widget.walletName, + walletName: walletName, oldPin: this.walletPin); }), ); @@ -125,7 +123,7 @@ class WalletOptionsState extends State { onPrimary: Colors.black, // foreground ), onPressed: () { - _deleteWallet(widget.walletName); + _walletOptions.deleteWallet(context, walletName); }, child: Text('Supprimer ce portefeuille', style: TextStyle(fontSize: 20)))), @@ -140,7 +138,7 @@ class WalletOptionsState extends State { SizedBox(height: 10) ]))), Visibility( - visible: !isWalletUnlock, + visible: !_walletOptions.isWalletUnlock, child: Expanded( child: Column(children: [ SizedBox(height: 80), @@ -202,28 +200,26 @@ class WalletOptionsState extends State { onCompleted: (_pin) async { print("Completed"); final resultWallet = - await _readLocalWallet(_pin.toUpperCase()); + await _walletOptions.readLocalWallet( + this.walletName, _pin.toUpperCase()); if (resultWallet == 'bad') { errorController.add(ErrorAnimationType .shake); // Triggering error shake animation - setState(() { - hasError = true; - pinColor = Colors.red[200]; - }); + hasError = true; + pinColor = Colors.red[200]; + notifyListeners(); } else { pinColor = Colors.green[200]; // setState(() {}); // await Future.delayed(Duration(milliseconds: 50)); this.walletPin = _pin.toUpperCase(); - isWalletUnlock = true; - setState(() {}); + // isWalletUnlock = true; + notifyListeners(); } }, onChanged: (value) { if (pinColor != Color(0xffF9F9F1)) { - setState(() { - pinColor = Color(0xffF9F9F1); - }); + pinColor = Color(0xffF9F9F1); } print(value); }, @@ -232,174 +228,4 @@ class WalletOptionsState extends State { ]))), ])))); } - - Future _getPubkeyFromDewif(_dewif, _pin) async { - String _pubkey; - RegExp regExp = new RegExp( - r'^[A-Z0-9]+$', - caseSensitive: false, - multiLine: false, - ); - - if (regExp.hasMatch(_pin) == true && _pin.length == 6) { - print("Le format du code PIN est correct."); - } else { - print('Format de code PIN invalide'); - return 'false'; - } - try { - _pubkey = await DubpRust.getDewifPublicKey(dewif: _dewif, pin: _pin); - setState(() { - this._pubkey.text = _pubkey; - }); - - return _pubkey; - } catch (e, stack) { - print('Bad PIN code !'); - print(e); - if (kReleaseMode) { - await sentry.Sentry.captureException( - e, - stackTrace: stack, - ); - } - return 'false'; - } - } - - Future _readLocalWallet(String _pin) async { - // print(pin); - try { - final file = await _localWallet(widget.walletName); - String _localDewif = await file.readAsString(); - String _localPubkey; - - if ((_localPubkey = await _getPubkeyFromDewif(_localDewif, _pin)) != - 'false') { - setState(() { - this._pubkey.text = _localPubkey; - }); - - return _localDewif; - } else { - throw 'Bad pubkey'; - } - } catch (e) { - print('ERROR READING FILE: $e'); - setState(() { - this._pubkey.clear(); - }); - return 'bad'; - } - } - - Future _renameWallet(_newName) async { - final appPath = await _localPath; - final _walletFile = Directory('$appPath/wallets/${widget.walletName}'); - - try { - _walletFile.rename('$appPath/wallets/$_newName'); - } catch (e) { - print('ERREUR lors du renommage du wallet: $e'); - } - } - - Future _renameWalletAlerte() async { - return showDialog( - context: context, - barrierDismissible: true, // user must tap button! - builder: (BuildContext context) { - return AlertDialog( - title: Text('Choisissez un nouveau nom pour ce portefeuille'), - content: SingleChildScrollView( - child: ListBody( - children: [ - TextField( - controller: this._newWalletName, - maxLines: 1, - textAlign: TextAlign.center, - decoration: InputDecoration(), - style: TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: FontWeight.bold)), - ], - ), - ), - actions: [ - TextButton( - child: Text("Valider"), - onPressed: () { - _renameWallet(this._newWalletName.text); - Navigator.pop(context, true); - }, - ), - ], - ); - }, - ); - } - - Future _deleteWallet(_name) async { - try { - final appPath = await _localPath; - final _walletFile = Directory('$appPath/wallets/$_name'); - print('DELETE THAT ?: $_walletFile'); - - final bool _answer = await _confirmDeletingWallet(); - - if (_answer) { - _walletFile.deleteSync(recursive: true); - Navigator.pop(context); - } - return 0; - } catch (e) { - return 1; - } - } - - Future _confirmDeletingWallet() async { - return showDialog( - context: context, - barrierDismissible: true, // user must tap button! - builder: (BuildContext context) { - return AlertDialog( - title: Text( - 'Êtes-vous sûr de vouloir supprimer le portefeuille "${widget.walletName}" ?'), - content: SingleChildScrollView( - child: ListBody( - children: [ - Text( - 'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'), - ], - ), - ), - actions: [ - TextButton( - child: Text("Non"), - onPressed: () { - Navigator.pop(context, false); - }, - ), - TextButton( - child: Text("Oui"), - onPressed: () { - Navigator.pop(context, true); - }, - ), - ], - ); - }, - ); - } - - Future get _localPath async { - final directory = await getApplicationDocumentsDirectory(); - return directory.path; - } - - Future _localWallet(_name) async { - final path = await _localPath; - return File('$path/wallets/$_name/wallet.dewif'); - } } diff --git a/lib/ui/myWallets/walletsHome.dart b/lib/ui/myWallets/walletsHome.dart index c109c23..7f44b31 100644 --- a/lib/ui/myWallets/walletsHome.dart +++ b/lib/ui/myWallets/walletsHome.dart @@ -2,21 +2,21 @@ import 'package:gecko/models/myWallets.dart'; import 'package:gecko/ui/myWallets/generateWalletsScreen.dart'; import 'package:flutter/material.dart'; import 'package:gecko/ui/myWallets/walletOptions.dart'; +import 'package:provider/provider.dart'; // ignore: must_be_immutable class WalletsHome extends StatelessWidget { - MyWalletsProvider myWalletProvider = MyWalletsProvider(); - @override Widget build(BuildContext context) { + MyWalletsProvider myWalletProvider = + Provider.of(context); print('BUILD: WalletsHome'); myWalletProvider.checkIfWalletExist(); myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames(); return Scaffold( floatingActionButton: Visibility( - visible: (myWalletProvider - .checkIfWalletExist()), //!checkIfWalletExist('MonWallet') && + visible: (myWalletProvider.checkIfWalletExist()), child: Container( height: 80.0, width: 80.0, @@ -84,19 +84,9 @@ class WalletsHome extends StatelessWidget { ]))); } - // Future resetWalletState() async { - // final bool _isExist = await checkIfWalletExist('MonWallet'); - // print('The wallet exist in resetWalletState(): ' + _isExist.toString()); - // // initState(); - // // _keyMyWallets.currentState.setState(() {}); - // // _keyMyWallets.currentState.initAppDirectory(); - // setState(() { - // // getAllWalletsNames(); - // // this.walletIsGenerated = true; - // }); - // } - myWalletsList(BuildContext context) { + MyWalletsProvider myWalletProvider = + Provider.of(context); return Column(children: [ SizedBox(height: 8), for (var repository in myWalletProvider.listWallets) @@ -111,22 +101,7 @@ class WalletsHome extends StatelessWidget { return WalletOptions(walletName: repository); })); }, - ), - SizedBox(height: 20), - SizedBox( - width: 75.0, - height: 25.0, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - elevation: 2, - primary: Color(0xffFFD68E), //Color(0xffFFD68E), // background - onPrimary: Colors.black, // foreground - ), - onPressed: () { - myWalletProvider.listWallets = - myWalletProvider.getAllWalletsNames(); - }, - child: Text('(Refresh)', style: TextStyle(fontSize: 10)))) + ) ]); } } diff --git a/lib/ui/settingsScreen.dart b/lib/ui/settingsScreen.dart index 39cd682..736b6bc 100644 --- a/lib/ui/settingsScreen.dart +++ b/lib/ui/settingsScreen.dart @@ -1,21 +1,10 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:dubp/dubp.dart'; +import 'package:gecko/models/myWallets.dart'; import 'dart:io'; -import 'dart:async'; -import 'package:path_provider/path_provider.dart'; - -class SettingsScreen extends StatefulWidget { - const SettingsScreen({Key keyGenWallet}) : super(key: keyGenWallet); - @override - _SettingsScreenState createState() => _SettingsScreenState(); -} - -class _SettingsScreenState extends State { - void initState() { - super.initState(); - } +// ignore: must_be_immutable +class SettingsScreen extends StatelessWidget { String generatedMnemonic; bool walletIsGenerated = false; NewWallet actualWallet; @@ -27,6 +16,8 @@ class _SettingsScreenState extends State { var pinColor = Colors.grey[300]; Directory appPath; + MyWalletsProvider _myWallets = MyWalletsProvider(); + @override Widget build(BuildContext context) { // getAppDirectory(); @@ -53,7 +44,7 @@ class _SettingsScreenState extends State { ), onPressed: () => { print('Suppression de tous les wallets'), - _deleteWallet() + _myWallets.deleteAllWallet(context) }, child: Text( "EFFACER TOUS MES PORTEFEUILLES, LE TEMPS DE L'ALPHA", @@ -61,56 +52,4 @@ class _SettingsScreenState extends State { SizedBox(height: 50), ])); } - - Future _deleteWallet() async { - try { - final appPath = await _localPath; - final _walletsFolder = Directory('$appPath/wallets'); - print('DELETE THAT ?: $_walletsFolder'); - - final bool _answer = await _confirmDeletingWallets(); - - if (_answer) { - _walletsFolder.deleteSync(recursive: true); - _walletsFolder.createSync(); - Navigator.pop(context); - } - return 0; - } catch (e) { - return 1; - } - } - - Future _confirmDeletingWallets() async { - return showDialog( - context: context, - barrierDismissible: true, // user must tap button! - builder: (BuildContext context) { - return AlertDialog( - title: Text( - 'Êtes-vous sûr de vouloir supprimer tous vos portefeuilles ?'), - content: SingleChildScrollView(child: Text('')), - actions: [ - TextButton( - child: Text("Non"), - onPressed: () { - Navigator.pop(context, false); - }, - ), - TextButton( - child: Text("Oui"), - onPressed: () { - Navigator.pop(context, true); - }, - ), - ], - ); - }, - ); - } - - Future get _localPath async { - final directory = await getApplicationDocumentsDirectory(); - return directory.path; - } }