diff --git a/assets/chests/0.png b/assets/chests/0.png new file mode 100755 index 0000000..71dcb9b Binary files /dev/null and b/assets/chests/0.png differ diff --git a/lib/globals.dart b/lib/globals.dart index 8953573..6bb6c42 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:gecko/models/chestData.dart'; import 'package:gecko/models/walletData.dart'; import 'package:hive/hive.dart'; import 'package:logger/logger.dart'; @@ -14,7 +15,7 @@ SharedPreferences prefs; String endPointGVA; int ramSys; Box walletBox; -Box chestBox; +Box chestBox; Box configBox; // String cesiumPod = "https://g1.data.le-sou.org"; diff --git a/lib/main.dart b/lib/main.dart index 2af5d1e..5ed289e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -18,6 +18,7 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/cesiumPlus.dart'; import 'package:gecko/models/changePin.dart'; +import 'package:gecko/models/chestData.dart'; import 'package:gecko/models/generateWallets.dart'; import 'package:gecko/models/history.dart'; import 'package:gecko/models/home.dart'; @@ -52,8 +53,9 @@ Future main() async { // Configure Hive and open boxes await Hive.initFlutter(appPath.path); Hive.registerAdapter(WalletDataAdapter()); + Hive.registerAdapter(ChestDataAdapter()); walletBox = await Hive.openBox("walletBox"); - chestBox = await Hive.openBox("chestBox"); + chestBox = await Hive.openBox("chestBox"); configBox = await Hive.openBox("configBox"); _walletsProvider.getDefaultWallet(); @@ -162,7 +164,7 @@ class Gecko extends StatelessWidget { bodyText1: TextStyle(), bodyText2: TextStyle(), ).apply( - bodyColor: Color(0xff855F2D), + bodyColor: Color(0xFF000000), ), colorScheme: ColorScheme.fromSwatch() .copyWith(secondary: Colors.grey[850]), diff --git a/lib/models/changePin.dart b/lib/models/changePin.dart index 5af359a..3c85b2e 100644 --- a/lib/models/changePin.dart +++ b/lib/models/changePin.dart @@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/chestData.dart'; class ChangePinProvider with ChangeNotifier { bool ischangedPin = false; @@ -12,7 +13,7 @@ class ChangePinProvider with ChangeNotifier { Future changePin(_name, _oldPin) async { try { - final _dewif = chestBox.get(0); + final _dewif = chestBox.get(configBox.get('currentChest')).dewif; NewWallet newWalletFile = await DubpRust.changeDewifPin( dewif: _dewif, @@ -29,10 +30,12 @@ class ChangePinProvider with ChangeNotifier { } } - Future storeWallet(context, _name, NewWallet _newWalletFile) async { - chestBox.put(0, _newWalletFile.dewif); + Future storeNewPinChest(context, NewWallet _newWalletFile) async { + ChestData currentChest = chestBox.getAt(configBox.get('currentChest')); + currentChest.dewif = _newWalletFile.dewif; + // currentChest.name = _name; + chestBox.add(currentChest); Navigator.pop(context); - return _name; } } diff --git a/lib/models/chestData.dart b/lib/models/chestData.dart new file mode 100644 index 0000000..e506add --- /dev/null +++ b/lib/models/chestData.dart @@ -0,0 +1,20 @@ +import 'package:hive_flutter/hive_flutter.dart'; + +part 'chestData.g.dart'; + +@HiveType(typeId: 1) +class ChestData extends HiveObject { + @HiveField(0) + String dewif; + + @HiveField(2) + String name; + + ChestData({this.dewif, this.name}); + + // representation of WalletData when debugging + @override + String toString() { + return this.name; + } +} diff --git a/lib/models/chestData.g.dart b/lib/models/chestData.g.dart new file mode 100644 index 0000000..095f182 --- /dev/null +++ b/lib/models/chestData.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'chestData.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class ChestDataAdapter extends TypeAdapter { + @override + final int typeId = 1; + + @override + ChestData read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return ChestData( + dewif: fields[0] as String, + name: fields[2] as String, + ); + } + + @override + void write(BinaryWriter writer, ChestData obj) { + writer + ..writeByte(2) + ..writeByte(0) + ..write(obj.dewif) + ..writeByte(2) + ..write(obj.name); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ChestDataAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/models/generateWallets.dart b/lib/models/generateWallets.dart index 8899751..52fb978 100644 --- a/lib/models/generateWallets.dart +++ b/lib/models/generateWallets.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/chestData.dart'; import 'package:gecko/models/walletData.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; @@ -40,11 +41,23 @@ class GenerateWalletsProvider with ChangeNotifier { void storeHDWChest( NewWallet _wallet, String _name, BuildContext context) async { + int chestNumber = chestBox.length; WalletData myWallet = - WalletData(chest: 0, number: 0, name: _name, derivation: 3); + WalletData(chest: chestNumber, number: 0, name: _name, derivation: 3); + + String chestName; + if (chestNumber == 0) { + chestName = 'Coffre à Gecko'; + } else { + chestName = 'Coffre à Gecko ${chestNumber + 1}'; + } walletBox.add(myWallet); - chestBox.put(0, _wallet.dewif); - configBox.put('currentChest', 0); + ChestData thisChest = ChestData( + dewif: _wallet.dewif, + name: chestName, + ); + chestBox.add(thisChest); + configBox.put('currentChest', chestNumber); // walletBox.get(1) } diff --git a/lib/models/history.dart b/lib/models/history.dart index 9be347c..d6f78ac 100644 --- a/lib/models/history.dart +++ b/lib/models/history.dart @@ -50,7 +50,7 @@ class HistoryProvider with ChangeNotifier { Future pay(BuildContext context, String pinCode) async { // MyWalletsProvider _myWalletProvider = MyWalletsProvider(); - String dewif = chestBox.get(0); + String dewif = chestBox.get(configBox.get('currentChest')).dewif; try { await DubpRust.simplePaymentFromTransparentAccount( accountIndex: defaultWallet.derivation, diff --git a/lib/models/myWallets.dart b/lib/models/myWallets.dart index 3cd63c4..664668f 100644 --- a/lib/models/myWallets.dart +++ b/lib/models/myWallets.dart @@ -22,7 +22,7 @@ class MyWalletsProvider with ChangeNotifier { return false; } - final List _walletList = readAllWallets(0); + final List _walletList = readAllWallets(getCurrentChest()); if (_walletList.isEmpty) { log.i('No wallets detected'); @@ -45,7 +45,7 @@ class MyWalletsProvider with ChangeNotifier { WalletData getWalletData(List _id) { if (_id.isEmpty) return WalletData(); - int _chest = _id[0]; + int _chest = _id[getCurrentChest()]; int _nbr = _id[1]; var _targetedWallet; @@ -63,7 +63,7 @@ class MyWalletsProvider with ChangeNotifier { MyWalletsProvider myWalletsProvider = MyWalletsProvider(); if (configBox.get('defaultWallet') == null) { - configBox.put('defaultWallet', [0, 0]); + configBox.put('defaultWallet', [getCurrentChest(), 0]); } defaultWallet = myWalletsProvider @@ -120,7 +120,7 @@ class MyWalletsProvider with ChangeNotifier { Future generateNewDerivation(context, String _name) async { int _newDerivationNbr; int _newWalletNbr; - int _chest = 0; + int _chest = getCurrentChest(); List _walletConfig = readAllWallets(_chest); if (_walletConfig.isEmpty) { diff --git a/lib/models/walletOptions.dart b/lib/models/walletOptions.dart index ba3da48..147d9a6 100644 --- a/lib/models/walletOptions.dart +++ b/lib/models/walletOptions.dart @@ -76,7 +76,7 @@ class WalletOptionsProvider with ChangeNotifier { context, WalletData _wallet, String _pin, int _pinLenght) async { isWalletUnlock = false; try { - String _localDewif = chestBox.get(0); + String _localDewif = chestBox.get(configBox.get('currentChest')).dewif; String _localPubkey; if ((_localPubkey = await _getPubkeyFromDewif( @@ -114,7 +114,7 @@ class WalletOptionsProvider with ChangeNotifier { int getPinLenght(_walletNbr) { String _localDewif; if (_walletNbr is int) { - _localDewif = chestBox.get(0); + _localDewif = chestBox.get(configBox.get('currentChest')).dewif; } else { _localDewif = _walletNbr; } diff --git a/lib/screens/myWallets/changePin.dart b/lib/screens/myWallets/changePin.dart index 19a87f0..563b247 100644 --- a/lib/screens/myWallets/changePin.dart +++ b/lib/screens/myWallets/changePin.dart @@ -92,8 +92,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier { onPressed: _changePin.newPin.text != '' ? () { _changePin.newPin.text = ''; - _changePin.storeWallet( - context, walletName, _newWalletFile); + _changePin.storeNewPinChest( + context, _newWalletFile); } : null, child: Text('Confirmer', style: TextStyle(fontSize: 28))), diff --git a/lib/screens/myWallets/chooseChest.dart b/lib/screens/myWallets/chooseChest.dart new file mode 100644 index 0000000..3a9fa19 --- /dev/null +++ b/lib/screens/myWallets/chooseChest.dart @@ -0,0 +1,78 @@ +import 'package:flutter/services.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/screens/home.dart'; +import 'package:flutter/material.dart'; +// import 'package:gecko/models/home.dart'; +// import 'package:provider/provider.dart'; + +// ignore: must_be_immutable +class ChooseChest extends StatelessWidget { + TextEditingController tplController = TextEditingController(); + + @override + Widget build(BuildContext context) { + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + int currentChest = configBox.get('currentChest'); + return Scaffold( + appBar: AppBar( + title: SizedBox( + height: 22, + child: Text('Sélectionner mon coffre'), + )), + floatingActionButton: Container( + height: 80.0, + width: 80.0, + child: FittedBox( + child: FloatingActionButton( + heroTag: "tplButton", + onPressed: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return HomeScreen(); + }), + ), + child: Container( + height: 40.0, + width: 40.0, + child: Icon(Icons.home, color: Colors.grey[850]), + ), + backgroundColor: + floattingYellow, //smoothYellow, //Color.fromARGB(500, 204, 255, 255), + ))), + body: SafeArea( + child: Column(children: [ + SizedBox(height: 150), + Center( + child: Image.asset( + 'assets/chests/$currentChest.png', + ), + ), + SizedBox(height: 20), + Text(chestBox.get(currentChest).name), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: yellowC, // background + onPrimary: Colors.black, // foreground + ), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return HomeScreen(); + }), + ); + }, + child: Text('Retour Accueil', style: TextStyle(fontSize: 20))), + SizedBox(height: 20), + GestureDetector( + onTap: () { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + }, + child: Icon(Icons.home)) + ]), + )); + } +} diff --git a/lib/screens/myWallets/walletsHome.dart b/lib/screens/myWallets/walletsHome.dart index 0f0b441..0d5e69e 100644 --- a/lib/screens/myWallets/walletsHome.dart +++ b/lib/screens/myWallets/walletsHome.dart @@ -5,14 +5,13 @@ import 'package:gecko/models/walletData.dart'; import 'package:gecko/models/walletOptions.dart'; import 'package:flutter/material.dart'; import 'package:gecko/screens/commonElements.dart'; +import 'package:gecko/screens/myWallets/chooseChest.dart'; import 'package:gecko/screens/myWallets/walletOptions.dart'; import 'package:gecko/screens/onBoarding/0_noKeychainFound.dart'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class WalletsHome extends StatelessWidget { final _derivationKey = GlobalKey(); - int firstWalletDerivation; @override Widget build(BuildContext context) { @@ -26,63 +25,58 @@ class WalletsHome extends StatelessWidget { myWalletProvider.readAllWallets(_currentChest); final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); - if (myWalletProvider.listWallets.isEmpty) { - firstWalletDerivation = myWalletProvider.listWallets[0].derivation; - - myWalletProvider.getDefaultWallet(); - } - - log.d("${myWalletProvider.pinCode},${myWalletProvider.pinLenght}"); - return WillPopScope( - onWillPop: () { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); - return Future.value(true); - }, - child: Scaffold( - appBar: AppBar( - leading: IconButton( - icon: Icon(Icons.arrow_back, color: Colors.black), - onPressed: () { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); - }), - title: Text('Mes portefeuilles', - key: Key('myWallets'), - style: TextStyle(color: Colors.grey[850])), - backgroundColor: Color(0xffFFD58D), + onWillPop: () { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + return Future.value(true); + }, + child: Scaffold( + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back, color: Colors.black), + onPressed: () { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + }), + title: Text('Mes portefeuilles', + key: Key('myWallets'), style: TextStyle(color: Colors.grey[850])), + backgroundColor: Color(0xffFFD58D), + ), + body: SafeArea( + child: + !isWalletsExists ? NoKeyChainScreen() : myWalletsTiles(context), + ), + ), + ); + } + + Widget chestOptions(BuildContext context) { + return Column(children: [ + SizedBox( + height: 90, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + elevation: 2, + primary: floattingYellow, // background + onPrimary: Colors.black, // foreground ), - floatingActionButton: Visibility( - visible: (isWalletsExists && firstWalletDerivation != -1), - child: Container( - height: 80.0, - width: 80.0, - child: FittedBox( - child: FloatingActionButton( - key: Key('addDerivation'), - heroTag: "buttonGenerateWallet", - onPressed: () { - showDialog( - context: context, - builder: (BuildContext context) { - return addNewDerivation(context, 1); - }); - }, - child: Container( - height: 40, - width: 40, - child: Icon(Icons.person_add_alt_1_rounded, - color: Colors.grey[850])), - backgroundColor: floattingYellow)))), - body: SafeArea( - child: !isWalletsExists - ? NoKeyChainScreen() - : myWalletsTiles(context)))); + onPressed: () => Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ChooseChest(); + }), + ), + child: Text( + "Changer de coffre", + style: TextStyle(fontSize: 16), + ), + )) + ]); } Widget myWalletsTiles(BuildContext context) { @@ -110,97 +104,138 @@ class WalletsHome extends StatelessWidget { List _listWallets = _myWalletProvider.listWallets; - return GridView.count( - key: Key('listWallets'), - crossAxisCount: 2, - childAspectRatio: 1, - crossAxisSpacing: 0, - mainAxisSpacing: 0, - children: [ - for (WalletData _repository in _listWallets) - Padding( + return CustomScrollView(slivers: [ + SliverGrid.count( + key: Key('listWallets'), + crossAxisCount: 2, + childAspectRatio: 1, + crossAxisSpacing: 0, + mainAxisSpacing: 0, + children: [ + for (WalletData _repository in _listWallets) + Padding( padding: EdgeInsets.all(16), child: GestureDetector( - onTap: () async { - await _walletOptions.readLocalWallet( - context, - _repository, - _myWalletProvider.pinCode, - _myWalletProvider.pinLenght); - Navigator.push( - context, - SmoothTransition( + onTap: () async { + await _walletOptions.readLocalWallet(context, _repository, + _myWalletProvider.pinCode, _myWalletProvider.pinLenght); + Navigator.push( + context, + SmoothTransition( + page: WalletOptions( + wallet: _repository, + ))); + + // Navigator.push(context, + // MaterialPageRoute(builder: (context) { + // return UnlockingWallet(wallet: _repository); + // })); + }, + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(12)), + child: Column(children: [ + 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( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(12))), + // contentPadding: const EdgeInsets.only(left: 7.0), + tileColor: _repository.id()[1] == defaultWallet.id()[1] + ? orangeC + : 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.name, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16.0, + color: _repository.id()[1] == + defaultWallet.id()[1] + ? Color(0xffF9F9F1) + : Colors.black)))), + // dense: true, + onTap: () { + Navigator.push( + context, + SmoothTransition( page: WalletOptions( - wallet: _repository, - ))); - - // Navigator.push(context, - // MaterialPageRoute(builder: (context) { - // return UnlockingWallet(wallet: _repository); - // })); - }, - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(12)), - child: Column(children: [ - 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', + wallet: _repository, + ), ), - )), - ListTile( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.vertical( - bottom: Radius.circular(12))), - // contentPadding: const EdgeInsets.only(left: 7.0), - tileColor: - _repository.id()[1] == defaultWallet.id()[1] - ? orangeC - : 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.name, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0, - color: _repository.id()[1] == - defaultWallet.id()[1] - ? Color(0xffF9F9F1) - : Colors.black)))), - // dense: true, - onTap: () { - Navigator.push( - context, - SmoothTransition( - page: WalletOptions( - wallet: _repository, - ))); - }, - ) - ])))) - ]); + ); + }, + ) + ]), + ), + ), + ), + addNewDerivation(context) + ]), + // SliverToBoxAdapter(child: Spacer()), + SliverPadding( + padding: EdgeInsets.symmetric(horizontal: 30), + sliver: SliverToBoxAdapter(child: chestOptions(context)), + ), + ]); } - Widget addNewDerivation(context, int _walletNbr) { + Widget addNewDerivation(context) { + return Padding( + padding: EdgeInsets.all(16), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(12)), + child: Column(children: [ + Expanded( + child: InkWell( + key: Key('addDerivation'), + onTap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return addNewDerivationPopup(context); + }); + }, + child: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration(color: floattingYellow), + child: Center( + child: Text( + '+', + style: TextStyle( + fontSize: 150, + fontWeight: FontWeight.w700, + color: Color(0xFFFCB437)), + )), + )), + ) + ]))); + } + + Widget addNewDerivationPopup(context) { final TextEditingController _newDerivationName = TextEditingController(); MyWalletsProvider _myWalletProvider = Provider.of(context); diff --git a/pubspec.yaml b/pubspec.yaml index d6fbafd..b3ffe6a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -76,6 +76,7 @@ flutter: - images/ - config/gva_endpoints.json - assets/ + - assets/chests/ - assets/icon/ - assets/onBoarding/ - assets/onBoarding/progress_bar/ diff --git a/test_driver/app_test.dart b/test_driver/app_test.dart index 7bcf48b..c540836 100644 --- a/test_driver/app_test.dart +++ b/test_driver/app_test.dart @@ -370,16 +370,22 @@ void main() { await goBack(); await driver.waitFor(find.text('Renommage wallet 2')); await createDerivation('Derivation 8'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 9'); await createDerivation('Derivation 10'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 11'); await createDerivation('Derivation 12'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 13'); await createDerivation('Derivation 14'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 15'); await createDerivation('Derivation 16'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 17'); await createDerivation('Derivation 18'); + await driver.scrollIntoView(find.text('+')); await createDerivation('Derivation 19'); await createDerivation('Derivation 20'); await sleep(400);