Merge branch 'dev'
This commit is contained in:
commit
6b42aab079
|
@ -26,6 +26,6 @@ subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
|
@ -23,7 +23,7 @@
|
||||||
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:",
|
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:",
|
||||||
"rememberPassword": "Keep this code in memory for 15 minutes",
|
"rememberPassword": "Keep this code in memory for 15 minutes",
|
||||||
"myRootWallet": "My root wallet",
|
"myRootWallet": "My root wallet",
|
||||||
"currentWallet": "My current chest",
|
"currentWallet": "My current wallet",
|
||||||
"wallet": "Wallet",
|
"wallet": "Wallet",
|
||||||
"displayMnemonic": "Display my mnemonic sentence",
|
"displayMnemonic": "Display my mnemonic sentence",
|
||||||
"changePassword": "Change my password",
|
"changePassword": "Change my password",
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
||||||
"received": "Received",
|
"received": "Received",
|
||||||
"sent": "Sent",
|
"sent": "Sent",
|
||||||
"createIdentity": "Create a new \nidentity",
|
"createIdentity": "Create a new\nidentity",
|
||||||
"memberAccountOf": "Account of {}",
|
"memberAccountOf": "Account of {}",
|
||||||
"pasteAddress": "Paste address from\nclipboard",
|
"pasteAddress": "Paste address from\nclipboard",
|
||||||
"historyStart": "Beginning of history",
|
"historyStart": "Beginning of history",
|
||||||
|
@ -217,5 +217,13 @@
|
||||||
"youHaveToBeConnectedToValidateChest": "You have to be connected\nto validate your chest",
|
"youHaveToBeConnectedToValidateChest": "You have to be connected\nto validate your chest",
|
||||||
"thisIdentityAlreadyExist": "This identity already exists",
|
"thisIdentityAlreadyExist": "This identity already exists",
|
||||||
"removedFromcontacts": "Removed from contacts",
|
"removedFromcontacts": "Removed from contacts",
|
||||||
"addedToContacts": "Added to contacts"
|
"addedToContacts": "Added to contacts",
|
||||||
|
"certificationsOf": "Certifications of {}",
|
||||||
|
"explainDraggableWallet": "Drag and drop a tile onto another to make a transaction, by holding down the tile.",
|
||||||
|
"skip": "Skip",
|
||||||
|
"fees": "fees: {} {}",
|
||||||
|
"feesExplanation": "To ensure network security, an execution fee is charged on each transaction.",
|
||||||
|
"feesExplanationDetails": "These fees are transferred to the common treasury account.",
|
||||||
|
"gotit": "Got it",
|
||||||
|
"moreInfo": "More information"
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
"toUnlockEnterPassword": "Para desbloquear tu cofre, introduce tu contraseña, lejos de lagartijas curiosas:",
|
"toUnlockEnterPassword": "Para desbloquear tu cofre, introduce tu contraseña, lejos de lagartijas curiosas:",
|
||||||
"rememberPassword": "Mantener en memoria mi contraseña durante 15 minutos",
|
"rememberPassword": "Mantener en memoria mi contraseña durante 15 minutos",
|
||||||
"myRootWallet": "Mi monedero principal",
|
"myRootWallet": "Mi monedero principal",
|
||||||
"currentWallet": "Mi cofre actual",
|
"currentWallet": "Mi monedero actual",
|
||||||
"wallet": "monedero",
|
"wallet": "monedero",
|
||||||
"displayMnemonic": "Mostrar mi frase de restauración",
|
"displayMnemonic": "Mostrar mi frase de restauración",
|
||||||
"changePassword": "Cambiar mi contraseña",
|
"changePassword": "Cambiar mi contraseña",
|
||||||
|
@ -203,7 +203,7 @@
|
||||||
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
||||||
"received": "Received",
|
"received": "Received",
|
||||||
"sent": "Sent",
|
"sent": "Sent",
|
||||||
"createIdentity": "Create a new \nidentity",
|
"createIdentity": "Create a new\nidentity",
|
||||||
"memberAccountOf": "Account of {}",
|
"memberAccountOf": "Account of {}",
|
||||||
"pasteAddress": "Paste address from\nclipboard",
|
"pasteAddress": "Paste address from\nclipboard",
|
||||||
"historyStart": "Beginning of history",
|
"historyStart": "Beginning of history",
|
||||||
|
@ -218,5 +218,13 @@
|
||||||
"youHaveToBeConnectedToValidateChest": "Tienes que tener conneción\npara validar tu cofre",
|
"youHaveToBeConnectedToValidateChest": "Tienes que tener conneción\npara validar tu cofre",
|
||||||
"thisIdentityAlreadyExist": "Esta identidad ya existe",
|
"thisIdentityAlreadyExist": "Esta identidad ya existe",
|
||||||
"removedFromcontacts": "Removed from contacts",
|
"removedFromcontacts": "Removed from contacts",
|
||||||
"addedToContacts": "Added to contacts"
|
"addedToContacts": "Added to contacts",
|
||||||
|
"certificationsOf": "Certifications of {}",
|
||||||
|
"explainDraggableWallet": "Drag and drop a tile onto another to make a transaction, by holding down the tile.",
|
||||||
|
"skip": "Skip",
|
||||||
|
"fees": "fees: {} {}",
|
||||||
|
"feesExplanation": "To ensure network security, an execution fee is charged on each transaction.",
|
||||||
|
"feesExplanationDetails": "These fees are transferred to the common treasury account.",
|
||||||
|
"gotit": "Got it",
|
||||||
|
"moreInfo": "More information"
|
||||||
}
|
}
|
|
@ -217,5 +217,13 @@
|
||||||
"youHaveToBeConnectedToValidateChest": "Vous devez vous connecter à internet\npour valider votre coffre",
|
"youHaveToBeConnectedToValidateChest": "Vous devez vous connecter à internet\npour valider votre coffre",
|
||||||
"thisIdentityAlreadyExist": "Cette identité existe déjà",
|
"thisIdentityAlreadyExist": "Cette identité existe déjà",
|
||||||
"removedFromcontacts": "Retiré des contact",
|
"removedFromcontacts": "Retiré des contact",
|
||||||
"addedToContacts": "Ajouté au contacts"
|
"addedToContacts": "Ajouté au contacts",
|
||||||
|
"certificationsOf": "Certifications de {}",
|
||||||
|
"explainDraggableWallet": "Faites glisser et déposez une tuile sur une autre pour effectuer une transaction, avec un appui long.",
|
||||||
|
"skip": "Passer",
|
||||||
|
"fees": "frais: {} {}",
|
||||||
|
"feesExplanation": "Pour garantir la sécurité du réseau, des frais d'exécution sont prélevés sur chaque transaction.",
|
||||||
|
"feesExplanationDetails": "Ces frais sont transférés vers le compte de trésorerie commune.",
|
||||||
|
"gotit": "J'ai compris",
|
||||||
|
"moreInfo": "Plus d'info"
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ version: "3.5"
|
||||||
services:
|
services:
|
||||||
duniter-v2s-gecko-tests:
|
duniter-v2s-gecko-tests:
|
||||||
container_name: duniter-v2s-gecko-tests
|
container_name: duniter-v2s-gecko-tests
|
||||||
image: duniter/duniter-v2s:debug-latest
|
image: duniter/duniter-v2s:debug-sha-4d5e08be
|
||||||
command: --sealing=manual
|
command: --sealing=manual
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:9615:9615"
|
- "127.0.0.1:9615:9615"
|
||||||
|
|
|
@ -25,7 +25,7 @@ void main() async {
|
||||||
await tapKey(keyConfirmSearch);
|
await tapKey(keyConfirmSearch);
|
||||||
await waitFor(test5.shortAddress());
|
await waitFor(test5.shortAddress());
|
||||||
await tapKey(keySearchResult(test5.address));
|
await tapKey(keySearchResult(test5.address));
|
||||||
await waitFor('certify'.tr());
|
await waitFor('createIdentity'.tr());
|
||||||
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 6), reverse: true);
|
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 6), reverse: true);
|
||||||
await waitFor('canRenewCertInX'.tr().substring(0, 8), reverse: true);
|
await waitFor('canRenewCertInX'.tr().substring(0, 8), reverse: true);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -10,6 +11,7 @@ void main() async {
|
||||||
// await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Gecko complete', (testerLoc) async {
|
testWidgets('Gecko complete', (testerLoc) async {
|
||||||
|
FlutterError.onError = ignoreOverflowErrors;
|
||||||
// Share WidgetTester to test provider
|
// Share WidgetTester to test provider
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
|
||||||
|
@ -50,8 +52,10 @@ Future payTest2() async {
|
||||||
await enterText(keyAmountField, '12.14');
|
await enterText(keyAmountField, '12.14');
|
||||||
await tapKey(keyConfirmPayment);
|
await tapKey(keyConfirmPayment);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 500);
|
||||||
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
|
|
||||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
await waitFor('12.14');
|
await waitFor('12.14');
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 500);
|
||||||
|
@ -63,8 +67,10 @@ Future certifyTest5() async {
|
||||||
// Create identity with Test1 account
|
// Create identity with Test1 account
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('identityCreated'.tr());
|
await waitFor('identityCreated'.tr());
|
||||||
|
|
||||||
|
@ -76,8 +82,10 @@ Future certifyTest5() async {
|
||||||
await tapKey(keyConfirmIdentity);
|
await tapKey(keyConfirmIdentity);
|
||||||
await enterText(keyEnterIdentityUsername, test5.name);
|
await enterText(keyEnterIdentityUsername, test5.name);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('identityConfirmed'.tr());
|
await waitFor('identityConfirmed'.tr());
|
||||||
humanRead(2);
|
humanRead(2);
|
||||||
|
@ -102,8 +110,10 @@ Future certifyTest5() async {
|
||||||
// Certify with test2 account
|
// Certify with test2 account
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('2');
|
await waitFor('2');
|
||||||
|
|
||||||
|
@ -117,10 +127,12 @@ Future certifyTest5() async {
|
||||||
// Certify with test3 account
|
// Certify with test3 account
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('mustWaitXBeforeCertify'.substring(0, 12));
|
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 8));
|
||||||
|
|
||||||
// Check if test5 is member
|
// Check if test5 is member
|
||||||
await tapKey(keyAppBarChest, duration: 300);
|
await tapKey(keyAppBarChest, duration: 300);
|
||||||
|
|
|
@ -35,12 +35,15 @@ void main() async {
|
||||||
await waitFor('memberValidated'.tr(), exactMatch: true);
|
await waitFor('memberValidated'.tr(), exactMatch: true);
|
||||||
|
|
||||||
// Revoke test5
|
// Revoke test5
|
||||||
await tapKey(keyManageMembership, duration: 1000);
|
await goBack();
|
||||||
|
await tapKey(keyOpenWallet(test5.address));
|
||||||
|
await tapKey(keyManageMembership, duration: 100);
|
||||||
await tapKey(keyRevokeIdty);
|
await tapKey(keyRevokeIdty);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 2000);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr().substring(3),
|
await tester.pump(const Duration(seconds: 2));
|
||||||
timeout: const Duration(seconds: 4));
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
await waitFor('noIdentity'.tr(), exactMatch: true);
|
await waitFor('noIdentity'.tr(), exactMatch: true);
|
||||||
await sleep();
|
await sleep();
|
||||||
|
@ -48,9 +51,8 @@ void main() async {
|
||||||
// Check test1 cannot be revoked
|
// Check test1 cannot be revoked
|
||||||
await goBack();
|
await goBack();
|
||||||
await tapKey(keyAddDerivation);
|
await tapKey(keyAddDerivation);
|
||||||
await tapKey(keyOpenWallet(test1.address), duration: 500);
|
await tapKey(keyOpenWallet(test1.address), duration: 300);
|
||||||
await tapKey(keyManageMembership, duration: 1000);
|
await tapKey(keyManageMembership, duration: 300);
|
||||||
await waitFor('youCannotRevokeThisIdentity'.tr().substring(0, 15));
|
await waitFor('youCannotRevokeThisIdentity'.tr().substring(0, 15));
|
||||||
|
|
||||||
}, timeout: testTimeout());
|
}, timeout: testTimeout());
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,10 @@ void main() async {
|
||||||
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
||||||
await waitForButtonEnabled(keyConfirm);
|
await waitForButtonEnabled(keyConfirm);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 2000);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('extrinsicValidated'.tr());
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
|
|
||||||
await tapKey(keyOpenWallet(test6.address), duration: 300);
|
await tapKey(keyOpenWallet(test6.address), duration: 300);
|
||||||
|
|
|
@ -66,11 +66,15 @@ Future restoreChest() async {
|
||||||
await enterText(keyPinForm, 'AAAAA', 0);
|
await enterText(keyPinForm, 'AAAAA', 0);
|
||||||
|
|
||||||
// Check if string "Accéder à mon coffre" is present in screen
|
// Check if string "Accéder à mon coffre" is present in screen
|
||||||
await waitFor('accessMyChest'.tr());
|
await waitFor('accessMyChest'.tr(), pumpDuration: 30);
|
||||||
|
|
||||||
// Go to wallets home
|
// Go to wallets home
|
||||||
await tapKey(keyGoWalletsHome, duration: 0);
|
await tapKey(keyGoWalletsHome, duration: 0);
|
||||||
|
|
||||||
|
// Skip tutorial
|
||||||
|
await sleep(500);
|
||||||
|
await tapKey(keyDragAndDrop).timeout(const Duration(seconds: 3));
|
||||||
|
|
||||||
// Check if string "ĞD" is present in screen
|
// Check if string "ĞD" is present in screen
|
||||||
await waitFor('ĞD');
|
await waitFor('ĞD');
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ Future goBack() async {
|
||||||
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
||||||
log.d('INTEGRATION TEST: Go back');
|
log.d('INTEGRATION TEST: Go back');
|
||||||
navigator.pop();
|
navigator.pop();
|
||||||
await tester.pump();
|
await tester.pumpAndSettle();
|
||||||
humanRead();
|
humanRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +129,10 @@ Future enterText(Key fieldKey, String textIn, [int duration = 200]) async {
|
||||||
|
|
||||||
Future<void> waitFor(String text,
|
Future<void> waitFor(String text,
|
||||||
{Duration timeout = const Duration(seconds: 5),
|
{Duration timeout = const Duration(seconds: 5),
|
||||||
bool reverse = false,
|
final bool reverse = false,
|
||||||
bool exactMatch = false}) async {
|
final bool exactMatch = false,
|
||||||
|
final bool settle = true,
|
||||||
|
final int pumpDuration = 100}) async {
|
||||||
final end = DateTime.now().add(timeout);
|
final end = DateTime.now().add(timeout);
|
||||||
|
|
||||||
Finder finder = exactMatch ? find.text(text) : find.textContaining(text);
|
Finder finder = exactMatch ? find.text(text) : find.textContaining(text);
|
||||||
|
@ -143,7 +145,9 @@ Future<void> waitFor(String text,
|
||||||
throw Exception('Timed out waiting for $searchType : "$text"');
|
throw Exception('Timed out waiting for $searchType : "$text"');
|
||||||
}
|
}
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
if (settle) {
|
||||||
|
await tester.pumpAndSettle(Duration(milliseconds: pumpDuration));
|
||||||
|
}
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
||||||
humanRead();
|
humanRead();
|
||||||
|
@ -317,6 +321,32 @@ String getWidgetText(Key key) {
|
||||||
return (word4Finder.evaluate().single.widget as Text).data!;
|
return (word4Finder.evaluate().single.widget as Text).data!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ignoreOverflowErrors(
|
||||||
|
FlutterErrorDetails details, {
|
||||||
|
bool forceReport = false,
|
||||||
|
}) {
|
||||||
|
bool ifIsOverflowError = false;
|
||||||
|
bool isUnableToLoadAsset = false;
|
||||||
|
|
||||||
|
// Detect overflow error.
|
||||||
|
var exception = details.exception;
|
||||||
|
if (exception is FlutterError) {
|
||||||
|
ifIsOverflowError = !exception.diagnostics.any(
|
||||||
|
(e) => e.value.toString().startsWith("A RenderFlex overflowed by"),
|
||||||
|
);
|
||||||
|
isUnableToLoadAsset = !exception.diagnostics.any(
|
||||||
|
(e) => e.value.toString().startsWith("Unable to load asset"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore if is overflow error.
|
||||||
|
if (ifIsOverflowError || isUnableToLoadAsset) {
|
||||||
|
debugPrint('Ignored Error');
|
||||||
|
} else {
|
||||||
|
FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TestWallet {
|
class TestWallet {
|
||||||
String address;
|
String address;
|
||||||
String name;
|
String name;
|
||||||
|
|
|
@ -11,6 +11,7 @@ const keyAppBarChest = Key('keyAppBarChest');
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
const keyParameters = Key('keyParameters');
|
const keyParameters = Key('keyParameters');
|
||||||
|
const keyDebugScreen = Key('keyDebugScreen');
|
||||||
const keyContacts = Key('keyContacts');
|
const keyContacts = Key('keyContacts');
|
||||||
const keyDrawerMenu = Key('keyDrawerMenu');
|
const keyDrawerMenu = Key('keyDrawerMenu');
|
||||||
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
||||||
|
@ -23,6 +24,7 @@ const keyImportG1v1 = Key('keyImportG1v1');
|
||||||
const keyChangeChest = Key('keyChangeChest');
|
const keyChangeChest = Key('keyChangeChest');
|
||||||
const keyListWallets = Key('keyListWallets');
|
const keyListWallets = Key('keyListWallets');
|
||||||
const keyAddDerivation = Key('keyAddDerivation');
|
const keyAddDerivation = Key('keyAddDerivation');
|
||||||
|
final keyDragAndDrop = GlobalKey(debugLabel: 'keyDragAndDrop');
|
||||||
|
|
||||||
// Wallet options
|
// Wallet options
|
||||||
const keyCopyAddress = Key('keyCopyAddress');
|
const keyCopyAddress = Key('keyCopyAddress');
|
||||||
|
|
|
@ -253,59 +253,52 @@ Future<QueryResult> _execQuery(
|
||||||
return await client.query(options);
|
return await client.query(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map computeHistoryView(repository) {
|
Map computeHistoryView(repository, String address) {
|
||||||
bool isTody = false;
|
|
||||||
bool isYesterday = false;
|
|
||||||
bool isThisWeek = false;
|
|
||||||
bool isMigrationTime = false;
|
|
||||||
String? dateDelimiter;
|
|
||||||
DateTime now = DateTime.now();
|
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
|
||||||
late double amount;
|
late double amount;
|
||||||
late String finalAmount;
|
late String finalAmount;
|
||||||
DateTime date = repository[0];
|
final DateTime date = repository[0];
|
||||||
String dateForm;
|
|
||||||
bool isDelimiter = true;
|
|
||||||
|
|
||||||
if ({4, 10, 11, 12}.contains(date.month)) {
|
final dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, {
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}";
|
1,
|
||||||
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
2,
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}";
|
7,
|
||||||
} else {
|
9
|
||||||
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
}.contains(date.month) ? 4 : 3)}";
|
||||||
|
|
||||||
|
DateTime normalizeDate(DateTime inputDate) {
|
||||||
|
return DateTime(inputDate.year, inputDate.month, inputDate.day);
|
||||||
}
|
}
|
||||||
|
|
||||||
final transactionDate = DateTime(date.year, date.month, date.day);
|
String getDateDelimiter() {
|
||||||
final todayDate = DateTime(now.year, now.month, now.day);
|
DateTime now = DateTime.now();
|
||||||
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
|
final transactionDate = normalizeDate(date.toLocal());
|
||||||
|
final todayDate = normalizeDate(now);
|
||||||
|
final yesterdayDate = normalizeDate(now.subtract(const Duration(days: 1)));
|
||||||
|
final isSameWeek = weekNumber(transactionDate) == weekNumber(now) &&
|
||||||
|
transactionDate.year == now.year;
|
||||||
|
final isTodayOrYesterday =
|
||||||
|
transactionDate == todayDate || transactionDate == yesterdayDate;
|
||||||
|
|
||||||
if (transactionDate == todayDate && !isTody) {
|
if (transactionDate == todayDate) {
|
||||||
dateDelimiter = "today".tr();
|
return "today".tr();
|
||||||
isTody = true;
|
} else if (transactionDate == yesterdayDate) {
|
||||||
} else if (transactionDate == yesterdayDate && !isYesterday) {
|
return "yesterday".tr();
|
||||||
dateDelimiter = "yesterday".tr();
|
} else if (isSameWeek && !isTodayOrYesterday) {
|
||||||
isYesterday = true;
|
return "thisWeek".tr();
|
||||||
} else if (weekNumber(date) == weekNumber(now) &&
|
} else if (!isSameWeek && !isTodayOrYesterday) {
|
||||||
date.year == now.year &&
|
if (transactionDate.year == now.year) {
|
||||||
transactionDate != yesterdayDate &&
|
return monthsInYear[transactionDate.month]!;
|
||||||
transactionDate != todayDate &&
|
} else {
|
||||||
!isThisWeek) {
|
return "${monthsInYear[transactionDate.month]} ${transactionDate.year}";
|
||||||
dateDelimiter = "thisWeek".tr();
|
}
|
||||||
isThisWeek = true;
|
|
||||||
} else if (dateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
|
|
||||||
transactionDate != todayDate &&
|
|
||||||
transactionDate != yesterdayDate &&
|
|
||||||
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
|
|
||||||
if (date.year == now.year) {
|
|
||||||
dateDelimiter = monthsInYear[date.month];
|
|
||||||
} else {
|
} else {
|
||||||
dateDelimiter = "${monthsInYear[date.month]} ${date.year}";
|
return '';
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
isDelimiter = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final dateDelimiter = getDateDelimiter();
|
||||||
|
|
||||||
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
||||||
|
|
||||||
if (isUdUnit) {
|
if (isUdUnit) {
|
||||||
|
@ -315,17 +308,19 @@ Map computeHistoryView(repository) {
|
||||||
finalAmount = '$amount $currencyName';
|
finalAmount = '$amount $currencyName';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0) {
|
bool isMigrationTime =
|
||||||
isMigrationTime = true;
|
startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0;
|
||||||
} else {
|
|
||||||
isMigrationTime = false;
|
//TODO: Migration date and transaction migration doesn't match, add this event to v2s indexer.
|
||||||
}
|
|
||||||
|
// log.d('debug date transaction: $date');
|
||||||
|
// log.d('debug date identity migration: ${sub.oldOwnerKeys[address]?[1]}');
|
||||||
|
// isChangeOwnerkeyTime = date.compareTo(sub.oldOwnerKeys[address]?[1] ?? DateTime(2000)) < 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'finalAmount': finalAmount,
|
'finalAmount': finalAmount,
|
||||||
'isMigrationTime': isMigrationTime,
|
'isMigrationTime': isMigrationTime,
|
||||||
'dateDelimiter': dateDelimiter ?? '',
|
'dateDelimiter': dateDelimiter,
|
||||||
'isDelimiter': isDelimiter,
|
|
||||||
'dateForm': dateForm,
|
'dateForm': dateForm,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
// NewWallet generatedWallet;
|
// NewWallet generatedWallet;
|
||||||
durt.NewWallet? actualWallet;
|
durt.NewWallet? actualWallet;
|
||||||
|
|
||||||
FocusNode walletNameFocus = FocusNode();
|
final walletNameFocus = FocusNode();
|
||||||
Color? askedWordColor = Colors.black;
|
Color? askedWordColor = Colors.black;
|
||||||
bool isAskedWordValid = false;
|
bool isAskedWordValid = false;
|
||||||
int scanedValidWalletNumber = -1;
|
int scanedValidWalletNumber = -1;
|
||||||
|
@ -33,8 +33,8 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
String? generatedMnemonic;
|
String? generatedMnemonic;
|
||||||
bool walletIsGenerated = true;
|
bool walletIsGenerated = true;
|
||||||
|
|
||||||
TextEditingController mnemonicController = TextEditingController();
|
final mnemonicController = TextEditingController();
|
||||||
TextEditingController pin = TextEditingController();
|
final pin = TextEditingController();
|
||||||
|
|
||||||
// Import wallet
|
// Import wallet
|
||||||
TextEditingController cesiumID = TextEditingController();
|
TextEditingController cesiumID = TextEditingController();
|
||||||
|
|
|
@ -7,6 +7,7 @@ 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_data.dart';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
import 'package:gecko/providers/home.dart';
|
import 'package:gecko/providers/home.dart';
|
||||||
import 'package:gecko/providers/my_wallets.dart';
|
import 'package:gecko/providers/my_wallets.dart';
|
||||||
import 'package:gecko/providers/wallet_options.dart';
|
import 'package:gecko/providers/wallet_options.dart';
|
||||||
|
@ -46,6 +47,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
bool isCesiumAddresLoading = false;
|
bool isCesiumAddresLoading = false;
|
||||||
late int udValue;
|
late int udValue;
|
||||||
Map<String, List<int>> certsCounterCache = {};
|
Map<String, List<int>> certsCounterCache = {};
|
||||||
|
Map<String, List> oldOwnerKeys = {};
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
////////// 1: API METHODS ///////////
|
////////// 1: API METHODS ///////////
|
||||||
|
@ -91,7 +93,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
try {
|
try {
|
||||||
return await sdk.webView!.evalJavascript('api.query.$call');
|
return await sdk.webView!.evalJavascript('api.query.$call');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.i("catched _getStorage error");
|
log.e("_getStorage error: $e");
|
||||||
return Future(() {});
|
return Future(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +200,16 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
return balanceRatio;
|
return balanceRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future getBalanceMulti(List addresses) async {
|
||||||
|
List stringifyAddresses = [];
|
||||||
|
for (var element in addresses) {
|
||||||
|
stringifyAddresses.add('"$element"');
|
||||||
|
}
|
||||||
|
final List balanceGlobal =
|
||||||
|
await _getStorage('system.account.multi($stringifyAddresses)');
|
||||||
|
log.d('debug multi: $balanceGlobal');
|
||||||
|
}
|
||||||
|
|
||||||
Future<Map<String, double>> getBalance(String address) async {
|
Future<Map<String, double>> getBalance(String address) async {
|
||||||
if (!nodeConnected) {
|
if (!nodeConnected) {
|
||||||
return {
|
return {
|
||||||
|
@ -219,6 +231,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
await _getStorage('universalDividend.pastReevals()');
|
await _getStorage('universalDividend.pastReevals()');
|
||||||
|
|
||||||
// Compute amount of claimable UDs
|
// Compute amount of claimable UDs
|
||||||
|
currentUdIndex = await getCurrentUdIndex();
|
||||||
final int unclaimedUds = _computeUnclaimUds(
|
final int unclaimedUds = _computeUnclaimUds(
|
||||||
idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals);
|
idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals);
|
||||||
|
|
||||||
|
@ -264,6 +277,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log.d(
|
||||||
|
// "debug computeUnclaimUds: ${pastReevals.reversed} --- $firstEligibleUd --- $currentUdIndex");
|
||||||
|
|
||||||
return totalAmount;
|
return totalAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +346,29 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
return certMeta;
|
return certMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List> getOldOwnerKey(String address) async {
|
||||||
|
// final walletOptions =
|
||||||
|
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||||
|
|
||||||
|
var idtyIndex = await _getIdentityIndexOf(address);
|
||||||
|
if (idtyIndex == 0) return [];
|
||||||
|
|
||||||
|
final Map? idtyData = await _getStorage('identity.identities($idtyIndex)');
|
||||||
|
if (idtyData == null || idtyData['oldOwnerKey'] == null) return [];
|
||||||
|
|
||||||
|
List oldKeys = idtyData['oldOwnerKey'] ?? [];
|
||||||
|
if (oldKeys.isEmpty) return [];
|
||||||
|
|
||||||
|
oldKeys[1] = blocNumberToDate(oldKeys[1]);
|
||||||
|
oldOwnerKeys.putIfAbsent(address, () => oldKeys);
|
||||||
|
|
||||||
|
return oldKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime blocNumberToDate(int blocNumber) {
|
||||||
|
return startBlockchainTime.add(Duration(seconds: blocNumber * 6));
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> idtyStatus(String address) async {
|
Future<String> idtyStatus(String address) async {
|
||||||
// final walletOptions =
|
// final walletOptions =
|
||||||
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||||
|
@ -560,10 +599,14 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
currentUdIndex =
|
currentUdIndex = await getCurrentUdIndex();
|
||||||
int.parse(await _getStorage('universalDividend.currentUdIndex()'));
|
|
||||||
await getBalanceRatio();
|
await getBalanceRatio();
|
||||||
|
|
||||||
|
// Currency parameters
|
||||||
|
await initCurrencyParameters();
|
||||||
|
// Indexer Blockchain start
|
||||||
|
getBlockStart();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
homeProvider.changeMessage(
|
homeProvider.changeMessage(
|
||||||
"wellConnectedToNode"
|
"wellConnectedToNode"
|
||||||
|
@ -594,6 +637,10 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> getCurrentUdIndex() async {
|
||||||
|
return int.parse(await _getStorage('universalDividend.currentUdIndex()'));
|
||||||
|
}
|
||||||
|
|
||||||
NetworkParams getDuniterCustomEndpoint() {
|
NetworkParams getDuniterCustomEndpoint() {
|
||||||
final nodeParams = NetworkParams();
|
final nodeParams = NetworkParams();
|
||||||
nodeParams.name = currencyName;
|
nodeParams.name = currencyName;
|
||||||
|
@ -911,6 +958,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
|
|
||||||
// log.d('debug: ${currencyParameters['minCertForMembership']}');
|
// log.d('debug: ${currencyParameters['minCertForMembership']}');
|
||||||
|
|
||||||
|
log.d(
|
||||||
|
"debug toCert: ${toCerts[0]} --- ${currencyParameters['minCertForMembership']!} --- $toIdtyStatus");
|
||||||
|
|
||||||
if (toIdtyStatus == 'noid') {
|
if (toIdtyStatus == 'noid') {
|
||||||
txInfo = TxInfoData(
|
txInfo = TxInfoData(
|
||||||
'identity',
|
'identity',
|
||||||
|
|
|
@ -10,7 +10,6 @@ import 'package:jdenticon_dart/jdenticon_dart.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
// import 'package:qrscan/qrscan.dart' as scanner;
|
// import 'package:qrscan/qrscan.dart' as scanner;
|
||||||
import 'package:barcode_scan2/barcode_scan2.dart';
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
import 'package:confetti/confetti.dart';
|
|
||||||
|
|
||||||
class WalletsProfilesProvider with ChangeNotifier {
|
class WalletsProfilesProvider with ChangeNotifier {
|
||||||
WalletsProfilesProvider(this.address);
|
WalletsProfilesProvider(this.address);
|
||||||
|
@ -24,8 +23,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
TextEditingController payAmount = TextEditingController();
|
TextEditingController payAmount = TextEditingController();
|
||||||
TextEditingController payComment = TextEditingController();
|
TextEditingController payComment = TextEditingController();
|
||||||
num? _balance;
|
num? _balance;
|
||||||
final centerController =
|
|
||||||
ConfettiController(duration: const Duration(milliseconds: 300));
|
|
||||||
|
|
||||||
Future<String> scan(context) async {
|
Future<String> scan(context) async {
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
|
@ -145,7 +142,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
snackMessage(homeContext,
|
snackMessage(homeContext,
|
||||||
message: 'removedFromcontacts'.tr(), duration: 4);
|
message: 'removedFromcontacts'.tr(), duration: 4);
|
||||||
} else {
|
} else {
|
||||||
centerController.play();
|
|
||||||
await contactsBox.put(profile.address, profile);
|
await contactsBox.put(profile.address, profile);
|
||||||
// drawStar(Size(50, 50));
|
// drawStar(Size(50, 50));
|
||||||
snackMessage(homeContext, message: 'addedToContacts'.tr(), duration: 4);
|
snackMessage(homeContext, message: 'addedToContacts'.tr(), duration: 4);
|
||||||
|
|
|
@ -5,18 +5,32 @@ import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.dart';
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/header_profile.dart';
|
import 'package:gecko/widgets/header_profile.dart';
|
||||||
import 'package:gecko/widgets/history_query.dart';
|
import 'package:gecko/widgets/history_query.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
class ActivityScreen extends StatefulWidget {
|
||||||
ActivityScreen({required this.address, required this.avatar, this.username})
|
const ActivityScreen(
|
||||||
|
{required this.address, required this.avatar, this.username})
|
||||||
: super(key: keyActivityScreen);
|
: super(key: keyActivityScreen);
|
||||||
final String address;
|
final String address;
|
||||||
final String? username;
|
final String? username;
|
||||||
final Image avatar;
|
final Image avatar;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ActivityScreen> createState() => _ActivityScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ActivityScreenState extends State<ActivityScreen> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
sub.getOldOwnerKey(widget.address);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: true);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: true);
|
||||||
|
@ -45,8 +59,8 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||||
),
|
),
|
||||||
bottomNavigationBar: const GeckoBottomAppBar(),
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
body: Column(children: <Widget>[
|
body: Column(children: <Widget>[
|
||||||
HeaderProfile(address: address, username: username),
|
HeaderProfile(address: widget.address, username: widget.username),
|
||||||
HistoryQuery(address: address),
|
HistoryQuery(address: widget.address),
|
||||||
])),
|
])),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ class CertificationsScreen extends StatelessWidget {
|
||||||
toolbarHeight: 60 * ratio,
|
toolbarHeight: 60 * ratio,
|
||||||
title: SizedBox(
|
title: SizedBox(
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Text('Certifications de $username'),
|
child: Text('certificationsOf'.tr(args: [username])),
|
||||||
)),
|
)),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Accordion(
|
child: Accordion(
|
||||||
|
@ -45,7 +45,10 @@ class CertificationsScreen extends StatelessWidget {
|
||||||
headerBackgroundColor: yellowC,
|
headerBackgroundColor: yellowC,
|
||||||
headerBackgroundColorOpened: orangeC,
|
headerBackgroundColorOpened: orangeC,
|
||||||
header: Row(children: [
|
header: Row(children: [
|
||||||
Text('received'.tr()),
|
Text(
|
||||||
|
'received'.tr(),
|
||||||
|
style: const TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
CertsCounter(address: address)
|
CertsCounter(address: address)
|
||||||
]),
|
]),
|
||||||
|
@ -60,7 +63,10 @@ class CertificationsScreen extends StatelessWidget {
|
||||||
headerBackgroundColor: yellowC,
|
headerBackgroundColor: yellowC,
|
||||||
headerBackgroundColorOpened: orangeC,
|
headerBackgroundColorOpened: orangeC,
|
||||||
header: Row(children: [
|
header: Row(children: [
|
||||||
Text('sent'.tr()),
|
Text(
|
||||||
|
'sent'.tr(),
|
||||||
|
style: const TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
CertsCounter(address: address, isSent: true)
|
CertsCounter(address: address, isSent: true)
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -95,10 +95,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
var connectivityResult = await (Connectivity().checkConnectivity());
|
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||||
if (connectivityResult != ConnectivityResult.none) {
|
if (connectivityResult != ConnectivityResult.none) {
|
||||||
await sub.connectNode(context);
|
await sub.connectNode(context);
|
||||||
// Currency parameters
|
|
||||||
await sub.initCurrencyParameters();
|
|
||||||
// Indexer Blockchain start
|
|
||||||
getBlockStart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -122,6 +118,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
isTall = true;
|
isTall = true;
|
||||||
ratio = 1.125;
|
ratio = 1.125;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: finish to implement multiqueries
|
||||||
|
|
||||||
|
// final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
|
// sub.getBalanceMulti([
|
||||||
|
// '5CQ8T4qpbYJq7uVsxGPQ5q2df7x3Wa4aRY6HUWMBYjfLZhnn',
|
||||||
|
// '5Dq8xjvkmbz7q4g2LbZgyExD26VSCutfEc6n4W4AfQeVHZqz'
|
||||||
|
// ]);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
drawer: MainDrawer(isWalletsExists: isWalletsExists),
|
drawer: MainDrawer(isWalletsExists: isWalletsExists),
|
||||||
|
|
|
@ -85,7 +85,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myWalletProvider.listWallets.isEmpty) {
|
if (myWalletProvider.listWallets.isEmpty) {
|
||||||
return Column(children: const <Widget>[
|
return const Column(children: <Widget>[
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Veuillez générer votre premier portefeuille',
|
'Veuillez générer votre premier portefeuille',
|
||||||
|
|
|
@ -61,11 +61,11 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
// log.d(_certs.data);
|
// log.d(_certs.data);
|
||||||
|
|
||||||
if (status.data == null) {
|
if (status.data == null) {
|
||||||
return Column(children: [
|
return const Column(children: [
|
||||||
const SizedBox(height: 80),
|
SizedBox(height: 80),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: const [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
width: 35,
|
width: 35,
|
||||||
|
|
|
@ -93,9 +93,9 @@ class ManageMembership extends StatelessWidget {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: const SizedBox(
|
||||||
height: 60,
|
height: 60,
|
||||||
child: Row(children: const <Widget>[
|
child: Row(children: <Widget>[
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Icon(Icons.change_circle_outlined, size: 35),
|
Icon(Icons.change_circle_outlined, size: 35),
|
||||||
SizedBox(width: 11.5),
|
SizedBox(width: 11.5),
|
||||||
|
|
|
@ -47,12 +47,12 @@ class MigrateIdentityScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (walletsList.length < 2) {
|
if (walletsList.length < 2) {
|
||||||
return Column(
|
return const Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 80),
|
SizedBox(height: 80),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: const [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
|
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
|
||||||
style: TextStyle(fontSize: 20),
|
style: TextStyle(fontSize: 20),
|
||||||
|
@ -78,20 +78,18 @@ class MigrateIdentityScreen extends StatelessWidget {
|
||||||
fromAddress, selectedWallet.address),
|
fromAddress, selectedWallet.address),
|
||||||
builder: (BuildContext context, AsyncSnapshot<List> status) {
|
builder: (BuildContext context, AsyncSnapshot<List> status) {
|
||||||
if (status.data == null) {
|
if (status.data == null) {
|
||||||
return Column(children: [
|
return const Column(children: [
|
||||||
const SizedBox(height: 80),
|
SizedBox(height: 80),
|
||||||
Row(
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
SizedBox(
|
||||||
children: const [
|
height: 35,
|
||||||
SizedBox(
|
width: 35,
|
||||||
height: 35,
|
child: CircularProgressIndicator(
|
||||||
width: 35,
|
color: orangeC,
|
||||||
child: CircularProgressIndicator(
|
strokeWidth: 4,
|
||||||
color: orangeC,
|
),
|
||||||
strokeWidth: 4,
|
),
|
||||||
),
|
]),
|
||||||
),
|
|
||||||
]),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +134,7 @@ class MigrateIdentityScreen extends StatelessWidget {
|
||||||
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
Row(children: const []),
|
const Row(children: []),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|
|
@ -81,7 +81,7 @@ class ShowSeed extends StatelessWidget {
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(
|
Clipboard.setData(
|
||||||
ClipboardData(text: seed.data));
|
ClipboardData(text: seed.data!));
|
||||||
snackCopySeed(context);
|
snackCopySeed(context);
|
||||||
},
|
},
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
|
|
|
@ -13,10 +13,10 @@ import 'package:gecko/providers/wallet_options.dart';
|
||||||
import 'package:gecko/providers/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:gecko/screens/certifications.dart';
|
import 'package:gecko/screens/certifications.dart';
|
||||||
import 'package:gecko/screens/activity.dart';
|
import 'package:gecko/screens/activity.dart';
|
||||||
import 'package:gecko/screens/myWallets/manage_membership.dart';
|
|
||||||
import 'package:gecko/screens/qrcode_fullscreen.dart';
|
import 'package:gecko/screens/qrcode_fullscreen.dart';
|
||||||
import 'package:gecko/widgets/balance.dart';
|
import 'package:gecko/widgets/balance.dart';
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
|
import 'package:gecko/widgets/buttons/manage_membership_button.dart';
|
||||||
import 'package:gecko/widgets/certifications.dart';
|
import 'package:gecko/widgets/certifications.dart';
|
||||||
import 'package:gecko/widgets/commons/offline_info.dart';
|
import 'package:gecko/widgets/commons/offline_info.dart';
|
||||||
import 'package:gecko/widgets/idty_status.dart';
|
import 'package:gecko/widgets/idty_status.dart';
|
||||||
|
@ -40,9 +40,8 @@ class WalletOptions extends StatelessWidget {
|
||||||
final myWalletProvider =
|
final myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
|
||||||
|
|
||||||
// final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
// sub.spawnBlock();
|
// sub.spawnBlock();
|
||||||
// sub.spawnBlock(0, 20);
|
// sub.spawnBlock(0, 20);
|
||||||
|
|
||||||
|
@ -146,7 +145,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
builder: (context, walletProvider, _) {
|
builder: (context, walletProvider, _) {
|
||||||
return NameByAddress(
|
return NameByAddress(
|
||||||
wallet: wallet,
|
wallet: wallet,
|
||||||
size: 27,
|
size: 29,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: wallet.isMember
|
fontWeight: wallet.isMember
|
||||||
? FontWeight.w500
|
? FontWeight.w500
|
||||||
|
@ -183,7 +182,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
]),
|
]),
|
||||||
SizedBox(height: isTall ? 5 : 0),
|
SizedBox(height: isTall ? 5 : 0),
|
||||||
Balance(
|
Balance(
|
||||||
address: walletProvider.address.text, size: 21),
|
address: walletProvider.address.text, size: 24),
|
||||||
const SizedBox(width: 30),
|
const SizedBox(width: 30),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => isWalletNameIndexed
|
onTap: () => isWalletNameIndexed
|
||||||
|
@ -245,6 +244,11 @@ class WalletOptions extends StatelessWidget {
|
||||||
SizedBox(height: 30 * ratio),
|
SizedBox(height: 30 * ratio),
|
||||||
Consumer<WalletOptionsProvider>(
|
Consumer<WalletOptionsProvider>(
|
||||||
builder: (context, walletProvider, _) {
|
builder: (context, walletProvider, _) {
|
||||||
|
final defaultWallet =
|
||||||
|
myWalletProvider.getDefaultWallet();
|
||||||
|
walletProvider.isDefaultWallet =
|
||||||
|
walletOptions.address.text ==
|
||||||
|
defaultWallet.address;
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
confirmIdentityButton(walletProvider),
|
confirmIdentityButton(walletProvider),
|
||||||
pubkeyWidget(walletProvider, ctx),
|
pubkeyWidget(walletProvider, ctx),
|
||||||
|
@ -278,7 +282,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
else
|
else
|
||||||
const SizedBox(),
|
const SizedBox(),
|
||||||
if (isMember.data!)
|
if (isMember.data!)
|
||||||
manageMembership(context)
|
const ManageMembershipButton()
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
@ -496,36 +500,6 @@ class WalletOptions extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget manageMembership(BuildContext context) {
|
|
||||||
final walletOptions =
|
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
|
||||||
return InkWell(
|
|
||||||
key: keyManageMembership,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return ManageMembership(
|
|
||||||
address: walletOptions.address.text,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
height: 40,
|
|
||||||
child: Row(children: <Widget>[
|
|
||||||
const SizedBox(width: 32),
|
|
||||||
Image.asset(
|
|
||||||
'assets/medal.png',
|
|
||||||
height: 45,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 22),
|
|
||||||
Text('manageMembership'.tr(), style: const TextStyle(fontSize: 20)),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget setDefaultWalletWidget(
|
Widget setDefaultWalletWidget(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
WalletOptionsProvider walletProvider,
|
WalletOptionsProvider walletProvider,
|
||||||
|
|
|
@ -6,7 +6,6 @@ import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.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';
|
||||||
|
@ -16,16 +15,15 @@ import 'package:gecko/screens/myWallets/chest_options.dart';
|
||||||
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
|
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||||
import 'package:gecko/screens/myWallets/wallet_options.dart';
|
import 'package:gecko/screens/myWallets/wallet_options.dart';
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
|
||||||
// import 'package:gecko/screens/myWallets/choose_chest.dart';
|
|
||||||
import 'package:gecko/widgets/balance.dart';
|
import 'package:gecko/widgets/balance.dart';
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/commons/offline_info.dart';
|
import 'package:gecko/widgets/commons/offline_info.dart';
|
||||||
import 'package:gecko/widgets/commons/smooth_transition.dart';
|
import 'package:gecko/widgets/commons/smooth_transition.dart';
|
||||||
|
import 'package:gecko/widgets/name_by_address.dart';
|
||||||
|
import 'package:gecko/widgets/payment_popup.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:truncate/truncate.dart';
|
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||||
// import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
|
||||||
|
|
||||||
class WalletsHome extends StatefulWidget {
|
class WalletsHome extends StatefulWidget {
|
||||||
const WalletsHome({Key? key}) : super(key: key);
|
const WalletsHome({Key? key}) : super(key: key);
|
||||||
|
@ -35,36 +33,8 @@ class WalletsHome extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WalletsHomeState extends State<WalletsHome> {
|
class _WalletsHomeState extends State<WalletsHome> {
|
||||||
final safeKey = GlobalKey();
|
|
||||||
// List<TargetFocus> targets = [];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
// targets
|
|
||||||
// .add(TargetFocus(identify: "Target 1", keyTarget: safeKey, contents: [
|
|
||||||
// TargetContent(
|
|
||||||
// align: ContentAlign.right,
|
|
||||||
// child: Column(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
// children: const <Widget>[
|
|
||||||
// Text(
|
|
||||||
// "Titulo lorem ipsum",
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// color: Colors.white,
|
|
||||||
// fontSize: 20.0),
|
|
||||||
// ),
|
|
||||||
// Padding(
|
|
||||||
// padding: EdgeInsets.only(top: 10.0),
|
|
||||||
// child: Text(
|
|
||||||
// "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pulvinar tortor eget maximus iaculis.",
|
|
||||||
// style: TextStyle(color: Colors.white),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// ],
|
|
||||||
// ))
|
|
||||||
// ]));
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,15 +222,14 @@ class _WalletsHomeState extends State<WalletsHome> {
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
||||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
|
|
||||||
if (!isWalletsExists) {
|
if (!isWalletsExists) {
|
||||||
return const Text('');
|
return const Text('');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myWalletProvider.listWallets.isEmpty) {
|
if (myWalletProvider.listWallets.isEmpty) {
|
||||||
return Expanded(
|
return const Expanded(
|
||||||
child: Column(children: const <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Veuillez générer votre premier portefeuille',
|
'Veuillez générer votre premier portefeuille',
|
||||||
|
@ -286,13 +255,45 @@ class _WalletsHomeState extends State<WalletsHome> {
|
||||||
} else {
|
} else {
|
||||||
nTule = 2;
|
nTule = 2;
|
||||||
}
|
}
|
||||||
// Offset followDragAnchorStrategy(
|
|
||||||
// Draggable<Object> d, BuildContext context, Offset point) {
|
|
||||||
// return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// showTutorial();
|
final tutorialCoachMark = TutorialCoachMark(
|
||||||
// Future.delayed(const Duration(seconds: 1), showTutorial);
|
targets: [
|
||||||
|
TargetFocus(
|
||||||
|
identify: "drag_and_drop",
|
||||||
|
keyTarget: keyDragAndDrop,
|
||||||
|
contents: [
|
||||||
|
TargetContent(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Image.asset('assets/drag-and-drop.png', height: 140),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Text(
|
||||||
|
'explainDraggableWallet'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 22, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
|
alignSkip: Alignment.bottomRight,
|
||||||
|
enableOverlayTab: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
colorShadow: orangeC,
|
||||||
|
textSkip: "skip".tr(),
|
||||||
|
paddingFocus: 10,
|
||||||
|
opacityShadow: 0.8,
|
||||||
|
);
|
||||||
|
|
||||||
|
// configBox.delete('showDraggableTutorial');
|
||||||
|
final bool showDraggableTutorial =
|
||||||
|
configBox.get('showDraggableTutorial') ?? true;
|
||||||
|
|
||||||
|
if (listWallets.length > 1 && showDraggableTutorial) {
|
||||||
|
tutorialCoachMark.show(context: context);
|
||||||
|
configBox.put('showDraggableTutorial', false);
|
||||||
|
}
|
||||||
|
|
||||||
return CustomScrollView(slivers: <Widget>[
|
return CustomScrollView(slivers: <Widget>[
|
||||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
||||||
|
@ -339,7 +340,11 @@ class _WalletsHomeState extends State<WalletsHome> {
|
||||||
.getWalletDataByAddress(senderAddress);
|
.getWalletDataByAddress(senderAddress);
|
||||||
await sub.setCurrentWallet(walletData!);
|
await sub.setCurrentWallet(walletData!);
|
||||||
sub.reload();
|
sub.reload();
|
||||||
paymentPopup(context, repository.address);
|
paymentPopup(
|
||||||
|
context,
|
||||||
|
repository.address,
|
||||||
|
g1WalletsBox.get(repository.address)!.username ??
|
||||||
|
repository.name!);
|
||||||
},
|
},
|
||||||
onMove: (details) {
|
onMove: (details) {
|
||||||
if (repository.address != myWalletProvider.lastFlyBy) {
|
if (repository.address != myWalletProvider.lastFlyBy) {
|
||||||
|
@ -370,97 +375,91 @@ class _WalletsHomeState extends State<WalletsHome> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: ClipOvalShadow(
|
child: SizedBox(
|
||||||
shadow: const Shadow(
|
key: repository.number == 1
|
||||||
color: Colors.transparent,
|
? keyDragAndDrop
|
||||||
offset: Offset(0, 0),
|
: const Key('nothing'),
|
||||||
blurRadius: 5,
|
child: ClipOvalShadow(
|
||||||
),
|
shadow: const Shadow(
|
||||||
clipper: CustomClipperOval(),
|
color: Colors.transparent,
|
||||||
child: ClipRRect(
|
offset: Offset(0, 0),
|
||||||
borderRadius:
|
blurRadius: 5,
|
||||||
const BorderRadius.all(Radius.circular(12)),
|
),
|
||||||
child: Column(children: <Widget>[
|
clipper: CustomClipperOval(),
|
||||||
Expanded(
|
child: ClipRRect(
|
||||||
child: Container(
|
borderRadius:
|
||||||
width: double.infinity,
|
const BorderRadius.all(Radius.circular(12)),
|
||||||
height: double.infinity,
|
child: Column(children: <Widget>[
|
||||||
decoration: const BoxDecoration(
|
Expanded(
|
||||||
gradient: RadialGradient(
|
child: Container(
|
||||||
radius: 0.8,
|
width: double.infinity,
|
||||||
colors: [
|
height: double.infinity,
|
||||||
Color.fromARGB(255, 255, 255, 211),
|
decoration: const BoxDecoration(
|
||||||
yellowC,
|
gradient: RadialGradient(
|
||||||
],
|
radius: 0.8,
|
||||||
|
colors: [
|
||||||
|
Color.fromARGB(255, 255, 255, 211),
|
||||||
|
yellowC,
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
child:
|
||||||
child:
|
// SvgPicture.asset('assets/chopp-gecko2.png',
|
||||||
// SvgPicture.asset('assets/chopp-gecko2.png',
|
// semanticsLabel: 'Gecko', height: 48),
|
||||||
// semanticsLabel: 'Gecko', height: 48),
|
repository.imageCustomPath == null ||
|
||||||
repository.imageCustomPath == null ||
|
repository.imageCustomPath == ''
|
||||||
repository.imageCustomPath == ''
|
? Image.asset(
|
||||||
? Image.asset(
|
'assets/avatars/${repository.imageDefaultPath}',
|
||||||
'assets/avatars/${repository.imageDefaultPath}',
|
alignment:
|
||||||
alignment: Alignment.bottomCenter,
|
Alignment.bottomCenter,
|
||||||
scale: 0.5,
|
scale: 0.5,
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.fitHeight,
|
||||||
image: FileImage(
|
image: FileImage(
|
||||||
File(repository
|
File(repository
|
||||||
.imageCustomPath!),
|
.imageCustomPath!),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
)),
|
||||||
)),
|
Stack(children: <Widget>[
|
||||||
Stack(children: <Widget>[
|
BalanceBuilder(
|
||||||
BalanceBuilder(
|
address: repository.address,
|
||||||
address: repository.address,
|
isDefault: repository.address ==
|
||||||
isDefault: repository.address ==
|
defaultWallet.address),
|
||||||
defaultWallet.address),
|
Row(
|
||||||
Row(
|
mainAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 7),
|
const SizedBox(height: 7),
|
||||||
Opacity(
|
Opacity(
|
||||||
opacity: 0.7,
|
opacity: 0.7,
|
||||||
child: Text(
|
child: NameByAddress(
|
||||||
duniterIndexer.walletNameIndexer[
|
wallet: repository,
|
||||||
repository.address] ??
|
size: 20,
|
||||||
truncate(
|
|
||||||
repository.name!, 20),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
color:
|
color:
|
||||||
defaultWallet.address ==
|
defaultWallet.address ==
|
||||||
repository.address
|
repository.address
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Colors.black,
|
: Colors.black,
|
||||||
fontWeight: FontWeight.w500),
|
fontWeight: FontWeight.w600,
|
||||||
),
|
fontStyle: FontStyle.normal,
|
||||||
)
|
))
|
||||||
// NameByAddress(
|
],
|
||||||
// wallet: repository,
|
),
|
||||||
// address: repository.address,
|
],
|
||||||
// size: 20,
|
),
|
||||||
// color: defaultWallet.address ==
|
]),
|
||||||
// repository.address
|
|
||||||
// ? Colors.white
|
|
||||||
// : Colors.black,
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]),
|
]),
|
||||||
]),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -16,7 +16,7 @@ class OnboardingStepEleven extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final conffetiController =
|
final conffetiController =
|
||||||
ConfettiController(duration: const Duration(milliseconds: 300));
|
ConfettiController(duration: const Duration(milliseconds: 500));
|
||||||
conffetiController.play();
|
conffetiController.play();
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () {
|
onWillPop: () {
|
||||||
|
@ -55,16 +55,29 @@ class OnboardingStepEleven extends StatelessWidget {
|
||||||
const SizedBox(height: 40),
|
const SizedBox(height: 40),
|
||||||
]),
|
]),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topLeft,
|
||||||
child: ConfettiWidget(
|
child: ConfettiWidget(
|
||||||
confettiController: conffetiController,
|
confettiController: conffetiController,
|
||||||
blastDirection: pi / 2,
|
blastDirection: pi * 0.1,
|
||||||
maxBlastForce: 5,
|
maxBlastForce: 10,
|
||||||
minBlastForce: 1,
|
minBlastForce: 1,
|
||||||
emissionFrequency: 0.01,
|
emissionFrequency: 0.01,
|
||||||
numberOfParticles: 10,
|
numberOfParticles: 7,
|
||||||
shouldLoop: false,
|
shouldLoop: false,
|
||||||
gravity: 0.1,
|
gravity: 0.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
child: ConfettiWidget(
|
||||||
|
confettiController: conffetiController,
|
||||||
|
blastDirection: pi * 0.9,
|
||||||
|
maxBlastForce: 10,
|
||||||
|
minBlastForce: 1,
|
||||||
|
emissionFrequency: 0.01,
|
||||||
|
numberOfParticles: 7,
|
||||||
|
shouldLoop: false,
|
||||||
|
gravity: 0.2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -94,7 +94,7 @@ class _ChooseChestState extends State<OnboardingStepFive> {
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(ClipboardData(
|
Clipboard.setData(ClipboardData(
|
||||||
text: generateWalletProvider.generatedMnemonic));
|
text: generateWalletProvider.generatedMnemonic!));
|
||||||
snackCopySeed(context);
|
snackCopySeed(context);
|
||||||
},
|
},
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
|
|
|
@ -16,8 +16,8 @@ class TemplateScreen extends StatelessWidget {
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Text('Template screen'),
|
child: Text('Template screen'),
|
||||||
)),
|
)),
|
||||||
body: SafeArea(
|
body: const SafeArea(
|
||||||
child: Column(children: const <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
Text('data'),
|
Text('data'),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:confetti/confetti.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
@ -15,18 +11,16 @@ import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.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:gecko/providers/wallet_options.dart';
|
|
||||||
import 'package:gecko/providers/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:gecko/screens/activity.dart';
|
import 'package:gecko/screens/activity.dart';
|
||||||
import 'package:gecko/widgets/commons/common_elements.dart';
|
import 'package:gecko/widgets/commons/common_elements.dart';
|
||||||
import 'package:gecko/screens/myWallets/choose_wallet.dart';
|
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||||
import 'package:gecko/screens/qrcode_fullscreen.dart';
|
import 'package:gecko/screens/qrcode_fullscreen.dart';
|
||||||
import 'package:gecko/screens/transaction_in_progress.dart';
|
import 'package:gecko/screens/transaction_in_progress.dart';
|
||||||
import 'package:gecko/widgets/balance.dart';
|
|
||||||
import 'package:gecko/widgets/bottom_app_bar.dart';
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/widgets/header_profile.dart';
|
import 'package:gecko/widgets/header_profile.dart';
|
||||||
import 'package:gecko/widgets/page_route_no_transition.dart';
|
import 'package:gecko/widgets/page_route_no_transition.dart';
|
||||||
|
import 'package:gecko/widgets/payment_popup.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
|
|
||||||
|
@ -53,7 +47,7 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
walletProfile.address = address;
|
walletProfile.address = address;
|
||||||
sub.setCurrentWallet(defaultWallet);
|
sub.setCurrentWallet(defaultWallet);
|
||||||
|
|
||||||
log.d('aaaaaaaaaaaaaaaaaaa: $username');
|
log.d("username: $username");
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
|
@ -64,16 +58,6 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
actions: [
|
actions: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
ConfettiWidget(
|
|
||||||
confettiController: walletProfile.centerController,
|
|
||||||
blastDirection: pi / 2,
|
|
||||||
maxBlastForce: 7,
|
|
||||||
minBlastForce: 3,
|
|
||||||
emissionFrequency: 0,
|
|
||||||
numberOfParticles: 7,
|
|
||||||
shouldLoop: false,
|
|
||||||
gravity: 0.001,
|
|
||||||
),
|
|
||||||
Consumer<WalletsProfilesProvider>(
|
Consumer<WalletsProfilesProvider>(
|
||||||
builder: (context, walletProfile, _) {
|
builder: (context, walletProfile, _) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
|
@ -360,8 +344,23 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
key: keyPay,
|
key: keyPay,
|
||||||
splashColor: yellowC,
|
splashColor: yellowC,
|
||||||
onTap: sub.nodeConnected
|
onTap: sub.nodeConnected
|
||||||
? () {
|
? () async {
|
||||||
paymentPopup(context, address);
|
String? pin;
|
||||||
|
if (myWalletProvider.pinCode == '') {
|
||||||
|
pin = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (homeContext) {
|
||||||
|
return UnlockingWallet(
|
||||||
|
wallet: defaultWallet);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (pin != null ||
|
||||||
|
myWalletProvider.pinCode != '') {
|
||||||
|
paymentPopup(context, address, username);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
|
@ -419,301 +418,3 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void paymentPopup(BuildContext context, String toAddress) {
|
|
||||||
final walletViewProvider =
|
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
|
||||||
|
|
||||||
final myWalletProvider =
|
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
|
||||||
|
|
||||||
const double shapeSize = 20;
|
|
||||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
|
||||||
log.d(defaultWallet.address);
|
|
||||||
|
|
||||||
bool canValidate = false;
|
|
||||||
|
|
||||||
final toWalletData = myWalletProvider.getWalletDataByAddress(toAddress);
|
|
||||||
|
|
||||||
Future executeTransfert() async {
|
|
||||||
String? pin;
|
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
log.d(pin);
|
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
|
||||||
// Payment workflow !
|
|
||||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
|
||||||
final acc = sub.getCurrentWallet();
|
|
||||||
log.d(
|
|
||||||
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin");
|
|
||||||
sub.pay(
|
|
||||||
fromAddress: acc.address!,
|
|
||||||
destAddress: toAddress,
|
|
||||||
amount: double.parse(walletViewProvider.payAmount.text),
|
|
||||||
password: pin ?? myWalletProvider.pinCode);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const TransactionInProgress();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showModalBottomSheet<void>(
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topRight: Radius.circular(shapeSize),
|
|
||||||
topLeft: Radius.circular(shapeSize),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
isScrollControlled: true,
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
|
||||||
final walletOptions =
|
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
|
||||||
|
|
||||||
double fees = 0;
|
|
||||||
return StatefulBuilder(
|
|
||||||
builder: (BuildContext context, StateSetter setState) {
|
|
||||||
if (walletViewProvider.payAmount.text != '' &&
|
|
||||||
(double.parse(walletViewProvider.payAmount.text) +
|
|
||||||
2 / balanceRatio) <=
|
|
||||||
(walletOptions.balanceCache[defaultWallet.address] ?? 0) &&
|
|
||||||
toAddress != defaultWallet.address) {
|
|
||||||
if ((walletOptions.balanceCache[toAddress] == 0 ||
|
|
||||||
walletOptions.balanceCache[toAddress] == null) &&
|
|
||||||
double.parse(walletViewProvider.payAmount.text) <
|
|
||||||
5 / balanceRatio) {
|
|
||||||
canValidate = false;
|
|
||||||
} else {
|
|
||||||
canValidate = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
canValidate = false;
|
|
||||||
}
|
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
bottom: MediaQuery.of(context).viewInsets.bottom),
|
|
||||||
child: Container(
|
|
||||||
height: 420,
|
|
||||||
decoration: const ShapeDecoration(
|
|
||||||
color: Color(0xffffeed1),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topRight: Radius.circular(shapeSize),
|
|
||||||
topLeft: Radius.circular(shapeSize),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 24, bottom: 0, left: 24, right: 24),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'executeATransfer'.tr(),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 26, fontWeight: FontWeight.w700),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
iconSize: 40,
|
|
||||||
icon: const Icon(Icons.cancel_outlined),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Text(
|
|
||||||
'from'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 19,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey[600]),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
|
||||||
return InkWell(
|
|
||||||
key: keyChangeChest,
|
|
||||||
onTap: () async {
|
|
||||||
String? pin;
|
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(
|
|
||||||
wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return ChooseWalletScreen(
|
|
||||||
pin: pin ?? myWalletProvider.pinCode);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border.all(
|
|
||||||
color: Colors.blueAccent.shade200, width: 2),
|
|
||||||
borderRadius:
|
|
||||||
const BorderRadius.all(Radius.circular(10.0)),
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.all(10),
|
|
||||||
child: Row(children: [
|
|
||||||
Text(defaultWallet.name!),
|
|
||||||
const Spacer(),
|
|
||||||
Balance(address: defaultWallet.address, size: 20),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'to'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 19,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey[600]),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 2),
|
|
||||||
Text(
|
|
||||||
toWalletData == null
|
|
||||||
? getShortPubkey(toAddress)
|
|
||||||
: toWalletData.name!,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 21,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'amount'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 19,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey[600]),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
Text(
|
|
||||||
'frais: $fees $currencyName',
|
|
||||||
style: const TextStyle(
|
|
||||||
color: orangeC,
|
|
||||||
fontSize: 17,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
TextField(
|
|
||||||
textInputAction: TextInputAction.done,
|
|
||||||
onEditingComplete: () async =>
|
|
||||||
canValidate ? await executeTransfert() : null,
|
|
||||||
key: keyAmountField,
|
|
||||||
controller: walletViewProvider.payAmount,
|
|
||||||
autofocus: true,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
keyboardType: const TextInputType.numberWithOptions(
|
|
||||||
decimal: true),
|
|
||||||
onChanged: (_) async {
|
|
||||||
fees = await sub.txFees(
|
|
||||||
defaultWallet.address,
|
|
||||||
toAddress,
|
|
||||||
double.parse(
|
|
||||||
walletViewProvider.payAmount.text == ''
|
|
||||||
? '0'
|
|
||||||
: walletViewProvider.payAmount.text));
|
|
||||||
log.d(fees);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
inputFormatters: <TextInputFormatter>[
|
|
||||||
FilteringTextInputFormatter.deny(',',
|
|
||||||
replacementString: '.'),
|
|
||||||
FilteringTextInputFormatter.allow(
|
|
||||||
RegExp(r'(^\d+\.?\d{0,2})')),
|
|
||||||
],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: '0.00',
|
|
||||||
suffix: Text(isUdUnit
|
|
||||||
? 'ud'.tr(args: [''])
|
|
||||||
: currencyName), // udUnitDisplay(40),
|
|
||||||
filled: true,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
focusedBorder: OutlineInputBorder(
|
|
||||||
borderSide:
|
|
||||||
BorderSide(color: Colors.grey[500]!, width: 2),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
contentPadding: const EdgeInsets.all(20),
|
|
||||||
),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 35,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 60,
|
|
||||||
child: ElevatedButton(
|
|
||||||
key: keyConfirmPayment,
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
|
||||||
backgroundColor: orangeC, // foreground
|
|
||||||
),
|
|
||||||
onPressed: canValidate
|
|
||||||
? () async => await executeTransfert()
|
|
||||||
: null,
|
|
||||||
child: Text(
|
|
||||||
'executeTheTransfer'.tr(),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 20, fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}).then((value) => walletViewProvider.payAmount.text = '');
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/wallet_options.dart';
|
||||||
|
import 'package:gecko/screens/myWallets/manage_membership.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class ManageMembershipButton extends StatelessWidget {
|
||||||
|
const ManageMembershipButton({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
|
return InkWell(
|
||||||
|
key: keyManageMembership,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
return ManageMembership(
|
||||||
|
address: walletOptions.address.text,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
const SizedBox(width: 32),
|
||||||
|
Image.asset(
|
||||||
|
'assets/medal.png',
|
||||||
|
height: 45,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 22),
|
||||||
|
Text('manageMembership'.tr(), style: const TextStyle(fontSize: 20)),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,12 +37,12 @@ class CertTile extends StatelessWidget {
|
||||||
title: Padding(
|
title: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 5),
|
padding: const EdgeInsets.only(bottom: 5),
|
||||||
child: Text(repository['name'],
|
child: Text(repository['name'],
|
||||||
style: const TextStyle(fontSize: 20)),
|
style: const TextStyle(fontSize: 22)),
|
||||||
),
|
),
|
||||||
subtitle: RichText(
|
subtitle: RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 18,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
|
@ -60,9 +60,9 @@ class CertTile extends StatelessWidget {
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: getShortPubkey(repository['address']),
|
text: getShortPubkey(repository['address']),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
color: Colors.grey[600],
|
color: Colors.grey[600],
|
||||||
),
|
fontSize: 18),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -8,7 +8,7 @@ class BuildProgressBar extends StatelessWidget {
|
||||||
required this.pagePosition,
|
required this.pagePosition,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final double pagePosition;
|
final int pagePosition;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
@ -155,11 +155,14 @@ Future<void> infoPopup(BuildContext context, String title) async {
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
key: keyInfoPopup,
|
key: keyInfoPopup,
|
||||||
child: const Text(
|
child: Padding(
|
||||||
"D'accord",
|
padding: const EdgeInsets.all(8),
|
||||||
style: TextStyle(
|
child: Text(
|
||||||
fontSize: 21,
|
"gotit".tr(),
|
||||||
color: Color(0xffD80000),
|
style: const TextStyle(
|
||||||
|
fontSize: 21,
|
||||||
|
color: Color(0xffD80000),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
|
@ -24,7 +24,7 @@ class InfoIntro extends StatelessWidget {
|
||||||
final String assetName;
|
final String assetName;
|
||||||
final String buttonText;
|
final String buttonText;
|
||||||
final Widget nextScreen;
|
final Widget nextScreen;
|
||||||
final double pagePosition;
|
final int pagePosition;
|
||||||
final bool isMd;
|
final bool isMd;
|
||||||
final bool isFast;
|
final bool isFast;
|
||||||
final double boxHeight;
|
final double boxHeight;
|
||||||
|
|
|
@ -24,11 +24,11 @@ class MainDrawer extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
|
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
|
||||||
DrawerHeader(
|
const DrawerHeader(
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
),
|
),
|
||||||
child: Column(children: const <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 0),
|
SizedBox(height: 0),
|
||||||
Image(
|
Image(
|
||||||
image: AssetImage('assets/icon/gecko_final.png'),
|
image: AssetImage('assets/icon/gecko_final.png'),
|
||||||
|
@ -64,7 +64,7 @@ class MainDrawer extends StatelessWidget {
|
||||||
),
|
),
|
||||||
if (kDebugMode)
|
if (kDebugMode)
|
||||||
ListTile(
|
ListTile(
|
||||||
key: keyParameters,
|
key: keyDebugScreen,
|
||||||
title: Text('Debug screen'.tr()),
|
title: Text('Debug screen'.tr()),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
|
@ -74,9 +74,9 @@ class HeaderProfile extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 23),
|
||||||
Balance(address: address, size: 22),
|
Balance(address: address, size: 25),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 9),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => duniterIndexer.walletNameIndexer[address] != null
|
onTap: () => duniterIndexer.walletNameIndexer[address] != null
|
||||||
? {
|
? {
|
||||||
|
|
|
@ -116,7 +116,12 @@ class HistoryQuery extends StatelessWidget {
|
||||||
child: ListView(
|
child: ListView(
|
||||||
key: keyListTransactions,
|
key: keyListTransactions,
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
children: <Widget>[HistoryView(result: result)],
|
children: <Widget>[
|
||||||
|
HistoryView(
|
||||||
|
result: result,
|
||||||
|
address: address,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -2,6 +2,9 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gecko/globals.dart';
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.dart';
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/screens/wallet_view.dart';
|
||||||
|
import 'package:gecko/widgets/page_route_no_transition.dart';
|
||||||
import 'package:gecko/widgets/transaction_tile.dart';
|
import 'package:gecko/widgets/transaction_tile.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';
|
||||||
|
@ -10,12 +13,16 @@ class HistoryView extends StatelessWidget {
|
||||||
const HistoryView({
|
const HistoryView({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.result,
|
required this.result,
|
||||||
|
required this.address,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
final QueryResult result;
|
final QueryResult result;
|
||||||
|
final String address;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
|
||||||
int keyID = 0;
|
int keyID = 0;
|
||||||
const double avatarSize = 200;
|
const double avatarSize = 200;
|
||||||
bool isMigrationPassed = false;
|
bool isMigrationPassed = false;
|
||||||
|
@ -32,7 +39,7 @@ class HistoryView extends StatelessWidget {
|
||||||
: Column(children: <Widget>[
|
: Column(children: <Widget>[
|
||||||
Column(
|
Column(
|
||||||
children: duniterIndexer.transBC!.map((repository) {
|
children: duniterIndexer.transBC!.map((repository) {
|
||||||
final answer = computeHistoryView(repository);
|
final answer = computeHistoryView(repository, address);
|
||||||
pastDelimiters.add(answer['dateDelimiter']);
|
pastDelimiters.add(answer['dateDelimiter']);
|
||||||
|
|
||||||
bool isMigrationTime = false;
|
bool isMigrationTime = false;
|
||||||
|
@ -64,8 +71,6 @@ class HistoryView extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// if ((countsDelimiter[answer['dateDelimiter']] ?? 0) >= 1)
|
|
||||||
|
|
||||||
if (pastDelimiters.length == 1 ||
|
if (pastDelimiters.length == 1 ||
|
||||||
pastDelimiters.length >= 2 &&
|
pastDelimiters.length >= 2 &&
|
||||||
!(pastDelimiters[pastDelimiters.length - 2] ==
|
!(pastDelimiters[pastDelimiters.length - 2] ==
|
||||||
|
@ -91,12 +96,56 @@ class HistoryView extends StatelessWidget {
|
||||||
]);
|
]);
|
||||||
}).toList()),
|
}).toList()),
|
||||||
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
||||||
Row(
|
const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: const <Widget>[
|
children: <Widget>[
|
||||||
CircularProgressIndicator(),
|
CircularProgressIndicator(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (!duniterIndexer.pageInfo!['hasNextPage'] &&
|
||||||
|
sub.oldOwnerKeys[address]?[0] != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => Navigator.push(
|
||||||
|
context,
|
||||||
|
PageNoTransit(builder: (context) {
|
||||||
|
return WalletViewScreen(
|
||||||
|
address: sub.oldOwnerKeys[address]![0],
|
||||||
|
username: '',
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.account_circle,
|
||||||
|
size: 40,
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 40),
|
||||||
|
Column(children: [
|
||||||
|
Text(
|
||||||
|
'Identité migré:'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 25,
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Ancienne adresse: ${getShortPubkey(sub.oldOwnerKeys[address]![0])}')
|
||||||
|
]),
|
||||||
|
const SizedBox(width: 40),
|
||||||
|
const Icon(
|
||||||
|
Icons.account_circle,
|
||||||
|
size: 40,
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
if (!duniterIndexer.pageInfo!['hasNextPage'])
|
if (!duniterIndexer.pageInfo!['hasNextPage'])
|
||||||
Column(
|
Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -109,4 +158,4 @@ class HistoryView extends StatelessWidget {
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
import 'package:gecko/providers/duniter_indexer.dart';
|
import 'package:gecko/providers/duniter_indexer.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
@ -22,6 +23,8 @@ class IdentityStatus extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
|
||||||
|
final walletData = walletBox.get(address) ?? WalletData(address: address);
|
||||||
|
|
||||||
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: sub.idtyStatus(address),
|
future: sub.idtyStatus(address),
|
||||||
|
@ -30,14 +33,20 @@ class IdentityStatus extends StatelessWidget {
|
||||||
duniterIndexer.idtyStatusCache[address] = snapshot.data.toString();
|
duniterIndexer.idtyStatusCache[address] = snapshot.data.toString();
|
||||||
switch (snapshot.data.toString()) {
|
switch (snapshot.data.toString()) {
|
||||||
case 'noid':
|
case 'noid':
|
||||||
|
walletData.isMember = false;
|
||||||
|
walletBox.put(address, walletData);
|
||||||
{
|
{
|
||||||
return showText('noIdentity'.tr());
|
return showText('noIdentity'.tr());
|
||||||
}
|
}
|
||||||
case 'Created':
|
case 'Created':
|
||||||
|
walletData.isMember = false;
|
||||||
|
walletBox.put(address, walletData);
|
||||||
{
|
{
|
||||||
return showText('identityCreated'.tr());
|
return showText('identityCreated'.tr());
|
||||||
}
|
}
|
||||||
case 'ConfirmedByOwner':
|
case 'ConfirmedByOwner':
|
||||||
|
walletData.isMember = false;
|
||||||
|
walletBox.put(address, walletData);
|
||||||
{
|
{
|
||||||
return isOwner
|
return isOwner
|
||||||
? showText('identityConfirmed'.tr())
|
? showText('identityConfirmed'.tr())
|
||||||
|
@ -49,17 +58,21 @@ class IdentityStatus extends StatelessWidget {
|
||||||
fontStyle: FontStyle.italic);
|
fontStyle: FontStyle.italic);
|
||||||
}
|
}
|
||||||
case 'Validated':
|
case 'Validated':
|
||||||
|
walletData.isMember = true;
|
||||||
|
walletBox.put(address, walletData);
|
||||||
{
|
{
|
||||||
return isOwner
|
return isOwner
|
||||||
? showText('memberValidated'.tr(), 18, true)
|
? showText('memberValidated'.tr(), 18, true)
|
||||||
: NameByAddress(
|
: NameByAddress(
|
||||||
wallet: WalletData(address: address),
|
wallet: WalletData(address: address),
|
||||||
size: 20,
|
size: 24,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
fontStyle: FontStyle.normal);
|
fontStyle: FontStyle.normal);
|
||||||
}
|
}
|
||||||
case 'expired':
|
case 'expired':
|
||||||
|
walletData.isMember = false;
|
||||||
|
walletBox.put(address, walletData);
|
||||||
{
|
{
|
||||||
return showText('identityExpired'.tr());
|
return showText('identityExpired'.tr());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,431 @@
|
||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
|
import 'package:gecko/providers/my_wallets.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/providers/wallet_options.dart';
|
||||||
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
|
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
||||||
|
import 'package:gecko/screens/transaction_in_progress.dart';
|
||||||
|
import 'package:gecko/widgets/balance.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
void paymentPopup(BuildContext context, String toAddress, String username) {
|
||||||
|
final walletViewProvider =
|
||||||
|
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||||
|
final myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
|
|
||||||
|
double fees = 0;
|
||||||
|
const double shapeSize = 20;
|
||||||
|
var defaultWallet = myWalletProvider.getDefaultWallet();
|
||||||
|
bool canValidate = false;
|
||||||
|
final amountFocus = FocusNode();
|
||||||
|
final dropdownKey = GlobalKey();
|
||||||
|
|
||||||
|
Future executeTransfert() async {
|
||||||
|
String? pin;
|
||||||
|
if (myWalletProvider.pinCode == '') {
|
||||||
|
pin = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (homeContext) {
|
||||||
|
return UnlockingWallet(wallet: defaultWallet);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
log.d(pin);
|
||||||
|
if (pin != null || myWalletProvider.pinCode != '') {
|
||||||
|
// Payment workflow !
|
||||||
|
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
|
final acc = sub.getCurrentWallet();
|
||||||
|
log.d(
|
||||||
|
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin");
|
||||||
|
sub.pay(
|
||||||
|
fromAddress: acc.address!,
|
||||||
|
destAddress: toAddress,
|
||||||
|
amount: double.parse(walletViewProvider.payAmount.text),
|
||||||
|
password: pin ?? myWalletProvider.pinCode);
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
return const TransactionInProgress();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
myWalletProvider.readAllWallets();
|
||||||
|
log.d(myWalletProvider.listWallets);
|
||||||
|
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topRight: Radius.circular(shapeSize),
|
||||||
|
topLeft: Radius.circular(shapeSize),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isScrollControlled: true,
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
final walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
|
|
||||||
|
return StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
|
if (walletViewProvider.payAmount.text != '' &&
|
||||||
|
(double.parse(walletViewProvider.payAmount.text) +
|
||||||
|
2 / balanceRatio) <=
|
||||||
|
(walletOptions.balanceCache[defaultWallet.address] ?? 0) &&
|
||||||
|
toAddress != defaultWallet.address) {
|
||||||
|
if ((walletOptions.balanceCache[toAddress] == 0 ||
|
||||||
|
walletOptions.balanceCache[toAddress] == null) &&
|
||||||
|
double.parse(walletViewProvider.payAmount.text) <
|
||||||
|
5 / balanceRatio) {
|
||||||
|
canValidate = false;
|
||||||
|
} else {
|
||||||
|
canValidate = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
canValidate = false;
|
||||||
|
}
|
||||||
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||||
|
child: Container(
|
||||||
|
height: 420,
|
||||||
|
decoration: const ShapeDecoration(
|
||||||
|
color: Color(0xffffeed1),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topRight: Radius.circular(shapeSize),
|
||||||
|
topLeft: Radius.circular(shapeSize),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 24, bottom: 0, left: 24, right: 24),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'executeATransfer'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 26, fontWeight: FontWeight.w700),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
iconSize: 40,
|
||||||
|
icon: const Icon(Icons.cancel_outlined),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Text(
|
||||||
|
'from'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey[600]),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
|
// TODO: about keyboard dismiss issue, should try this: https://stackoverflow.com/a/76352647/8301867
|
||||||
|
return DropdownButton(
|
||||||
|
dropdownColor: const Color(0xffffeed1),
|
||||||
|
elevation: 12,
|
||||||
|
key: dropdownKey,
|
||||||
|
value: defaultWallet,
|
||||||
|
// onTap: () async {
|
||||||
|
// await Future.delayed(const Duration(milliseconds: 10));
|
||||||
|
// amountFocus.requestFocus();
|
||||||
|
// },
|
||||||
|
selectedItemBuilder: (_) {
|
||||||
|
return myWalletProvider.listWallets
|
||||||
|
.map((WalletData wallet) {
|
||||||
|
return Container(
|
||||||
|
width: 408,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.blueAccent.shade200,
|
||||||
|
width: 2),
|
||||||
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.circular(10.0)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Row(children: [
|
||||||
|
Text(g1WalletsBox
|
||||||
|
.get(wallet.address)
|
||||||
|
?.username ??
|
||||||
|
wallet.name!),
|
||||||
|
const Spacer(),
|
||||||
|
Balance(address: wallet.address, size: 20),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
},
|
||||||
|
onChanged: (WalletData? newSelectedWallet) async {
|
||||||
|
defaultWallet = newSelectedWallet!;
|
||||||
|
await sub.setCurrentWallet(newSelectedWallet);
|
||||||
|
sub.reload();
|
||||||
|
amountFocus.requestFocus();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
items: myWalletProvider.listWallets
|
||||||
|
.map((WalletData wallet) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
value: wallet,
|
||||||
|
child: Container(
|
||||||
|
color: const Color(0xffffeed1),
|
||||||
|
width: 408,
|
||||||
|
height: 80,
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Row(children: [
|
||||||
|
Text(g1WalletsBox
|
||||||
|
.get(wallet.address)
|
||||||
|
?.username ??
|
||||||
|
wallet.name!),
|
||||||
|
const Spacer(),
|
||||||
|
Balance(address: wallet.address, size: 20),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'to'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey[600]),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
username == ''
|
||||||
|
? getShortPubkey(toAddress)
|
||||||
|
: username,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 21,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'amount'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey[600]),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
InkWell(
|
||||||
|
onTap: () => infoFeesPopup(context),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.info_outlined, color: orangeC),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Text(
|
||||||
|
'fees'.tr(
|
||||||
|
args: [fees.toString(), currencyName]),
|
||||||
|
style: const TextStyle(
|
||||||
|
color: orangeC,
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
TextField(
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
onEditingComplete: () async =>
|
||||||
|
canValidate ? await executeTransfert() : null,
|
||||||
|
key: keyAmountField,
|
||||||
|
controller: walletViewProvider.payAmount,
|
||||||
|
autofocus: true,
|
||||||
|
focusNode: amountFocus,
|
||||||
|
maxLines: 1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
keyboardType: const TextInputType.numberWithOptions(
|
||||||
|
decimal: true),
|
||||||
|
onChanged: (_) async {
|
||||||
|
fees = await sub.txFees(
|
||||||
|
defaultWallet.address,
|
||||||
|
toAddress,
|
||||||
|
double.parse(
|
||||||
|
walletViewProvider.payAmount.text == ''
|
||||||
|
? '0'
|
||||||
|
: walletViewProvider.payAmount.text));
|
||||||
|
log.d(fees);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
inputFormatters: <TextInputFormatter>[
|
||||||
|
FilteringTextInputFormatter.deny(',',
|
||||||
|
replacementString: '.'),
|
||||||
|
FilteringTextInputFormatter.allow(
|
||||||
|
RegExp(r'(^\d+\.?\d{0,2})')),
|
||||||
|
],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '0.00',
|
||||||
|
suffix: Text(isUdUnit
|
||||||
|
? 'ud'.tr(args: [''])
|
||||||
|
: currencyName), // udUnitDisplay(40),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.transparent,
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: Colors.grey[500]!, width: 2),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.all(20),
|
||||||
|
),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 35,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 60,
|
||||||
|
child: ElevatedButton(
|
||||||
|
key: keyConfirmPayment,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.white, elevation: 4,
|
||||||
|
backgroundColor: orangeC, // foreground
|
||||||
|
),
|
||||||
|
onPressed: canValidate
|
||||||
|
? () async => await executeTransfert()
|
||||||
|
: null,
|
||||||
|
child: Text(
|
||||||
|
'executeTheTransfer'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}).then((value) => walletViewProvider.payAmount.text = '');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> infoFeesPopup(BuildContext context) async {
|
||||||
|
return showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: true,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.info_outlined, color: orangeC, size: 40),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Text(
|
||||||
|
'feesExplanation'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Text(
|
||||||
|
'feesExplanationDetails'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w300),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async => await _launchUrl('https://duniter.org'),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
bottom: 2,
|
||||||
|
),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
width: 1,
|
||||||
|
))),
|
||||||
|
child: Text(
|
||||||
|
'moreInfo'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
color: Colors.blueAccent,
|
||||||
|
// decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
key: keyInfoPopup,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
'gotit'.tr(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 21,
|
||||||
|
color: Color(0xffD80000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _launchUrl(String url) async {
|
||||||
|
if (!await launchUrl(Uri.parse(url))) {
|
||||||
|
throw Exception('Could not launch $url');
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,7 +75,6 @@ class SearchIdentityQuery extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchProvider.resultLenght = identities.length;
|
searchProvider.resultLenght = identities.length;
|
||||||
// TODO: Find a way to reload a provider here, in Widget build... riverpod refacto needed...
|
|
||||||
|
|
||||||
double avatarSize = 55;
|
double avatarSize = 55;
|
||||||
return Expanded(
|
return Expanded(
|
||||||
|
@ -125,7 +124,7 @@ class SearchIdentityQuery extends StatelessWidget {
|
||||||
walletsProfiles.address = profile['pubkey'];
|
walletsProfiles.address = profile['pubkey'];
|
||||||
return WalletViewScreen(
|
return WalletViewScreen(
|
||||||
address: profile['pubkey'],
|
address: profile['pubkey'],
|
||||||
username: name,
|
username: profile['name'] ?? '',
|
||||||
avatar:
|
avatar:
|
||||||
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
||||||
);
|
);
|
||||||
|
|
|
@ -100,8 +100,7 @@ class SearchResult extends StatelessWidget {
|
||||||
walletsProfilesClass.address = g1Wallet.address;
|
walletsProfilesClass.address = g1Wallet.address;
|
||||||
return WalletViewScreen(
|
return WalletViewScreen(
|
||||||
address: g1Wallet.address,
|
address: g1Wallet.address,
|
||||||
username:
|
username: g1WalletsBox.get(g1Wallet)!.username ?? '',
|
||||||
duniterIndexer.walletNameIndexer[g1Wallet.address] ?? '',
|
|
||||||
avatar: g1WalletsBox.get(g1Wallet.address)?.avatar,
|
avatar: g1WalletsBox.get(g1Wallet.address)?.avatar,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|
578
pubspec.lock
578
pubspec.lock
File diff suppressed because it is too large
Load Diff
13
pubspec.yaml
13
pubspec.yaml
|
@ -5,7 +5,7 @@ description: Pay with G1.
|
||||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
version: 0.1.0+56
|
version: 0.1.1+58
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.12.0 <3.0.0'
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
@ -34,8 +34,8 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/insinfo/qr.flutter.git
|
url: https://github.com/insinfo/qr.flutter.git
|
||||||
ref: master
|
ref: master
|
||||||
responsive_framework: ^0.2.0
|
responsive_framework: 0.2.0
|
||||||
sentry_flutter: ^6.18.0
|
sentry_flutter: ^7.4.1
|
||||||
shared_preferences: ^2.0.7
|
shared_preferences: ^2.0.7
|
||||||
truncate: ^3.0.1
|
truncate: ^3.0.1
|
||||||
unorm_dart: ^0.2.0
|
unorm_dart: ^0.2.0
|
||||||
|
@ -49,7 +49,7 @@ dependencies:
|
||||||
url: https://github.com/poka-IT/sdk.git
|
url: https://github.com/poka-IT/sdk.git
|
||||||
# ref: gecko-fixes-2
|
# ref: gecko-fixes-2
|
||||||
ref: ff98a117e86060a91113107f31355a17ccfb346c
|
ref: ff98a117e86060a91113107f31355a17ccfb346c
|
||||||
dots_indicator: ^2.1.0
|
dots_indicator: ^3.0.0
|
||||||
connectivity_plus: ^3.0.2
|
connectivity_plus: ^3.0.2
|
||||||
image_cropper: ^3.0.0
|
image_cropper: ^3.0.0
|
||||||
easy_localization: ^3.0.1
|
easy_localization: ^3.0.1
|
||||||
|
@ -64,13 +64,14 @@ dependencies:
|
||||||
graphql: ^5.1.1
|
graphql: ^5.1.1
|
||||||
hive_generator: ^2.0.0
|
hive_generator: ^2.0.0
|
||||||
riverpod: ^2.1.1
|
riverpod: ^2.1.1
|
||||||
tutorial_coach_mark: ^1.2.4
|
tutorial_coach_mark: ^1.2.8
|
||||||
confetti: ^0.7.0
|
confetti: ^0.7.0
|
||||||
|
url_launcher: ^6.1.11
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
# flutter_launcher_icons: ^0.9.2
|
# flutter_launcher_icons: ^0.9.2
|
||||||
# flutter_launcher_icons_maker: ^^0.10.2
|
# flutter_launcher_icons_maker: ^^0.10.2
|
||||||
flutter_launcher_icons: ^0.12.0
|
flutter_launcher_icons: ^0.13.0
|
||||||
icons_launcher: ^2.0.6
|
icons_launcher: ^2.0.6
|
||||||
build_runner: ^2.1.2
|
build_runner: ^2.1.2
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue