Implemente cesium wallet view

This commit is contained in:
poka 2021-11-17 06:20:23 +01:00
parent 4f316c40f5
commit 106fcf2835
17 changed files with 564 additions and 543 deletions

View File

@ -22,6 +22,7 @@ import 'package:gecko/globals.dart';
import 'package:gecko/models/cesium_plus.dart'; import 'package:gecko/models/cesium_plus.dart';
import 'package:gecko/models/change_pin.dart'; import 'package:gecko/models/change_pin.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/generate_wallets.dart'; import 'package:gecko/models/generate_wallets.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';
@ -136,6 +137,7 @@ class Gecko extends StatelessWidget {
ChangeNotifierProvider(create: (_) => HomeProvider()), ChangeNotifierProvider(create: (_) => HomeProvider()),
ChangeNotifierProvider(create: (_) => HistoryProvider('')), ChangeNotifierProvider(create: (_) => HistoryProvider('')),
ChangeNotifierProvider(create: (_) => MyWalletsProvider()), ChangeNotifierProvider(create: (_) => MyWalletsProvider()),
ChangeNotifierProvider(create: (_) => ChestProvider()),
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()), ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()), ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
ChangeNotifierProvider(create: (_) => ChangePinProvider()), ChangeNotifierProvider(create: (_) => ChangePinProvider()),

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'chest_data.g.dart'; part 'chest_data.g.dart';
@ -17,6 +19,9 @@ class ChestData extends HiveObject {
String imageName; String imageName;
@HiveField(5) @HiveField(5)
File imageFile;
@HiveField(6)
bool isCesium; bool isCesium;
ChestData({ ChestData({
@ -24,6 +29,7 @@ class ChestData extends HiveObject {
this.name, this.name,
this.defaultWallet, this.defaultWallet,
this.imageName, this.imageName,
this.imageFile,
this.isCesium, this.isCesium,
}); });

View File

@ -21,14 +21,15 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
name: fields[2] as String, name: fields[2] as String,
defaultWallet: fields[3] as int, defaultWallet: fields[3] as int,
imageName: fields[4] as String, imageName: fields[4] as String,
isCesium: fields[5] as bool, imageFile: fields[5] as File,
isCesium: fields[6] as bool,
); );
} }
@override @override
void write(BinaryWriter writer, ChestData obj) { void write(BinaryWriter writer, ChestData obj) {
writer writer
..writeByte(5) ..writeByte(6)
..writeByte(0) ..writeByte(0)
..write(obj.dewif) ..write(obj.dewif)
..writeByte(2) ..writeByte(2)
@ -38,6 +39,8 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
..writeByte(4) ..writeByte(4)
..write(obj.imageName) ..write(obj.imageName)
..writeByte(5) ..writeByte(5)
..write(obj.imageFile)
..writeByte(6)
..write(obj.isCesium); ..write(obj.isCesium);
} }

View File

@ -0,0 +1,53 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
class ChestProvider with ChangeNotifier {
void rebuildWidget() {
notifyListeners();
}
Future deleteChest(context, ChestData _chest) async {
final bool _answer = await _confirmDeletingChest(context, _chest.name);
if (_answer) {
chestBox.delete(_chest.key);
int lastChest = chestBox.toMap().keys.first;
configBox.put('currentChest', lastChest);
notifyListeners();
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
}
}
Future<bool> _confirmDeletingChest(context, String _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 coffre "$_walletName" ?'),
actions: <Widget>[
TextButton(
child: const Text("Non", key: Key('cancelDeleting')),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: const Text("Oui", key: Key('confirmDeleting')),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
},
);
}
}

View File

