Migrate all widget to stateless with provider fine
This commit is contained in:
parent
3d501f4544
commit
caf35fe19f
|
@ -4,6 +4,7 @@ import 'package:gecko/models/generateWallets.dart';
|
||||||
import 'package:gecko/models/history.dart';
|
import 'package:gecko/models/history.dart';
|
||||||
import 'package:gecko/models/home.dart';
|
import 'package:gecko/models/home.dart';
|
||||||
import 'package:gecko/models/myWallets.dart';
|
import 'package:gecko/models/myWallets.dart';
|
||||||
|
import 'package:gecko/models/walletOptions.dart';
|
||||||
import 'package:gecko/ui/home.dart';
|
import 'package:gecko/ui/home.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -93,39 +94,32 @@ class Gecko extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
DubpRust.setup();
|
DubpRust.setup();
|
||||||
return
|
return MultiProvider(
|
||||||
// MultiProvider(
|
providers: [
|
||||||
// providers: [
|
// Provider(create: (context) => HistoryProvider()),
|
||||||
// Provider(create: (context) => HistoryProvider()),
|
// Provider(create: (context) => MyWalletsProvider()),
|
||||||
// Provider(create: (context) => MyWalletsProvider()),
|
ChangeNotifierProvider(create: (_) => HomeProvider()),
|
||||||
// ],
|
ChangeNotifierProvider(create: (_) => HistoryProvider('')),
|
||||||
// child:
|
ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
|
||||||
MaterialApp(
|
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
|
||||||
title: 'Ğecko',
|
ChangeNotifierProvider(create: (_) => WalletOptionsProvider())
|
||||||
theme: ThemeData(
|
],
|
||||||
primaryColor: Color(0xffFFD58D),
|
child: GraphQLProvider(
|
||||||
accentColor: Colors.grey[850],
|
client: _client,
|
||||||
textTheme: TextTheme(
|
child: MaterialApp(
|
||||||
bodyText1: TextStyle(),
|
title: 'Ğecko',
|
||||||
bodyText2: TextStyle(),
|
theme: ThemeData(
|
||||||
).apply(
|
primaryColor: Color(0xffFFD58D),
|
||||||
bodyColor: Color(0xff855F2D),
|
accentColor: Colors.grey[850],
|
||||||
// displayColor: Colors.blue,
|
textTheme: TextTheme(
|
||||||
|
bodyText1: TextStyle(),
|
||||||
|
bodyText2: TextStyle(),
|
||||||
|
).apply(
|
||||||
|
bodyColor: Color(0xff855F2D),
|
||||||
|
// displayColor: Colors.blue,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
home: HomeScreen(),
|
||||||
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(),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,23 @@ import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart' as sentry;
|
import 'package:sentry_flutter/sentry_flutter.dart' as sentry;
|
||||||
|
|
||||||
class GenerateWalletsProvider with ChangeNotifier {
|
class GenerateWalletsProvider with ChangeNotifier {
|
||||||
NewWallet generatedWallet;
|
GenerateWalletsProvider();
|
||||||
|
// NewWallet generatedWallet;
|
||||||
|
NewWallet actualWallet;
|
||||||
|
|
||||||
FocusNode walletNameFocus = FocusNode();
|
FocusNode walletNameFocus = FocusNode();
|
||||||
Color askedWordColor = Colors.black;
|
Color askedWordColor = Colors.black;
|
||||||
bool isAskedWordValid = false;
|
bool isAskedWordValid = false;
|
||||||
int nbrWord;
|
int nbrWord;
|
||||||
|
|
||||||
String generatedMnemonic;
|
String generatedMnemonic;
|
||||||
bool walletIsGenerated = false;
|
bool walletIsGenerated = true;
|
||||||
NewWallet actualWallet;
|
|
||||||
|
|
||||||
TextEditingController mnemonicController = TextEditingController();
|
TextEditingController mnemonicController = TextEditingController();
|
||||||
TextEditingController pubkey = TextEditingController();
|
TextEditingController pubkey = TextEditingController();
|
||||||
TextEditingController pin = TextEditingController();
|
TextEditingController pin = TextEditingController();
|
||||||
|
|
||||||
Future storeWallet(_name, _pubkey, BuildContext context) async {
|
Future storeWallet(NewWallet wallet, _name, BuildContext context) async {
|
||||||
final appPath = await _localPath;
|
final appPath = await _localPath;
|
||||||
final Directory walletNameDirectory = Directory('$appPath/wallets/$_name');
|
final Directory walletNameDirectory = Directory('$appPath/wallets/$_name');
|
||||||
final walletFile = File('${walletNameDirectory.path}/wallet.dewif');
|
final walletFile = File('${walletNameDirectory.path}/wallet.dewif');
|
||||||
|
@ -34,10 +36,11 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
walletNameDirectory.createSync();
|
walletNameDirectory.createSync();
|
||||||
walletFile.writeAsString('${generatedWallet.dewif}');
|
walletFile.writeAsString('${wallet.dewif}');
|
||||||
|
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
Navigator.pop(context, _pubkey.text);
|
Navigator.pop(context, wallet.publicKey);
|
||||||
|
// notifyListeners();
|
||||||
|
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +51,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAskedWord(String value, String _mnemo) {
|
void checkAskedWord(String value, String _mnemo) {
|
||||||
nbrWord = getRandomInt();
|
// nbrWord = getRandomInt();
|
||||||
|
|
||||||
final runesAsked = _mnemo.split(' ')[nbrWord].runes;
|
final runesAsked = _mnemo.split(' ')[nbrWord].runes;
|
||||||
List<int> runesAskedUnaccent = [];
|
List<int> runesAskedUnaccent = [];
|
||||||
|
@ -71,10 +74,11 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
isAskedWordValid = true;
|
isAskedWordValid = true;
|
||||||
askedWordColor = Colors.green[600];
|
askedWordColor = Colors.green[600];
|
||||||
walletNameFocus.nextFocus();
|
walletNameFocus.nextFocus();
|
||||||
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
isAskedWordValid = false;
|
isAskedWordValid = false;
|
||||||
}
|
}
|
||||||
notifyListeners();
|
// notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
String removeDiacritics(String str) {
|
String removeDiacritics(String str) {
|
||||||
|
@ -118,6 +122,8 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
child: Text("J'ai compris"),
|
child: Text("J'ai compris"),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
askedWordColor = Colors.green[500];
|
||||||
|
isAskedWordValid = true;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -128,10 +134,10 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
|
|
||||||
Future<String> generateMnemonic() async {
|
Future<String> generateMnemonic() async {
|
||||||
try {
|
try {
|
||||||
this.generatedMnemonic =
|
generatedMnemonic = await DubpRust.genMnemonic(language: Language.french);
|
||||||
await DubpRust.genMnemonic(language: Language.french);
|
|
||||||
this.actualWallet = await generateWallet(this.generatedMnemonic);
|
this.actualWallet = await generateWallet(this.generatedMnemonic);
|
||||||
this.walletIsGenerated = true;
|
walletIsGenerated = true;
|
||||||
|
// notifyListeners();
|
||||||
} catch (e, stack) {
|
} catch (e, stack) {
|
||||||
print(e);
|
print(e);
|
||||||
if (kReleaseMode) {
|
if (kReleaseMode) {
|
||||||
|
@ -142,7 +148,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// await checkIfWalletExist();
|
// await checkIfWalletExist();
|
||||||
return this.generatedMnemonic;
|
return generatedMnemonic;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<NewWallet> generateWallet(generatedMnemonic) async {
|
Future<NewWallet> generateWallet(generatedMnemonic) async {
|
||||||
|
@ -162,11 +168,11 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
mnemonicController.text = generatedMnemonic;
|
mnemonicController.text = generatedMnemonic;
|
||||||
pubkey.text = actualWallet.publicKey;
|
pubkey.text = this.actualWallet.publicKey;
|
||||||
pin.text = actualWallet.pin;
|
pin.text = this.actualWallet.pin;
|
||||||
notifyListeners();
|
// notifyListeners();
|
||||||
|
|
||||||
return actualWallet;
|
return this.actualWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changePinCode() async {
|
Future<void> changePinCode() async {
|
||||||
|
@ -175,7 +181,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
oldPin: this.actualWallet.pin,
|
oldPin: this.actualWallet.pin,
|
||||||
);
|
);
|
||||||
|
|
||||||
pin.text = actualWallet.pin;
|
pin.text = this.actualWallet.pin;
|
||||||
notifyListeners();
|
// notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,6 @@ class HistoryProvider with ChangeNotifier {
|
||||||
final TextEditingController _outputPubkey = new TextEditingController();
|
final TextEditingController _outputPubkey = new TextEditingController();
|
||||||
// String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug
|
// String pubkey = 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'; // For debug
|
||||||
|
|
||||||
// FetchMoreOptions opts;
|
|
||||||
// ScrollController scrollController = new ScrollController();
|
|
||||||
|
|
||||||
Future scan() async {
|
Future scan() async {
|
||||||
await Permission.camera.request();
|
await Permission.camera.request();
|
||||||
String barcode;
|
String barcode;
|
||||||
|
@ -28,7 +25,6 @@ class HistoryProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
return 'false';
|
return 'false';
|
||||||
}
|
}
|
||||||
// this._outputPubkey.text = "";
|
|
||||||
if (barcode != null) {
|
if (barcode != null) {
|
||||||
this._outputPubkey.text = barcode;
|
this._outputPubkey.text = barcode;
|
||||||
isPubkey(barcode);
|
isPubkey(barcode);
|
||||||
|
@ -59,13 +55,4 @@ class HistoryProvider with ChangeNotifier {
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrollListener() {
|
|
||||||
// if (scrollController.offset >= scrollController.position.maxScrollExtent &&
|
|
||||||
// !scrollController.position.outOfRange) {
|
|
||||||
// print('On est en bas !!');
|
|
||||||
// // fetchMore(opts);
|
|
||||||
// notifyListeners();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MyWalletsProvider with ChangeNotifier {
|
class MyWalletsProvider with ChangeNotifier {
|
||||||
// Directory appPath;
|
|
||||||
List listWallets = [];
|
List listWallets = [];
|
||||||
|
|
||||||
bool checkIfWalletExist() {
|
bool checkIfWalletExist() {
|
||||||
|
@ -24,28 +24,14 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
List contents = walletsFolder.listSync();
|
List contents = walletsFolder.listSync();
|
||||||
if (contents.length == 0) {
|
if (contents.length == 0) {
|
||||||
print('No wallets detected');
|
print('No wallets detected');
|
||||||
notifyListeners();
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
print('Some wallets have been detected:');
|
print('Some wallets have been detected:');
|
||||||
for (var _wallets in contents) {
|
for (var _wallets in contents) {
|
||||||
print(_wallets);
|
print(_wallets);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
|
||||||
return true;
|
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 {}
|
Future importWallet() async {}
|
||||||
|
@ -63,8 +49,62 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
print(_name);
|
print(_name);
|
||||||
listWallets.add(_name);
|
listWallets.add(_name);
|
||||||
});
|
});
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
return listWallets;
|
return listWallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> 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<bool> _confirmDeletingAllWallets(context) async {
|
||||||
|
return showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true, // user must tap button!
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
MyWalletsProvider _myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context);
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(
|
||||||
|
'Êtes-vous sûr de vouloir supprimer tous vos portefeuilles ?'),
|
||||||
|
content: SingleChildScrollView(child: Text('')),
|
||||||
|
actions: <Widget>[
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<NewWallet> 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<bool> renameWalletAlerte(context, _walletName) async {
|
||||||
|
return showDialog<bool>(
|
||||||
|
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: <Widget>[
|
||||||
|
TextField(
|
||||||
|
controller: this._newWalletName,
|
||||||
|
maxLines: 1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
decoration: InputDecoration(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: Text("Valider"),
|
||||||
|
onPressed: () {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_renameWallet(_walletName, this._newWalletName.text);
|
||||||
|
});
|
||||||
|
notifyListeners();
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> 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<bool> _confirmDeletingWallet(context, _walletName) async {
|
||||||
|
return showDialog<bool>(
|
||||||
|
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: <Widget>[
|
||||||
|
Text(
|
||||||
|
'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: Text("Non"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, false);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text("Oui"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<NewWallet> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,6 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
|
||||||
_historyProvider = Provider.of<HistoryProvider>(context);
|
_historyProvider = Provider.of<HistoryProvider>(context);
|
||||||
this._outputPubkey.text = _historyProvider.pubkey;
|
this._outputPubkey.text = _historyProvider.pubkey;
|
||||||
print('Build pubkey : ' + _historyProvider.pubkey);
|
print('Build pubkey : ' + _historyProvider.pubkey);
|
||||||
// scrollController.addListener(scrollListener);
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
floatingActionButton: Container(
|
floatingActionButton: Container(
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
|
|
|
@ -9,8 +9,6 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
// HomeProvider _homeProvider = HomeProvider();
|
|
||||||
|
|
||||||
var currentTab = [HistoryScreen(), WalletsHome()];
|
var currentTab = [HistoryScreen(), WalletsHome()];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -89,8 +87,7 @@ class HomeScreen extends StatelessWidget {
|
||||||
currentIndex: _homeProvider.currentIndex,
|
currentIndex: _homeProvider.currentIndex,
|
||||||
items: [
|
items: [
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: new Icon(Icons
|
icon: new Icon(Icons.format_list_bulleted),
|
||||||
.format_list_bulleted), //Icons.person_add_alt_1_rounded //Icons.lock
|
|
||||||
label: 'Accueil',
|
label: 'Accueil',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
|
|
|
@ -1,42 +1,33 @@
|
||||||
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:dubp/dubp.dart';
|
||||||
|
import 'package:gecko/models/walletOptions.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ChangePinScreen extends StatefulWidget {
|
// ignore: must_be_immutable
|
||||||
const ChangePinScreen(
|
class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
||||||
|
ChangePinScreen(
|
||||||
{Key keyMyWallets, @required this.walletName, @required this.oldPin})
|
{Key keyMyWallets, @required this.walletName, @required this.oldPin})
|
||||||
: super(key: keyMyWallets);
|
: super(key: keyMyWallets);
|
||||||
|
|
||||||
final String walletName;
|
final String walletName;
|
||||||
final oldPin;
|
final oldPin;
|
||||||
@override
|
|
||||||
ChangePinScreenState createState() => ChangePinScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChangePinScreenState extends State<ChangePinScreen> {
|
|
||||||
Directory appPath;
|
Directory appPath;
|
||||||
TextEditingController _newPin = new TextEditingController();
|
NewWallet _newWalletFile;
|
||||||
bool ischangedPin = false;
|
|
||||||
NewWallet newWalletFile;
|
|
||||||
|
|
||||||
Future<NewWallet> get badWallet => null;
|
|
||||||
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
changePin(widget.walletName, widget.oldPin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
WalletOptionsProvider _walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context);
|
||||||
|
_walletOptions.changePin(walletName, oldPin);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Text(widget.walletName),
|
child: Text(walletName),
|
||||||
)),
|
)),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
|
@ -57,7 +48,7 @@ class ChangePinScreenState extends State<ChangePinScreen> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TextField(
|
TextField(
|
||||||
enabled: true,
|
enabled: true,
|
||||||
controller: this._newPin,
|
controller: _walletOptions.newPin,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
decoration: InputDecoration(),
|
decoration: InputDecoration(),
|
||||||
|
@ -68,8 +59,9 @@ class ChangePinScreenState extends State<ChangePinScreen> {
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.replay),
|
icon: Icon(Icons.replay),
|
||||||
color: Color(0xffD28928),
|
color: Color(0xffD28928),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
changePin(widget.walletName, widget.oldPin);
|
_newWalletFile =
|
||||||
|
await _walletOptions.changePin(walletName, oldPin);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -85,50 +77,10 @@ class ChangePinScreenState extends State<ChangePinScreen> {
|
||||||
primary: Colors.green[400], //Color(0xffFFD68E), // background
|
primary: Colors.green[400], //Color(0xffFFD68E), // background
|
||||||
onPrimary: Colors.black, // foreground
|
onPrimary: Colors.black, // foreground
|
||||||
),
|
),
|
||||||
onPressed: (ischangedPin)
|
onPressed: () => _walletOptions.storeWallet(
|
||||||
? () => storeWallet(widget.walletName)
|
context, walletName, _newWalletFile),
|
||||||
: null,
|
|
||||||
child: Text('Confirmer', style: TextStyle(fontSize: 28))),
|
child: Text('Confirmer', style: TextStyle(fontSize: 28))),
|
||||||
)
|
)
|
||||||
]))));
|
]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<NewWallet> 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<String> get _localPath async {
|
|
||||||
final directory = await getApplicationDocumentsDirectory();
|
|
||||||
return directory.path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import 'package:dubp/dubp.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gecko/models/generateWallets.dart';
|
import 'package:gecko/models/generateWallets.dart';
|
||||||
|
import 'package:gecko/models/myWallets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
|
@ -8,37 +10,42 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
|
||||||
ConfirmStoreWallet({
|
ConfirmStoreWallet({
|
||||||
Key validationKey,
|
Key validationKey,
|
||||||
@required this.generatedMnemonic,
|
@required this.generatedMnemonic,
|
||||||
@required generatedWallet,
|
@required this.generatedWallet,
|
||||||
}) : super(key: validationKey);
|
}) : super(key: validationKey);
|
||||||
|
|
||||||
String generatedMnemonic;
|
String generatedMnemonic;
|
||||||
|
NewWallet generatedWallet;
|
||||||
|
|
||||||
// @override
|
TextEditingController _mnemonicController = TextEditingController();
|
||||||
// void dispose() {
|
TextEditingController _pubkey = TextEditingController();
|
||||||
// _wordFocus.dispose();
|
TextEditingController _inputRestoreWord = TextEditingController();
|
||||||
// _walletNameFocus.dispose();
|
TextEditingController walletName = TextEditingController();
|
||||||
// super.dispose();
|
|
||||||
// }
|
|
||||||
|
|
||||||
TextEditingController _mnemonicController = new TextEditingController();
|
|
||||||
TextEditingController _pubkey = new TextEditingController();
|
|
||||||
TextEditingController _inputRestoreWord = new TextEditingController();
|
|
||||||
TextEditingController walletName = new TextEditingController();
|
|
||||||
FocusNode _wordFocus = FocusNode();
|
FocusNode _wordFocus = FocusNode();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context);
|
GenerateWalletsProvider _generateWalletProvider =
|
||||||
|
Provider.of<GenerateWalletsProvider>(context);
|
||||||
|
MyWalletsProvider _myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context);
|
||||||
|
print("JE BUILD !!!");
|
||||||
|
|
||||||
this._mnemonicController.text = generatedMnemonic;
|
this._mnemonicController.text = generatedMnemonic;
|
||||||
this._pubkey.text = _generateWalletProvider.generatedWallet.publicKey;
|
this._pubkey.text = generatedWallet.publicKey;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
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(
|
title: SizedBox(
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Text('Confirmez ce portefeuille'),
|
child: Text('Confirmez ce portefeuille'),
|
||||||
)),
|
)),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
|
@ -97,12 +104,10 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
focusNode: _generateWalletProvider.walletNameFocus,
|
focusNode: _generateWalletProvider.walletNameFocus,
|
||||||
// autofocus: true,
|
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
FilteringTextInputFormatter.allow(
|
FilteringTextInputFormatter.allow(
|
||||||
RegExp('[A-Za-z|0-9|\\-|_| ]')),
|
RegExp('[A-Za-z|0-9|\\-|_| ]')),
|
||||||
],
|
],
|
||||||
// enabled: isAskedWordValid,
|
|
||||||
controller: this.walletName,
|
controller: this.walletName,
|
||||||
textInputAction: TextInputAction.next,
|
textInputAction: TextInputAction.next,
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
|
@ -130,8 +135,20 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
|
||||||
),
|
),
|
||||||
onPressed: (_generateWalletProvider.isAskedWordValid &&
|
onPressed: (_generateWalletProvider.isAskedWordValid &&
|
||||||
this.walletName.text != '')
|
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,
|
: null,
|
||||||
child:
|
child:
|
||||||
Text('Confirmer', style: TextStyle(fontSize: 28))),
|
Text('Confirmer', style: TextStyle(fontSize: 28))),
|
||||||
|
|
|
@ -7,8 +7,6 @@ import 'package:super_tooltip/super_tooltip.dart';
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class GenerateWalletsScreen extends StatelessWidget {
|
class GenerateWalletsScreen extends StatelessWidget {
|
||||||
SuperTooltip tooltip;
|
SuperTooltip tooltip;
|
||||||
// final formKey = GlobalKey<FormState>();
|
|
||||||
|
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
String validPin = 'NO PIN';
|
String validPin = 'NO PIN';
|
||||||
String currentText = "";
|
String currentText = "";
|
||||||
|
@ -16,8 +14,11 @@ class GenerateWalletsScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var _generateWalletProvider = Provider.of<GenerateWalletsProvider>(context);
|
GenerateWalletsProvider _generateWalletProvider =
|
||||||
|
Provider.of<GenerateWalletsProvider>(context);
|
||||||
_generateWalletProvider.generateMnemonic();
|
_generateWalletProvider.generateMnemonic();
|
||||||
|
print('IS GENERATED ? : ' +
|
||||||
|
_generateWalletProvider.walletIsGenerated.toString());
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
|
@ -31,10 +32,6 @@ class GenerateWalletsScreen extends StatelessWidget {
|
||||||
child: FloatingActionButton(
|
child: FloatingActionButton(
|
||||||
heroTag: "buttonGenerateWallet",
|
heroTag: "buttonGenerateWallet",
|
||||||
onPressed: () => _generateWalletProvider.generateMnemonic(),
|
onPressed: () => _generateWalletProvider.generateMnemonic(),
|
||||||
// print(resultScan);
|
|
||||||
// if (resultScan != 'false') {
|
|
||||||
// onTabTapped(0);
|
|
||||||
// }
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 40.0,
|
height: 40.0,
|
||||||
width: 40.0,
|
width: 40.0,
|
||||||
|
@ -128,7 +125,6 @@ class GenerateWalletsScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
// Expanded(child: Align(alignment: Alignment.bottomCenter)),
|
|
||||||
new ElevatedButton(
|
new ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
primary: Color(0xffFFD68E), // background
|
primary: Color(0xffFFD68E), // background
|
||||||
|
@ -136,28 +132,18 @@ class GenerateWalletsScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
onPressed: _generateWalletProvider.walletIsGenerated
|
onPressed: _generateWalletProvider.walletIsGenerated
|
||||||
? () {
|
? () {
|
||||||
|
_generateWalletProvider.nbrWord =
|
||||||
|
_generateWalletProvider.getRandomInt();
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
return ConfirmStoreWallet(
|
return ConfirmStoreWallet(
|
||||||
// validationKey: _keyValidWallets,
|
|
||||||
generatedMnemonic:
|
generatedMnemonic:
|
||||||
_generateWalletProvider.generatedMnemonic,
|
_generateWalletProvider.generatedMnemonic,
|
||||||
generatedWallet:
|
generatedWallet:
|
||||||
_generateWalletProvider.actualWallet);
|
_generateWalletProvider.actualWallet);
|
||||||
}),
|
}),
|
||||||
)
|
);
|
||||||
// .then((value) => setState(() {
|
|
||||||
// if (value != null) {
|
|
||||||
// _pin.clear();
|
|
||||||
// _mnemonicController.clear();
|
|
||||||
// _pubkey.clear();
|
|
||||||
// this.generatedMnemonic = null;
|
|
||||||
// this.actualWallet = null;
|
|
||||||
// this.walletIsGenerated = false;
|
|
||||||
// }
|
|
||||||
// }))
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text('Enregistrer ce portefeuille',
|
child: Text('Enregistrer ce portefeuille',
|
||||||
|
|
|
@ -1,57 +1,54 @@
|
||||||
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:dubp/dubp.dart';
|
||||||
|
import 'package:gecko/models/walletOptions.dart';
|
||||||
import 'package:gecko/ui/myWallets/changePin.dart';
|
import 'package:gecko/ui/myWallets/changePin.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:pin_code_fields/pin_code_fields.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 {
|
// ignore: must_be_immutable
|
||||||
const WalletOptions({Key keyMyWallets, @required this.walletName})
|
class WalletOptions extends StatelessWidget with ChangeNotifier {
|
||||||
|
WalletOptions({Key keyMyWallets, @required this.walletName})
|
||||||
: super(key: keyMyWallets);
|
: super(key: keyMyWallets);
|
||||||
|
String walletName;
|
||||||
|
|
||||||
final String walletName;
|
|
||||||
@override
|
|
||||||
WalletOptionsState createState() => WalletOptionsState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class WalletOptionsState extends State<WalletOptions> {
|
|
||||||
StreamController<ErrorAnimationType> errorController;
|
StreamController<ErrorAnimationType> errorController;
|
||||||
Directory appPath;
|
Directory appPath;
|
||||||
TextEditingController _pubkey = new TextEditingController();
|
|
||||||
TextEditingController _enterPin = new TextEditingController();
|
TextEditingController _enterPin = new TextEditingController();
|
||||||
TextEditingController _newWalletName = new TextEditingController();
|
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
String validPin = 'NO PIN';
|
String validPin = 'NO PIN';
|
||||||
var pinColor = Color(0xffF9F9F1);
|
var pinColor = Color(0xffF9F9F1);
|
||||||
bool isWalletUnlock = false;
|
|
||||||
var walletPin = '';
|
var walletPin = '';
|
||||||
|
|
||||||
Future<NewWallet> get badWallet => null;
|
Future<NewWallet> get badWallet => null;
|
||||||
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
errorController = StreamController<ErrorAnimationType>();
|
|
||||||
isWalletUnlock = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
WalletOptionsProvider _walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context);
|
||||||
|
errorController = StreamController<ErrorAnimationType>();
|
||||||
|
// _walletOptions.isWalletUnlock = false;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back, color: Colors.black),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
_walletOptions.isWalletUnlock = false;
|
||||||
|
}),
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Text(widget.walletName),
|
child: Text(walletName),
|
||||||
)),
|
)),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: isWalletUnlock,
|
visible: _walletOptions.isWalletUnlock,
|
||||||
child: Expanded(
|
child: Expanded(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
|
@ -64,7 +61,7 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
),
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
Text(
|
Text(
|
||||||
this._pubkey.text,
|
_walletOptions.pubkey.text,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
@ -83,9 +80,10 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
0xffFFD68E), //Color(0xffFFD68E), // background
|
0xffFFD68E), //Color(0xffFFD68E), // background
|
||||||
onPrimary: Colors.black, // foreground
|
onPrimary: Colors.black, // foreground
|
||||||
),
|
),
|
||||||
onPressed: () =>
|
onPressed: () => _walletOptions
|
||||||
_renameWalletAlerte().then((_) {
|
.renameWalletAlerte(context, walletName)
|
||||||
setState(() {});
|
.then((_) {
|
||||||
|
notifyListeners();
|
||||||
}),
|
}),
|
||||||
child: Text('Renommer ce portefeuille',
|
child: Text('Renommer ce portefeuille',
|
||||||
style: TextStyle(fontSize: 20)))))),
|
style: TextStyle(fontSize: 20)))))),
|
||||||
|
@ -106,7 +104,7 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
return ChangePinScreen(
|
return ChangePinScreen(
|
||||||
walletName: widget.walletName,
|
walletName: walletName,
|
||||||
oldPin: this.walletPin);
|
oldPin: this.walletPin);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -125,7 +123,7 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
onPrimary: Colors.black, // foreground
|
onPrimary: Colors.black, // foreground
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_deleteWallet(widget.walletName);
|
_walletOptions.deleteWallet(context, walletName);
|
||||||
},
|
},
|
||||||
child: Text('Supprimer ce portefeuille',
|
child: Text('Supprimer ce portefeuille',
|
||||||
style: TextStyle(fontSize: 20)))),
|
style: TextStyle(fontSize: 20)))),
|
||||||
|
@ -140,7 +138,7 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
SizedBox(height: 10)
|
SizedBox(height: 10)
|
||||||
]))),
|
]))),
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: !isWalletUnlock,
|
visible: !_walletOptions.isWalletUnlock,
|
||||||
child: Expanded(
|
child: Expanded(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 80),
|
SizedBox(height: 80),
|
||||||
|
@ -202,28 +200,26 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
onCompleted: (_pin) async {
|
onCompleted: (_pin) async {
|
||||||
print("Completed");
|
print("Completed");
|
||||||
final resultWallet =
|
final resultWallet =
|
||||||
await _readLocalWallet(_pin.toUpperCase());
|
await _walletOptions.readLocalWallet(
|
||||||
|
this.walletName, _pin.toUpperCase());
|
||||||
if (resultWallet == 'bad') {
|
if (resultWallet == 'bad') {
|
||||||
errorController.add(ErrorAnimationType
|
errorController.add(ErrorAnimationType
|
||||||
.shake); // Triggering error shake animation
|
.shake); // Triggering error shake animation
|
||||||
setState(() {
|
hasError = true;
|
||||||
hasError = true;
|
pinColor = Colors.red[200];
|
||||||
pinColor = Colors.red[200];
|
notifyListeners();
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
pinColor = Colors.green[200];
|
pinColor = Colors.green[200];
|
||||||
// setState(() {});
|
// setState(() {});
|
||||||
// await Future.delayed(Duration(milliseconds: 50));
|
// await Future.delayed(Duration(milliseconds: 50));
|
||||||
this.walletPin = _pin.toUpperCase();
|
this.walletPin = _pin.toUpperCase();
|
||||||
isWalletUnlock = true;
|
// isWalletUnlock = true;
|
||||||
setState(() {});
|
notifyListeners();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (pinColor != Color(0xffF9F9F1)) {
|
if (pinColor != Color(0xffF9F9F1)) {
|
||||||
setState(() {
|
pinColor = Color(0xffF9F9F1);
|
||||||
pinColor = Color(0xffF9F9F1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
print(value);
|
print(value);
|
||||||
},
|
},
|
||||||
|
@ -232,174 +228,4 @@ class WalletOptionsState extends State<WalletOptions> {
|
||||||
]))),
|
]))),
|
||||||
]))));
|
]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
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<bool> _renameWalletAlerte() async {
|
|
||||||
return showDialog<bool>(
|
|
||||||
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: <Widget>[
|
|
||||||
TextField(
|
|
||||||
controller: this._newWalletName,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
decoration: InputDecoration(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.0,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.bold)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
child: Text("Valider"),
|
|
||||||
onPressed: () {
|
|
||||||
_renameWallet(this._newWalletName.text);
|
|
||||||
Navigator.pop(context, true);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<int> _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<bool> _confirmDeletingWallet() async {
|
|
||||||
return showDialog<bool>(
|
|
||||||
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: <Widget>[
|
|
||||||
Text(
|
|
||||||
'Vous pourrez restaurer ce portefeuille à tout moment grace à votre phrase de restauration.'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
child: Text("Non"),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context, false);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: Text("Oui"),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context, true);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> get _localPath async {
|
|
||||||
final directory = await getApplicationDocumentsDirectory();
|
|
||||||
return directory.path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<File> _localWallet(_name) async {
|
|
||||||
final path = await _localPath;
|
|
||||||
return File('$path/wallets/$_name/wallet.dewif');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,21 @@ import 'package:gecko/models/myWallets.dart';
|
||||||
import 'package:gecko/ui/myWallets/generateWalletsScreen.dart';
|
import 'package:gecko/ui/myWallets/generateWalletsScreen.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/ui/myWallets/walletOptions.dart';
|
import 'package:gecko/ui/myWallets/walletOptions.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class WalletsHome extends StatelessWidget {
|
class WalletsHome extends StatelessWidget {
|
||||||
MyWalletsProvider myWalletProvider = MyWalletsProvider();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
MyWalletsProvider myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context);
|
||||||
print('BUILD: WalletsHome');
|
print('BUILD: WalletsHome');
|
||||||
myWalletProvider.checkIfWalletExist();
|
myWalletProvider.checkIfWalletExist();
|
||||||
myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames();
|
myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
floatingActionButton: Visibility(
|
floatingActionButton: Visibility(
|
||||||
visible: (myWalletProvider
|
visible: (myWalletProvider.checkIfWalletExist()),
|
||||||
.checkIfWalletExist()), //!checkIfWalletExist('MonWallet') &&
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 80.0,
|
height: 80.0,
|
||||||
width: 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) {
|
myWalletsList(BuildContext context) {
|
||||||
|
MyWalletsProvider myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context);
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
for (var repository in myWalletProvider.listWallets)
|
for (var repository in myWalletProvider.listWallets)
|
||||||
|
@ -111,22 +101,7 @@ class WalletsHome extends StatelessWidget {
|
||||||
return WalletOptions(walletName: repository);
|
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))))
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,10 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:dubp/dubp.dart';
|
import 'package:dubp/dubp.dart';
|
||||||
|
import 'package:gecko/models/myWallets.dart';
|
||||||
import 'dart:io';
|
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<SettingsScreen> {
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class SettingsScreen extends StatelessWidget {
|
||||||
String generatedMnemonic;
|
String generatedMnemonic;
|
||||||
bool walletIsGenerated = false;
|
bool walletIsGenerated = false;
|
||||||
NewWallet actualWallet;
|
NewWallet actualWallet;
|
||||||
|
@ -27,6 +16,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
var pinColor = Colors.grey[300];
|
var pinColor = Colors.grey[300];
|
||||||
Directory appPath;
|
Directory appPath;
|
||||||
|
|
||||||
|
MyWalletsProvider _myWallets = MyWalletsProvider();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// getAppDirectory();
|
// getAppDirectory();
|
||||||
|
@ -53,7 +44,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
),
|
),
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
print('Suppression de tous les wallets'),
|
print('Suppression de tous les wallets'),
|
||||||
_deleteWallet()
|
_myWallets.deleteAllWallet(context)
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
"EFFACER TOUS MES PORTEFEUILLES, LE TEMPS DE L'ALPHA",
|
"EFFACER TOUS MES PORTEFEUILLES, LE TEMPS DE L'ALPHA",
|
||||||
|
@ -61,56 +52,4 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
SizedBox(height: 50),
|
SizedBox(height: 50),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> _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<bool> _confirmDeletingWallets() async {
|
|
||||||
return showDialog<bool>(
|
|
||||||
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: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
child: Text("Non"),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context, false);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: Text("Oui"),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context, true);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> get _localPath async {
|
|
||||||
final directory = await getApplicationDocumentsDirectory();
|
|
||||||
return directory.path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue