Complete review of wallet unlocking; Improve routes using

This commit is contained in:
poka 2021-03-08 02:20:48 +01:00
parent 9d11b7fcb5
commit 693426a156
6 changed files with 295 additions and 329 deletions

View File

@ -207,7 +207,10 @@ class WalletOptionsProvider with ChangeNotifier {
final _walletFile = Directory('${walletsDirectory.path}/$_walletNbr'); final _walletFile = Directory('${walletsDirectory.path}/$_walletNbr');
await _walletFile.delete(recursive: true); await _walletFile.delete(recursive: true);
} }
Navigator.pop(context); Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
} }
return 0; return 0;
} }

View File

@ -4,7 +4,6 @@ import 'package:gecko/models/history.dart';
import 'package:gecko/models/home.dart'; import 'package:gecko/models/home.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/myWallets.dart';
import 'package:gecko/screens/myWallets/walletsHome.dart';
import 'package:gecko/screens/onBoarding/1_noKeychainFound.dart'; import 'package:gecko/screens/onBoarding/1_noKeychainFound.dart';
import 'dart:ui'; import 'dart:ui';
import 'package:gecko/screens/settings.dart'; import 'package:gecko/screens/settings.dart';
@ -271,13 +270,8 @@ class HomeScreen extends StatelessWidget {
height: 57)), height: 57)),
onTap: () { onTap: () {
isWalletsExists isWalletsExists
? Navigator.push( ? Navigator.pushNamed(
context, context, '/mywallets')
MaterialPageRoute(
builder: (context) {
return WalletsHome();
}),
)
: Navigator.push(context, : Navigator.push(context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) { builder: (context) {

View File

@ -0,0 +1,164 @@
import 'dart:async';
import 'package:dubp/dubp.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/walletOptions.dart';
import 'package:gecko/screens/commonElements.dart';
import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/walletOptions.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class UnlockingWallet extends StatelessWidget {
UnlockingWallet(
{Key keyUnlockWallet,
@required this.walletNbr,
@required this.walletName,
@required this.derivation})
: super(key: keyUnlockWallet);
int walletNbr;
String walletName;
int derivation;
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController;
final formKey = GlobalKey<FormState>();
bool hasError = false;
var pinColor = Color(0xffF9F9F1);
var walletPin = '';
Future<NewWallet> get badWallet => null;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
final int _pinLenght = _walletOptions.getPinLenght(this.walletNbr);
errorController = StreamController<ErrorAnimationType>();
return Scaffold(
// backgroundColor: Colors.brown[600],
body: SafeArea(
child: Column(children: <Widget>[
SizedBox(height: 20),
Expanded(
child: Column(children: <Widget>[
SizedBox(height: 150),
Text(
'Veuillez tapper votre code secret pour dévérouiller votre portefeuille.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
fontWeight: FontWeight.w400),
),
SizedBox(height: 50),
pinForm(context, _pinLenght, walletNbr, derivation),
]),
),
GestureDetector(
onTap: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
},
child: Icon(Icons.home))
]),
));
}
Widget pinForm(context, _pinLenght, int _walletNbr, int _derivation) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController _enterPin = TextEditingController();
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
return Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
autoFocus: true,
appContext: context,
pastedTextStyle: TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: _pinLenght,
obscureText: false,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v.length < _pinLenght) {
return "Votre code PIN fait $_pinLenght caractères";
} else {
return null;
}
},
pinTheme: PinTheme(
activeColor: pinColor,
borderWidth: 4,
shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(5),
fieldHeight: 60,
fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
),
cursorColor: Colors.black,
animationDuration: Duration(milliseconds: 300),
textStyle: TextStyle(fontSize: 20, height: 1.6),
backgroundColor: Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: _enterPin,
keyboardType: TextInputType.text,
boxShadows: [
BoxShadow(
offset: Offset(0, 1),
color: Colors.black12,
blurRadius: 10,
)
],
onCompleted: (_pin) async {
print("Completed");
final resultWallet = await _walletOptions.readLocalWallet(
this.walletNbr,
_pin.toUpperCase(),
_pinLenght,
this.derivation);
if (resultWallet == 'bad') {
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600];
_walletOptions.reloadBuild();
} else {
pinColor = Colors.green[400];
// await Future.delayed(Duration(milliseconds: 50));
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
walletNbr: walletNbr,
walletName: walletName,
derivation: derivation)));
}
},
onChanged: (value) {
if (pinColor != Color(0xFFA4B600)) {
pinColor = Color(0xFFA4B600);
}
print(value);
},
)),
);
}
}

