Merge branch 'figmaWalletsViewsUX' into 'master'

Add figma UX for wallet option screen - rework wallet list storage

See merge request clients/gecko!9
This commit is contained in:
pokapow 2021-03-23 16:45:41 +00:00
commit 2d1652db2c
29 changed files with 974 additions and 280 deletions

9
assets/chopp-gecko.svg Executable file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

BIN
assets/chopp-gecko2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
assets/walletOptions/QR_icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
assets/walletOptions/camera.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

BIN
assets/walletOptions/clock.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

BIN
assets/walletOptions/edit.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

BIN
assets/walletOptions/ellipse1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/walletOptions/key.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

BIN
assets/walletOptions/trash.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,8 +1,13 @@
import 'dart:io'; import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
// Files paths
Directory appPath; Directory appPath;
Directory walletsDirectory; Directory walletsDirectory;
File defaultWalletFile;
File currentChestFile;
String defaultWallet;
String appVersion; String appVersion;
SharedPreferences prefs; SharedPreferences prefs;
String endPointGVA; String endPointGVA;

View File

@ -25,12 +25,14 @@ Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
HomeProvider _homeProvider = HomeProvider(); HomeProvider _homeProvider = HomeProvider();
MyWalletsProvider _walletsProvider = MyWalletsProvider();
await _homeProvider.getAppPath(); await _homeProvider.getAppPath();
await _homeProvider.createDefaultAvatar(); await _homeProvider.createDefaultAvatar();
await _walletsProvider.initWalletFolder();
appVersion = await _homeProvider.getAppVersion(); appVersion = await _homeProvider.getAppVersion();
prefs = await SharedPreferences.getInstance(); prefs = await SharedPreferences.getInstance();
final HiveStore _store = // final HiveStore _store =
await HiveStore.open(path: '${appPath.path}/gqlCache'); // await HiveStore.open(path: '${appPath.path}/gqlCache');
// Get a valid GVA endpoint // Get a valid GVA endpoint
endPointGVA = await _homeProvider.getValidEndpoint(); endPointGVA = await _homeProvider.getValidEndpoint();
@ -49,7 +51,7 @@ Future<void> main() async {
await SentryFlutter.init((options) { await SentryFlutter.init((options) {
options.dsn = options.dsn =
'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110'; 'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110';
}, appRunner: () => runApp(Gecko(endPointGVA, _store))); }, appRunner: () => runApp(Gecko(endPointGVA)));
// runZoned<Future<void>>( // runZoned<Future<void>>(
// () async { // () async {
@ -66,14 +68,13 @@ Future<void> main() async {
} else { } else {
print('Debug mode enabled: No sentry alerte'); print('Debug mode enabled: No sentry alerte');
runApp(Gecko(endPointGVA, _store)); runApp(Gecko(endPointGVA));
} }
} }
class Gecko extends StatelessWidget { class Gecko extends StatelessWidget {
Gecko(this.randomEndpoint, this._store); Gecko(this.randomEndpoint);
final String randomEndpoint; final String randomEndpoint;
final HiveStore _store;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -84,7 +85,7 @@ class Gecko extends StatelessWidget {
final _client = ValueNotifier( final _client = ValueNotifier(
GraphQLClient( GraphQLClient(
cache: GraphQLCache(store: _store), cache: GraphQLCache(),
link: _httpLink, link: _httpLink,
), ),
); );

View File

@ -67,7 +67,7 @@ class CesiumPlusProvider with ChangeNotifier {
String _name; String _name;
List queryOptions = await _buildQuery(_pubkey); List queryOptions = await _buildQuery(_pubkey);
final response = await http.post(queryOptions[0], final response = await http.post((Uri.parse(queryOptions[0])),
body: queryOptions[1], headers: queryOptions[2]); body: queryOptions[1], headers: queryOptions[2]);
// print('RESULT CESIUM QUERY: ${response.body}'); //For debug // print('RESULT CESIUM QUERY: ${response.body}'); //For debug
final responseJson = json.decode(response.body); final responseJson = json.decode(response.body);
@ -87,7 +87,7 @@ class CesiumPlusProvider with ChangeNotifier {
Future<List> getAvatar(String _pubkey) async { Future<List> getAvatar(String _pubkey) async {
List queryOptions = await _buildQuery(_pubkey); List queryOptions = await _buildQuery(_pubkey);
final response = await http.post(queryOptions[0], final response = await http.post((Uri.parse(queryOptions[0])),
body: queryOptions[1], headers: queryOptions[2]); body: queryOptions[1], headers: queryOptions[2]);
// print('RESULT CESIUM QUERY: ${response.body}'); //For debug // print('RESULT CESIUM QUERY: ${response.body}'); //For debug
final responseJson = json.decode(response.body); final responseJson = json.decode(response.body);

View File

@ -10,7 +10,6 @@ import 'package:gecko/globals.dart';
import 'package:pdf/pdf.dart'; import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw; import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
import 'package:truncate/truncate.dart';
class GenerateWalletsProvider with ChangeNotifier { class GenerateWalletsProvider with ChangeNotifier {
GenerateWalletsProvider(); GenerateWalletsProvider();
@ -39,50 +38,38 @@ class GenerateWalletsProvider with ChangeNotifier {
bool canImport = false; bool canImport = false;
bool isPinChanged = false; bool isPinChanged = false;
Future storeWallet(NewWallet wallet, String _name, BuildContext context, Future storeHDWChest(
{bool isHD = false}) async { NewWallet _wallet, String _name, BuildContext context) async {
int nbrWallet; // Directory walletDirectory;
if (isHD) {
nbrWallet = 0; final Directory hdDirectory = Directory('${walletsDirectory.path}/0');
} else { await hdDirectory.create();
nbrWallet = 1;
final configFile = File('${hdDirectory.path}/list.conf');
File _currentChestFile = File('${walletsDirectory.path}/currentChest.conf');
final dewifFile = File('${hdDirectory.path}/wallet.dewif');
// List<String> _lastConfig = [];
// _lastConfig = await masterConfigFile.readAsLines();
// final int _lastDerivation = int.parse(_lastConfig.last.split(':')[2]);
// final int _derivationNbr = _lastDerivation + 3;
final int _derivationNbr = 3;
List _pubkeysTmp = await DubpRust.getBip32DewifAccountsPublicKeys(
dewif: _wallet.dewif,
secretCode: _wallet.pin,
accountsIndex: [_derivationNbr]);
String _pubkey = _pubkeysTmp[0];
await configFile.writeAsString('0:0:$_name:$_derivationNbr:$_pubkey');
await dewifFile.writeAsString(_wallet.dewif);
bool isCurrentChestExist = _currentChestFile.existsSync();
if (isCurrentChestExist) {
await _currentChestFile.delete();
} }
await _currentChestFile.create();
Directory walletNbrDirectory; await _currentChestFile.writeAsString('0');
do {
nbrWallet++;
walletNbrDirectory = Directory('${walletsDirectory.path}/$nbrWallet');
} while (await walletNbrDirectory.exists());
final walletFile = File('${walletNbrDirectory.path}/wallet.dewif');
await walletNbrDirectory.create();
await walletFile.writeAsString(wallet.dewif);
final configFile = File('${walletNbrDirectory.path}/config.txt');
if (isHD) {
final int _derivationNbr = 3;
List _pubkeysTmp = await DubpRust.getBip32DewifAccountsPublicKeys(
dewif: wallet.dewif,
secretCode: wallet.pin,
accountsIndex: [_derivationNbr]);
String _pubkey = _pubkeysTmp[0];
await configFile
.writeAsString('$nbrWallet:$_name:$_derivationNbr:$_pubkey');
// Navigator.pop(context, true);
} else {
final int _derivationNbr = -1;
String _pubkey = await DubpRust.getDewifPublicKey(
dewif: wallet.dewif,
pin: wallet.pin,
);
await configFile
.writeAsString('$nbrWallet:$_name:$_derivationNbr:$_pubkey');
}
// Navigator.pop(context, true);
return _name; return _name;
} }
@ -167,11 +154,9 @@ class GenerateWalletsProvider with ChangeNotifier {
generatedMnemonic = await DubpRust.genMnemonic(language: Language.french); generatedMnemonic = await DubpRust.genMnemonic(language: Language.french);
this.actualWallet = await generateWallet(this.generatedMnemonic); this.actualWallet = await generateWallet(this.generatedMnemonic);
walletIsGenerated = true; walletIsGenerated = true;
// notifyListeners();
} catch (e) { } catch (e) {
print(e); print(e);
} }
// await checkIfWalletExist();
return generatedMnemonic; return generatedMnemonic;
} }
@ -259,12 +244,12 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
Future importWallet(context, _cesiumID, _cesiumPWD) async { Future importWallet(context, _cesiumID, _cesiumPWD) async {
String _walletPubkey = await DubpRust.getLegacyPublicKey( // String _walletPubkey = await DubpRust.getLegacyPublicKey(
salt: _cesiumID, password: _cesiumPWD); // salt: _cesiumID, password: _cesiumPWD);
String shortPubkey = truncate(_walletPubkey, 9, // String shortPubkey = truncate(_walletPubkey, 9,
omission: "...", position: TruncatePosition.end); // omission: "...", position: TruncatePosition.end);
await storeWallet( // await storeWallet(
actualWallet, 'Portefeuille Cesium - $shortPubkey', context); // actualWallet, 'Portefeuille Cesium - $shortPubkey', context);
cesiumID.text = ''; cesiumID.text = '';
cesiumPWD.text = ''; cesiumPWD.text = '';
cesiumPubkey.text = ''; cesiumPubkey.text = '';

View File

@ -4,6 +4,7 @@ import 'package:gecko/globals.dart';
import 'package:gecko/models/home.dart'; import 'package:gecko/models/home.dart';
import 'package:gecko/screens/history.dart'; import 'package:gecko/screens/history.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:qrscan/qrscan.dart' as scanner; import 'package:qrscan/qrscan.dart' as scanner;
@ -24,6 +25,7 @@ class HistoryProvider with ChangeNotifier {
Map pageInfo; Map pageInfo;
bool isHistoryScreen = false; bool isHistoryScreen = false;
String historySwitchButtun = "Voir l'historique"; String historySwitchButtun = "Voir l'historique";
String rawSvg;
Future scan(context) async { Future scan(context) async {
await Permission.camera.request(); await Permission.camera.request();
@ -43,7 +45,7 @@ class HistoryProvider with ChangeNotifier {
return barcode; return barcode;
} }
String isPubkey(context, pubkey) { String isPubkey(context, pubkey, {bool goHistory}) {
HomeProvider _homeProvider = HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false); Provider.of<HomeProvider>(context, listen: false);
final RegExp regExp = new RegExp( final RegExp regExp = new RegExp(
@ -62,8 +64,16 @@ class HistoryProvider with ChangeNotifier {
this.outputPubkey.text = pubkey; this.outputPubkey.text = pubkey;
isHistoryScreen = false; if (goHistory == null) goHistory = false;
historySwitchButtun = "Voir l'historique";
if (goHistory) {
isHistoryScreen = true;
historySwitchButtun = "Payer";
} else {
isHistoryScreen = false;
historySwitchButtun = "Voir l'historique";
}
_homeProvider.handleSearchEnd(); _homeProvider.handleSearchEnd();
Navigator.push( Navigator.push(
context, context,
@ -101,7 +111,6 @@ class HistoryProvider with ChangeNotifier {
// Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f // Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f
List parseHistory(txs, _pubkey) { List parseHistory(txs, _pubkey) {
// print(txs);
var transBC = []; var transBC = [];
int i = 0; int i = 0;
@ -135,7 +144,7 @@ class HistoryProvider with ChangeNotifier {
transBC[i].add(date); transBC[i].add(date);
// print( // print(
// "DEBUG date et comment: ${date.toString()} -- ${transaction['comment'].toString()}"); // "DEBUG date et comment: ${date.toString()} -- ${transaction['comment'].toString()}");
int amountBrut = int.parse(output.split(':')[0]); final int amountBrut = int.parse(output.split(':')[0]);
final base = int.parse(output.split(':')[1]); final base = int.parse(output.split(':')[1]);
final int applyBase = base - currentBase; final int applyBase = base - currentBase;
final num amount = final num amount =
@ -242,6 +251,10 @@ class HistoryProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
String generateIdenticon(String _pubkey) {
return Jdenticon.toSvg(_pubkey);
}
// num getBalance(_pubkey) { // num getBalance(_pubkey) {
// getBalance(_pubkey); // getBalance(_pubkey);
// } // }

View File

@ -8,13 +8,50 @@ import 'package:provider/provider.dart';
class MyWalletsProvider with ChangeNotifier { class MyWalletsProvider with ChangeNotifier {
String listWallets; String listWallets;
Future initWalletFolder() async {
await getDefaultWallet();
final bool isWalletFolderExist = await walletsDirectory.exists();
if (!isWalletFolderExist) {
await Directory(walletsDirectory.path).create();
}
File _currentChestFile = File('${walletsDirectory.path}/currentChest.conf');
await _currentChestFile.create();
await _currentChestFile.writeAsString('0');
final bool isChestsExist =
await Directory('${walletsDirectory.path}/0').exists();
if (!isChestsExist) {
await Directory('${walletsDirectory.path}/0').create();
await Directory('${walletsDirectory.path}/1').create();
await File('${walletsDirectory.path}/0/list.conf').create();
await File('${walletsDirectory.path}/0/order.conf').create();
await File('${walletsDirectory.path}/1/list.conf').create();
await File('${walletsDirectory.path}/1/order.conf').create();
}
}
int getCurrentChest() {
File _currentChestFile = File('${walletsDirectory.path}/currentChest.conf');
bool isCurrentChestExist = _currentChestFile.existsSync();
if (!isCurrentChestExist) {
_currentChestFile.createSync();
_currentChestFile.writeAsString('0');
}
return int.parse(_currentChestFile.readAsStringSync());
}
bool checkIfWalletExist() { bool checkIfWalletExist() {
if (appPath == null) { if (appPath == null) {
return false; return false;
} }
List contents = walletsDirectory.listSync(); final String _walletList = getAllWalletsNames(0);
if (contents.length == 0) {
if (_walletList == '') {
print('No wallets detected'); print('No wallets detected');
return false; return false;
} else { } else {
@ -23,12 +60,7 @@ class MyWalletsProvider with ChangeNotifier {
} }
} }
String getAllWalletsNames() { String getAllWalletsNames(int _chest) {
final bool _isWalletsExists = checkIfWalletExist();
if (!_isWalletsExists) {
return '';
}
if (listWallets != null && listWallets.isNotEmpty) { if (listWallets != null && listWallets.isNotEmpty) {
listWallets = ''; listWallets = '';
} }
@ -36,24 +68,39 @@ class MyWalletsProvider with ChangeNotifier {
listWallets = ''; listWallets = '';
} }
print(walletsDirectory.path);
// int i = 0; // int i = 0;
walletsDirectory File _walletConfig = File('${walletsDirectory.path}/$_chest/list.conf');
.listSync(recursive: false, followLinks: false) _walletConfig.readAsLinesSync().forEach((element) {
.forEach((_wallet) { if (listWallets != '') {
File _walletConfig = File('${_wallet.path}/config.txt'); listWallets += '\n';
_walletConfig.readAsLinesSync().forEach((element) { }
if (listWallets != '') { listWallets += element;
listWallets += '\n'; // listWallets += "${element.split(':')[0]}:${element.split(':')[1]}:${element.split(':')[2]}"
}
listWallets += element;
// listWallets += "${element.split(':')[0]}:${element.split(':')[1]}:${element.split(':')[2]}"
});
}); });
print(listWallets); print(listWallets);
return listWallets; return listWallets;
} }
Future getDefaultWallet() async {
defaultWalletFile = File('${appPath.path}/defaultWallet');
bool isdefaultWalletFile = await defaultWalletFile.exists();
if (!isdefaultWalletFile) {
await File(defaultWalletFile.path).create();
}
try {
defaultWallet = await defaultWalletFile.readAsString();
} catch (e) {
defaultWallet = '0:0';
}
if (defaultWallet == '') defaultWallet = '0:0';
}
Future<int> deleteAllWallet(context) async { Future<int> deleteAllWallet(context) async {
try { try {
print('DELETE THAT ?: $walletsDirectory'); print('DELETE THAT ?: $walletsDirectory');
@ -63,6 +110,7 @@ class MyWalletsProvider with ChangeNotifier {
if (_answer) { if (_answer) {
await walletsDirectory.delete(recursive: true); await walletsDirectory.delete(recursive: true);
await walletsDirectory.create(); await walletsDirectory.create();
await initWalletFolder();
notifyListeners(); notifyListeners();
Navigator.pop(context); Navigator.pop(context);
} }
@ -95,7 +143,7 @@ class MyWalletsProvider with ChangeNotifier {
onPressed: () { onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets = _myWalletProvider.listWallets =
_myWalletProvider.getAllWalletsNames(); _myWalletProvider.getAllWalletsNames(getCurrentChest());
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}); });
Navigator.pop(context, true); Navigator.pop(context, true);
@ -107,22 +155,26 @@ class MyWalletsProvider with ChangeNotifier {
); );
} }
Future<void> generateNewDerivation( Future<void> generateNewDerivation(context, String _name) async {
context, String _name, int _walletNbr) async {
int _newDerivationNbr; int _newDerivationNbr;
final _walletConfig = int _newWalletNbr;
File('${walletsDirectory.path}/$_walletNbr/config.txt'); final _walletConfig = File('${walletsDirectory.path}/0/list.conf');
if (await _walletConfig.readAsString() == '') { if (await _walletConfig.readAsString() == '') {
_newDerivationNbr = 3; _newDerivationNbr = 3;
_newWalletNbr = 0;
} else { } else {
String _lastWallet = String _lastWallet =
await _walletConfig.readAsLines().then((value) => value.last); await _walletConfig.readAsLines().then((value) => value.last);
int _lastDerivation = int.parse(_lastWallet.split(':')[2]); int _lastDerivation = int.parse(_lastWallet.split(':')[3]);
_newDerivationNbr = _lastDerivation + 3; _newDerivationNbr = _lastDerivation + 3;
int _lastWalletNbr = int.parse(_lastWallet.split(':')[1]);
_newWalletNbr = _lastWalletNbr + 1;
} }
await _walletConfig.writeAsString('\n$_walletNbr:$_name:$_newDerivationNbr', await _walletConfig.writeAsString(
'\n0:$_newWalletNbr:$_name:$_newDerivationNbr',
mode: FileMode.append); mode: FileMode.append);
print(await _walletConfig.readAsString()); print(await _walletConfig.readAsString());

View File

@ -1,7 +1,7 @@
const String getHistory = r''' const String getHistory = r'''
query ($pubkey: String!, $number: Int!, $cursor: String) { query ($pubkey: String!, $number: Int!, $cursor: String) {
txsHistoryBc( txsHistoryBc(
pubkeyOrScript: $pubkey script: $pubkey
pagination: { pageSize: $number, ord: DESC, cursor: $cursor } pagination: { pageSize: $number, ord: DESC, cursor: $cursor }
) { ) {
both { both {
@ -52,8 +52,13 @@ const String getHistory = r'''
const String getBalance = r''' const String getBalance = r'''
query ($pubkey: String!) { query ($pubkey: String!) {
balance(script: $pubkey) { balance(script: $pubkey) {
amount amount
base base
}
currentUd {
amount
base
}
} }
'''; ''';

View File

@ -1,9 +1,15 @@
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:fast_base58/fast_base58.dart';
import 'package:flutter/foundation.dart'; 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:image_picker/image_picker.dart';
import 'package:truncate/truncate.dart';
import 'package:qrscan/qrscan.dart' as scanner;
class WalletOptionsProvider with ChangeNotifier { class WalletOptionsProvider with ChangeNotifier {
TextEditingController pubkey = TextEditingController(); TextEditingController pubkey = TextEditingController();
@ -11,6 +17,11 @@ class WalletOptionsProvider with ChangeNotifier {
bool isWalletUnlock = false; bool isWalletUnlock = false;
bool ischangedPin = false; bool ischangedPin = false;
TextEditingController newPin = new TextEditingController(); TextEditingController newPin = new TextEditingController();
bool isEditing = false;
bool isBalanceBlur = true;
FocusNode walletNameFocus = FocusNode();
TextEditingController nameController = TextEditingController();
String walletID;
Future<NewWallet> get badWallet => null; Future<NewWallet> get badWallet => null;
@ -65,8 +76,7 @@ class WalletOptionsProvider with ChangeNotifier {
int _walletNbr, String _pin, int _pinLenght, int derivation) async { int _walletNbr, String _pin, int _pinLenght, int derivation) async {
isWalletUnlock = false; isWalletUnlock = false;
try { try {
File _walletFile = File _walletFile = File('${walletsDirectory.path}/0/wallet.dewif');
File('${walletsDirectory.path}/$_walletNbr/wallet.dewif');
String _localDewif = await _walletFile.readAsString(); String _localDewif = await _walletFile.readAsString();
String _localPubkey; String _localPubkey;
@ -107,8 +117,7 @@ class WalletOptionsProvider with ChangeNotifier {
int getPinLenght(_walletNbr) { int getPinLenght(_walletNbr) {
String _localDewif; String _localDewif;
if (_walletNbr is int) { if (_walletNbr is int) {
File _walletFile = File _walletFile = File('${walletsDirectory.path}/0/wallet.dewif');
File('${walletsDirectory.path}/$_walletNbr/wallet.dewif');
_localDewif = _walletFile.readAsStringSync(); _localDewif = _walletFile.readAsStringSync();
} else { } else {
_localDewif = _walletNbr; _localDewif = _walletNbr;
@ -120,22 +129,36 @@ class WalletOptionsProvider with ChangeNotifier {
return _pinLenght; return _pinLenght;
} }
Future _renameWallet(_walletName, _newName, _walletNbr, _derivation) async { Future _renameWallet(_walletID, _newName) async {
final _walletConfig = final _walletConfig = File('${walletsDirectory.path}/0/list.conf');
File('${walletsDirectory.path}/$_walletNbr/config.txt');
String newConfig = String newConfig =
await _walletConfig.readAsLines().then((List<String> lines) { await _walletConfig.readAsLines().then((List<String> lines) {
int nbrLines = lines.length; int nbrLines = lines.length;
int _index = lines.indexOf('$_walletNbr:$_walletName:$_derivation'); // print(lines);
print(nbrLines); // print(nbrLines);
// int _index = lines.indexOf('0:$_walletNbr:$_walletName:$_derivation');
if (nbrLines != 1) { if (nbrLines != 1) {
lines.removeWhere((element) => for (String wLine in lines) {
element.contains('$_walletNbr:$_walletName:$_derivation')); String wID = "${wLine.split(':')[0]}:${wLine.split(':')[1]}";
lines.insert(_index, '$_walletNbr:$_newName:$_derivation'); print(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
print(wLine);
String deri = wLine.split(':')[3];
print("($wID == $_walletID ???");
if (wID == _walletID) {
lines.remove(wLine);
lines.add('$_walletID:$_newName:$deri');
// return '$_walletID:$_newName:$deri';
print('OOUUUUUUUIIIIIIIIIIIIIIIIIII');
}
}
// lines.removeWhere((element) =>
// '${element.split(':')[0]}:${element.split(':')[1]}' == _walletID);
// lines.add('$_walletID:$_newName:$deri');
return lines.join('\n'); return lines.join('\n');
} else { } else {
return '$_walletNbr:$_newName:$_derivation'; return 'true';
} }
}); });
@ -172,8 +195,8 @@ class WalletOptionsProvider with ChangeNotifier {
child: Text("Valider"), child: Text("Valider"),
onPressed: () { onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
await _renameWallet(_walletName, this._newWalletName.text, // await _renameWallet(_walletName, this._newWalletName.text,
_walletNbr, _derivation); // _walletNbr, _derivation);
}); });
// notifyListeners(); // notifyListeners();
Navigator.pop(context, true); Navigator.pop(context, true);
@ -185,18 +208,37 @@ class WalletOptionsProvider with ChangeNotifier {
); );
} }
Future<bool> editWalletName(_wID) async {
bool nameState;
if (isEditing) {
if (!nameController.text.contains(':') &&
nameController.text.length <= 39) {
await _renameWallet(_wID, nameController.text);
nameState = true;
} else {
nameState = false;
}
} else {
walletNameFocus.requestFocus();
nameState = true;
}
isEditing ? isEditing = false : isEditing = true;
notifyListeners();
return nameState;
}
Future<int> deleteWallet(context, _walletNbr, _name, _derivation) async { Future<int> deleteWallet(context, _walletNbr, _name, _derivation) async {
final bool _answer = await _confirmDeletingWallet(context, _name); final bool _answer = await _confirmDeletingWallet(context, _name);
if (_answer) { if (_answer) {
final _walletConfig = final _walletConfig = File('${walletsDirectory.path}/0/list.conf');
File('${walletsDirectory.path}/$_walletNbr/config.txt');
if (_derivation != -1) { if (_derivation != -1) {
String newConfig = String newConfig =
await _walletConfig.readAsLines().then((List<String> lines) { await _walletConfig.readAsLines().then((List<String> lines) {
lines.removeWhere( lines.removeWhere((element) =>
(element) => element.contains('$_walletNbr:$_name:$_derivation')); element.contains('0:$_walletNbr:$_name:$_derivation'));
return lines.join('\n'); return lines.join('\n');
}); });
@ -289,6 +331,53 @@ class WalletOptionsProvider with ChangeNotifier {
ScaffoldMessenger.of(context).showSnackBar(snackBar); ScaffoldMessenger.of(context).showSnackBar(snackBar);
} }
String getShortPubkey(String pubkey) {
List<int> pubkeyByte = Base58Decode(pubkey);
Digest pubkeyS256 = sha256.convert(sha256.convert(pubkeyByte).bytes);
String pubkeyCheksum = Base58Encode(pubkeyS256.bytes);
String pubkeyChecksumShort = truncate(pubkeyCheksum, 3,
omission: "", position: TruncatePosition.end);
String pubkeyShort = truncate(pubkey, 5,
omission: String.fromCharCode(0x2026),
position: TruncatePosition.end) +
truncate(pubkey, 4, omission: "", position: TruncatePosition.start) +
':$pubkeyChecksumShort';
return pubkeyShort;
}
void bluringBalance() {
isBalanceBlur = !isBalanceBlur;
notifyListeners();
}
Future<Uint8List> generateQRcode(String _pubkey) async {
return await scanner.generateBarCode(_pubkey);
}
Future defAsDefaultWallet(String _id) async {
await defaultWalletFile.delete();
await defaultWalletFile.create();
await defaultWalletFile
.writeAsString(_id)
.then((value) => notifyListeners());
}
Future changeAvatar() async {
File _image;
final picker = ImagePicker();
final pickedFile = await picker.getImage(source: ImageSource.gallery);
if (pickedFile != null) {
_image = File(pickedFile.path);
return _image;
} else {
print('No image selected.');
}
}
void reloadBuild() { void reloadBuild() {
notifyListeners(); notifyListeners();
} }

View File

@ -1,5 +1,4 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/cesiumPlus.dart'; import 'package:gecko/models/cesiumPlus.dart';
@ -11,6 +10,7 @@ import 'package:flutter/foundation.dart';
import 'dart:ui'; import 'dart:ui';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
class HistoryScreen extends StatelessWidget with ChangeNotifier { class HistoryScreen extends StatelessWidget with ChangeNotifier {
@ -25,6 +25,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
FetchMore fetchMore; FetchMore fetchMore;
FetchMoreOptions opts; FetchMoreOptions opts;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -37,6 +38,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
WidgetsBinding.instance.addPostFrameCallback((_) {}); WidgetsBinding.instance.addPostFrameCallback((_) {});
return Scaffold( return Scaffold(
key: _scaffoldKey,
appBar: AppBar( appBar: AppBar(
title: _homeProvider.appBarExplorer, title: _homeProvider.appBarExplorer,
actions: [ actions: [
@ -153,8 +155,14 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
return const Text('Aucune donnée à afficher.'); return const Text('Aucune donnée à afficher.');
} }
final num balance = _historyProvider num balance;
.removeDecimalZero(result.data['balance']['amount'] / 100);
if (result.data['balance'] == null) {
balance = 0.0;
} else {
balance = _historyProvider
.removeDecimalZero(result.data['balance']['amount'] / 100);
}
opts = _historyProvider.checkQueryResult( opts = _historyProvider.checkQueryResult(
result, opts, _outputPubkey.text); result, opts, _outputPubkey.text);
@ -179,7 +187,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
if (_isFirstExec) if (_isFirstExec)
Container( Container(
padding: const EdgeInsets.fromLTRB( padding: const EdgeInsets.fromLTRB(
12, 0, 5, 0), 20, 0, 30, 0),
child: FutureBuilder( child: FutureBuilder(
future: future:
_cesiumPlusProvider.getAvatar( _cesiumPlusProvider.getAvatar(
@ -235,7 +243,21 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
Container( Container(
padding: const EdgeInsets.fromLTRB( padding: const EdgeInsets.fromLTRB(
30, 0, 5, 0), // .only(right: 15), 30, 0, 5, 0), // .only(right: 15),
child: Text('TODO')), child: Card(
child: Column(
children: <Widget>[
SvgPicture.string(
_historyProvider
.generateIdenticon(
_historyProvider
.pubkey),
fit: BoxFit.contain,
height: 64,
width: 64,
),
],
),
)),
SizedBox(width: 0) SizedBox(width: 0)
]), ]),
if (_isFirstExec) if (_isFirstExec)
@ -254,7 +276,7 @@ class HistoryScreen extends StatelessWidget with ChangeNotifier {
initialData: '...', initialData: '...',
builder: (context, snapshot) { builder: (context, snapshot) {
return Text( return Text(
snapshot.data != '' snapshot.data != null
? snapshot.data ? snapshot.data
: '-', : '-',
style: style:

View File

@ -28,6 +28,7 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
this._mnemonicController.text = generatedMnemonic; this._mnemonicController.text = generatedMnemonic;
return WillPopScope( return WillPopScope(
@ -126,11 +127,10 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
.isAskedWordValid && .isAskedWordValid &&
this.walletName.text != '') this.walletName.text != '')
? () async { ? () async {
await _generateWalletProvider.storeWallet( await _generateWalletProvider.storeHDWChest(
generatedWallet, generatedWallet,
walletName.text, walletName.text,
context, context);
isHD: true);
_generateWalletProvider.isAskedWordValid = _generateWalletProvider.isAskedWordValid =
false; false;
_generateWalletProvider.askedWordColor = _generateWalletProvider.askedWordColor =
@ -138,8 +138,8 @@ class ConfirmStoreWallet extends StatelessWidget with ChangeNotifier {
WidgetsBinding.instance WidgetsBinding.instance
.addPostFrameCallback((_) { .addPostFrameCallback((_) {
_myWalletProvider.listWallets = _myWalletProvider.listWallets =
_myWalletProvider _myWalletProvider.getAllWalletsNames(
.getAllWalletsNames(); _currentChest);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
}); });
} }

View File

@ -0,0 +1,166 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/myWallets.dart';
import 'package:gecko/models/walletOptions.dart';
import 'dart:async';
import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
// ignore: must_be_immutable
class WalletOptionsOld extends StatelessWidget with ChangeNotifier {
WalletOptionsOld(
{Key keyMyWallets,
@required this.walletNbr,
@required this.walletName,
@required this.derivation})
: super(key: keyMyWallets);
int walletNbr;
String walletName;
int derivation;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
print("Build walletOptions");
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
// _walletOptions.isWalletUnlock = false;
print("Is unlock ? ${_walletOptions.isWalletUnlock}");
final int _currentChest = _myWalletProvider.getCurrentChest();
return WillPopScope(
onWillPop: () {
_walletOptions.isWalletUnlock = false;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isWalletUnlock = false;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
}),
title: SizedBox(
height: 22,
child: Text(walletName),
)),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Expanded(
child: Column(children: <Widget>[
SizedBox(height: 15),
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(
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(
_currentChest);
_myWalletProvider
.rebuildWidget();
});
Navigator.popUntil(
context,
ModalRoute.withName(
'/mywallets'),
);
}
}),
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(_currentChest);
_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)
])),
]),
)),
));
}
}

View File

@ -1,7 +1,12 @@
import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/history.dart';
import 'package:gecko/models/myWallets.dart'; import 'package:gecko/models/myWallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/walletOptions.dart'; import 'package:gecko/models/walletOptions.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'dart:async'; import 'dart:async';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -17,6 +22,9 @@ class WalletOptions extends StatelessWidget with ChangeNotifier {
int walletNbr; int walletNbr;
String walletName; String walletName;
int derivation; int derivation;
int _nbrLinesName = 1;
bool _isNewNameValid = false;
bool isDefaultWallet;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -26,137 +34,390 @@ 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);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
// _walletOptions.isWalletUnlock = false; final int _currentChest = _myWalletProvider.getCurrentChest();
print("Is unlock ? ${_walletOptions.isWalletUnlock}"); final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
if (_walletOptions.nameController.text == null ||
_isNewNameValid == false) {
_walletOptions.nameController.text = walletName;
} else {
walletName = _walletOptions.nameController.text;
}
_walletOptions.walletID = '0:$walletNbr';
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall)
_nbrLinesName = 3;
defaultWallet == _walletOptions.walletID
? isDefaultWallet = true
: isDefaultWallet = false;
// print(_walletOptions.generateQRcode(_walletOptions.pubkey.text));
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
_walletOptions.isWalletUnlock = false; _walletOptions.isEditing = false;
Navigator.popUntil( _walletOptions.isBalanceBlur = true;
context, Navigator.popUntil(
ModalRoute.withName('/mywallets'), context,
); ModalRoute.withName('/'),
return Future<bool>.value(true); );
}, Navigator.pushNamed(context, '/mywallets');
child: Scaffold( return Future<bool>.value(true);
},
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.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil( Navigator.popUntil(
context, context,
ModalRoute.withName('/mywallets'), ModalRoute.withName('/'),
); );
Navigator.pushNamed(context, '/mywallets');
}), }),
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text(walletName), child: Text(_walletOptions.nameController.text),
)), )),
body: Builder( body: Builder(
builder: (ctx) => SafeArea( builder: (ctx) => SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
Expanded( Container(
height: isTall ? 15 : 0,
color: Color(0xffFFD68E),
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xffFFD68E),
Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
SizedBox(width: 25),
InkWell(
onTap: () async {
await _walletOptions.changeAvatar();
print('CHANGE AVATAR');
},
child: Image.asset(
'assets/chopp-gecko2.png',
)),
InkWell(
onTap: () async {
await _walletOptions.changeAvatar();
print('CHANGE AVATAR');
},
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: 15), Image.asset(
Text( 'assets/walletOptions/camera.png',
'Clé publique:', ),
style: TextStyle( SizedBox(height: 100)
fontSize: 15.0, ])),
color: Colors.grey[600], // SizedBox(width: 20),
fontWeight: FontWeight.w400), Column(children: <Widget>[
), Row(children: <Widget>[
SizedBox(height: 15), Column(children: <Widget>[
GestureDetector( SizedBox(
onTap: () { width: 260,
Clipboard.setData(ClipboardData( child: TextField(
text: _walletOptions.pubkey.text)); // autofocus: true,
_walletOptions.snackCopyKey(ctx); focusNode: _walletOptions.walletNameFocus,
}, enabled: _walletOptions.isEditing,
child: Text( controller: _walletOptions.nameController,
_walletOptions.pubkey.text, maxLines: _nbrLinesName,
style: TextStyle( textAlign: TextAlign.center,
fontSize: 14.0, decoration: InputDecoration(
color: Colors.black, border: InputBorder.none,
fontWeight: FontWeight.bold, focusedBorder: InputBorder.none,
fontFamily: 'Monospace'), enabledBorder: InputBorder.none,
)), disabledBorder: InputBorder.none,
Expanded( contentPadding: EdgeInsets.all(15.0),
child: Align( ),
alignment: Alignment.bottomCenter, style: TextStyle(
child: SizedBox( fontSize: isTall ? 27 : 23,
height: 50, color: Colors.black,
width: 300, fontWeight: FontWeight.w400,
child: ElevatedButton( fontFamily: 'Monospace')),
style: ElevatedButton.styleFrom( ),
elevation: 5, SizedBox(height: isTall ? 5 : 0),
primary: Color( Query(
0xffFFD68E), //Color(0xffFFD68E), // background options: QueryOptions(
onPrimary: Colors.black, // foreground document: gql(getBalance),
), variables: {
onPressed: () => _walletOptions 'pubkey': _walletOptions.pubkey.text,
.renameWalletAlerte(
context,
walletName,
walletNbr,
derivation)
.then((_result) {
if (_result == true) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
_myWalletProvider
.listWallets =
_myWalletProvider
.getAllWalletsNames();
_myWalletProvider
.rebuildWidget();
});
Navigator.popUntil(
context,
ModalRoute.withName(
'/mywallets'),
);
}
}),
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', pollInterval: Duration(seconds: 1),
style: TextStyle(fontSize: 20)))), ),
SizedBox(height: 50), builder: (QueryResult result,
Text( {VoidCallback refetch, FetchMore fetchMore}) {
'Portefeuille déverrouillé', if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Text('Loading');
}
// List repositories = result.data['viewer']['repositories']['nodes'];
String wBalanceUD;
if (result.data['balance'] == null) {
wBalanceUD = '0.0';
} else {
int wBalanceG1 =
result.data['balance']['amount'];
int currentUD =
result.data['currentUd']['amount'];
double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse(
(wBalanceUDBrut).toStringAsFixed(2))
.toString();
}
return Row(children: <Widget>[
ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: _walletOptions.isBalanceBlur
? 6
: 0,
sigmaY: _walletOptions.isBalanceBlur
? 5
: 0),
child: Text('$wBalanceUD',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black)),
),
Text(' DU',
style: TextStyle(
fontSize: isTall ? 20 : 18,
color: Colors.black))
]);
// Text(
// '$wBalanceUD DU',
// style: TextStyle(
// fontSize: 20, color: Colors.black),
// );
},
),
SizedBox(height: 5),
InkWell(
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
)),
]),
SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
onTap: () async {
// _walletOptions.isEditing = true;
// _walletOptions.reloadBuild();
// _walletOptions.walletNameFocus
// .requestFocus();
_isNewNameValid = await _walletOptions
.editWalletName(_walletOptions.walletID);
// .then((_) {
// _walletOptions.walletNameFocus
// .requestFocus();
// _walletOptions.reloadBuild();
// });
// .then(
// (_result) {
// if (_result == true) {
// WidgetsBinding.instance
// .addPostFrameCallback((_) {
// _myWalletProvider.listWallets =
// _myWalletProvider
// .getAllWalletsNames(
// _currentChest);
// _myWalletProvider.rebuildWidget();
// });
// Navigator.popUntil(
// context,
// ModalRoute.withName('/mywallets'),
// );
// }
// },
// );
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
// Image.asset(
// 'assets/walletOptions/edit.png',
// ),
SizedBox(
height: 60,
)
])
]),
]),
])),
SizedBox(height: 4 * ratio),
FutureBuilder(
future: _walletOptions
.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) {
return snapshot.data != null
? Image.memory(snapshot.data,
height: isTall ? 300 : 270)
: Text('-', style: TextStyle(fontSize: 20));
}),
SizedBox(height: 15 * ratio),
GestureDetector(
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
),
SizedBox(width: 10),
Text("${shortPubkey.split(':')[0]}:",
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(8),
),
elevation: 1,
primary: Color(0xffD28928), // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
),
SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15,
color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
onTap: () {
_historyProvider.isPubkey(ctx, _walletOptions.pubkey.text,
goHistory: true);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
),
SizedBox(width: 12),
Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 12 * ratio),
InkWell(
onTap: !isDefaultWallet
? () async {
await _walletOptions
.defAsDefaultWallet(_walletOptions.walletID)
.then((value) => {
_myWalletProvider
.getAllWalletsNames(_currentChest),
_myWalletProvider.rebuildWidget()
});
}
: null,
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
SizedBox(width: 31),
CircleAvatar(
backgroundColor:
Colors.grey[isDefaultWallet ? 300 : 500],
child: Image.asset(
'assets/walletOptions/android-checkmark.png',
)),
SizedBox(width: 12),
Text(
isDefaultWallet
? 'Ce portefeuille est celui par defaut'
: 'Définir comme portefeuille par défaut',
style: TextStyle(
fontSize: 20,
color: isDefaultWallet
? Colors.grey[500]
: Colors.black)),
]))),
SizedBox(height: 17 * ratio),
InkWell(
onTap: () async {
await _walletOptions.deleteWallet(
context, walletNbr, walletName, derivation);
WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider.getAllWalletsNames(_currentChest);
_myWalletProvider.rebuildWidget();
});
},
child: Row(children: <Widget>[
SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
),
SizedBox(width: 14),
Text('Supprimer ce portefeuille',
style: TextStyle( style: TextStyle(
color: Colors.green, fontSize: 20, color: Color(0xffD80000))),
fontWeight: FontWeight.w700, ])),
fontSize: 15), ]),
), ),
SizedBox(height: 10) )),
])), );
]),
)),
));
} }
} }

View File

@ -1,4 +1,5 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.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';
@ -19,12 +20,18 @@ class WalletsHome extends StatelessWidget {
WalletOptionsProvider _walletOptions = WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
_walletOptions.isWalletUnlock = false; _walletOptions.isWalletUnlock = false;
myWalletProvider.listWallets = myWalletProvider.getAllWalletsNames();
final int _currentChest = myWalletProvider.getCurrentChest();
myWalletProvider.listWallets =
myWalletProvider.getAllWalletsNames(_currentChest);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
if (myWalletProvider.listWallets != '') { if (myWalletProvider.listWallets != '') {
firstWalletDerivation = firstWalletDerivation =
int.parse(myWalletProvider.listWallets.split('\n')[0].split(':')[2]); int.parse(myWalletProvider.listWallets.split('\n')[0].split(':')[3]);
myWalletProvider.getDefaultWallet();
} }
return Scaffold( return Scaffold(
@ -57,10 +64,10 @@ class WalletsHome extends StatelessWidget {
body: SafeArea( body: SafeArea(
child: !isWalletsExists child: !isWalletsExists
? NoKeyChainScreen() ? NoKeyChainScreen()
: myWalletsList(context))); : myWalletsTiles(context)));
} }
Widget myWalletsList(BuildContext context) { Widget myWalletsTiles(BuildContext context) {
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
@ -72,39 +79,101 @@ class WalletsHome extends StatelessWidget {
if (_myWalletProvider.listWallets == '') { if (_myWalletProvider.listWallets == '') {
return Expanded( return Expanded(
child: Center( child: Column(children: <Widget>[
child: Text( Center(
'Veuillez générer votre premier portefeuille', child: Text(
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500), 'Veuillez générer votre premier portefeuille',
))); style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
)),
]));
} }
List _listWallets = _myWalletProvider.listWallets.split('\n'); List _listWallets = _myWalletProvider.listWallets.split('\n');
// final int nbrOfWallets = _listWallets.length;
// print(_listWallets);
// print("${_listWallets[0].split(':')[0]}:${_listWallets[0].split(':')[2]}");
// print(defaultWallet);
return Expanded( return GridView.count(
child: ListView(children: <Widget>[ crossAxisCount: 2,
SizedBox(height: 8), childAspectRatio: 1,
for (String _repository in _listWallets) crossAxisSpacing: 0,
ListTile( mainAxisSpacing: 0,
contentPadding: const EdgeInsets.only(left: 7.0), children: <Widget>[
leading: Padding( for (String _repository in _listWallets)
padding: const EdgeInsets.all(6.0), Padding(
child: Text("0 Ğ1", style: TextStyle(fontSize: 14.0))), padding: EdgeInsets.all(16),
// subtitle: Text(_repository.split(':')[3], child: GestureDetector(
// style: TextStyle(fontSize: 12.0, fontFamily: 'Monospace')), onTap: () {
title: Navigator.push(context,
Text(_repository.split(':')[1], style: TextStyle(fontSize: 16.0)), MaterialPageRoute(builder: (context) {
dense: true, return UnlockingWallet(
onTap: () { walletNbr: int.parse(_repository.split(':')[1]),
Navigator.push(context, MaterialPageRoute(builder: (context) { walletName: _repository.split(':')[2],
return UnlockingWallet( derivation: int.parse(_repository.split(':')[3]));
walletNbr: int.parse(_repository.split(':')[0]), }));
walletName: _repository.split(':')[1], },
derivation: int.parse(_repository.split(':')[2])); child: ClipRRect(
})); borderRadius: BorderRadius.all(Radius.circular(12)),
}, child: Column(children: <Widget>[
) Expanded(
])); child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: RadialGradient(
radius: 1,
colors: [
Colors.green[100],
Colors.green[500],
],
)),
child:
// SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48),
Image.asset(
'assets/chopp-gecko2.png',
),
)),
ListTile(
// contentPadding: const EdgeInsets.only(left: 7.0),
tileColor:
"${_repository.split(':')[0]}:${_repository.split(':')[1]}" ==
defaultWallet
? Color(0xffD28928)
: Color(0xffFFD58D),
// leading: Text('IMAGE'),
// subtitle: Text(_repository.split(':')[3],
// style: TextStyle(fontSize: 12.0, fontFamily: 'Monospace')),
title: Center(
child: Padding(
padding:
EdgeInsets.symmetric(horizontal: 5),
child: Text(_repository.split(':')[2],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
color:
"${_repository.split(':')[0]}:${_repository.split(':')[1]}" ==
defaultWallet
? Color(0xffF9F9F1)
: Colors.black)))),
// dense: true,
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return UnlockingWallet(
walletNbr:
int.parse(_repository.split(':')[1]),
walletName: _repository.split(':')[2],
derivation:
int.parse(_repository.split(':')[3]));
}));
},
)
]))))
]);
} }
Widget addNewDerivation(context, int _walletNbr) { Widget addNewDerivation(context, int _walletNbr) {
@ -142,7 +211,7 @@ class WalletsHome extends StatelessWidget {
onPressed: () async { onPressed: () async {
await _myWalletProvider await _myWalletProvider
.generateNewDerivation( .generateNewDerivation(
context, _newDerivationName.text, _walletNbr) context, _newDerivationName.text)
.then((_) => _newDerivationName.text == ''); .then((_) => _newDerivationName.text == '');
}, },
child: Text("Créer")), child: Text("Créer")),

View File

@ -61,6 +61,8 @@ class OnboardingStepFourteen extends StatelessWidget {
GenerateWalletsProvider _generateWalletProvider = GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
return Form( return Form(
key: formKey, key: formKey,
child: Padding( child: Padding(
@ -116,10 +118,9 @@ class OnboardingStepFourteen extends StatelessWidget {
if (resultWallet) { if (resultWallet) {
pinColor = Colors.green[500]; pinColor = Colors.green[500];
print(generatedWallet.pin); print(generatedWallet.pin);
await _generateWalletProvider.storeWallet( await _generateWalletProvider.storeHDWChest(
generatedWallet, 'Mon portefeuille courant', context, generatedWallet, 'Mon portefeuille courant', context);
isHD: true); _myWalletProvider.getAllWalletsNames(_currentChest);
_myWalletProvider.getAllWalletsNames();
_walletOptions.reloadBuild(); _walletOptions.reloadBuild();
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
Navigator.push( Navigator.push(

View File

@ -295,7 +295,14 @@ packages:
name: image_picker name: image_picker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.7.2" version: "0.7.3"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
image_picker_platform_interface: image_picker_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -317,6 +324,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.3"
jdenticon_dart:
dependency: "direct main"
description:
name: jdenticon_dart
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
js: js:
dependency: transitive dependency: transitive
description: description:

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages. # pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.1+20 version: 0.0.1+22
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.7.0 <3.0.0"
@ -19,7 +19,7 @@ dependencies:
qrscan: ^0.2.22 qrscan: ^0.2.22
permission_handler: ^6.0.1 permission_handler: ^6.0.1
image_gallery_saver: ^1.6.8 image_gallery_saver: ^1.6.8
image_picker: ^0.7.2 image_picker: ^0.7.3
# graphql_flutter: ^4.0.1 #^3.1.0 # graphql_flutter: ^4.0.1 #^3.1.0
graphql_flutter: ^5.0.0-nullsafety.1 graphql_flutter: ^5.0.0-nullsafety.1
provider: ^4.3.2+3 provider: ^4.3.2+3
@ -45,6 +45,7 @@ dependencies:
flutter_svg: ^0.20.0-nullsafety flutter_svg: ^0.20.0-nullsafety
responsive_framework: ^0.0.14 responsive_framework: ^0.0.14
responsive_builder: ^0.3.0 responsive_builder: ^0.3.0
jdenticon_dart: ^2.0.0
flutter_icons: flutter_icons:
android: "ic_launcher" android: "ic_launcher"
@ -67,3 +68,4 @@ flutter:
- assets/icon/ - assets/icon/
- assets/onBoarding/ - assets/onBoarding/
- assets/onBoarding/progress_bar/ - assets/onBoarding/progress_bar/
- assets/walletOptions/