WIP: refactor payment UX workflow

This commit is contained in:
poka 2022-05-25 20:40:55 +02:00
parent e9291d9277
commit 0009fc4009
7 changed files with 267 additions and 125 deletions

View File

@ -24,6 +24,7 @@ class MyWalletsProvider with ChangeNotifier {
// configBox.delete('endpoint'); // configBox.delete('endpoint');
if (!configBox.containsKey('endpoint') || configBox.get('endpoint') == '') { if (!configBox.containsKey('endpoint') || configBox.get('endpoint') == '') {
log.d('No endpoint, configure...'); log.d('No endpoint, configure...');
// configBox.put('endpoint', 'wss://gdev.librelois.fr/ws');
configBox.put('endpoint', 'ws://127.0.0.1:9944'); configBox.put('endpoint', 'ws://127.0.0.1:9944');
} }

View File

@ -26,6 +26,7 @@ class SubstrateSdk with ChangeNotifier {
bool importIsLoading = false; bool importIsLoading = false;
int blocNumber = 0; int blocNumber = 0;
bool isLoadingEndpoint = false; bool isLoadingEndpoint = false;
String debugConnection = '';
TextEditingController jsonKeystore = TextEditingController(); TextEditingController jsonKeystore = TextEditingController();
TextEditingController keystorePassword = TextEditingController(); TextEditingController keystorePassword = TextEditingController();
@ -48,7 +49,7 @@ class SubstrateSdk with ChangeNotifier {
n.endpoint = configBox.get('endpoint'); n.endpoint = configBox.get('endpoint');
n.ss58 = ss58; n.ss58 = ss58;
node.add(n); node.add(n);
int timeout = 7000; int timeout = 10000;
// if (n.endpoint!.startsWith('ws://')) { // if (n.endpoint!.startsWith('ws://')) {
// timeout = 5000; // timeout = 5000;
@ -85,20 +86,19 @@ class SubstrateSdk with ChangeNotifier {
notifyListeners(); notifyListeners();
if (res != null) { if (res != null) {
nodeConnected = true; nodeConnected = true;
notifyListeners();
snackNode(ctx, true);
} else {
nodeConnected = false;
notifyListeners();
snackNode(ctx, false);
}
// Subscribe bloc number // Subscribe bloc number
if (nodeConnected) {
sdk.api.setting.subscribeBestNumber((res) { sdk.api.setting.subscribeBestNumber((res) {
blocNumber = int.parse(res.toString()); blocNumber = int.parse(res.toString());
notifyListeners(); notifyListeners();
}); });
notifyListeners();
snackNode(ctx, true);
} else {
nodeConnected = false;
debugConnection = res.toString();
notifyListeners();
snackNode(ctx, false);
} }
log.d(sdk.api.connectedNode?.endpoint); log.d(sdk.api.connectedNode?.endpoint);
@ -371,12 +371,12 @@ class SubstrateSdk with ChangeNotifier {
); );
try { try {
final tata = await sdk.api.tx.signAndSend( final result = await sdk.api.tx.signAndSend(
txInfo, txInfo,
[name], [name],
password, password,
); );
log.d(tata); log.d(result);
return 'confirmed'; return 'confirmed';
} on Exception catch (e) { } on Exception catch (e) {
log.e(e); log.e(e);

View File

@ -265,6 +265,10 @@ class WalletsProfilesProvider with ChangeNotifier {
return balance; return balance;
} }
void reload() {
notifyListeners();
}
} }
snackCopyKey(context) { snackCopyKey(context) {

View File

@ -3,9 +3,10 @@ import 'package:gecko/globals.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/generate_wallets.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:carousel_slider/carousel_slider.dart'; import 'package:carousel_slider/carousel_slider.dart';
import 'package:gecko/screens/onBoarding/5.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChooseChest extends StatefulWidget { class ChooseChest extends StatefulWidget {
@ -136,28 +137,54 @@ class _ChooseChestState extends State<ChooseChest> {
), ),
), ),
), ),
const SizedBox(height: 20), // const SizedBox(height: 20),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: InkWell(
key: const Key('createNewChest'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const OnboardingStepFive(skipIntro: true);
}),
);
},
child: SizedBox(
width: 400,
height: 50,
child: Center(
child: Text('Créer un nouveau coffre',
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600))),
),
),
),
),
InkWell( InkWell(
key: const Key('createNewChest'), key: const Key('importChest'),
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return GenerateFastChestScreen(); return const RestoreChest(skipIntro: true);
}), }),
); );
}, },
child: SizedBox( child: SizedBox(
width: 400, width: 400,
height: 70, height: 50,
child: Center( child: Center(
child: Text('Créer un nouveau coffre', child: Text('Importer un coffre',
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
color: orangeC, color: orangeC,
fontWeight: FontWeight.w600))), fontWeight: FontWeight.w600))),
)), )),
const SizedBox(height: 10), const SizedBox(height: 20),
]), ]),
)); ));
} }