View File

@ -1,10 +1,8 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:dubp/dubp.dart';
import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/myWallets.dart';
import 'package:gecko/models/walletOptions.dart'; import 'package:gecko/models/walletOptions.dart';
import 'dart:async'; import 'dart:async';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -20,15 +18,6 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
String walletName; String walletName;
int derivation; int derivation;
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController;
final formKey = GlobalKey<FormState>();
bool hasError = false;
var pinColor = Color(0xffF9F9F1);
var walletPin = '';
Future<NewWallet> get badWallet => null;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
@ -37,319 +26,137 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
errorController = StreamController<ErrorAnimationType>();
// _walletOptions.isWalletUnlock = false; // _walletOptions.isWalletUnlock = false;
print("Is unlock ? ${_walletOptions.isWalletUnlock}"); print("Is unlock ? ${_walletOptions.isWalletUnlock}");
final int _pinLenght = _walletOptions.getPinLenght(this.walletNbr);
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
_walletOptions.isWalletUnlock = false; _walletOptions.isWalletUnlock = false;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
return Future<bool>.value(true); return Future<bool>.value(true);
}, },
child: Scaffold( child: Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black), icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { onPressed: () {
_walletOptions.isWalletUnlock = false; _walletOptions.isWalletUnlock = false;
Navigator.of(context).pop(); Navigator.popUntil(
}), context,
title: SizedBox( ModalRoute.withName('/mywallets'),
height: 22, );
child: Text(walletName), }),
)), title: SizedBox(
body: Builder( height: 22,
builder: (ctx) => SafeArea( child: Text(walletName),
child: Column(children: <Widget>[ )),
Visibility( body: Builder(
visible: _walletOptions.isWalletUnlock, builder: (ctx) => SafeArea(
child: Expanded( child: Column(children: <Widget>[
child: Column(children: <Widget>[ Expanded(
SizedBox(height: 15), child: Column(children: <Widget>[
Text( SizedBox(height: 15),
'Clé publique:', Text(
'Clé publique:',
style: TextStyle(
fontSize: 15.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
SizedBox(height: 15),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Text(
_walletOptions.pubkey.text,
style: TextStyle( style: TextStyle(
fontSize: 15.0, fontSize: 14.0,
color: Colors.grey[600],
fontWeight: FontWeight.w400),
),
SizedBox(height: 15),
GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Text(
_walletOptions.pubkey.text,
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.bold,
fontFamily: 'Monospace'),
)),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 50,
width: 300,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 5,
primary: Color(
0xffFFD68E), //Color(0xffFFD68E), // background
onPrimary:
Colors.black, // foreground
),
onPressed: () => _walletOptions
.renameWalletAlerte(
context,
walletName,
walletNbr,
derivation)
.then((_result) {
if (_result == true) {
WidgetsBinding.instance
.addPostFrameCallback(
(_) {
_myWalletProvider
.listWallets =
_myWalletProvider
.getAllWalletsNames();
_myWalletProvider
.rebuildWidget();
});
Navigator.pop(
context, true);
}
}),
child: Text(
'Renommer ce portefeuille',
style: TextStyle(
fontSize: 20)))))),
SizedBox(height: 30),
SizedBox(
height: 50,
width: 300,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 6,
primary: Colors
.redAccent, //Color(0xffFFD68E), // background
onPrimary: Colors.black, // foreground
),
onPressed: () async {
await _walletOptions.deleteWallet(context,
walletNbr, walletName, derivation);
WidgetsBinding.instance
.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider
.getAllWalletsNames();
_myWalletProvider.rebuildWidget();
});
},
child: Text('Supprimer ce portefeuille',
style: TextStyle(fontSize: 20)))),
SizedBox(height: 50),
Text(
'Portefeuille déverrouillé',
style: TextStyle(
color: Colors.green,
fontWeight: FontWeight.w700,
fontSize: 15),
),
SizedBox(height: 10)
]))),
Visibility(
visible: !_walletOptions.isWalletUnlock,
child: Expanded(
child: Column(children: <Widget>[
SizedBox(height: 80),
Text(
'Veuillez tapper votre code secret pour dévérouiller votre portefeuille.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
color: Colors.black, color: Colors.black,
fontWeight: FontWeight.w400), fontWeight: FontWeight.bold,
), fontFamily: 'Monospace'),
SizedBox(height: 50), )),
pinForm(context, _pinLenght, walletNbr, derivation) Expanded(
// Form( child: Align(
// key: formKey, alignment: Alignment.bottomCenter,
// child: Padding( child: SizedBox(
// padding: const EdgeInsets.symmetric( height: 50,
// vertical: 8.0, horizontal: 30), width: 300,
// child: PinCodeTextField( child: ElevatedButton(
// autoFocus: true, style: ElevatedButton.styleFrom(
// appContext: context, elevation: 5,
// pastedTextStyle: TextStyle( primary: Color(
// color: Colors.green.shade600, 0xffFFD68E), //Color(0xffFFD68E), // background
// fontWeight: FontWeight.bold, onPrimary: Colors.black, // foreground
// ), ),
// length: _pinLenght, onPressed: () => _walletOptions
// obscureText: false, .renameWalletAlerte(
// obscuringCharacter: '*', context,
// animationType: AnimationType.fade, walletName,
// validator: (v) { walletNbr,
// if (v.length < _pinLenght) { derivation)
// return "Votre code PIN fait $_pinLenght caractères"; .then((_result) {
// } else { if (_result == true) {
// return null; WidgetsBinding.instance
// } .addPostFrameCallback((_) {
// }, _myWalletProvider
// pinTheme: PinTheme( .listWallets =
// shape: PinCodeFieldShape.box, _myWalletProvider
// borderRadius: BorderRadius.circular(5), .getAllWalletsNames();
// fieldHeight: 60, _myWalletProvider
// fieldWidth: 50, .rebuildWidget();
// activeFillColor: hasError });
// ? Colors.orange Navigator.popUntil(
// : Colors.white, context,
// ), ModalRoute.withName(
// cursorColor: Colors.black, '/mywallets'),
// animationDuration: );
// Duration(milliseconds: 300), }
// textStyle: }),
// TextStyle(fontSize: 20, height: 1.6), child: Text('Renommer ce portefeuille',
// backgroundColor: pinColor, style: TextStyle(fontSize: 20)))))),
// enableActiveFill: false, SizedBox(height: 30),
// errorAnimationController: errorController, SizedBox(
// controller: _enterPin, height: 50,
// keyboardType: TextInputType.text, width: 300,
// boxShadows: [ child: ElevatedButton(
// BoxShadow( style: ElevatedButton.styleFrom(
// offset: Offset(0, 1), elevation: 6,
// color: Colors.black12, primary: Colors
// blurRadius: 10, .redAccent, //Color(0xffFFD68E), // background
// ) onPrimary: Colors.black, // foreground
// ], ),
// onCompleted: (_pin) async { onPressed: () async {
// print("Completed"); await _walletOptions.deleteWallet(context,
// final resultWallet = walletNbr, walletName, derivation);
// await _walletOptions.readLocalWallet( WidgetsBinding.instance
// this.walletNbr, .addPostFrameCallback((_) {
// _pin.toUpperCase(), _myWalletProvider.listWallets =
// _pinLenght, _myWalletProvider.getAllWalletsNames();
// this.derivation); _myWalletProvider.rebuildWidget();
// if (resultWallet == 'bad') { });
// errorController.add(ErrorAnimationType },
// .shake); // Triggering error shake animation child: Text('Supprimer ce portefeuille',
// hasError = true; style: TextStyle(fontSize: 20)))),
// pinColor = Colors.red[200]; SizedBox(height: 50),
// notifyListeners(); Text(
// } else { 'Portefeuille déverrouillé',
// pinColor = Colors.green[200]; style: TextStyle(
// // setState(() {}); color: Colors.green,
// // await Future.delayed(Duration(milliseconds: 50)); fontWeight: FontWeight.w700,
// this.walletPin = _pin.toUpperCase(); fontSize: 15),
// // isWalletUnlock = true; ),
// notifyListeners(); SizedBox(height: 10)
// } ])),
// }, ]),
// onChanged: (value) { )),
// if (pinColor != Color(0xffF9F9F1)) { ));
// pinColor = Color(0xffF9F9F1);
// }
// print(value);
// },
// )),
// )
]))),
])))));
}
Widget pinForm(context, _pinLenght, int _walletNbr, int _derivation) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController _enterPin = TextEditingController();
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
return Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
autoFocus: true,
appContext: context,
pastedTextStyle: TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: _pinLenght,
obscureText: false,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v.length < _pinLenght) {
return "Votre code PIN fait $_pinLenght caractères";
} else {
return null;
}
},
pinTheme: PinTheme(
activeColor: pinColor,
borderWidth: 4,
shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(5),
fieldHeight: 60,
fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
),
cursorColor: Colors.black,
animationDuration: Duration(milliseconds: 300),
textStyle: TextStyle(fontSize: 20, height: 1.6),
backgroundColor: Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: _enterPin,
keyboardType: TextInputType.text,
boxShadows: [
BoxShadow(
offset: Offset(0, 1),
color: Colors.black12,
blurRadius: 10,
)
],
onCompleted: (_pin) async {
print("Completed");
final resultWallet = await _walletOptions.readLocalWallet(
this.walletNbr,
_pin.toUpperCase(),
_pinLenght,
this.derivation);
if (resultWallet == 'bad') {
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600];
_walletOptions.reloadBuild();
} else {
pinColor = Colors.green[400];
// setState(() {});
// await Future.delayed(Duration(milliseconds: 50));
this.walletPin = _pin.toUpperCase();
_walletOptions.isWalletUnlock = true;
// isWalletUnlock = true;
_walletOptions.reloadBuild();
// notifyListeners();
}
},
onChanged: (value) {
if (pinColor != Color(0xFFA4B600)) {
pinColor = Color(0xFFA4B600);
}
print(value);
},
)),
);
} }
} }

