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

View File

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

View File

@ -21,14 +21,15 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
name: fields[2] as String,
defaultWallet: fields[3] as int,
imageName: fields[4] as String,
isCesium: fields[5] as bool,
imageFile: fields[5] as File,
isCesium: fields[6] as bool,
);
}
@override
void write(BinaryWriter writer, ChestData obj) {
writer
..writeByte(5)
..writeByte(6)
..writeByte(0)
..write(obj.dewif)
..writeByte(2)
@ -38,6 +39,8 @@ class ChestDataAdapter extends TypeAdapter<ChestData> {
..writeByte(4)
..write(obj.imageName)
..writeByte(5)
..write(obj.imageFile)
..writeByte(6)
..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 isPinChanged = false;
void storeHDWChest(
Future storeHDWChest(
NewWallet _wallet, String _name, BuildContext context) async {
int chestNumber = chestBox.length;
WalletData myWallet = WalletData(
chest: chestNumber,
number: 0,
name: _name,
derivation: 3,
imageName: '0.png');
int chestNumber = 0;
chestBox.toMap().forEach((key, value) {
if (!value.isCesium) {
chestNumber++;
}
});
String chestName;
if (chestNumber == 0) {
@ -55,7 +54,6 @@ class GenerateWalletsProvider with ChangeNotifier {
} else {
chestName = 'Coffre à Ğecko ${chestNumber + 1}';
}
walletBox.add(myWallet);
ChestData thisChest = ChestData(
dewif: _wallet.dewif,
name: chestName,
@ -63,8 +61,19 @@ class GenerateWalletsProvider with ChangeNotifier {
imageName: '${chestNumber % 8}.png',
isCesium: false,
);
chestBox.add(thisChest);
configBox.put('currentChest', chestNumber);
await chestBox.add(thisChest);
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) {
@ -240,16 +249,31 @@ class GenerateWalletsProvider with ChangeNotifier {
isCesiumIDVisible = 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(
dewif: actualWallet.dewif,
name: 'Coffre à Cesium',
name: chestName,
imageName: 'cesium.png',
defaultWallet: 0,
isCesium: true);
int chestNumber = chestBox.length;
chestBox.add(cesiumChest);
configBox.put('currentChest', chestNumber);
await chestBox.add(cesiumChest).then((value) => null);
int chestKey = await chestBox.toMap().keys.last;
// chestBox.toMap().
await configBox.put('currentChest', chestKey);
notifyListeners();
}

View File

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

View File

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

View File

@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:image_picker/image_picker.dart';
@ -24,7 +25,6 @@ class WalletOptionsProvider with ChangeNotifier {
bool isBalanceBlur = true;
FocusNode walletNameFocus = FocusNode();
TextEditingController nameController = TextEditingController();
List<int> walletID;
bool isDefaultWallet;
Future<NewWallet> get badWallet => null;
@ -125,63 +125,28 @@ class WalletOptionsProvider with ChangeNotifier {
return _pinLenght;
}
void _renameWallet(List<int> _walletID, _newName) async {
MyWalletsProvider myWalletClass = MyWalletsProvider();
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();
WalletData _walletTarget = myWalletClass.getWalletData(_walletID);
_walletTarget.name = _newName;
await walletBox.put(_walletTarget.key, _walletTarget);
WalletData _walletTarget = myWalletClass.getWalletData(_walletID);
_walletTarget.name = _newName;
await walletBox.put(_walletTarget.key, _walletTarget);
}
_newWalletName.text = '';
}
Future<bool> renameWalletAlerte(
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 editWalletName(List<int> _wID, {bool isCesium}) {
bool nameState;
if (isEditing) {
if (!nameController.text.contains(':') &&
nameController.text.length <= 39) {
_renameWallet(_wID, nameController.text);
_renameWallet(_wID, nameController.text, isCesium: isCesium);
nameState = true;
} else {
nameState = false;
@ -281,10 +246,11 @@ class WalletOptionsProvider with ChangeNotifier {
File _image;
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
XFile pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
_image = File(pickedFile.path);
log.i(pickedFile.path);
return _image;
} else {
log.w('No image selected.');

View File

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

View File

@ -1,399 +1,310 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/my_wallets.dart';
import 'package:gecko/models/queries.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/wallet_options.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
// ignore: must_be_immutable
class CesiumWalletOptions extends StatelessWidget {
CesiumWalletOptions({Key keyMyWallets, @required this.cesiumWallet})
: super(key: keyMyWallets);
WalletData cesiumWallet;
int _nbrLinesName = 1;
bool _isNewNameValid = false;
int _nbrLinesName = 1;
bool _isNewNameValid = false;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
Widget cesiumWalletOptions(BuildContext context, ChestData cesiumWallet) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
ChestProvider _chestProvider = Provider.of<ChestProvider>(context);
HistoryProvider _historyProvider = Provider.of<HistoryProvider>(context);
final int _currentChest = _myWalletProvider.getCurrentChest();
final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
final String shortPubkey =
_walletOptions.getShortPubkey(_walletOptions.pubkey.text);
if (_walletOptions.nameController.text == null ||
_isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name;
} else {
cesiumWallet.name = _walletOptions.nameController.text;
}
if (_walletOptions.nameController.text == null || _isNewNameValid == false) {
_walletOptions.nameController.text = cesiumWallet.name;
} else {
cesiumWallet.name = _walletOptions.nameController.text;
}
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall) {
_nbrLinesName = 3;
}
_walletOptions.nameController.text.length >= 15
? _nbrLinesName = 2
: _nbrLinesName = 1;
if (_walletOptions.nameController.text.length >= 26 && isTall) {
_nbrLinesName = 3;
}
_walletOptions.walletID = [0, cesiumWallet.number];
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,
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),
return Scaffold(
resizeToAvoidBottomInset: false,
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Container(
height: isTall ? 30 : 15,
color: yellowC,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
body: Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
Container(
height: isTall ? 15 : 0,
color: yellowC,
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: cesiumWallet.imageFile == null
? Image.asset(
'assets/chests/${cesiumWallet.imageName}',
width: 110,
)
: Image.file(cesiumWallet.imageFile, width: 110),
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
yellowC,
const Color(0xfffafafa),
],
)),
child: Row(children: <Widget>[
const SizedBox(width: 25),
InkWell(
onTap: () async {
File newAvatar = await _walletOptions.changeAvatar();
if (newAvatar != null) {
cesiumWallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
),
const SizedBox(height: 100)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const 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),
// );
},
),
const SizedBox(height: 5),
InkWell(
onTap: () async {
await _walletOptions.changeAvatar();
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
'assets/avatars/${cesiumWallet.imageName}',
width: 110,
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
)),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
await _walletOptions.changeAvatar();
_isNewNameValid = _walletOptions.editWalletName(
[cesiumWallet.key, 0],
isCesium: cesiumWallet.isCesium);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: Column(children: <Widget>[
Image.asset(
'assets/walletOptions/camera.png',
),
const SizedBox(height: 100)
])),
Column(children: <Widget>[
Row(children: <Widget>[
Column(children: <Widget>[
SizedBox(
width: 260,
child: TextField(
key: const Key('walletName'),
autofocus: false,
focusNode: _walletOptions.walletNameFocus,
enabled: _walletOptions.isEditing,
controller: _walletOptions.nameController,
maxLines: _nbrLinesName,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? 27 : 23,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Monospace')),
),
SizedBox(height: isTall ? 5 : 0),
Query(
options: QueryOptions(
document: gql(getBalance),
variables: {
'pubkey': _walletOptions.pubkey.text,
},
// pollInterval: Duration(seconds: 1),
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const 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)
: const Text('-', style: TextStyle(fontSize: 20));
}),
SizedBox(height: 15 * ratio),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
),
const SizedBox(width: 10),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const 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),
// );
},
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
const SizedBox(height: 5),
InkWell(
key: const Key('displayBalance'),
onTap: () {
_walletOptions.bluringBalance();
},
child: Image.asset(
_walletOptions.isBalanceBlur
? 'assets/walletOptions/icon_oeuil.png'
: 'assets/walletOptions/icon_oeuil_close.png',
)),
]),
const SizedBox(width: 0),
Column(children: <Widget>[
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = _walletOptions
.editWalletName(_walletOptions.walletID);
await Future.delayed(
const Duration(milliseconds: 30));
_walletOptions.walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
_walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 20,
height: 20),
)),
const 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)
: const Text('-', style: TextStyle(fontSize: 20));
}),
SizedBox(height: 15 * ratio),
GestureDetector(
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(
ClipboardData(text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/key.png',
),
const SizedBox(width: 10),
Text("${shortPubkey.split(':')[0]}:",
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace',
color: Colors.black)),
Text(shortPubkey.split(':')[1],
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
fontFamily: 'Monospace')),
const SizedBox(width: 15),
SizedBox(
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 1,
primary: orangeC, // 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',
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15,
color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.isPubkey(ctx, _walletOptions.pubkey.text,
goHistory: true);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
),
const SizedBox(width: 12),
const Text('Historique des transactions',
style:
TextStyle(fontSize: 20, color: Colors.black)),
]))),
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(
key: const Key('deleteWallet'),
onTap: !_walletOptions.isDefaultWallet
? () async {
await _walletOptions.deleteWallet(
context, cesiumWallet);
WidgetsBinding.instance.addPostFrameCallback((_) {
_myWalletProvider.listWallets =
_myWalletProvider
.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
});
}
: null,
child: Row(children: <Widget>[
const SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
),
const SizedBox(width: 14),
const Text('Supprimer ce portefeuille',
style: TextStyle(
fontSize: 20, color: Color(0xffD80000))),
])),
]),
),
),
));
}
onPressed: () {
Clipboard.setData(ClipboardData(
text: _walletOptions.pubkey.text));
_walletOptions.snackCopyKey(ctx);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
),
const SizedBox(width: 7),
Text('Copier',
style: TextStyle(
fontSize: 15, color: Colors.grey[50]))
]))),
]))),
SizedBox(height: 10 * ratio),
InkWell(
key: const Key('displayHistory'),
onTap: () {
_historyProvider.isPubkey(ctx, _walletOptions.pubkey.text,
goHistory: true);
},
child: SizedBox(
height: 50,
child: Row(children: <Widget>[
const SizedBox(width: 30),
Image.asset(
'assets/walletOptions/clock.png',
),
const SizedBox(width: 12),
const Text('Historique des transactions',
style: TextStyle(fontSize: 20, color: Colors.black)),
]))),
SizedBox(height: 12 * ratio),
InkWell(
key: const Key('deleteWallet'),
onTap: () async {
await _chestProvider.deleteChest(context, cesiumWallet);
},
child: Row(children: <Widget>[
const SizedBox(width: 33),
Image.asset(
'assets/walletOptions/trash.png',
),
const SizedBox(width: 14),
const Text('Supprimer ce coffre',
style: TextStyle(fontSize: 20, color: Color(0xffD80000))),
])),
]),
),
),
);
}

