Compare commits
10 Commits
f4ed793e56
...
5e2d4c465a
Author | SHA1 | Date |
---|---|---|
poka | 5e2d4c465a | |
poka | 2301472567 | |
poka | 611d715ded | |
poka | 0a47c3b2e3 | |
poka | abb2810e47 | |
poka | c316c0d630 | |
poka | 5b04c5b19e | |
poka | 21a56bbc96 | |
poka | 777fa39ad2 | |
poka | 2264a9fc81 |
|
@ -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",
|
||||
|
@ -218,5 +218,12 @@
|
|||
"thisIdentityAlreadyExist": "This identity already exists",
|
||||
"removedFromcontacts": "Removed from contacts",
|
||||
"addedToContacts": "Added to contacts",
|
||||
"certificationsOf": "Certifications of {}"
|
||||
"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",
|
||||
|
@ -219,5 +219,12 @@
|
|||
"thisIdentityAlreadyExist": "Esta identidad ya existe",
|
||||
"removedFromcontacts": "Removed from contacts",
|
||||
"addedToContacts": "Added to contacts",
|
||||
"certificationsOf": "Certifications of {}"
|
||||
"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"
|
||||
}
|
|
@ -218,5 +218,12 @@
|
|||
"thisIdentityAlreadyExist": "Cette identité existe déjà",
|
||||
"removedFromcontacts": "Retiré des contact",
|
||||
"addedToContacts": "Ajouté au contacts",
|
||||
"certificationsOf": "Certifications de {}"
|
||||
"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"
|
||||
}
|
|
@ -71,6 +71,10 @@ Future restoreChest() async {
|
|||
// 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');
|
||||
|
||||
|
|
|
@ -24,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');
|
||||
|
|
|
@ -8,7 +8,6 @@ import 'package:gecko/globals.dart';
|
|||
import 'package:gecko/models/queries_indexer.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DuniterIndexer with ChangeNotifier {
|
||||
Map<String, String?> walletNameIndexer = {};
|
||||
|
@ -255,61 +254,51 @@ Future<QueryResult> _execQuery(
|
|||
}
|
||||
|
||||
Map computeHistoryView(repository, String address) {
|
||||
bool isTody = false;
|
||||
bool isYesterday = false;
|
||||
bool isThisWeek = false;
|
||||
bool isMigrationTime = false;
|
||||
bool isChangeOwnerkeyTime = false;
|
||||
String? dateDelimiter;
|
||||
DateTime now = DateTime.now();
|
||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
|
||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: 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) {
|
||||
|
@ -319,27 +308,20 @@ Map computeHistoryView(repository, String address) {
|
|||
finalAmount = '$amount $currencyName';
|
||||
}
|
||||
|
||||
if (startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0) {
|
||||
isMigrationTime = true;
|
||||
} else {
|
||||
isMigrationTime = false;
|
||||
}
|
||||
bool isMigrationTime =
|
||||
startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0;
|
||||
|
||||
log.d('taaaaaaaaaaaaaa: $date');
|
||||
log.d('taaaaaaa: ${sub.oldOwnerKeys[address]?[1]}');
|
||||
if (date.compareTo(sub.oldOwnerKeys[address]?[1] ?? DateTime(2000)) < 0) {
|
||||
isChangeOwnerkeyTime = true;
|
||||
} else {
|
||||
isChangeOwnerkeyTime = 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 {
|
||||
'finalAmount': finalAmount,
|
||||
'isMigrationTime': isMigrationTime,
|
||||
'dateDelimiter': dateDelimiter ?? '',
|
||||
'isDelimiter': isDelimiter,
|
||||
'dateDelimiter': dateDelimiter,
|
||||
'dateForm': dateForm,
|
||||
'isChangeOwnerkeyTime': isChangeOwnerkeyTime
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -93,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(() {});
|
||||
}
|
||||
}
|
||||
|
@ -200,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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -118,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>[
|
||||
|
|
|
@ -15,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: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);
|
||||
|
@ -34,9 +33,6 @@ class WalletsHome extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _WalletsHomeState extends State<WalletsHome> {
|
||||
final safeKey = GlobalKey();
|
||||
// List<TargetFocus> targets = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
@ -232,8 +228,8 @@ class _WalletsHomeState extends State<WalletsHome> {
|
|||
}
|
||||
|
||||
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',
|
||||
|
@ -259,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)),
|
||||
|
@ -312,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) {
|
||||
|
@ -343,83 +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: NameByAddress(
|
||||
wallet: repository,
|
||||
size: 20,
|
||||
color: defaultWallet.address ==
|
||||
repository.address
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontStyle: FontStyle.normal,
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
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.w600,
|
||||
fontStyle: FontStyle.normal,
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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,6 +47,8 @@ class WalletViewScreen extends StatelessWidget {
|
|||
walletProfile.address = address;
|
||||
sub.setCurrentWallet(defaultWallet);
|
||||
|
||||
log.d("username: $username");
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
resizeToAvoidBottomInset: true,
|
||||
|
@ -62,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(
|
||||
|
@ -358,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(
|
||||
|
@ -417,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 = '');
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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';
|
||||
|
@ -18,6 +21,8 @@ class HistoryView extends StatelessWidget {
|
|||
@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;
|
||||
|
@ -66,28 +71,6 @@ class HistoryView extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
if (answer['isChangeOwnerkeyTime'])
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Image(
|
||||
image: AssetImage('assets/party.png'), height: 40),
|
||||
const SizedBox(width: 40),
|
||||
Text(
|
||||
'Identité migré !'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 25,
|
||||
color: Colors.blueAccent,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
const SizedBox(width: 40),
|
||||
const Image(
|
||||
image: AssetImage('assets/party.png'), height: 40),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (pastDelimiters.length == 1 ||
|
||||
pastDelimiters.length >= 2 &&
|
||||
!(pastDelimiters[pastDelimiters.length - 2] ==
|
||||
|
@ -113,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>[
|
||||
|
|
|
@ -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... or not ...
|
||||
|
||||
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.0+57
|
||||
|
||||
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