Merge branch 'dev'
This commit is contained in:
commit
6b42aab079
|
@ -26,6 +26,6 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register("clean", Delete) {
|
||||
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:",
|
||||
"rememberPassword": "Keep this code in memory for 15 minutes",
|
||||
"myRootWallet": "My root wallet",
|
||||
"currentWallet": "My current chest",
|
||||
"currentWallet": "My current wallet",
|
||||
"wallet": "Wallet",
|
||||
"displayMnemonic": "Display my mnemonic sentence",
|
||||
"changePassword": "Change my password",
|
||||
|
@ -202,7 +202,7 @@
|
|||
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
||||
"received": "Received",
|
||||
"sent": "Sent",
|
||||
"createIdentity": "Create a new \nidentity",
|
||||
"createIdentity": "Create a new\nidentity",
|
||||
"memberAccountOf": "Account of {}",
|
||||
"pasteAddress": "Paste address from\nclipboard",
|
||||
"historyStart": "Beginning of history",
|
||||
|
@ -217,5 +217,13 @@
|
|||
"youHaveToBeConnectedToValidateChest": "You have to be connected\nto validate your chest",
|
||||
"thisIdentityAlreadyExist": "This identity already exists",
|
||||
"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:",
|
||||
"rememberPassword": "Mantener en memoria mi contraseña durante 15 minutos",
|
||||
"myRootWallet": "Mi monedero principal",
|
||||
"currentWallet": "Mi cofre actual",
|
||||
"currentWallet": "Mi monedero actual",
|
||||
"wallet": "monedero",
|
||||
"displayMnemonic": "Mostrar mi frase de restauración",
|
||||
"changePassword": "Cambiar mi contraseña",
|
||||
|
@ -203,7 +203,7 @@
|
|||
"smithCantMigrateIdentity": "You can't migrate this identity while you're member of smith web",
|
||||
"received": "Received",
|
||||
"sent": "Sent",
|
||||
"createIdentity": "Create a new \nidentity",
|
||||
"createIdentity": "Create a new\nidentity",
|
||||
"memberAccountOf": "Account of {}",
|
||||
"pasteAddress": "Paste address from\nclipboard",
|
||||
"historyStart": "Beginning of history",
|
||||
|
@ -218,5 +218,13 @@
|
|||
"youHaveToBeConnectedToValidateChest": "Tienes que tener conneción\npara validar tu cofre",
|
||||
"thisIdentityAlreadyExist": "Esta identidad ya existe",
|
||||
"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",
|
||||
"thisIdentityAlreadyExist": "Cette identité existe déjà",
|
||||
"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:
|
||||
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
|
||||
ports:
|
||||
- "127.0.0.1:9615:9615"
|
||||
|
|
|
@ -25,7 +25,7 @@ void main() async {
|
|||
await tapKey(keyConfirmSearch);
|
||||
await waitFor(test5.shortAddress());
|
||||
await tapKey(keySearchResult(test5.address));
|
||||
await waitFor('certify'.tr());
|
||||
await waitFor('createIdentity'.tr());
|
||||
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 6), reverse: true);
|
||||
await waitFor('canRenewCertInX'.tr().substring(0, 8), reverse: true);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
@ -10,6 +11,7 @@ void main() async {
|
|||
// await dotenv.load();
|
||||
|
||||
testWidgets('Gecko complete', (testerLoc) async {
|
||||
FlutterError.onError = ignoreOverflowErrors;
|
||||
// Share WidgetTester to test provider
|
||||
tester = testerLoc;
|
||||
|
||||
|
@ -50,8 +52,10 @@ Future payTest2() async {
|
|||
await enterText(keyAmountField, '12.14');
|
||||
await tapKey(keyConfirmPayment);
|
||||
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 waitFor('12.14');
|
||||
spawnBlock(duration: 500);
|
||||
|
@ -63,8 +67,10 @@ Future certifyTest5() async {
|
|||
// Create identity with Test1 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
||||
spawnBlock(duration: 1000);
|
||||
await tester.pump(const Duration(seconds: 2));
|
||||
await waitFor('sending'.tr(),
|
||||
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('identityCreated'.tr());
|
||||
|
||||
|
@ -76,8 +82,10 @@ Future certifyTest5() async {
|
|||
await tapKey(keyConfirmIdentity);
|
||||
await enterText(keyEnterIdentityUsername, test5.name);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
||||
spawnBlock(duration: 1000);
|
||||
await tester.pump(const Duration(seconds: 2));
|
||||
await waitFor('sending'.tr(),
|
||||
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('identityConfirmed'.tr());
|
||||
humanRead(2);
|
||||
|
@ -102,8 +110,10 @@ Future certifyTest5() async {
|
|||
// Certify with test2 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
||||
spawnBlock(duration: 1000);
|
||||
await tester.pump(const Duration(seconds: 2));
|
||||
await waitFor('sending'.tr(),
|
||||
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('2');
|
||||
|
||||
|
@ -117,10 +127,12 @@ Future certifyTest5() async {
|
|||
// Certify with test3 account
|
||||
await tapKey(keyCertify);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 500);
|
||||
await waitFor('extrinsicValidated'.tr(), timeout: const Duration(seconds: 1));
|
||||
spawnBlock(duration: 1000);
|
||||
await tester.pump(const Duration(seconds: 2));
|
||||
await waitFor('sending'.tr(),
|
||||
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||
await tapKey(keyCloseTransactionScreen);
|
||||
await waitFor('mustWaitXBeforeCertify'.substring(0, 12));
|
||||
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 8));
|
||||
|
||||
// Check if test5 is member
|
||||
await tapKey(keyAppBarChest, duration: 300);
|
||||
|
|
|
@ -35,12 +35,15 @@ void main() async {
|
|||
await waitFor('memberValidated'.tr(), exactMatch: true);
|
||||
|
||||
// Revoke test5
|
||||
await tapKey(keyManageMembership, duration: 1000);
|
||||
await goBack();
|
||||
await tapKey(keyOpenWallet(test5.address));
|
||||
await tapKey(keyManageMembership, duration: 100);
|
||||
await tapKey(keyRevokeIdty);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 2000);
|
||||
await waitFor('extrinsicValidated'.tr().substring(3),
|
||||
timeout: const Duration(seconds: 4));
|
||||
spawnBlock(duration: 1000);
|
||||
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 waitFor('noIdentity'.tr(), exactMatch: true);
|
||||
await sleep();
|
||||
|
@ -48,9 +51,8 @@ void main() async {
|
|||
// Check test1 cannot be revoked
|
||||
await goBack();
|
||||
await tapKey(keyAddDerivation);
|
||||
await tapKey(keyOpenWallet(test1.address), duration: 500);
|
||||
await tapKey(keyManageMembership, duration: 1000);
|
||||
await tapKey(keyOpenWallet(test1.address), duration: 300);
|
||||
await tapKey(keyManageMembership, duration: 300);
|
||||
await waitFor('youCannotRevokeThisIdentity'.tr().substring(0, 15));
|
||||
|
||||
}, timeout: testTimeout());
|
||||
}
|
||||
|
|
|
@ -42,8 +42,10 @@ void main() async {
|
|||
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
||||
await waitForButtonEnabled(keyConfirm);
|
||||
await tapKey(keyConfirm);
|
||||
spawnBlock(duration: 2000);
|
||||
await waitFor('extrinsicValidated'.tr());
|
||||
spawnBlock(duration: 1000);
|
||||
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(keyOpenWallet(test6.address), duration: 300);
|
||||
|
|
|
@ -66,11 +66,15 @@ Future restoreChest() async {
|
|||
await enterText(keyPinForm, 'AAAAA', 0);
|
||||
|
||||
// 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
|
||||
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
|
||||
await waitFor('ĞD');
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ Future goBack() async {
|
|||
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
||||
log.d('INTEGRATION TEST: Go back');
|
||||
navigator.pop();
|
||||
await tester.pump();
|
||||
await tester.pumpAndSettle();
|
||||
humanRead();
|
||||
}
|
||||
|
||||
|
@ -129,8 +129,10 @@ Future enterText(Key fieldKey, String textIn, [int duration = 200]) async {
|
|||
|
||||
Future<void> waitFor(String text,
|
||||
{Duration timeout = const Duration(seconds: 5),
|
||||
bool reverse = false,
|
||||
bool exactMatch = false}) async {
|
||||
final bool reverse = false,
|
||||
final bool exactMatch = false,
|
||||
final bool settle = true,
|
||||
final int pumpDuration = 100}) async {
|
||||
final end = DateTime.now().add(timeout);
|
||||
|
||||
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"');
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
if (settle) {
|
||||
await tester.pumpAndSettle(Duration(milliseconds: pumpDuration));
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
||||
humanRead();
|
||||
|
@ -317,6 +321,32 @@ String getWidgetText(Key key) {
|
|||
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 {
|
||||
String address;
|
||||
String name;
|
||||
|
|
|
@ -11,6 +11,7 @@ const keyAppBarChest = Key('keyAppBarChest');
|
|||
|
||||
// Home
|
||||
const keyParameters = Key('keyParameters');
|
||||
const keyDebugScreen = Key('keyDebugScreen');
|
||||
const keyContacts = Key('keyContacts');
|
||||
const keyDrawerMenu = Key('keyDrawerMenu');
|
||||
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
||||
|
@ -23,6 +24,7 @@ const keyImportG1v1 = Key('keyImportG1v1');
|
|||
const keyChangeChest = Key('keyChangeChest');
|
||||
const keyListWallets = Key('keyListWallets');
|
||||
const keyAddDerivation = Key('keyAddDerivation');
|
||||
final keyDragAndDrop = GlobalKey(debugLabel: 'keyDragAndDrop');
|
||||
|
||||
// Wallet options
|
||||
const keyCopyAddress = Key('keyCopyAddress');
|
||||
|
|
|
@ -253,59 +253,52 @@ Future<QueryResult> _execQuery(
|
|||
return await client.query(options);
|
||||
}
|
||||
|
||||
Map computeHistoryView(repository) {
|
||||
bool isTody = false;
|
||||
bool isYesterday = false;
|
||||
bool isThisWeek = false;
|
||||
bool isMigrationTime = false;
|
||||
String? dateDelimiter;
|
||||
DateTime now = DateTime.now();
|
||||
Map computeHistoryView(repository, String address) {
|
||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
|
||||
late double amount;
|
||||
late String finalAmount;
|
||||
DateTime date = repository[0];
|
||||
String dateForm;
|
||||
bool isDelimiter = true;
|
||||
final DateTime date = repository[0];
|
||||
|
||||
if ({4, 10, 11, 12}.contains(date.month)) {
|
||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}";
|
||||
} else if ({1, 2, 7, 9}.contains(date.month)) {
|
||||
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}";
|
||||
} else {
|
||||
dateForm = "${date.day} ${monthsInYear[date.month]}";
|
||||
final dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, {
|
||||
1,
|
||||
2,
|
||||
7,
|
||||
9
|
||||
}.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);
|
||||
final todayDate = DateTime(now.year, now.month, now.day);
|
||||
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
|
||||
String getDateDelimiter() {
|
||||
DateTime now = DateTime.now();
|
||||
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) {
|
||||
dateDelimiter = "today".tr();
|
||||
isTody = true;
|
||||
} else if (transactionDate == yesterdayDate && !isYesterday) {
|
||||
dateDelimiter = "yesterday".tr();
|
||||
isYesterday = true;
|
||||
} else if (weekNumber(date) == weekNumber(now) &&
|
||||
date.year == now.year &&
|
||||
transactionDate != yesterdayDate &&
|
||||
transactionDate != todayDate &&
|
||||
!isThisWeek) {
|
||||
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];
|
||||
if (transactionDate == todayDate) {
|
||||
return "today".tr();
|
||||
} else if (transactionDate == yesterdayDate) {
|
||||
return "yesterday".tr();
|
||||
} else if (isSameWeek && !isTodayOrYesterday) {
|
||||
return "thisWeek".tr();
|
||||
} else if (!isSameWeek && !isTodayOrYesterday) {
|
||||
if (transactionDate.year == now.year) {
|
||||
return monthsInYear[transactionDate.month]!;
|
||||
} else {
|
||||
return "${monthsInYear[transactionDate.month]} ${transactionDate.year}";
|
||||
}
|
||||
} else {
|
||||
dateDelimiter = "${monthsInYear[date.month]} ${date.year}";
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
isDelimiter = false;
|
||||
}
|
||||
|
||||
final dateDelimiter = getDateDelimiter();
|
||||
|
||||
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
||||
|
||||
if (isUdUnit) {
|
||||
|
@ -315,17 +308,19 @@ Map computeHistoryView(repository) {
|
|||
finalAmount = '$amount $currencyName';
|
||||
}
|
||||
|
||||
if (startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0) {
|
||||
isMigrationTime = true;
|
||||
} else {
|
||||
isMigrationTime = false;
|
||||
}
|
||||
bool isMigrationTime =
|
||||
startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0;
|
||||
|
||||
//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 {
|
||||
'finalAmount': finalAmount,
|
||||
'isMigrationTime': isMigrationTime,
|
||||
'dateDelimiter': dateDelimiter ?? '',
|
||||
'isDelimiter': isDelimiter,
|
||||
'dateDelimiter': dateDelimiter,
|
||||
'dateForm': dateForm,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
// NewWallet generatedWallet;
|
||||
durt.NewWallet? actualWallet;
|
||||
|
||||
FocusNode walletNameFocus = FocusNode();
|
||||
final walletNameFocus = FocusNode();
|
||||
Color? askedWordColor = Colors.black;
|
||||
bool isAskedWordValid = false;
|
||||
int scanedValidWalletNumber = -1;
|
||||
|
@ -33,8 +33,8 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
String? generatedMnemonic;
|
||||
bool walletIsGenerated = true;
|
||||
|
||||
TextEditingController mnemonicController = TextEditingController();
|
||||
TextEditingController pin = TextEditingController();
|
||||
final mnemonicController = TextEditingController();
|
||||
final pin = TextEditingController();
|
||||
|
||||
// Import wallet
|
||||
TextEditingController cesiumID = TextEditingController();
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_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/my_wallets.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
|
@ -46,6 +47,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
bool isCesiumAddresLoading = false;
|
||||
late int udValue;
|
||||
Map<String, List<int>> certsCounterCache = {};
|
||||
Map<String, List> oldOwnerKeys = {};
|
||||
|
||||
/////////////////////////////////////
|
||||
////////// 1: API METHODS ///////////
|
||||
|
@ -91,7 +93,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
try {
|
||||
return await sdk.webView!.evalJavascript('api.query.$call');
|
||||
} catch (e) {
|
||||
log.i("catched _getStorage error");
|
||||
log.e("_getStorage error: $e");
|
||||
return Future(() {});
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +200,16 @@ class SubstrateSdk with ChangeNotifier {
|
|||
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 {
|
||||
if (!nodeConnected) {
|
||||
return {
|
||||
|
@ -219,6 +231,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
await _getStorage('universalDividend.pastReevals()');
|
||||
|
||||
// Compute amount of claimable UDs
|
||||
currentUdIndex = await getCurrentUdIndex();
|
||||
final int unclaimedUds = _computeUnclaimUds(
|
||||
idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals);
|
||||
|
||||
|
@ -264,6 +277,9 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
// log.d(
|
||||
// "debug computeUnclaimUds: ${pastReevals.reversed} --- $firstEligibleUd --- $currentUdIndex");
|
||||
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
|
@ -330,6 +346,29 @@ class SubstrateSdk with ChangeNotifier {
|
|||
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 {
|
||||
// final walletOptions =
|
||||
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||
|
@ -560,10 +599,14 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
notifyListeners();
|
||||
});
|
||||
currentUdIndex =
|
||||
int.parse(await _getStorage('universalDividend.currentUdIndex()'));
|
||||
currentUdIndex = await getCurrentUdIndex();
|
||||
await getBalanceRatio();
|
||||
|
||||
// Currency parameters
|
||||
await initCurrencyParameters();
|
||||
// Indexer Blockchain start
|
||||
getBlockStart();
|
||||
|
||||
notifyListeners();
|
||||
homeProvider.changeMessage(
|
||||
"wellConnectedToNode"
|
||||
|
@ -594,6 +637,10 @@ class SubstrateSdk with ChangeNotifier {
|
|||
return node;
|
||||
}
|
||||
|
||||
Future<int> getCurrentUdIndex() async {
|
||||
return int.parse(await _getStorage('universalDividend.currentUdIndex()'));
|
||||
}
|
||||
|
||||
NetworkParams getDuniterCustomEndpoint() {
|
||||
final nodeParams = NetworkParams();
|
||||
nodeParams.name = currencyName;
|
||||
|
@ -911,6 +958,9 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
// log.d('debug: ${currencyParameters['minCertForMembership']}');
|
||||
|
||||
log.d(
|
||||
"debug toCert: ${toCerts[0]} --- ${currencyParameters['minCertForMembership']!} --- $toIdtyStatus");
|
||||
|
||||
if (toIdtyStatus == 'noid') {
|
||||
txInfo = TxInfoData(
|
||||
'identity',
|
||||
|
|
|
@ -10,7 +10,6 @@ import 'package:jdenticon_dart/jdenticon_dart.dart';
|
|||
import 'package:permission_handler/permission_handler.dart';
|
||||
// import 'package:qrscan/qrscan.dart' as scanner;
|
||||
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||
import 'package:confetti/confetti.dart';
|
||||
|
||||
class WalletsProfilesProvider with ChangeNotifier {
|
||||
WalletsProfilesProvider(this.address);
|
||||
|
@ -24,8 +23,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
TextEditingController payAmount = TextEditingController();
|
||||
TextEditingController payComment = TextEditingController();
|
||||
num? _balance;
|
||||
final centerController =
|
||||
ConfettiController(duration: const Duration(milliseconds: 300));
|
||||
|
||||
Future<String> scan(context) async {
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
|
@ -145,7 +142,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
snackMessage(homeContext,
|
||||
message: 'removedFromcontacts'.tr(), duration: 4);
|
||||
} else {
|
||||
centerController.play();
|
||||
await contactsBox.put(profile.address, profile);
|
||||
// drawStar(Size(50, 50));
|
||||
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:flutter/material.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/header_profile.dart';
|
||||
import 'package:gecko/widgets/history_query.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
||||
ActivityScreen({required this.address, required this.avatar, this.username})
|
||||
class ActivityScreen extends StatefulWidget {
|
||||
const ActivityScreen(
|
||||
{required this.address, required this.avatar, this.username})
|
||||
: super(key: keyActivityScreen);
|
||||
final String address;
|
||||
final String? username;
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: true);
|
||||
|
@ -45,8 +59,8 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
),
|
||||
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||
body: Column(children: <Widget>[
|
||||
HeaderProfile(address: address, username: username),
|
||||
HistoryQuery(address: address),
|
||||
HeaderProfile(address: widget.address, username: widget.username),
|
||||
HistoryQuery(address: widget.address),
|
||||
])),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class CertificationsScreen extends StatelessWidget {
|
|||
toolbarHeight: 60 * ratio,
|
||||
title: SizedBox(
|
||||
height: 22,
|
||||
child: Text('Certifications de $username'),
|
||||
child: Text('certificationsOf'.tr(args: [username])),
|
||||
)),
|
||||
body: SafeArea(
|
||||
child: Accordion(
|
||||
|
@ -45,7 +45,10 @@ class CertificationsScreen extends StatelessWidget {
|
|||
headerBackgroundColor: yellowC,
|
||||
headerBackgroundColorOpened: orangeC,
|
||||
header: Row(children: [
|
||||
Text('received'.tr()),
|
||||
Text(
|
||||
'received'.tr(),
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
CertsCounter(address: address)
|
||||
]),
|
||||
|
@ -60,7 +63,10 @@ class CertificationsScreen extends StatelessWidget {
|
|||
headerBackgroundColor: yellowC,
|
||||
headerBackgroundColorOpened: orangeC,
|
||||
header: Row(children: [
|
||||
Text('sent'.tr()),
|
||||
Text(
|
||||
'sent'.tr(),
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
CertsCounter(address: address, isSent: true)
|
||||
]),
|
||||
|
|
|
@ -95,10 +95,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
var connectivityResult = await (Connectivity().checkConnectivity());
|
||||
if (connectivityResult != ConnectivityResult.none) {
|
||||
await sub.connectNode(context);
|
||||
// Currency parameters
|
||||
await sub.initCurrencyParameters();
|
||||
// Indexer Blockchain start
|
||||
getBlockStart();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -122,6 +118,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
isTall = true;
|
||||
ratio = 1.125;
|
||||
}
|
||||
|
||||
//TODO: finish to implement multiqueries
|
||||
|
||||
// final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
// sub.getBalanceMulti([
|
||||
// '5CQ8T4qpbYJq7uVsxGPQ5q2df7x3Wa4aRY6HUWMBYjfLZhnn',
|
||||
// '5Dq8xjvkmbz7q4g2LbZgyExD26VSCutfEc6n4W4AfQeVHZqz'
|
||||
// ]);
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
drawer: MainDrawer(isWalletsExists: isWalletsExists),
|
||||
|
|
|
@ -85,7 +85,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
}
|
||||
|
||||
if (myWalletProvider.listWallets.isEmpty) {
|
||||
return Column(children: const <Widget>[
|
||||
return const Column(children: <Widget>[
|
||||
Center(
|
||||
child: Text(
|
||||
'Veuillez générer votre premier portefeuille',
|
||||
|
|
|
@ -61,11 +61,11 @@ class ImportG1v1 extends StatelessWidget {
|
|||
// log.d(_certs.data);
|
||||
|
||||
if (status.data == null) {
|
||||
return Column(children: [
|
||||
const SizedBox(height: 80),
|
||||
return const Column(children: [
|
||||
SizedBox(height: 80),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: const [
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 35,
|
||||
width: 35,
|
||||
|
|
|
@ -93,9 +93,9 @@ class ManageMembership extends StatelessWidget {
|
|||
}),
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
child: const SizedBox(
|
||||
height: 60,
|
||||
child: Row(children: const <Widget>[
|
||||
child: Row(children: <Widget>[
|
||||
SizedBox(width: 16),
|
||||
Icon(Icons.change_circle_outlined, size: 35),
|
||||
SizedBox(width: 11.5),
|
||||
|
|
|
@ -47,12 +47,12 @@ class MigrateIdentityScreen extends StatelessWidget {
|
|||
);
|
||||
|
||||
if (walletsList.length < 2) {
|
||||
return Column(
|
||||
return const Column(
|
||||
children: [
|
||||
const SizedBox(height: 80),
|
||||
SizedBox(height: 80),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: const [
|
||||
children: [
|
||||
Text(
|
||||
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
|
||||
style: TextStyle(fontSize: 20),
|
||||
|
@ -78,20 +78,18 @@ class MigrateIdentityScreen extends StatelessWidget {
|
|||
fromAddress, selectedWallet.address),
|
||||
builder: (BuildContext context, AsyncSnapshot<List> status) {
|
||||
if (status.data == null) {
|
||||
return Column(children: [
|
||||
const SizedBox(height: 80),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: const [
|
||||
SizedBox(
|
||||
height: 35,
|
||||
width: 35,
|
||||
child: CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 4,
|
||||
),
|
||||
),
|
||||
]),
|
||||
return const Column(children: [
|
||||
SizedBox(height: 80),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
SizedBox(
|
||||
height: 35,
|
||||
width: 35,
|
||||
child: CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 4,
|
||||
),
|
||||
),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -136,7 +134,7 @@ class MigrateIdentityScreen extends StatelessWidget {
|
|||
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
||||
|
||||
return Column(children: <Widget>[
|
||||
Row(children: const []),
|
||||
const Row(children: []),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
SizedBox(
|
||||
|
|
|
@ -81,7 +81,7 @@ class ShowSeed extends StatelessWidget {
|
|||
),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: seed.data));
|
||||
ClipboardData(text: seed.data!));
|
||||
snackCopySeed(context);
|
||||
},
|
||||
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/screens/certifications.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/widgets/balance.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/commons/offline_info.dart';
|
||||
import 'package:gecko/widgets/idty_status.dart';
|
||||
|
@ -40,9 +40,8 @@ class WalletOptions extends StatelessWidget {
|
|||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(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(0, 20);
|
||||
|
||||
|
@ -146,7 +145,7 @@ class WalletOptions extends StatelessWidget {
|
|||
builder: (context, walletProvider, _) {
|
||||
return NameByAddress(
|
||||
wallet: wallet,
|
||||
size: 27,
|
||||
size: 29,
|
||||
color: Colors.black,
|
||||
fontWeight: wallet.isMember
|
||||
? FontWeight.w500
|
||||
|
@ -183,7 +182,7 @@ class WalletOptions extends StatelessWidget {
|
|||
]),
|
||||
SizedBox(height: isTall ? 5 : 0),
|
||||
Balance(
|
||||
address: walletProvider.address.text, size: 21),
|
||||
address: walletProvider.address.text, size: 24),
|
||||
const SizedBox(width: 30),
|
||||
InkWell(
|
||||
onTap: () => isWalletNameIndexed
|
||||
|
@ -245,6 +244,11 @@ class WalletOptions extends StatelessWidget {
|
|||
SizedBox(height: 30 * ratio),
|
||||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, walletProvider, _) {
|
||||
final defaultWallet =
|
||||
myWalletProvider.getDefaultWallet();
|
||||
walletProvider.isDefaultWallet =
|
||||
walletOptions.address.text ==
|
||||
defaultWallet.address;
|
||||
return Column(children: [
|
||||
confirmIdentityButton(walletProvider),
|
||||
pubkeyWidget(walletProvider, ctx),
|
||||
|
@ -278,7 +282,7 @@ class WalletOptions extends StatelessWidget {
|
|||
else
|
||||
const SizedBox(),
|
||||
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(
|
||||
BuildContext context,
|
||||
WalletOptionsProvider walletProvider,
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:flutter_markdown/flutter_markdown.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_data.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/models/wallet_data.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/unlocking_wallet.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/bottom_app_bar.dart';
|
||||
import 'package:gecko/widgets/commons/offline_info.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: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 {
|
||||
const WalletsHome({Key? key}) : super(key: key);
|
||||
|
@ -35,36 +33,8 @@ class WalletsHome extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _WalletsHomeState extends State<WalletsHome> {
|
||||
final safeKey = GlobalKey();
|
||||
// List<TargetFocus> targets = [];
|
||||
|
||||
@override
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -252,15 +222,14 @@ class _WalletsHomeState extends State<WalletsHome> {
|
|||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
||||
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
if (!isWalletsExists) {
|
||||
return const Text('');
|
||||
}
|
||||
|
||||
if (myWalletProvider.listWallets.isEmpty) {
|
||||
return Expanded(
|
||||
child: Column(children: const <Widget>[
|
||||
return const Expanded(
|
||||
child: Column(children: <Widget>[
|
||||
Center(
|
||||
child: Text(
|
||||
'Veuillez générer votre premier portefeuille',
|
||||
|
@ -286,13 +255,45 @@ class _WalletsHomeState extends State<WalletsHome> {
|
|||
} else {
|
||||
nTule = 2;
|
||||
}
|
||||
// Offset followDragAnchorStrategy(
|
||||
// Draggable<Object> d, BuildContext context, Offset point) {
|
||||
// return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0);
|
||||
// }
|
||||
|
||||
// showTutorial();
|
||||
// Future.delayed(const Duration(seconds: 1), showTutorial);
|
||||
final tutorialCoachMark = TutorialCoachMark(
|
||||
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>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
||||
|
@ -339,7 +340,11 @@ class _WalletsHomeState extends State<WalletsHome> {
|
|||
.getWalletDataByAddress(senderAddress);
|
||||
await sub.setCurrentWallet(walletData!);
|
||||
sub.reload();
|
||||
paymentPopup(context, repository.address);
|
||||
paymentPopup(
|
||||
context,
|
||||
repository.address,
|
||||
g1WalletsBox.get(repository.address)!.username ??
|
||||
repository.name!);
|
||||
},
|
||||
onMove: (details) {
|
||||
if (repository.address != myWalletProvider.lastFlyBy) {
|
||||
|
@ -370,97 +375,91 @@ class _WalletsHomeState extends State<WalletsHome> {
|
|||
),
|
||||
);
|
||||
},
|
||||
child: ClipOvalShadow(
|
||||
shadow: const Shadow(
|
||||
color: Colors.transparent,
|
||||
offset: Offset(0, 0),
|
||||
blurRadius: 5,
|
||||
),
|
||||
clipper: CustomClipperOval(),
|
||||
child: ClipRRect(
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(12)),
|
||||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
radius: 0.8,
|
||||
colors: [
|
||||
Color.fromARGB(255, 255, 255, 211),
|
||||
yellowC,
|
||||
],
|
||||
child: SizedBox(
|
||||
key: repository.number == 1
|
||||
? keyDragAndDrop
|
||||
: const Key('nothing'),
|
||||
child: ClipOvalShadow(
|
||||
shadow: const Shadow(
|
||||
color: Colors.transparent,
|
||||
offset: Offset(0, 0),
|
||||
blurRadius: 5,
|
||||
),
|
||||
clipper: CustomClipperOval(),
|
||||
child: ClipRRect(
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(12)),
|
||||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
radius: 0.8,
|
||||
colors: [
|
||||
Color.fromARGB(255, 255, 255, 211),
|
||||
yellowC,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
child:
|
||||
// SvgPicture.asset('assets/chopp-gecko2.png',
|
||||
// semanticsLabel: 'Gecko', height: 48),
|
||||
repository.imageCustomPath == null ||
|
||||
repository.imageCustomPath == ''
|
||||
? Image.asset(
|
||||
'assets/avatars/${repository.imageDefaultPath}',
|
||||
alignment: Alignment.bottomCenter,
|
||||
scale: 0.5,
|
||||
)
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.transparent,
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fitHeight,
|
||||
image: FileImage(
|
||||
File(repository
|
||||
.imageCustomPath!),
|
||||
child:
|
||||
// SvgPicture.asset('assets/chopp-gecko2.png',
|
||||
// semanticsLabel: 'Gecko', height: 48),
|
||||
repository.imageCustomPath == null ||
|
||||
repository.imageCustomPath == ''
|
||||
? Image.asset(
|
||||
'assets/avatars/${repository.imageDefaultPath}',
|
||||
alignment:
|
||||
Alignment.bottomCenter,
|
||||
scale: 0.5,
|
||||
)
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.transparent,
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fitHeight,
|
||||
image: FileImage(
|
||||
File(repository
|
||||
.imageCustomPath!),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
Stack(children: <Widget>[
|
||||
BalanceBuilder(
|
||||
address: repository.address,
|
||||
isDefault: repository.address ==
|
||||
defaultWallet.address),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(height: 7),
|
||||
Opacity(
|
||||
opacity: 0.7,
|
||||
child: Text(
|
||||
duniterIndexer.walletNameIndexer[
|
||||
repository.address] ??
|
||||
truncate(
|
||||
repository.name!, 20),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
)),
|
||||
Stack(children: <Widget>[
|
||||
BalanceBuilder(
|
||||
address: repository.address,
|
||||
isDefault: repository.address ==
|
||||
defaultWallet.address),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(height: 7),
|
||||
Opacity(
|
||||
opacity: 0.7,
|
||||
child: NameByAddress(
|
||||
wallet: repository,
|
||||
size: 20,
|
||||
color:
|
||||
defaultWallet.address ==
|
||||
repository.address
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
)
|
||||
// NameByAddress(
|
||||
// wallet: repository,
|
||||
// address: repository.address,
|
||||
// size: 20,
|
||||
// color: defaultWallet.address ==
|
||||
// repository.address
|
||||
// ? Colors.white
|
||||
// : Colors.black,
|
||||
// ),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: FontStyle.normal,
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -16,7 +16,7 @@ class OnboardingStepEleven extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final conffetiController =
|
||||
ConfettiController(duration: const Duration(milliseconds: 300));
|
||||
ConfettiController(duration: const Duration(milliseconds: 500));
|
||||
conffetiController.play();
|
||||
return WillPopScope(
|
||||
onWillPop: () {
|
||||
|
@ -55,16 +55,29 @@ class OnboardingStepEleven extends StatelessWidget {
|
|||
const SizedBox(height: 40),
|
||||
]),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
alignment: Alignment.topLeft,
|
||||
child: ConfettiWidget(
|
||||
confettiController: conffetiController,
|
||||
blastDirection: pi / 2,
|
||||
maxBlastForce: 5,
|
||||
blastDirection: pi * 0.1,
|
||||
maxBlastForce: 10,
|
||||
minBlastForce: 1,
|
||||
emissionFrequency: 0.01,
|
||||
numberOfParticles: 10,
|
||||
numberOfParticles: 7,
|
||||
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: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: generateWalletProvider.generatedMnemonic));
|
||||
text: generateWalletProvider.generatedMnemonic!));
|
||||
snackCopySeed(context);
|
||||
},
|
||||
child: Row(children: <Widget>[
|
||||
|
|
|
@ -16,8 +16,8 @@ class TemplateScreen extends StatelessWidget {
|
|||
height: 22,
|
||||
child: Text('Template screen'),
|
||||
)),
|
||||
body: SafeArea(
|
||||
child: Column(children: const <Widget>[
|
||||
body: const SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
SizedBox(height: 20),
|
||||
Text('data'),
|
||||
SizedBox(height: 20),
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:confetti/confetti.dart';
|
||||
import 'package:easy_localization/easy_localization.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/my_wallets.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/screens/activity.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/qrcode_fullscreen.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/header_profile.dart';
|
||||
import 'package:gecko/widgets/page_route_no_transition.dart';
|
||||
import 'package:gecko/widgets/payment_popup.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
||||
|
@ -53,7 +47,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
walletProfile.address = address;
|
||||
sub.setCurrentWallet(defaultWallet);
|
||||
|
||||
log.d('aaaaaaaaaaaaaaaaaaa: $username');
|
||||
log.d("username: $username");
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
|
@ -64,16 +58,6 @@ class WalletViewScreen extends StatelessWidget {
|
|||
actions: [
|
||||
Row(
|
||||
children: [
|
||||
ConfettiWidget(
|
||||
confettiController: walletProfile.centerController,
|
||||
blastDirection: pi / 2,
|
||||
maxBlastForce: 7,
|
||||
minBlastForce: 3,
|
||||
emissionFrequency: 0,
|
||||
numberOfParticles: 7,
|
||||
shouldLoop: false,
|
||||
gravity: 0.001,
|
||||
),
|
||||
Consumer<WalletsProfilesProvider>(
|
||||
builder: (context, walletProfile, _) {
|
||||
return IconButton(
|
||||
|
@ -360,8 +344,23 @@ class WalletViewScreen extends StatelessWidget {
|
|||
key: keyPay,
|
||||
splashColor: yellowC,
|
||||
onTap: sub.nodeConnected
|
||||
? () {
|
||||
paymentPopup(context, address);
|
||||
? () async {
|
||||
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,
|
||||
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(
|
||||
padding: const EdgeInsets.only(bottom: 5),
|
||||
child: Text(repository['name'],
|
||||
style: const TextStyle(fontSize: 20)),
|
||||
style: const TextStyle(fontSize: 22)),
|
||||
),
|
||||
subtitle: RichText(
|
||||
text: TextSpan(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
color: Colors.grey[700],
|
||||
),
|
||||
children: <TextSpan>[
|
||||
|
@ -60,9 +60,9 @@ class CertTile extends StatelessWidget {
|
|||
TextSpan(
|
||||
text: getShortPubkey(repository['address']),
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.grey[600],
|
||||
fontSize: 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -8,7 +8,7 @@ class BuildProgressBar extends StatelessWidget {
|
|||
required this.pagePosition,
|
||||
}) : super(key: key);
|
||||
|
||||
final double pagePosition;
|
||||
final int pagePosition;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -155,11 +155,14 @@ Future<void> infoPopup(BuildContext context, String title) async {
|
|||
children: [
|
||||
TextButton(
|
||||
key: keyInfoPopup,
|
||||
child: const Text(
|
||||
"D'accord",
|
||||
style: TextStyle(
|
||||
fontSize: 21,
|
||||
color: Color(0xffD80000),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Text(
|
||||
"gotit".tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 21,
|
||||
color: Color(0xffD80000),
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
|
|
|
@ -24,7 +24,7 @@ class InfoIntro extends StatelessWidget {
|
|||
final String assetName;
|
||||
final String buttonText;
|
||||
final Widget nextScreen;
|
||||
final double pagePosition;
|
||||
final int pagePosition;
|
||||
final bool isMd;
|
||||
final bool isFast;
|
||||
final double boxHeight;
|
||||
|
|
|
@ -24,11 +24,11 @@ class MainDrawer extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
|
||||
DrawerHeader(
|
||||
decoration: const BoxDecoration(
|
||||
const DrawerHeader(
|
||||
decoration: BoxDecoration(
|
||||
color: orangeC,
|
||||
),
|
||||
child: Column(children: const <Widget>[
|
||||
child: Column(children: <Widget>[
|
||||
SizedBox(height: 0),
|
||||
Image(
|
||||
image: AssetImage('assets/icon/gecko_final.png'),
|
||||
|
@ -64,7 +64,7 @@ class MainDrawer extends StatelessWidget {
|
|||
),
|
||||
if (kDebugMode)
|
||||
ListTile(
|
||||
key: keyParameters,
|
||||
key: keyDebugScreen,
|
||||
title: Text('Debug screen'.tr()),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
|
|
|
@ -74,9 +74,9 @@ class HeaderProfile extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
]),
|
||||
const SizedBox(height: 25),
|
||||
Balance(address: address, size: 22),
|
||||
const SizedBox(height: 10),
|
||||
const SizedBox(height: 23),
|
||||
Balance(address: address, size: 25),
|
||||
const SizedBox(height: 9),
|
||||
InkWell(
|
||||
onTap: () => duniterIndexer.walletNameIndexer[address] != null
|
||||
? {
|
||||
|
|
|
@ -116,7 +116,12 @@ class HistoryQuery extends StatelessWidget {
|
|||
child: ListView(
|
||||
key: keyListTransactions,
|
||||
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:gecko/globals.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:graphql_flutter/graphql_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -10,12 +13,16 @@ class HistoryView extends StatelessWidget {
|
|||
const HistoryView({
|
||||
Key? key,
|
||||
required this.result,
|
||||
required this.address,
|
||||
}) : super(key: key);
|
||||
final QueryResult result;
|
||||
final String address;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
const double avatarSize = 200;
|
||||
bool isMigrationPassed = false;
|
||||
|
@ -32,7 +39,7 @@ class HistoryView extends StatelessWidget {
|
|||
: Column(children: <Widget>[
|
||||
Column(
|
||||
children: duniterIndexer.transBC!.map((repository) {
|
||||
final answer = computeHistoryView(repository);
|
||||
final answer = computeHistoryView(repository, address);
|
||||
pastDelimiters.add(answer['dateDelimiter']);
|
||||
|
||||
bool isMigrationTime = false;
|
||||
|
@ -64,8 +71,6 @@ class HistoryView extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
// if ((countsDelimiter[answer['dateDelimiter']] ?? 0) >= 1)
|
||||
|
||||
if (pastDelimiters.length == 1 ||
|
||||
pastDelimiters.length >= 2 &&
|
||||
!(pastDelimiters[pastDelimiters.length - 2] ==
|
||||
|
@ -91,12 +96,56 @@ class HistoryView extends StatelessWidget {
|
|||
]);
|
||||
}).toList()),
|
||||
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
|
||||
Row(
|
||||
const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: const <Widget>[
|
||||
children: <Widget>[
|
||||
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'])
|
||||
Column(
|
||||
children: <Widget>[
|
||||
|
@ -109,4 +158,4 @@ class HistoryView extends StatelessWidget {
|
|||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/providers/duniter_indexer.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
|
@ -22,6 +23,8 @@ class IdentityStatus extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
final walletData = walletBox.get(address) ?? WalletData(address: address);
|
||||
|
||||
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return FutureBuilder(
|
||||
future: sub.idtyStatus(address),
|
||||
|
@ -30,14 +33,20 @@ class IdentityStatus extends StatelessWidget {
|
|||
duniterIndexer.idtyStatusCache[address] = snapshot.data.toString();
|
||||
switch (snapshot.data.toString()) {
|
||||
case 'noid':
|
||||
walletData.isMember = false;
|
||||
walletBox.put(address, walletData);
|
||||
{
|
||||
return showText('noIdentity'.tr());
|
||||
}
|
||||
case 'Created':
|
||||
walletData.isMember = false;
|
||||
walletBox.put(address, walletData);
|
||||
{
|
||||
return showText('identityCreated'.tr());
|
||||
}
|
||||
case 'ConfirmedByOwner':
|
||||
walletData.isMember = false;
|
||||
walletBox.put(address, walletData);
|
||||
{
|
||||
return isOwner
|
||||
? showText('identityConfirmed'.tr())
|
||||
|
@ -49,17 +58,21 @@ class IdentityStatus extends StatelessWidget {
|
|||
fontStyle: FontStyle.italic);
|
||||
}
|
||||
case 'Validated':
|
||||
walletData.isMember = true;
|
||||
walletBox.put(address, walletData);
|
||||
{
|
||||
return isOwner
|
||||
? showText('memberValidated'.tr(), 18, true)
|
||||
: NameByAddress(
|
||||
wallet: WalletData(address: address),
|
||||
size: 20,
|
||||
size: 24,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: FontStyle.normal);
|
||||
}
|
||||
case 'expired':
|
||||
walletData.isMember = false;
|
||||
walletBox.put(address, walletData);
|
||||
{
|
||||
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;
|
||||
// TODO: Find a way to reload a provider here, in Widget build... riverpod refacto needed...
|
||||
|
||||
double avatarSize = 55;
|
||||
return Expanded(
|
||||
|
@ -125,7 +124,7 @@ class SearchIdentityQuery extends StatelessWidget {
|
|||
walletsProfiles.address = profile['pubkey'];
|
||||
return WalletViewScreen(
|
||||
address: profile['pubkey'],
|
||||
username: name,
|
||||
username: profile['name'] ?? '',
|
||||
avatar:
|
||||
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
||||
);
|
||||
|
|
|
@ -100,8 +100,7 @@ class SearchResult extends StatelessWidget {
|
|||
walletsProfilesClass.address = g1Wallet.address;
|
||||
return WalletViewScreen(
|
||||
address: g1Wallet.address,
|
||||
username:
|
||||
duniterIndexer.walletNameIndexer[g1Wallet.address] ?? '',
|
||||
username: g1WalletsBox.get(g1Wallet)!.username ?? '',
|
||||
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.
|
||||
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:
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
@ -34,8 +34,8 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/insinfo/qr.flutter.git
|
||||
ref: master
|
||||
responsive_framework: ^0.2.0
|
||||
sentry_flutter: ^6.18.0
|
||||
responsive_framework: 0.2.0
|
||||
sentry_flutter: ^7.4.1
|
||||
shared_preferences: ^2.0.7
|
||||
truncate: ^3.0.1
|
||||
unorm_dart: ^0.2.0
|
||||
|
@ -49,7 +49,7 @@ dependencies:
|
|||
url: https://github.com/poka-IT/sdk.git
|
||||
# ref: gecko-fixes-2
|
||||
ref: ff98a117e86060a91113107f31355a17ccfb346c
|
||||
dots_indicator: ^2.1.0
|
||||
dots_indicator: ^3.0.0
|
||||
connectivity_plus: ^3.0.2
|
||||
image_cropper: ^3.0.0
|
||||
easy_localization: ^3.0.1
|
||||
|
@ -64,13 +64,14 @@ dependencies:
|
|||
graphql: ^5.1.1
|
||||
hive_generator: ^2.0.0
|
||||
riverpod: ^2.1.1
|
||||
tutorial_coach_mark: ^1.2.4
|
||||
tutorial_coach_mark: ^1.2.8
|
||||
confetti: ^0.7.0
|
||||
url_launcher: ^6.1.11
|
||||
|
||||
dev_dependencies:
|
||||
# flutter_launcher_icons: ^0.9.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
|
||||
build_runner: ^2.1.2
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in New Issue