View File

@ -45,7 +45,7 @@ class _ChooseChestState extends State<ChooseChest> {
options: CarouselOptions(
height: 210,
onPageChanged: (index, reason) {
currentChest = index;
currentChest = chestBox.toMap().keys.toList()[index];
setState(() {});
},
enableInfiniteScroll: false,
@ -57,10 +57,15 @@ class _ChooseChestState extends State<ChooseChest> {
return Builder(
builder: (BuildContext context) {
return Column(children: <Widget>[
Image.asset(
'assets/chests/${i.value.imageName}',
height: 150,
),
i.value.imageFile == null
? Image.asset(
'assets/chests/${i.value.imageName}',
height: 150,
)
: Image.file(
i.value.imageFile,
height: 150,
),
const SizedBox(height: 30),
Text(
i.value.name,
@ -71,28 +76,30 @@ class _ChooseChestState extends State<ChooseChest> {
);
}).toList(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: chestBox.toMap().entries.map((entry) {
return GestureDetector(
onTap: () =>
buttonCarouselController.animateToPage(entry.key),
child: Container(
width: 12.0,
height: 12.0,
margin: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: (Theme.of(context).brightness == Brightness.dark
? Colors.white
: Colors.black)
.withOpacity(
currentChest == entry.key ? 0.9 : 0.4)),
),
);
}).toList(),
),
if (chestBox.values.toList().length > 1)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: chestBox.toMap().entries.map((entry) {
return GestureDetector(
onTap: () =>
buttonCarouselController.animateToPage(entry.key),
child: Container(
width: 12.0,
height: 12.0,
margin: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 4.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
(Theme.of(context).brightness == Brightness.dark
? Colors.white
: Colors.black)
.withOpacity(
currentChest == entry.key ? 0.9 : 0.4)),
),
);
}).toList(),
),
SizedBox(height: 80 * ratio),
SizedBox(
width: 400,

View File

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

View File

@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -46,13 +47,10 @@ class WalletOptions extends StatelessWidget {
_nbrLinesName = 3;
}
_walletOptions.walletID = [0, wallet.number];
WalletData defaultWallet =
_myWalletProvider.getDefaultWallet(_currentChest);
_walletOptions.isDefaultWallet =
(defaultWallet.number == _walletOptions.walletID[1]);
_walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
int currentChest = _myWalletProvider.getCurrentChest();
@ -107,15 +105,30 @@ class WalletOptions extends StatelessWidget {
const SizedBox(width: 25),
InkWell(
onTap: () async {
await _walletOptions.changeAvatar();
File newAvatar =
await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Image.asset(
'assets/avatars/${wallet.imageName}',
width: 110,
)),
child: wallet.imageFile == null
? Image.asset(
'assets/avatars/${wallet.imageName}',
width: 110,
)
: Image.file(
wallet.imageFile,
width: 110,
)),
InkWell(
onTap: () async {
await _walletOptions.changeAvatar();
File newAvatar =
await _walletOptions.changeAvatar();
if (newAvatar != null) {
wallet.imageFile = newAvatar;
}
_walletOptions.reloadBuild();
},
child: Column(children: <Widget>[
Image.asset(
@ -227,8 +240,9 @@ class WalletOptions extends StatelessWidget {
InkWell(
key: const Key('renameWallet'),
onTap: () async {
_isNewNameValid = _walletOptions
.editWalletName(_walletOptions.walletID);
_isNewNameValid =
_walletOptions.editWalletName(wallet.id(),
isCesium: false);
await Future.delayed(
const Duration(milliseconds: 30));
_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:flutter/material.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/wallet_options.dart';
import 'package:gecko/screens/onBoarding/0_no_keychain_found.dart';
@ -62,18 +63,18 @@ class WalletsHome extends StatelessWidget {
child: !isWalletsExists
? const NoKeyChainScreen()
: _currentChest.isCesium
? cesiumWalletOptions(context)
? cesiumWalletOptions(context, _currentChest)
: myWalletsTiles(context),
),
),
);
}
Widget cesiumWalletOptions(BuildContext context) {
return Column(children: const [
Center(child: Text('This is a Cesium wallet')),
]);
}
// Widget cesiumWalletOptions(BuildContext context) {
// return Column(children: const [
// Center(child: Text('This is a Cesium wallet')),
// ]);
// }
Widget chestOptions(BuildContext context) {
return Column(children: [
@ -214,11 +215,17 @@ class WalletsHome extends StatelessWidget {
child:
// SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48),
Image.asset(
'assets/avatars/${_repository.imageName}',
alignment: Alignment.bottomCenter,
scale: 0.5,
),
_repository.imageFile == null
? Image.asset(
'assets/avatars/${_repository.imageName}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
: Image.file(
_repository.imageFile,
alignment: Alignment.bottomCenter,
scale: 0.5,
),
)),
// balanceBuilder(context, _walletOptions.pubkey.text),
ListTile(

View File

@ -176,6 +176,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
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:
dependency: transitive
description:

View File

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

View File

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