@ -39,15 +39,14 @@ class GenerateWalletsProvider with ChangeNotifier {
bool canImport = false; bool canImport = false;
bool isPinChanged = false; bool isPinChanged = false;
void storeHDWChest( Future storeHDWChest(
NewWallet _wallet, String _name, BuildContext context) async { NewWallet _wallet, String _name, BuildContext context) async {
int chestNumber = chestBox.length; int chestNumber = 0;
WalletData myWallet = WalletData( chestBox.toMap().forEach((key, value) {
chest: chestNumber, if (!value.isCesium) {
number: 0, chestNumber++;
name: _name, }
derivation: 3, });
imageName: '0.png');
String chestName; String chestName;
if (chestNumber == 0) { if (chestNumber == 0) {
@ -55,7 +54,6 @@ class GenerateWalletsProvider with ChangeNotifier {
} else { } else {
chestName = 'Coffre à Ğecko ${chestNumber + 1}'; chestName = 'Coffre à Ğecko ${chestNumber + 1}';
} }
walletBox.add(myWallet);
ChestData thisChest = ChestData( ChestData thisChest = ChestData(
dewif: _wallet.dewif, dewif: _wallet.dewif,
name: chestName, name: chestName,
@ -63,8 +61,19 @@ class GenerateWalletsProvider with ChangeNotifier {
imageName: '${chestNumber % 8}.png', imageName: '${chestNumber % 8}.png',
isCesium: false, isCesium: false,
); );
chestBox.add(thisChest); await chestBox.add(thisChest);
configBox.put('currentChest', chestNumber); int chestKey = chestBox.keys.last;
WalletData myWallet = WalletData(
chest: chestKey,
number: 0,
name: _name,
derivation: 3,
imageName: '0.png');
await walletBox.add(myWallet);
await configBox.put('currentChest', chestKey);
notifyListeners();
} }
void checkAskedWord(String inputWord, String _mnemo) { void checkAskedWord(String inputWord, String _mnemo) {
@ -240,16 +249,31 @@ class GenerateWalletsProvider with ChangeNotifier {
isCesiumIDVisible = false; isCesiumIDVisible = false;
isCesiumPWDVisible = false; isCesiumPWDVisible = false;
int chestNumber = 0;
chestBox.toMap().forEach((key, value) {
if (value.isCesium) {
chestNumber++;
}
});
String chestName;
if (chestNumber == 0) {
chestName = 'Coffre à Césium';
} else {
chestName = 'Coffre à Césium ${chestNumber + 1}';
}
ChestData cesiumChest = ChestData( ChestData cesiumChest = ChestData(
dewif: actualWallet.dewif, dewif: actualWallet.dewif,
name: 'Coffre à Cesium', name: chestName,
imageName: 'cesium.png', imageName: 'cesium.png',
defaultWallet: 0, defaultWallet: 0,
isCesium: true); isCesium: true);
int chestNumber = chestBox.length; await chestBox.add(cesiumChest).then((value) => null);
chestBox.add(cesiumChest); int chestKey = await chestBox.toMap().keys.last;
configBox.put('currentChest', chestNumber); // chestBox.toMap().
await configBox.put('currentChest', chestKey);
notifyListeners(); notifyListeners();
} }

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'wallet_data.g.dart'; part 'wallet_data.g.dart';
@ -19,8 +21,16 @@ class WalletData extends HiveObject {
@HiveField(4) @HiveField(4)
String imageName; String imageName;
@HiveField(5)
File imageFile;
WalletData( WalletData(
{this.chest, this.number, this.name, this.derivation, this.imageName}); {this.chest,
this.number,
this.name,
this.derivation,
this.imageName,
this.imageFile});
// representation of WalletData when debugging // representation of WalletData when debugging
@override @override
@ -34,7 +44,7 @@ class WalletData extends HiveObject {
} }
// returns only the id part of the ':'-separated string // returns only the id part of the ':'-separated string
List id() { List<int> id() {
return [chest, number]; return [chest, number];
} }
} }

View File

@ -22,13 +22,14 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
name: fields[2] as String, name: fields[2] as String,
derivation: fields[3] as int, derivation: fields[3] as int,
imageName: fields[4] as String, imageName: fields[4] as String,
imageFile: fields[5] as File,
); );
} }
@override @override
void write(BinaryWriter writer, WalletData obj) { void write(BinaryWriter writer, WalletData obj) {
writer writer
..writeByte(5) ..writeByte(6)
..writeByte(0) ..writeByte(0)
..write(obj.chest) ..write(obj.chest)
..writeByte(1) ..writeByte(1)
@ -38,7 +39,9 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
..writeByte(3) ..writeByte(3)
..write(obj.derivation) ..write(obj.derivation)
..writeByte(4) ..writeByte(4)
..write(obj.imageName); ..write(obj.imageName)
..writeByte(5)
..write(obj.imageFile);
} }
@override @override

View File

@ -8,6 +8,7 @@ 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:gecko/models/chest_data.dart';
import 'package:gecko/models/my_wallets.dart'; import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@ -24,7 +25,6 @@ class WalletOptionsProvider with ChangeNotifier {
bool isBalanceBlur = true; bool isBalanceBlur = true;
FocusNode walletNameFocus = FocusNode(); FocusNode walletNameFocus = FocusNode();
TextEditingController nameController = TextEditingController(); TextEditingController nameController = TextEditingController();
List<int> walletID;
bool isDefaultWallet; bool isDefaultWallet;
Future<NewWallet> get badWallet => null; Future<NewWallet> get badWallet => null;
@ -125,63 +125,28 @@ class WalletOptionsProvider with ChangeNotifier {
return _pinLenght; return _pinLenght;
} }
void _renameWallet(List<int> _walletID, _newName) async { void _renameWallet(List<int> _walletID, _newName, {bool isCesium}) async {
if (isCesium) {
ChestData _chestTarget = chestBox.get(_walletID[0]);
_chestTarget.name = _newName;
await chestBox.put(_chestTarget.key, _chestTarget);
} else {
MyWalletsProvider myWalletClass = MyWalletsProvider(); MyWalletsProvider myWalletClass = MyWalletsProvider();
WalletData _walletTarget = myWalletClass.getWalletData(_walletID); WalletData _walletTarget = myWalletClass.getWalletData(_walletID);
_walletTarget.name = _newName; _walletTarget.name = _newName;
await walletBox.put(_walletTarget.key, _walletTarget); await walletBox.put(_walletTarget.key, _walletTarget);
}
_newWalletName.text = ''; _newWalletName.text = '';
} }
Future<bool> renameWalletAlerte( bool editWalletName(List<int> _wID, {bool isCesium}) {
context, _walletName, _walletNbr, _derivation) async {
return showDialog<bool>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Choisissez un nouveau nom pour ce portefeuille'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
TextField(
controller: _newWalletName,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
],
),
),
actions: <Widget>[
TextButton(
child: const Text("Valider"),
onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) async {
// await _renameWallet(_walletName, this._newWalletName.text,
// _walletNbr, _derivation);
});
// notifyListeners();
Navigator.pop(context, true);
},
),
],
);
},
);
}
bool editWalletName(List<int> _wID) {
bool nameState; bool nameState;
if (isEditing) { if (isEditing) {
if (!nameController.text.contains(':') && if (!nameController.text.contains(':') &&
nameController.text.length <= 39) { nameController.text.length <= 39) {
_renameWallet(_wID, nameController.text); _renameWallet(_wID, nameController.text, isCesium: isCesium);
nameState = true; nameState = true;
} else { } else {
nameState = false; nameState = false;
@ -281,10 +246,11 @@ class WalletOptionsProvider with ChangeNotifier {
File _image; File _image;
final picker = ImagePicker(); final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery); XFile pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) { if (pickedFile != null) {
_image = File(pickedFile.path); _image = File(pickedFile.path);
log.i(pickedFile.path);
return _image; return _image;
} else { } else {
log.w('No image selected.'); log.w('No image selected.');

View File

@ -1,5 +1,6 @@
import 'package:dubp/dubp.dart'; import 'package:dubp/dubp.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_provider.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:flutter/material.dart'; import 'package:flutter/material.dart';
@ -23,10 +24,9 @@ class HomeScreen extends StatelessWidget {
HistoryProvider _historyStatic = HistoryProvider(''); HistoryProvider _historyStatic = HistoryProvider('');
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); Provider.of<ChestProvider>(context);
WalletData defaultWallet = final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
_myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
// walletBox.toMap().forEach((key, value) { // walletBox.toMap().forEach((key, value) {
// if (value.chest == 0) { // if (value.chest == 0) {
@ -281,6 +281,9 @@ class HomeScreen extends StatelessWidget {
image: AssetImage('assets/lock.png'), image: AssetImage('assets/lock.png'),
height: 57)), height: 57)),
onTap: () { onTap: () {
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(
configBox.get('currentChest'));
isWalletsExists isWalletsExists
? Navigator.push(context, ? Navigator.push(context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {

View File

@ -1,39 +1,31 @@
import 'dart:io';
import 'dart:ui'; 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/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/chest_provider.dart';
import 'package:gecko/models/history.dart'; import 'package:gecko/models/history.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/queries.dart'; import 'package:gecko/models/queries.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart'; import 'package:gecko/models/wallet_options.dart';
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/services.dart'; import 'package:flutter/services.dart';
// ignore: must_be_immutable int _nbrLinesName = 1;
class CesiumWalletOptions extends StatelessWidget { bool _isNewNameValid = false;
CesiumWalletOptions({Key keyMyWallets, @required this.cesiumWallet})
: super(key: keyMyWallets);
WalletData cesiumWallet;
int _nbrLinesName = 1;
bool _isNewNameValid = false;
@override Widget cesiumWalletOptions(BuildContext context, ChestData cesiumWallet) {
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions = WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context); Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider = ChestProvider _chestProvider = Provider.of<ChestProvider>(context);
Provider.of<MyWalletsProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context); HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
final String shortPubkey = final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text); _walletOptions.getShortPubkey(_walletOptions.pubkey.text);
if (_walletOptions.nameController.text == null || if (_walletOptions.nameController.text == null || _isNewNameValid == false) {
_isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name; _walletOptions.nameController.text = cesiumWallet.name;
} else { } else {
cesiumWallet.name = _walletOptions.nameController.text; cesiumWallet.name = _walletOptions.nameController.text;
@ -46,51 +38,13 @@ class CesiumWalletOptions extends StatelessWidget {
_nbrLinesName = 3; _nbrLinesName = 3;
} }
_walletOptions.walletID = [0, cesiumWallet.number]; return Scaffold(
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(_currentChest);
_walletOptions.isDefaultWallet =
(defaultWallet.number == _walletOptions.walletID[1]);
int currentChest = _myWalletProvider.getCurrentChest();
log.d("Wallet options: $currentChest:${cesiumWallet.number}");
return WillPopScope(
onWillPop: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
return Future<bool>.value(true);
},
child: Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = true;
Navigator.popUntil(
context,
ModalRoute.withName('/mywallets'),
);
}),
title: SizedBox(
height: 22,
child: Text(_walletOptions.nameController.text),
)),
body: Builder( body: Builder(
builder: (ctx) => SafeArea( builder: (ctx) => SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
Container( Container(
height: isTall ? 15 : 0, height: isTall ? 30 : 15,
color: yellowC, color: yellowC,
), ),
Container( Container(
@ -107,15 +61,26 @@ class CesiumWalletOptions extends StatelessWidget {
const SizedBox(width: 25), const SizedBox(width: 25),
InkWell( InkWell(
onTap: () async { onTap: () async {
await _walletOptions.changeAvatar(); File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
}, },
child: Image.asset( child: cesiumWallet.imageFile == null
'assets/avatars/${cesiumWallet.imageName}', ? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110, width: 110,
)), )
: Image.file(cesiumWallet.imageFile, width: 110),
),
InkWell( InkWell(
onTap: () async { onTap: () async {
await _walletOptions.changeAvatar(); File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
}, },
child: Column(children: <Widget>[ child: Column(children: <Widget>[
Image.asset( Image.asset(
@ -173,10 +138,8 @@ class CesiumWalletOptions extends StatelessWidget {
if (result.data['balance'] == null) { if (result.data['balance'] == null) {
wBalanceUD = '0.0'; wBalanceUD = '0.0';
} else { } else {
int wBalanceG1 = int wBalanceG1 = result.data['balance']['amount'];
result.data['balance']['amount']; int currentUD = result.data['currentUd']['amount'];
int currentUD =
result.data['currentUd']['amount'];
double wBalanceUDBrut = double wBalanceUDBrut =
wBalanceG1 / currentUD; // .toString(); wBalanceG1 / currentUD; // .toString();
wBalanceUD = double.parse( wBalanceUD = double.parse(
@ -186,12 +149,8 @@ class CesiumWalletOptions extends StatelessWidget {
return Row(children: <Widget>[ return Row(children: <Widget>[
ImageFiltered( ImageFiltered(
imageFilter: ImageFilter.blur( imageFilter: ImageFilter.blur(
sigmaX: _walletOptions.isBalanceBlur sigmaX: _walletOptions.isBalanceBlur ? 6 : 0,
? 6 sigmaY: _walletOptions.isBalanceBlur ? 5 : 0),
: 0,
sigmaY: _walletOptions.isBalanceBlur
? 5
: 0),
child: Text(wBalanceUD, child: Text(wBalanceUD,
style: TextStyle( style: TextStyle(
fontSize: isTall ? 20 : 18, fontSize: isTall ? 20 : 18,
@ -227,8 +186,9 @@ class CesiumWalletOptions extends StatelessWidget {
InkWell( InkWell(
key: const Key('renameWallet'), key: const Key('renameWallet'),
onTap: () async { onTap: () async {
_isNewNameValid = _walletOptions _isNewNameValid = _walletOptions.editWalletName(
.editWalletName(_walletOptions.walletID); [cesiumWallet.key, 0],
isCesium: cesiumWallet.isCesium);
await Future.delayed( await Future.delayed(
const Duration(milliseconds: 30)); const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus(); _walletOptions.walletNameFocus.requestFocus();
@ -250,12 +210,10 @@ class CesiumWalletOptions extends StatelessWidget {
])), ])),
SizedBox(height: 4 * ratio), SizedBox(height: 4 * ratio),
FutureBuilder( FutureBuilder(
future: _walletOptions future: _walletOptions.generateQRcode(_walletOptions.pubkey.text),
.generateQRcode(_walletOptions.pubkey.text),
builder: (context, snapshot) { builder: (context, snapshot) {
return snapshot.data != null return snapshot.data != null
? Image.memory(snapshot.data, ? Image.memory(snapshot.data, height: isTall ? 300 : 270)
height: isTall ? 300 : 270)
: const Text('-', style: TextStyle(fontSize: 20)); : const Text('-', style: TextStyle(fontSize: 20));
}), }),
SizedBox(height: 15 * ratio), SizedBox(height: 15 * ratio),
@ -309,8 +267,7 @@ class CesiumWalletOptions extends StatelessWidget {
const SizedBox(width: 7), const SizedBox(width: 7),
Text('Copier', Text('Copier',
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15, color: Colors.grey[50]))
color: Colors.grey[50]))
]))), ]))),
]))), ]))),
SizedBox(height: 10 * ratio), SizedBox(height: 10 * ratio),
@ -329,71 +286,25 @@ class CesiumWalletOptions extends StatelessWidget {
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
const Text('Historique des transactions', const Text('Historique des transactions',
style: style: TextStyle(fontSize: 20, color: Colors.black)),
TextStyle(fontSize: 20, color: Colors.black)),
]))), ]))),
SizedBox(height: 12 * ratio), SizedBox(height: 12 * ratio),
InkWell(
key: const Key('setDefaultWallet'),
onTap: !_walletOptions.isDefaultWallet
? () {
defaultWallet = cesiumWallet;
chestBox.get(currentChest).defaultWallet =
cesiumWallet.number;
_myWalletProvider.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
}
: null,
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 31),
CircleAvatar(
backgroundColor: Colors.grey[
_walletOptions.isDefaultWallet ? 300 : 500],
child: Image.asset(
'assets/walletOptions/android-checkmark.png',
)),
const SizedBox(width: 12),
Text(
_walletOptions.isDefaultWallet
? 'Ce portefeuille est celui par defaut'
: 'Définir comme portefeuille par défaut',
style: TextStyle(
fontSize: 20,
color: _walletOptions.isDefaultWallet
? Colors.grey[500]
: Colors.black)),
]))),
SizedBox(height: 17 * ratio),
if (!_walletOptions.isDefaultWallet)
InkWell( InkWell(
key: const Key('deleteWallet'), key: const Key('deleteWallet'),
onTap: !_walletOptions.isDefaultWallet onTap: () async {
? () async { await _chestProvider.deleteChest(context, cesiumWallet);
await _walletOptions.deleteWallet( },
context, cesiumWallet);
WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider
.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
});
}
: null,
child: Row(children: <Widget>[ child: Row(children: <Widget>[
const SizedBox(width: 33), const SizedBox(width: 33),
Image.asset( Image.asset(
'assets/walletOptions/trash.png', 'assets/walletOptions/trash.png',
), ),
const SizedBox(width: 14), const SizedBox(width: 14),
const Text('Supprimer ce portefeuille', const Text('Supprimer ce coffre',
style: TextStyle( style: TextStyle(fontSize: 20, color: Color(0xffD80000))),
fontSize: 20, color: Color(0xffD80000))),
])), ])),
]), ]),
), ),
), ),
)); );
}
} }