View File

@ -2,7 +2,7 @@ import 'package:flutter/services.dart';
import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/myWallets.dart';
import 'package:gecko/models/walletOptions.dart'; import 'package:gecko/models/walletOptions.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/walletOptions.dart'; import 'package:gecko/screens/myWallets/unlockingWallet.dart';
import 'package:gecko/screens/onBoarding/1_noKeychainFound.dart'; import 'package:gecko/screens/onBoarding/1_noKeychainFound.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -97,7 +97,7 @@ class WalletsHome extends StatelessWidget {
dense: true, dense: true,
onTap: () { onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) { Navigator.push(context, MaterialPageRoute(builder: (context) {
return WalletOptions( return UnlockingWallet(
walletNbr: int.parse(_repository.split(':')[0]), walletNbr: int.parse(_repository.split(':')[0]),
walletName: _repository.split(':')[1], walletName: _repository.split(':')[1],
derivation: int.parse(_repository.split(':')[2])); derivation: int.parse(_repository.split(':')[2]));

View File

@ -71,11 +71,9 @@ class TemplateScreen extends StatelessWidget {
SizedBox(height: 20), SizedBox(height: 20),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
Navigator.push( Navigator.popUntil(
context, context,
MaterialPageRoute(builder: (context) { ModalRoute.withName('/'),
return HomeScreen();
}),
); );
}, },
child: Icon(Icons.home)) child: Icon(Icons.home))