View File

@ -22,9 +22,7 @@ class ChooseWalletScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context); // HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -50,19 +48,22 @@ class ChooseWalletScreen extends StatelessWidget {
onPrimary: Colors.white, // foreground onPrimary: Colors.white, // foreground
), ),
onPressed: () async { onPressed: () async {
final acc = _sub.getCurrentWallet(); Navigator.pop(context);
log.d( Navigator.pop(context);
"fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.outputPubkey.text}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $pin"); // Payment workflow !
final resultPay = await _sub.pay(context, // final acc = _sub.getCurrentWallet();
fromAddress: acc.address!, // log.d(
destAddress: _walletViewProvider.outputPubkey.text, // "fromAddress: ${acc.address!},destAddress: ${_walletViewProvider.outputPubkey.text}, amount: ${double.parse(_walletViewProvider.payAmount.text)}, password: $pin");
amount: // final resultPay = await _sub.pay(context,
double.parse(_walletViewProvider.payAmount.text), // fromAddress: acc.address!,
password: pin.toUpperCase()); // destAddress: _walletViewProvider.outputPubkey.text,
await paymentsResult(context, resultPay); // amount:
// double.parse(_walletViewProvider.payAmount.text),
// password: pin.toUpperCase());
// await paymentsResult(context, resultPay);
}, },
child: const Text( child: const Text(
'Valider le paiement', 'Choisir ce portefeuille',
style: style:
TextStyle(fontSize: 24, fontWeight: FontWeight.w600), TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
), ),
@ -80,6 +81,8 @@ class ChooseWalletScreen extends StatelessWidget {
Provider.of<MyWalletsProvider>(context); Provider.of<MyWalletsProvider>(context);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false); SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(currentChest); _myWalletProvider.getDefaultWallet(currentChest);
@ -129,8 +132,12 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
chestBox.get(currentChest)!.defaultWallet =
_repository.number;
_sub.setCurrentWallet(_repository.address!); _sub.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); _myWalletProvider.rebuildWidget();
_walletViewProvider.reload();
}, },
child: ClipOvalShadow( child: ClipOvalShadow(
shadow: const Shadow( shadow: const Shadow(
@ -196,8 +203,11 @@ class ChooseWalletScreen extends StatelessWidget {
onTap: () { onTap: () {
_derivation = _repository.derivation!; _derivation = _repository.derivation!;
_selectedId = _repository.id(); _selectedId = _repository.id();
chestBox.get(currentChest)!.defaultWallet =
_repository.number;
_sub.setCurrentWallet(_repository.address!); _sub.setCurrentWallet(_repository.address!);
_myWalletProvider.rebuildWidget(); // _myWalletProvider.rebuildWidget();
_sub.reload();
}, },
) )
]), ]),

View File

@ -212,21 +212,33 @@ class UnlockingWallet extends StatelessWidget {
pinFocus.requestFocus(); pinFocus.requestFocus();
} else { } else {
pinColor = Colors.green[400]; pinColor = Colors.green[400];
if (action == "mywallets") { switch (action) {
Navigator.push( case "mywallets":
context, Navigator.push(
MaterialPageRoute(builder: (context) { context,
return const WalletsHome(); MaterialPageRoute(builder: (context) {
}), return const WalletsHome();
); }),
} else if (action == "pay") { );
Navigator.push( break;
context, case "changeWallet":
MaterialPageRoute(builder: (context) { Navigator.push(
return ChooseWalletScreen( context,
chest: currentChestNumber, pin: _pin.toUpperCase()); MaterialPageRoute(builder: (context) {
}), return ChooseWalletScreen(
); chest: currentChestNumber, pin: _pin.toUpperCase());
}),
);
break;
case "pay":
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ChooseWalletScreen(
chest: currentChestNumber, pin: _pin.toUpperCase());
}),
);
break;
} }
} }
}, },

View File

@ -2,6 +2,7 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
@ -23,11 +24,11 @@ class WalletViewScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider _historyProvider = WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false); Provider.of<WalletsProfilesProvider>(context, listen: false);
CesiumPlusProvider _cesiumPlusProvider = CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false); Provider.of<CesiumPlusProvider>(context, listen: false);
_historyProvider.pubkey = pubkey!; _walletViewProvider.pubkey = pubkey!;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
@ -41,7 +42,8 @@ class WalletViewScreen extends StatelessWidget {
), ),
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
headerProfileView(context, _historyProvider, _cesiumPlusProvider), headerProfileView(
context, _walletViewProvider, _cesiumPlusProvider),
SizedBox(height: isTall ? 120 : 70), SizedBox(height: isTall ? 120 : 70),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
Column(children: <Widget>[ Column(children: <Widget>[
@ -163,7 +165,7 @@ class WalletViewScreen extends StatelessWidget {
image: AssetImage('assets/vector_white.png'), image: AssetImage('assets/vector_white.png'),
)), )),
onTap: () { onTap: () {
paymentPopup(context, _historyProvider); paymentPopup(context, _walletViewProvider);
}), }),
), ),
), ),
@ -182,11 +184,14 @@ class WalletViewScreen extends StatelessWidget {
void paymentPopup( void paymentPopup(
BuildContext context, WalletsProfilesProvider _walletViewProvider) { BuildContext context, WalletsProfilesProvider _walletViewProvider) {
// WalletsProfilesProvider _walletViewProvider = WalletsProfilesProvider _walletViewProvider =
// Provider.of<WalletsProfilesProvider>(context); Provider.of<WalletsProfilesProvider>(context, listen: false);
const double shapeSize = 20;
MyWalletsProvider _myWalletProvider = MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
const double shapeSize = 20;
WalletData? defaultWallet = WalletData? defaultWallet =
_myWalletProvider.getDefaultWallet(configBox.get('currentChest')); _myWalletProvider.getDefaultWallet(configBox.get('currentChest'));
_walletViewProvider.outputPubkey.text = pubkey!; _walletViewProvider.outputPubkey.text = pubkey!;
@ -218,7 +223,8 @@ class WalletViewScreen extends StatelessWidget {
), ),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.only(
top: 24, bottom: 0, left: 24, right: 24),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -230,86 +236,168 @@ class WalletViewScreen extends StatelessWidget {
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Text( Text(
'Saisissez dans le champ ci-dessous le montant à virer.', 'Depuis:',
style: TextStyle( style: TextStyle(
fontSize: 19, fontSize: 19,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.grey[600]), color: Colors.grey[600]),
), ),
const Spacer(), const SizedBox(height: 10),
Center( Consumer<SubstrateSdk>(builder: (context, _sub, _) {
child: Column(children: <Widget>[ return InkWell(
TextField( onTap: () {
controller: _walletViewProvider.payAmount, Navigator.push(
autofocus: true, context,
maxLines: 1, MaterialPageRoute(
textAlign: TextAlign.center, builder: (context) {
keyboardType: TextInputType.number, return UnlockingWallet(
onChanged: (_) => setState(() {}), wallet: defaultWallet, action: "pay");
inputFormatters: <TextInputFormatter>[ },
FilteringTextInputFormatter.allow( ),
RegExp(r'^\d+\.?\d{0,2}')), );
], },
// onChanged: (v) => _searchProvider.rebuildWidget(), child: Container(
decoration: InputDecoration( width: double.infinity,
hintText: '0.00', // height: 25,
suffix: Text(currencyName), decoration: BoxDecoration(
filled: true,
fillColor: Colors.transparent,
// border: OutlineInputBorder( // border: OutlineInputBorder(
// borderSide: // borderSide:
// BorderSide(color: Colors.grey[500], width: 2), // BorderSide(color: Colors.grey[500], width: 2),
// borderRadius: BorderRadius.circular(8)), // borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder( border: Border.all(
borderSide: BorderSide( color:
color: Colors.grey[500]!, width: 2), Colors.grey[500]!, // Set border color
borderRadius: BorderRadius.circular(8), width: 2), // Set border width
), borderRadius: const BorderRadius.all(
contentPadding: const EdgeInsets.all(20), Radius.circular(10.0)), // Set ro
),
style: const TextStyle(
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w600,
), ),
padding: const EdgeInsets.all(10),
child: Row(children: [
Text(defaultWallet!.name!),
const Spacer(),
FutureBuilder(
future:
_sub.getBalance(defaultWallet.address!),
builder: (BuildContext context,
AsyncSnapshot<num?> _balance) {
if (_balance.connectionState !=
ConnectionState.done ||
_balance.hasError) {
if (balanceCache[
defaultWallet.address!] !=
null) {
return Text(
balanceCache[
defaultWallet.address!]!,
style: const TextStyle(
fontSize: 20,
));
} else {
return SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
color: orangeC,
strokeWidth: 2,
),
);
}
}
balanceCache[defaultWallet.address!] =
"${_balance.data.toString()} $currencyName";
return Text(
balanceCache[defaultWallet.address!]!,
style: const TextStyle(
fontSize: 20,
),
);
}),
]),
), ),
const SizedBox(height: 40), );
// const Spacer(), }),
SizedBox( const Spacer(),
width: double.infinity,
height: 60, // const SizedBox(height: 10),
child: ElevatedButton( Text(
style: ElevatedButton.styleFrom( 'Montant:',
elevation: 4, style: TextStyle(
primary: orangeC, // background fontSize: 19,
onPrimary: Colors.white, // foreground fontWeight: FontWeight.w500,
), color: Colors.grey[600]),
onPressed:
_walletViewProvider.payAmount.text != ''
? () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "pay");
},
),
);
}
: null,
child: const Text(
'Effectuer le virement',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 20),
]),
), ),
const SizedBox(height: 10),
TextField(
controller: _walletViewProvider.payAmount,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
onChanged: (_) => setState(() {
// _walletViewProvider.reload();
}),
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(
RegExp(r'^\d+\.?\d{0,2}')),
],
// onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
hintText: '0.00',
suffix: Text(currencyName),
filled: true,
fillColor: Colors.transparent,
// border: OutlineInputBorder(
// borderSide:
// BorderSide(color: Colors.grey[500], width: 2),
// borderRadius: BorderRadius.circular(8)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey[500]!, width: 2),
borderRadius: BorderRadius.circular(8),
),
contentPadding: const EdgeInsets.all(20),
),
style: const TextStyle(
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
// const SizedBox(height: 40),
const Spacer(),
SizedBox(
width: double.infinity,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: _walletViewProvider.payAmount.text != ''
? () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UnlockingWallet(
wallet: defaultWallet,
action: "pay");
},
),
);
}
: null,
child: const Text(
'Effectuer le virement',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.w600),
),
),
),
const Spacer(),
]), ]),
), ),
), ),