View File

@ -45,7 +45,7 @@ class _ChooseChestState extends State<ChooseChest> {
options: CarouselOptions( options: CarouselOptions(
height: 210, height: 210,
onPageChanged: (index, reason) { onPageChanged: (index, reason) {
currentChest = index; currentChest = chestBox.toMap().keys.toList()[index];
setState(() {}); setState(() {});
}, },
enableInfiniteScroll: false, enableInfiniteScroll: false,
@ -57,9 +57,14 @@ class _ChooseChestState extends State<ChooseChest> {
return Builder( return Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
return Column(children: <Widget>[ return Column(children: <Widget>[
Image.asset( i.value.imageFile == null
? Image.asset(
'assets/chests/${i.value.imageName}', 'assets/chests/${i.value.imageName}',
height: 150, height: 150,
)
: Image.file(
i.value.imageFile,
height: 150,
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
Text( Text(
@ -71,6 +76,7 @@ class _ChooseChestState extends State<ChooseChest> {
); );
}).toList(), }).toList(),
), ),
if (chestBox.values.toList().length > 1)
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: chestBox.toMap().entries.map((entry) { children: chestBox.toMap().entries.map((entry) {
@ -84,7 +90,8 @@ class _ChooseChestState extends State<ChooseChest> {
vertical: 8.0, horizontal: 4.0), vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: (Theme.of(context).brightness == Brightness.dark color:
(Theme.of(context).brightness == Brightness.dark
? Colors.white ? Colors.white
: Colors.black) : Colors.black)
.withOpacity( .withOpacity(

View File

@ -23,7 +23,6 @@ class UnlockingWallet extends StatelessWidget {
// ignore: close_sinks // ignore: close_sinks
StreamController<ErrorAnimationType> errorController; StreamController<ErrorAnimationType> errorController;
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
bool hasError = false;
var pinColor = const Color(0xffF9F9F1); var pinColor = const Color(0xffF9F9F1);
var walletPin = ''; var walletPin = '';
String resultPay; String resultPay;
@ -56,9 +55,14 @@ class UnlockingWallet extends StatelessWidget {
child: Column(children: <Widget>[ child: Column(children: <Widget>[
SizedBox(height: isTall ? 80 : 20), SizedBox(height: isTall ? 80 : 20),
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Image.asset( currentChest.imageFile == null
? Image.asset(
'assets/chests/${currentChest.imageName}', 'assets/chests/${currentChest.imageName}',
height: isTall ? 130 : 100, width: isTall ? 130 : 100,
)
: Image.file(
currentChest.imageFile,
width: isTall ? 130 : 100,
), ),
const SizedBox(width: 5), const SizedBox(width: 5),
SizedBox( SizedBox(
@ -123,11 +127,14 @@ class UnlockingWallet extends StatelessWidget {
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context); HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
FocusNode pinFocus = FocusNode();
return Form( return Form(
key: formKey, key: formKey,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30), padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30),
child: PinCodeTextField( child: PinCodeTextField(
focusNode: pinFocus,
autoFocus: true, autoFocus: true,
appContext: context, appContext: context,
pastedTextStyle: TextStyle( pastedTextStyle: TextStyle(
@ -152,7 +159,7 @@ class UnlockingWallet extends StatelessWidget {
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
fieldHeight: 50 * ratio, fieldHeight: 50 * ratio,
fieldWidth: 50, fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black, activeFillColor: Colors.black,
), ),
cursorColor: Colors.black, cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300), animationDuration: const Duration(milliseconds: 300),
@ -180,9 +187,9 @@ class UnlockingWallet extends StatelessWidget {
if (resultWallet == 'bad') { if (resultWallet == 'bad') {
errorController.add(ErrorAnimationType errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation .shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600]; pinColor = Colors.red[600];
_walletOptions.reloadBuild(); _walletOptions.reloadBuild();
pinFocus.requestFocus();
} else { } else {
pinColor = Colors.green[400]; pinColor = Colors.green[400];
// await Future.delayed(Duration(milliseconds: 50)); // await Future.delayed(Duration(milliseconds: 50));

View File

@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -46,13 +47,10 @@ class WalletOptions extends StatelessWidget {
_nbrLinesName = 3; _nbrLinesName = 3;
} }
_walletOptions.walletID = [0, wallet.number];
WalletData defaultWallet = WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(_currentChest); _myWalletProvider.getDefaultWallet(_currentChest);
_walletOptions.isDefaultWallet = _walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
(defaultWallet.number == _walletOptions.walletID[1]);
int currentChest = _myWalletProvider.getCurrentChest(); int currentChest = _myWalletProvider.getCurrentChest();
@ -107,15 +105,30 @@ class WalletOptions extends StatelessWidget {
const SizedBox(width: 25), const SizedBox(width: 25),
InkWell( InkWell(
onTap: () async { onTap: () async {
File newAvatar =
await _walletOptions.changeAvatar(); await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
}, },
child: Image.asset( child: wallet.imageFile == null
? Image.asset(
'assets/avatars/${wallet.imageName}', 'assets/avatars/${wallet.imageName}',
width: 110, width: 110,
)
: Image.file(
wallet.imageFile,
width: 110,
)), )),
InkWell( InkWell(
onTap: () async { onTap: () async {
File newAvatar =
await _walletOptions.changeAvatar(); await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
}, },
child: Column(children: <Widget>[ child: Column(children: <Widget>[
Image.asset( Image.asset(
@ -227,8 +240,9 @@ class WalletOptions extends StatelessWidget {
InkWell( InkWell(
key: const Key('renameWallet'), key: const Key('renameWallet'),
onTap: () async { onTap: () async {
_isNewNameValid = _walletOptions _isNewNameValid =
.editWalletName(_walletOptions.walletID); _walletOptions.editWalletName(wallet.id(),
isCesium: false);
await Future.delayed( await Future.delayed(
const Duration(milliseconds: 30)); const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus(); _walletOptions.walletNameFocus.requestFocus();

View File

@ -7,6 +7,7 @@ import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart'; import 'package:gecko/models/wallet_options.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/cesium_wallet_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart'; import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart'; import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/screens/onBoarding/0_no_keychain_found.dart'; import 'package:gecko/screens/onBoarding/0_no_keychain_found.dart';
@ -62,18 +63,18 @@ class WalletsHome extends StatelessWidget {
child: !isWalletsExists child: !isWalletsExists
? const NoKeyChainScreen() ? const NoKeyChainScreen()
: _currentChest.isCesium : _currentChest.isCesium
? cesiumWalletOptions(context) ? cesiumWalletOptions(context, _currentChest)
: myWalletsTiles(context), : myWalletsTiles(context),
), ),
), ),
); );
} }
Widget cesiumWalletOptions(BuildContext context) { // Widget cesiumWalletOptions(BuildContext context) {
return Column(children: const [ // return Column(children: const [
Center(child: Text('This is a Cesium wallet')), // Center(child: Text('This is a Cesium wallet')),
]); // ]);
} // }
Widget chestOptions(BuildContext context) { Widget chestOptions(BuildContext context) {
return Column(children: [ return Column(children: [
@ -214,10 +215,16 @@ class WalletsHome extends StatelessWidget {
child: child:
// SvgPicture.asset('assets/chopp-gecko2.png', // SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48), // semanticsLabel: 'Gecko', height: 48),
Image.asset( _repository.imageFile == null
? Image.asset(
'assets/avatars/${_repository.imageName}', 'assets/avatars/${_repository.imageName}',
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
scale: 0.5, scale: 0.5,
)
: Image.file(
_repository.imageFile,
alignment: Alignment.bottomCenter,
scale: 0.5,
), ),
)), )),
// balanceBuilder(context, _walletOptions.pubkey.text), // balanceBuilder(context, _walletOptions.pubkey.text),

View File

@ -176,6 +176,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
confirm_dialog:
dependency: "direct main"
description:
name: confirm_dialog
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
connectivity_plus: connectivity_plus:
dependency: transitive dependency: transitive
description: description:

View File

@ -56,6 +56,7 @@ dependencies:
assorted_layout_widgets: ^5.2.1 assorted_layout_widgets: ^5.2.1
carousel_slider: ^4.0.0 carousel_slider: ^4.0.0
flutter_lints: ^1.0.4 flutter_lints: ^1.0.4
confirm_dialog: ^1.0.0
flutter_icons: flutter_icons:
android: "ic_launcher" android: "ic_launcher"
@ -79,6 +80,7 @@ flutter:
- images/ - images/
- config/gva_endpoints.json - config/gva_endpoints.json
- assets/ - assets/
- assets/customs/
- assets/avatars/ - assets/avatars/
- assets/chests/ - assets/chests/
- assets/icon/ - assets/icon/

View File

@ -1,8 +1,8 @@
// Imports the Flutter Driver API. // ignore_for_file: avoid_print
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter_driver/flutter_driver.dart'; import 'package:flutter_driver/flutter_driver.dart';
import 'package:gecko/globals.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
// import 'package:flutter/services.dart'; // import 'package:flutter/services.dart';
@ -71,13 +71,8 @@ void main() {
} }
// Create a derivation // Create a derivation
Future createDerivation(String _name) async { Future createDerivation() async {
await tapOn('addDerivation'); await tapOn('addDerivation');
await sleep(100);
await driver.enterText(_name);
await tapOn('validDerivation');
await sleep(300); await sleep(300);
} }
@ -109,7 +104,7 @@ void main() {
await sleep(300); await sleep(300);
await tapOn('generateKeychain'); await tapOn('generateKeychain');
while (await getText('generatedPin') == '') { while (await getText('generatedPin') == '') {
log.i('Waiting for pin code generation...'); print('Waiting for pin code generation...');
await sleep(100); await sleep(100);
} }
pinCode = await getText('generatedPin'); pinCode = await getText('generatedPin');
@ -172,7 +167,7 @@ void main() {
await tapOn('goStep7'); await tapOn('goStep7');
while (await getText('word1') == '...') { while (await getText('word1') == '...') {
log.i('Waiting for Mnemonic generation...'); print('Waiting for Mnemonic generation...');
await sleep(100); await sleep(100);
} }
@ -226,7 +221,7 @@ void main() {
await tapOn('goStep11'); await tapOn('goStep11');
while (await getText('generatedPin') == '') { while (await getText('generatedPin') == '') {
log.i('Waiting for pin code generation...'); print('Waiting for pin code generation...');
await sleep(100); await sleep(100);
} }
@ -258,7 +253,7 @@ void main() {
{timeout = const Duration(seconds: 2)}) async { {timeout = const Duration(seconds: 2)}) async {
await tapOn('goWalletHome'); await tapOn('goWalletHome');
expect(await getText('myWallets'), "Mes portefeuilles"); expect(await getText('myWallets'), "Coffre à Ğecko");
await sleep(300); await sleep(300);
// Go to first derivation and rename it // Go to first derivation and rename it
@ -281,10 +276,10 @@ void main() {
{timeout = const Duration(seconds: 2)}) async { {timeout = const Duration(seconds: 2)}) async {
await driver.waitFor(find.text('Renommage wallet 1'), timeout: timeout); await driver.waitFor(find.text('Renommage wallet 1'), timeout: timeout);
// Add a second derivation // Add a second derivation
await createDerivation('Derivation 2'); await createDerivation();
// Go to second derivation options // Go to second derivation options
await driver.tap(find.text('Derivation 2')); await driver.tap(find.text('Portefeuille 2'));
await sleep(100); await sleep(100);
// Test options // Test options
@ -305,14 +300,14 @@ void main() {
await goBack(); await goBack();
// Add a third derivation // Add a third derivation
await createDerivation('Derivation 3'); await createDerivation();
// Add a fourth derivation // Add a fourth derivation
await createDerivation('Derivation 4'); await createDerivation();
await sleep(50); await sleep(50);
// Go to third derivation options // Go to third derivation options
await driver.tap(find.text('Derivation 3')); await driver.tap(find.text('Portefeuille 3'));
await sleep(100); await sleep(100);
await tapOn('displayBalance'); await tapOn('displayBalance');
@ -323,10 +318,10 @@ void main() {
test('My wallets - Extra tests', ( test('My wallets - Extra tests', (
{timeout = const Duration(seconds: 2)}) async { {timeout = const Duration(seconds: 2)}) async {
// Add derivation 5,6 and 7 // Add derivation 5,6 and 7
await driver.waitFor(find.text('Derivation 4'), timeout: timeout); await driver.waitFor(find.text('Portefeuille 4'), timeout: timeout);
await createDerivation('Derivation 5'); await createDerivation();
await createDerivation('Derivation 6'); await createDerivation();
await createDerivation('Derivation 7'); await createDerivation();
// Go home and come back to my wallets view // Go home and come back to my wallets view
await goBack(); await goBack();
@ -338,12 +333,12 @@ void main() {
await sleep(200); await sleep(200);
// Go to derivation 6 and delete it // Go to derivation 6 and delete it
await driver.tap(find.text('Derivation 6')); await driver.tap(find.text('Portefeuille 6'));
await sleep(100); await sleep(100);
await deleteWallet(true); await deleteWallet(true);
// Go to 2nd derivation and check if it's de default // Go to 2nd derivation and check if it's de default
await driver.tap(find.text('Derivation 2')); await driver.tap(find.text('Portefeuille 2'));
await driver.waitFor(find.text('Ce portefeuille est celui par defaut')); await driver.waitFor(find.text('Ce portefeuille est celui par defaut'));
await tapOn('setDefaultWallet'); await tapOn('setDefaultWallet');
await sleep(100); await sleep(100);
@ -369,43 +364,44 @@ void main() {
await sleep(400); await sleep(400);
await goBack(); await goBack();
await driver.waitFor(find.text('Renommage wallet 2')); await driver.waitFor(find.text('Renommage wallet 2'));
await createDerivation('Derivation 8');
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 9'); await createDerivation();
await createDerivation('Derivation 10'); await createDerivation();
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 11'); await createDerivation();
await createDerivation('Derivation 12'); await createDerivation();
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 13'); await createDerivation();
await createDerivation('Derivation 14'); await createDerivation();
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 15'); await createDerivation();
await createDerivation('Derivation 16'); await createDerivation();
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 17'); await createDerivation();
await createDerivation('Derivation 18'); await createDerivation();
await driver.scrollIntoView(find.text('+')); await driver.scrollIntoView(find.text('+'));
await createDerivation('Derivation 19'); await createDerivation();
await createDerivation('Derivation 20'); await createDerivation();
await driver.scrollIntoView(find.text('+'));
await createDerivation();
await sleep(400); await sleep(400);
// Scroll the wallet screen until Derivation 20 and open it // Scroll the wallet screen until Derivation 20 and open it
await driver.scrollUntilVisible( await driver.scrollUntilVisible(
find.byValueKey('listWallets'), find.byValueKey('listWallets'),
find.text('Derivation 20'), find.text('Portefeuille 20'),
dyScroll: -300.0, dyScroll: -300.0,
); );
await driver.waitFor(find.text('Derivation 20')); await driver.waitFor(find.text('Portefeuille 20'));
await sleep(400); await sleep(400);
await driver.tap(find.text('Derivation 20')); await driver.tap(find.text('Portefeuille 20'));
await tapOn('copyPubkey'); await tapOn('copyPubkey');
}); });
test('Search - Search Pi profile, navigate in history transactions', ( test('Search - Search Pi profile, navigate in history transactions', (
{timeout = const Duration(seconds: 2)}) async { {timeout = const Duration(seconds: 2)}) async {
await driver.waitFor(find.text('Derivation 20'), timeout: timeout); await driver.waitFor(find.text('Portefeuille 20'), timeout: timeout);
await goBack(); await goBack();
await goBack(); await goBack();
await sleep(200); await sleep(200);
@ -448,7 +444,7 @@ void main() {
await sleep(200); await sleep(200);
await driver.enterText(pincode); await driver.enterText(pincode);
await sleep(100); await sleep(100);
await createDerivation('Derivation 2'); await createDerivation();
await sleep(100); await sleep(100);
await driver.tap(find.text('Fast wallet')); await driver.tap(find.text('Fast wallet'));
await driver.waitFor(find.text('Fast wallet')); await driver.waitFor(find.text('Fast wallet'));