From d7731504c7b188a4642f8363c48e68afa6c7ef98 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 7 Dec 2022 23:10:28 +0100 Subject: [PATCH] big refacto: home screen stateful; walletnames refacto --- assets/translations/fr.json | 2 +- integration_test/utility/tests_utility.dart | 6 +- lib/globals.dart | 2 +- lib/main.dart | 24 +- lib/models/wallet_data.dart | 24 +- lib/models/wallet_data.g.dart | 33 +- lib/providers/generate_wallets.dart | 12 +- lib/providers/home.dart | 106 +----- lib/providers/my_wallets.dart | 24 +- lib/providers/substrate_sdk.dart | 11 +- lib/providers/wallet_options.dart | 10 +- lib/screens/activity.dart | 9 +- lib/screens/home.dart | 349 ++++++++++---------- lib/screens/myWallets/chest_options.dart | 6 +- lib/screens/myWallets/unlocking_wallet.dart | 53 +-- lib/screens/myWallets/wallet_options.dart | 164 +++++---- lib/screens/myWallets/wallets_home.dart | 121 +++---- lib/screens/my_contacts.dart | 7 +- lib/screens/onBoarding/10.dart | 12 +- lib/screens/search.dart | 1 - lib/screens/search_result.dart | 7 +- lib/screens/wallet_view.dart | 6 +- lib/widgets/bottom_app_bar.dart | 117 +++++++ lib/widgets/idty_status.dart | 38 +-- lib/widgets/name_by_address.dart | 36 +- lib/widgets/wallet_name_controller.dart | 68 ---- pubspec.lock | 8 +- pubspec.yaml | 6 +- 28 files changed, 615 insertions(+), 647 deletions(-) create mode 100644 lib/widgets/bottom_app_bar.dart delete mode 100644 lib/widgets/wallet_name_controller.dart diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 68c74ea..f10c89a 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -66,7 +66,7 @@ "chooseAnotherPassword": "Choisir un autre code secret", "iNotedMyPassword": "J'ai noté mon code secret", "geckoWillCheckPassword": "Gecko va vérifier avec vous si vous avez bien mémorisé votre code secret.\n\nTapez votre code secret dans le champ ci-dessous pour vérifier que vous l’avez bien noté.", - "yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !", + "yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre et votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !", "allGood": "C’est tout bon !", "areYouSureToDeleteWallet": "Êtes-vous sûr de vouloir supprimer le coffre \"{}\" ?", "areYouSureForgetAllChests": "Êtes-vous sûr de vouloir oublier tous vos coffres ?", diff --git a/integration_test/utility/tests_utility.dart b/integration_test/utility/tests_utility.dart index 1343f19..e10d879 100644 --- a/integration_test/utility/tests_utility.dart +++ b/integration_test/utility/tests_utility.dart @@ -259,14 +259,14 @@ Future _addImportAccount( final address = await sub.importAccount( mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA'); final myWallet = WalletData( - version: dataVersion, chest: chest, address: address, number: number, name: name, derivation: derivation, - imageDefaultPath: '${number % 4}.png'); - await walletBox.add(myWallet); + imageDefaultPath: '${number % 4}.png', + isOwned: true); + await walletBox.put(myWallet.address, myWallet); return myWallet; } diff --git a/lib/globals.dart b/lib/globals.dart index 6b026f0..b66925a 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -7,7 +7,7 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:logger/logger.dart'; // Version of box data -const int dataVersion = 4; +const int dataVersion = 6; late String appVersion; const int pinLength = 5; diff --git a/lib/main.dart b/lib/main.dart index 48fd8e3..e0ef2ba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,10 +19,11 @@ import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:gecko/globals.dart'; -import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/chest_data.dart'; -import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/providers/cesium_plus.dart'; +import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/settings_provider.dart'; @@ -31,7 +32,6 @@ import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/search.dart'; -import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/screens/home.dart'; import 'package:flutter/material.dart'; @@ -62,29 +62,17 @@ Future main() async { await homeProvider.initHive(); appVersion = await homeProvider.getAppVersion(); - // Reset GraphQL cache - // final cache = HiveStore(); - // cache.reset(); - // Configure Hive and open boxes Hive.registerAdapter(WalletDataAdapter()); Hive.registerAdapter(ChestDataAdapter()); Hive.registerAdapter(G1WalletsListAdapter()); Hive.registerAdapter(IdAdapter()); - walletBox = await Hive.openBox("walletBox"); chestBox = await Hive.openBox("chestBox"); - configBox = await Hive.openBox("configBox"); - await Hive.deleteBoxFromDisk('g1WalletsBox'); - g1WalletsBox = await Hive.openBox("g1WalletsBox"); - contactsBox = await Hive.openBox("contactsBox"); - await homeProvider.getValidEndpoints(); - // await configBox.delete('isCacheChecked'); - if (configBox.get('isCacheChecked') == null) { - configBox.put('isCacheChecked', false); - } - // log.d(await configBox.get('endpoint')); + // Reset GraphQL cache + // final cache = HiveStore(); + // cache.reset(); HttpOverrides.global = MyHttpOverrides(); diff --git a/lib/models/wallet_data.dart b/lib/models/wallet_data.dart index 35e6f89..2a759ef 100644 --- a/lib/models/wallet_data.dart +++ b/lib/models/wallet_data.dart @@ -7,35 +7,39 @@ class WalletData extends HiveObject { String address; @HiveField(1) - int? version; - - @HiveField(2) int? chest; - @HiveField(3) + @HiveField(2) int? number; - @HiveField(4) + @HiveField(3) String? name; - @HiveField(5) + @HiveField(4) int? derivation; - @HiveField(6) + @HiveField(5) String? imageDefaultPath; - @HiveField(7) + @HiveField(6) String? imageCustomPath; + @HiveField(7) + bool isOwned; + + @HiveField(8) + bool isMember; + WalletData( {required this.address, - this.version, this.chest, this.number, this.name, this.derivation, this.imageDefaultPath, - this.imageCustomPath}); + this.imageCustomPath, + this.isOwned = false, + this.isMember = false}); // representation of WalletData when debugging @override diff --git a/lib/models/wallet_data.g.dart b/lib/models/wallet_data.g.dart index 4bba2e1..20a0479 100644 --- a/lib/models/wallet_data.g.dart +++ b/lib/models/wallet_data.g.dart @@ -18,36 +18,39 @@ class WalletDataAdapter extends TypeAdapter { }; return WalletData( address: fields[0] as String, - version: fields[1] as int?, - chest: fields[2] as int?, - number: fields[3] as int?, - name: fields[4] as String?, - derivation: fields[5] as int?, - imageDefaultPath: fields[6] as String?, - imageCustomPath: fields[7] as String?, + chest: fields[1] as int?, + number: fields[2] as int?, + name: fields[3] as String?, + derivation: fields[4] as int?, + imageDefaultPath: fields[5] as String?, + imageCustomPath: fields[6] as String?, + isOwned: fields[7] as bool, + isMember: fields[8] as bool, ); } @override void write(BinaryWriter writer, WalletData obj) { writer - ..writeByte(8) + ..writeByte(9) ..writeByte(0) ..write(obj.address) ..writeByte(1) - ..write(obj.version) - ..writeByte(2) ..write(obj.chest) - ..writeByte(3) + ..writeByte(2) ..write(obj.number) - ..writeByte(4) + ..writeByte(3) ..write(obj.name) - ..writeByte(5) + ..writeByte(4) ..write(obj.derivation) - ..writeByte(6) + ..writeByte(5) ..write(obj.imageDefaultPath) + ..writeByte(6) + ..write(obj.imageCustomPath) ..writeByte(7) - ..write(obj.imageCustomPath); + ..write(obj.isOwned) + ..writeByte(8) + ..write(obj.isMember); } @override diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index e792ac2..9a9fcbc 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -414,14 +414,14 @@ class GenerateWalletsProvider with ChangeNotifier { password: pin.text); WalletData myWallet = WalletData( - version: dataVersion, chest: currentChestNumber, address: addressData.address!, number: scanedValidWalletNumber, name: walletName, derivation: derivationNbr, - imageDefaultPath: '${scanedValidWalletNumber % 4}.png'); - await walletBox.add(myWallet); + imageDefaultPath: '${scanedValidWalletNumber % 4}.png', + isOwned: true); + await walletBox.put(myWallet.address, myWallet); scanedValidWalletNumber = scanedValidWalletNumber + 1; } scanedWalletNumber = scanedWalletNumber + 1; @@ -454,14 +454,14 @@ class GenerateWalletsProvider with ChangeNotifier { await sub.importAccount(mnemonic: generatedMnemonic!, password: pin.text); WalletData myWallet = WalletData( - version: dataVersion, chest: currentChestNumber, address: addressData.address!, number: 0, name: walletName, derivation: -1, - imageDefaultPath: '0.png'); - await walletBox.add(myWallet); + imageDefaultPath: '0.png', + isOwned: true); + await walletBox.put(myWallet.address, myWallet); return true; } else { return false; diff --git a/lib/providers/home.dart b/lib/providers/home.dart index bdb376a..484441e 100644 --- a/lib/providers/home.dart +++ b/lib/providers/home.dart @@ -11,15 +11,8 @@ import 'package:flutter/services.dart'; import 'dart:async'; 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/myWallets/wallets_home.dart'; -import 'package:gecko/screens/search.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb; import 'package:path_provider/path_provider.dart' as pp; @@ -34,6 +27,7 @@ class HomeProvider with ChangeNotifier { Widget appBarTitle = Text('Ğecko', style: TextStyle(color: Colors.grey[850])); String homeMessage = "loading".tr(); String defaultMessage = "noLizard".tr(); + bool isWalletBoxInit = false; Future initHive() async { late Directory hivePath; @@ -135,104 +129,6 @@ class HomeProvider with ChangeNotifier { // volume: volume, mode: PlayerMode.LOW_LATENCY, stayAwake: false); // } - Widget bottomAppBar(BuildContext context) { - final myWalletProvider = - Provider.of(context, listen: false); - WalletsProfilesProvider historyProvider = - Provider.of(context, listen: false); - - final size = MediaQuery.of(context).size; - - const bool showBottomBar = true; - - return Visibility( - visible: showBottomBar, - child: Container( - color: yellowC, - width: size.width, - height: 80, - child: - // Stack( - // children: [ - // // CustomPaint( - // // size: Size(size.width, 110), - // // painter: CustomRoundedButton(), - // // ), - Row(mainAxisAlignment: MainAxisAlignment.start, children: [ - // SizedBox(width: 0), - const Spacer(), - const SizedBox(width: 11), - IconButton( - key: keyAppBarSearch, - iconSize: 40, - icon: const Image(image: AssetImage('assets/loupe-noire.png')), - onPressed: () { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); - Navigator.push( - context, - MaterialPageRoute(builder: (homeContext) { - return const SearchScreen(); - }), - ); - }, - ), - const SizedBox(width: 22), - const Spacer(), - IconButton( - key: keyAppBarQrcode, - iconSize: 70, - icon: const Image(image: AssetImage('assets/qrcode-scan.png')), - onPressed: () async { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); - historyProvider.scan(homeContext); - }, - ), - const Spacer(), - const SizedBox(width: 15), - IconButton( - key: keyAppBarChest, - iconSize: 60, - icon: const Image(image: AssetImage('assets/wallet.png')), - onPressed: () async { - WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; - if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( - context, - MaterialPageRoute( - builder: (homeContext) { - return UnlockingWallet(wallet: defaultWallet); - }, - ), - ); - } - - if (pin != null || myWalletProvider.pinCode != '') { - Navigator.popUntil( - context, - ModalRoute.withName('/'), - ); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const WalletsHome(); - }), - ); - } - }, - ), - const Spacer(), - ]), - ), - ); - } - void reload() { notifyListeners(); } diff --git a/lib/providers/my_wallets.dart b/lib/providers/my_wallets.dart index ffc7fc3..e17c295 100644 --- a/lib/providers/my_wallets.dart +++ b/lib/providers/my_wallets.dart @@ -48,7 +48,7 @@ class MyWalletsProvider with ChangeNotifier { } WalletData? getWalletDataById(List id) { - if (id.isEmpty) return WalletData(address: ''); + if (id.isEmpty) return WalletData(address: '', isOwned: true); int? chest = id[0]; int? nbr = id[1]; WalletData? targetedWallet; @@ -78,12 +78,12 @@ class MyWalletsProvider with ChangeNotifier { WalletData getDefaultWallet([int? chest]) { if (chestBox.isEmpty) { - return WalletData(address: '', chest: 0, number: 0); + return WalletData(address: '', chest: 0, number: 0, isOwned: true); } else { chest ??= getCurrentChest(); int? defaultWalletNumber = chestBox.get(chest)!.defaultWallet; return getWalletDataById([chest, defaultWalletNumber]) ?? - WalletData(address: '', chest: chest, number: 0); + WalletData(address: '', chest: chest, number: 0, isOwned: true); } } @@ -134,15 +134,15 @@ class MyWalletsProvider with ChangeNotifier { context, defaultWallet.address, newDerivationNbr, pinCode); WalletData newWallet = WalletData( - version: dataVersion, chest: chest, address: address, number: newWalletNbr, name: name, derivation: newDerivationNbr, - imageDefaultPath: '${newWalletNbr % 4}.png'); + imageDefaultPath: '${newWalletNbr % 4}.png', + isOwned: true); - await walletBox.add(newWallet); + await walletBox.put(newWallet.address, newWallet); isNewDerivationLoading = false; notifyListeners(); @@ -158,6 +158,9 @@ class MyWalletsProvider with ChangeNotifier { int? chest = getCurrentChest(); List walletConfig = readAllWallets(chest); + walletConfig.sort((p1, p2) { + return Comparable.compare(p1.number!, p2.number!); + }); if (walletConfig.isEmpty) { newWalletNbr = 0; @@ -172,15 +175,15 @@ class MyWalletsProvider with ChangeNotifier { await sub.generateRootKeypair(defaultWallet.address, pinCode); WalletData newWallet = WalletData( - version: dataVersion, chest: chest, address: address, number: newWalletNbr, name: name, derivation: -1, - imageDefaultPath: '${newWalletNbr % 4}.png'); + imageDefaultPath: '${newWalletNbr % 4}.png', + isOwned: true); - await walletBox.add(newWallet); + await walletBox.put(newWallet.address, newWallet); isNewDerivationLoading = false; notifyListeners(); @@ -194,6 +197,9 @@ class MyWalletsProvider with ChangeNotifier { chestNumber ??= getCurrentChest(); List walletConfig = readAllWallets(chestNumber); + walletConfig.sort((p1, p2) { + return Comparable.compare(p1.number!, p2.number!); + }); if (walletConfig.isEmpty) { newDerivationNbr = 2; diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 4fe6c73..1a88a60 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -251,8 +251,13 @@ class SubstrateSdk with ChangeNotifier { return totalAmount; } - Future isMemberGet(String address) async { - return await idtyStatus(address) == 'Validated'; + Future isMember(String address) async { + final isMember = await idtyStatus(address) == 'Validated'; + final walletData = walletBox.get(address) ?? WalletData(address: address); + walletData.isMember = isMember; + walletBox.put(address, walletData); + notifyListeners(); + return isMember; } Future isSmithGet(String address) async { @@ -272,7 +277,7 @@ class SubstrateSdk with ChangeNotifier { Map result = {}; final toStatus = await idtyStatus(to); - if (from != to && await isMemberGet(from)) { + if (from != to && await isMember(from)) { final removableOn = await getCertValidityPeriod(from, to); final certMeta = await getCertMeta(from); final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0; diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 4a4990f..7d03ce9 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -129,11 +129,6 @@ class WalletOptionsProvider with ChangeNotifier { } } - Future isMember(BuildContext context, String address) async { - final sub = Provider.of(context, listen: false); - return await sub.idtyStatus(address) == 'Validated'; - } - Future confirmIdentityPopup(BuildContext context) async { TextEditingController idtyName = TextEditingController(); final sub = Provider.of(context, listen: false); @@ -234,8 +229,7 @@ class WalletOptionsProvider with ChangeNotifier { transType: 'comfirmIdty', fromAddress: getShortPubkey(wallet.address), - toAddress: - getShortPubkey(wallet.address), + toAddress: getShortPubkey(wallet.address), ); }), ); @@ -311,7 +305,7 @@ class WalletOptionsProvider with ChangeNotifier { if (canValidateNameBool) { nameController.text = walletName.text; _renameWallet(wID, walletName.text, isCesium: false); - // notifyListeners(); + notifyListeners(); Navigator.pop(context); } }, diff --git a/lib/screens/activity.dart b/lib/screens/activity.dart index ea775e7..25b7be2 100644 --- a/lib/screens/activity.dart +++ b/lib/screens/activity.dart @@ -7,10 +7,10 @@ import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/duniter_indexer.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:flutter/material.dart'; import 'package:gecko/screens/wallet_view.dart'; +import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:gecko/widgets/header_profile.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:provider/provider.dart'; @@ -31,11 +31,6 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { @override Widget build(BuildContext context) { - HomeProvider homeProvider = - Provider.of(context, listen: false); - - // log.d('aaaaaaaaaaaaaaaaaaaaa $startBlockchainTime'); - return Scaffold( key: _scaffoldKey, appBar: AppBar( @@ -46,7 +41,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { child: Text('accountActivity'.tr()), ), ), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: Column(children: [ HeaderProfile(address: address, username: username), historyQuery(context), diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 922fbe9..64a368b 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -4,7 +4,8 @@ import 'package:bubble/bubble.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; -import 'package:gecko/models/stateful_wrapper.dart'; +import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -22,21 +23,109 @@ import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/onBoarding/1.dart'; import 'package:gecko/screens/search.dart'; import 'package:gecko/screens/settings.dart'; +import 'package:hive_flutter/hive_flutter.dart'; import 'package:provider/provider.dart'; import 'package:gecko/screens/my_contacts.dart'; -class HomeScreen extends StatelessWidget { +class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); + @override + State createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + final homeProviderInit = + Provider.of(context, listen: false); + final sub = Provider.of(context, listen: false); + final duniterIndexer = + Provider.of(context, listen: false); + final myWalletProvider = + Provider.of(context, listen: false); + + configBox = await Hive.openBox("configBox"); + final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); + + if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi(); + if (sub.sdkReady && !sub.nodeConnected) { + // Check if versionData non compatible, drop everything + if (isWalletsExists && + (configBox.get('dataVersion') ?? 0) < dataVersion) { + await infoPopup(context, "chestNotCompatibleMustReinstallGecko".tr()); + await Hive.deleteBoxFromDisk('walletBox'); + await Hive.deleteBoxFromDisk('chestBox'); + chestBox = await Hive.openBox("chestBox"); + await configBox.delete('defaultWallet'); + await sub.deleteAllAccounts(); + configBox.put('dataVersion', dataVersion); + myWalletProvider.reload(); + } + + walletBox = await Hive.openBox("walletBox"); + await Hive.deleteBoxFromDisk('g1WalletsBox'); + g1WalletsBox = await Hive.openBox("g1WalletsBox"); + contactsBox = await Hive.openBox("contactsBox"); + + homeProviderInit.isWalletBoxInit = true; + myWalletProvider.reload(); + + duniterIndexer.getValidIndexerEndpoint(); + + await homeProviderInit.getValidEndpoints(); + // await configBox.delete('isCacheChecked'); + if (configBox.get('isCacheChecked') == null) { + configBox.put('isCacheChecked', false); + } + // log.d(await configBox.get('endpoint')); + + // var connectivityResult = + // await (Connectivity().checkConnectivity()); + + // if (connectivityResult != ConnectivityResult.mobile && + // connectivityResult != ConnectivityResult.wifi) { + // homeProvider.changeMessage( + // "notConnectedToInternet".tr(), 0); + // sub.nodeConnected = false; + // } + + // TODO: fix random bad network status on startup + HomeProvider homeProvider = + Provider.of(context, listen: false); + Connectivity() + .onConnectivityChanged + .listen((ConnectivityResult result) async { + log.d('Network changed: $result'); + if (result == ConnectivityResult.none) { + sub.nodeConnected = false; + await sub.sdk.api.setting.unsubscribeBestNumber(); + homeProvider.changeMessage("notConnectedToInternet".tr(), 0); + sub.reload(); + } else { + await sub.connectNode(context); + // Currency parameters + sub.initCurrencyParameters(); + } + + // Indexer Blockchain start + getBlockStart(); + }); + // await sub.connectNode(ctx); + } + // _duniterIndexer.checkIndexerEndpointBackground(); + }); + super.initState(); + } + @override Widget build(BuildContext context) { homeContext = context; final myWalletProvider = Provider.of(context); Provider.of(context); - final sub = Provider.of(context, listen: false); - final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); isTall = false; @@ -46,148 +135,65 @@ class HomeScreen extends StatelessWidget { ratio = 1.125; } return Scaffold( - resizeToAvoidBottomInset: false, - drawer: Drawer( - child: Column( - children: [ - Expanded( - child: ListView(padding: EdgeInsets.zero, children: [ - DrawerHeader( - decoration: const BoxDecoration( - color: orangeC, + resizeToAvoidBottomInset: false, + drawer: Drawer( + child: Column( + children: [ + Expanded( + child: ListView(padding: EdgeInsets.zero, children: [ + DrawerHeader( + decoration: const BoxDecoration( + color: orangeC, + ), + child: Column(children: const [ + SizedBox(height: 0), + Image( + image: AssetImage('assets/icon/gecko_final.png'), + height: 130), + ]), ), - child: Column(children: const [ - SizedBox(height: 0), - Image( - image: AssetImage('assets/icon/gecko_final.png'), - height: 130), - ]), - ), - ListTile( - key: keyParameters, - title: Text('parameters'.tr()), - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return SettingsScreen(); - }), - ); - }, - ), - ListTile( - key: keyContacts, - title: Text('contactsManagement'.tr()), - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const ContactsScreen(); - }), - ); - }, - ), - ])), - Align( - alignment: FractionalOffset.bottomCenter, - child: Text('Ğecko v$appVersion')), - const SizedBox(height: 20) - ], + ListTile( + key: keyParameters, + title: Text('parameters'.tr()), + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return SettingsScreen(); + }), + ); + }, + ), + ListTile( + key: keyContacts, + title: Text('contactsManagement'.tr()), + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const ContactsScreen(); + }), + ); + }, + ), + ])), + Align( + alignment: FractionalOffset.bottomCenter, + child: Text('Ğecko v$appVersion')), + const SizedBox(height: 20) + ], + ), ), - ), - // bottomNavigationBar: _homeProvider.bottomBar(context, 1), - backgroundColor: const Color(0xffF9F9F1), - body: Builder( - builder: (ctx) => StatefulWrapper( - onInit: () { - WidgetsBinding.instance.addPostFrameCallback((_) async { - final duniterIndexer = - Provider.of(ctx, listen: false); - duniterIndexer.getValidIndexerEndpoint(); - - if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi(); - if (sub.sdkReady && !sub.nodeConnected) { - // Check if versionData non compatible, drop everything - if (walletBox.isNotEmpty && - walletBox.getAt(0)!.version! < dataVersion) { - await infoPopup( - context, "chestNotCompatibleMustReinstallGecko".tr()); - await walletBox.clear(); - await chestBox.clear(); - await configBox.delete('defaultWallet'); - await sub.deleteAllAccounts(); - myWalletProvider.reload(); - } - - // var connectivityResult = - // await (Connectivity().checkConnectivity()); - - // if (connectivityResult != ConnectivityResult.mobile && - // connectivityResult != ConnectivityResult.wifi) { - // homeProvider.changeMessage( - // "notConnectedToInternet".tr(), 0); - // sub.nodeConnected = false; - // } - - // TODO: fix random bad network status on startup - HomeProvider homeProvider = - Provider.of(ctx, listen: false); - Connectivity() - .onConnectivityChanged - .listen((ConnectivityResult result) async { - log.d('Network changed: $result'); - if (result == ConnectivityResult.none) { - sub.nodeConnected = false; - await sub.sdk.api.setting.unsubscribeBestNumber(); - homeProvider.changeMessage( - "notConnectedToInternet".tr(), 0); - sub.reload(); - } else { - await sub.connectNode(ctx); - // Currency parameters - sub.initCurrencyParameters(); - } - - // Indexer Blockchain start - getBlockStart(); - }); - // await sub.connectNode(ctx); - } - // _duniterIndexer.checkIndexerEndpointBackground(); - }); - }, - child: isWalletsExists ? geckHome(context) : welcomeHome(context) - // bottomNavigationBar: BottomNavigationBar( - // backgroundColor: backgroundColor, - // fixedColor: Colors.grey[850], - // unselectedItemColor: const Color(0xffBD935C), - // type: BottomNavigationBarType.fixed, - // onTap: (index) { - // _homeProvider.currentIndex = index; - // }, - // currentIndex: _homeProvider.currentIndex, - // items: [ - // BottomNavigationBarItem( - // icon: Image.asset('assets/block-space-disabled.png', height: 26), - // activeIcon: Image.asset('assets/blockchain.png', height: 26), - // label: 'Explorateur', - // ), - // const BottomNavigationBarItem( - // icon: Icon(Icons.lock), - // label: 'Mes portefeuilles', - // ), - // ], - // ), - ), - ), - ); + backgroundColor: const Color(0xffF9F9F1), + body: isWalletsExists ? geckHome(context) : welcomeHome(context)); } } Widget geckHome(context) { final myWalletProvider = Provider.of(context); + final homeProvider = Provider.of(context, listen: false); Provider.of(context); WalletsProfilesProvider historyProvider = @@ -334,42 +340,47 @@ Widget geckHome(context) { child: ClipOval( key: keyOpenWalletsHomme, child: Material( - color: orangeC, // button color + color: homeProvider.isWalletBoxInit + ? orangeC + : Colors.grey[500], // button color child: InkWell( + onTap: !homeProvider.isWalletBoxInit + ? null + : () async { + WalletData? defaultWallet = + myWalletProvider.getDefaultWallet(); + 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 const WalletsHome(); + }), + ); + } + // log.d(_myWalletProvider.pinCode); + + // Navigator.pushNamed( + // context, '/mywallets'))); + }, child: Padding( padding: const EdgeInsets.all(18), child: Image( image: const AssetImage( 'assets/home/wallet.png'), - height: 68 * ratio)), - onTap: () async { - WalletData? defaultWallet = - myWalletProvider.getDefaultWallet(); - 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 const WalletsHome(); - }), - ); - } - // log.d(_myWalletProvider.pinCode); - - // Navigator.pushNamed( - // context, '/mywallets'))); - }), + height: 68 * ratio))), ), ), ), diff --git a/lib/screens/myWallets/chest_options.dart b/lib/screens/myWallets/chest_options.dart index b8df652..ff12b43 100644 --- a/lib/screens/myWallets/chest_options.dart +++ b/lib/screens/myWallets/chest_options.dart @@ -8,7 +8,6 @@ import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/common_elements.dart'; @@ -16,6 +15,7 @@ import 'package:gecko/screens/myWallets/change_pin.dart'; import 'package:gecko/screens/myWallets/custom_derivations.dart'; import 'package:gecko/screens/myWallets/show_seed.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:provider/provider.dart'; class ChestOptions extends StatelessWidget { @@ -26,8 +26,6 @@ class ChestOptions extends StatelessWidget { @override Widget build(BuildContext context) { final chestProvider = Provider.of(context, listen: false); - HomeProvider homeProvider = - Provider.of(context, listen: false); ChestData currentChest = chestBox.get(configBox.get('currentChest'))!; @@ -50,7 +48,7 @@ class ChestOptions extends StatelessWidget { height: 22, child: Text(currentChest.name!), )), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: Stack(children: [ Builder( builder: (ctx) => SafeArea( diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index c5534ef..c370a3a 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -125,29 +125,32 @@ class UnlockingWallet extends StatelessWidget { pinForm(context, pinLenght), SizedBox(height: 3 * ratio), if (canUnlock) - InkWell( - key: keyCachePassword, - onTap: () { - walletOptions.changePinCacheChoice(); - }, - child: Row(children: [ - const SizedBox(height: 30), - const Spacer(), - Icon( - configBox.get('isCacheChecked') - ? Icons.check_box - : Icons.check_box_outline_blank, - color: orangeC, - ), - const SizedBox(width: 8), - Text( - 'rememberPassword'.tr(), - style: TextStyle( - fontSize: 16, color: Colors.grey[700]), - ), - const Spacer() - ]), - ), + Consumer( + builder: (context, sub, _) { + return InkWell( + key: keyCachePassword, + onTap: () { + walletOptions.changePinCacheChoice(); + }, + child: Row(children: [ + const SizedBox(height: 30), + const Spacer(), + Icon( + configBox.get('isCacheChecked') + ? Icons.check_box + : Icons.check_box_outline_blank, + color: orangeC, + ), + const SizedBox(width: 8), + Text( + 'rememberPassword'.tr(), + style: TextStyle( + fontSize: 16, color: Colors.grey[700]), + ), + const Spacer() + ]), + ); + }), const SizedBox(height: 10), // if (canUnlock) InkWell( @@ -213,7 +216,7 @@ class UnlockingWallet extends StatelessWidget { obscureText: true, obscuringCharacter: '*', animationType: AnimationType.slide, - animationDuration: const Duration(milliseconds: 80), + animationDuration: const Duration(milliseconds: 40), validator: (v) { if (v!.length < pinLenght) { return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]); @@ -250,7 +253,7 @@ class UnlockingWallet extends StatelessWidget { final isValid = await sub.checkPassword( defaultWallet.address, pin.toUpperCase()); if (!isValid) { - await Future.delayed(const Duration(milliseconds: 50)); + await Future.delayed(const Duration(milliseconds: 20)); pinColor = Colors.red[600]; myWalletProvider.isPinLoading = false; myWalletProvider.isPinValid = false; diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index a7cb1f7..b48ca9f 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -6,7 +6,6 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -18,6 +17,7 @@ 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/certifications.dart'; import 'package:gecko/widgets/idty_status.dart'; import 'package:gecko/widgets/name_by_address.dart'; @@ -39,9 +39,8 @@ class WalletOptions extends StatelessWidget { Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); - HomeProvider homeProvider = - Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); + final sub = Provider.of(context, listen: false); // final sub = Provider.of(context, listen: false); // sub.spawnBlock(); @@ -50,6 +49,8 @@ class WalletOptions extends StatelessWidget { log.d(walletOptions.address.text); final currentChest = myWalletProvider.getCurrentChest(); + bool isWalletNameIndexed = + duniterIndexer.walletNameIndexer[walletOptions.address.text] != null; // final currentWallet = _myWalletProvider.getDefaultWallet(); // log.d(_walletOptions.getAddress(_currentChest, 3)); @@ -81,7 +82,10 @@ class WalletOptions extends StatelessWidget { height: 22, child: Consumer( builder: (context, walletProvider, _) { - return Text(wallet.name!); + return Text(isWalletNameIndexed + ? duniterIndexer + .walletNameIndexer[walletOptions.address.text]! + : wallet.name!); }), ), actions: [ @@ -104,7 +108,7 @@ class WalletOptions extends StatelessWidget { ), ], ), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: Stack(children: [ Builder( builder: (ctx) => SafeArea( @@ -125,65 +129,95 @@ class WalletOptions extends StatelessWidget { backgroundColor, ], )), - child: Row( - // mainAxisAlignment: MainAxisAlignment.end, - children: [ - const Spacer(flex: 1), - avatar(walletProvider), - const Spacer(flex: 1), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - NameByAddress( - address: walletProvider.address.text, - wallet: wallet, - size: 27, - canEdit: false, - color: Colors.black, - fontWeight: FontWeight.w400, - fontStyle: FontStyle.normal), - SizedBox(height: isTall ? 5 : 0), - Balance( - address: walletProvider.address.text, - size: 21), - const SizedBox(width: 30), - InkWell( - onTap: () => duniterIndexer.walletNameIndexer[ - walletProvider.address.text] != - null - ? { - Navigator.push( - context, - PageNoTransit(builder: (context) { - return CertificationsScreen( - address: walletProvider - .address.text, - username: duniterIndexer - .walletNameIndexer[ - walletProvider - .address.text]!); - }), - ), - } - : null, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - IdentityStatus( - address: walletOptions.address.text, - isOwner: true, - color: orangeC), - Certifications( - address: - walletProvider.address.text, - size: 15) - ]), + child: Row(children: [ + const Spacer(flex: 1), + avatar(walletProvider), + const Spacer(flex: 1), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Stack(children: [ + SizedBox( + width: 250, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Consumer( + builder: (context, walletProvider, _) { + return NameByAddress( + wallet: wallet, + size: 27, + color: Colors.black, + fontWeight: wallet.isMember + ? FontWeight.w500 + : FontWeight.w400, + fontStyle: FontStyle.normal); + }) + ], ), - SizedBox(height: 10 * ratio), - ]), - const Spacer(flex: 2), - ]), + ), + const SizedBox(width: 10), + if (duniterIndexer + .walletNameIndexer[wallet.address] == + null) + Positioned( + right: 0, + child: InkWell( + key: keyRenameWallet, + onTap: () async { + await walletOptions.editWalletName( + context, wallet.id()); + await Future.delayed( + const Duration(milliseconds: 30)); + }, + child: ClipRRect( + child: Image.asset( + walletOptions.isEditing + ? 'assets/walletOptions/android-checkmark.png' + : 'assets/walletOptions/edit.png', + width: 25, + height: 25), + ), + ), + ), + ]), + SizedBox(height: isTall ? 5 : 0), + Balance( + address: walletProvider.address.text, size: 21), + const SizedBox(width: 30), + InkWell( + onTap: () => isWalletNameIndexed + ? { + Navigator.push( + context, + PageNoTransit(builder: (context) { + return CertificationsScreen( + address: + walletProvider.address.text, + username: duniterIndexer + .walletNameIndexer[ + walletProvider + .address.text]!); + }), + ), + } + : null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + IdentityStatus( + address: walletOptions.address.text, + isOwner: true, + color: orangeC), + Certifications( + address: walletProvider.address.text, + size: 15) + ]), + ), + SizedBox(height: 10 * ratio), + ]), + const Spacer(flex: 2), + ]), ); }), Expanded( @@ -227,8 +261,8 @@ class WalletOptions extends StatelessWidget { SizedBox(height: 17 * ratio), // walletProvider.isMember(context, _walletOptions.address.text) FutureBuilder( - future: walletProvider.isMember( - context, walletOptions.address.text), + future: + sub.isMember(walletOptions.address.text), builder: (BuildContext context, AsyncSnapshot isMember) { if (isMember.connectionState != diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 9b1611b..67e5b0e 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -1,14 +1,12 @@ // ignore_for_file: use_build_context_synchronously import 'dart:io'; - import 'package:easy_localization/easy_localization.dart'; - 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/home.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'; @@ -22,9 +20,10 @@ 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/widgets/balance.dart'; -import 'package:gecko/widgets/name_by_address.dart'; +import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:provider/provider.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:truncate/truncate.dart'; class WalletsHome extends StatelessWidget { const WalletsHome({Key? key}) : super(key: key); @@ -32,8 +31,6 @@ class WalletsHome extends StatelessWidget { @override Widget build(BuildContext context) { final myWalletProvider = Provider.of(context); - HomeProvider homeProvider = - Provider.of(context, listen: false); final currentChestNumber = myWalletProvider.getCurrentChest(); final ChestData currentChest = chestBox.get(currentChestNumber)!; @@ -66,7 +63,7 @@ class WalletsHome extends StatelessWidget { backgroundColor: const Color(0xffFFD58D), ), bottomNavigationBar: myWalletProvider.lastFlyBy == '' - ? homeProvider.bottomAppBar(context) + ? const GeckoBottomAppBar() : dragInfo(context), body: SafeArea( child: Stack(children: [ @@ -204,6 +201,7 @@ class WalletsHome extends StatelessWidget { Provider.of(context, listen: false); final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); final sub = Provider.of(context, listen: false); + final duniterIndexer = Provider.of(context, listen: false); if (!isWalletsExists) { return const Text(''); @@ -220,7 +218,12 @@ class WalletsHome extends StatelessWidget { ])); } - List listWallets = myWalletProvider.listWallets; + // Get wallet list and sort by derivation number + List listWallets = myWalletProvider.listWallets; + listWallets.sort((p1, p2) { + return Comparable.compare(p1.number!, p2.number!); + }); + WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); final screenWidth = MediaQuery.of(context).size.width; int nTule = 2; @@ -244,7 +247,7 @@ class WalletsHome extends StatelessWidget { crossAxisSpacing: 0, mainAxisSpacing: 0, children: [ - for (WalletData repository in listWallets as Iterable) + for (WalletData repository in listWallets) LongPressDraggable( delay: const Duration(milliseconds: 200), data: repository.address, @@ -326,12 +329,12 @@ class WalletsHome extends StatelessWidget { child: Container( width: double.infinity, height: double.infinity, - decoration: BoxDecoration( + decoration: const BoxDecoration( gradient: RadialGradient( - radius: 0.6, + radius: 0.8, colors: [ - Colors.green[400]!, - const Color(0xFFE7E7A6), + Color.fromARGB(255, 255, 255, 211), + yellowC, ], )), child: @@ -364,8 +367,42 @@ class WalletsHome extends StatelessWidget { repository.address, repository.address == defaultWallet.address), - nameBuilder(context, repository, - defaultWallet, currentChestNumber), + 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, + 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, + // ), + ], + ), + ], + ), ]), ]), ), @@ -389,58 +426,24 @@ class WalletsHome extends StatelessWidget { width: double.infinity, color: isDefault ? orangeC : yellowC, child: Padding( - padding: const EdgeInsets.only(left: 5, right: 5, top: 38), + padding: + const EdgeInsets.only(left: 5, right: 5, top: 38, bottom: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Balance( - address: address, - size: 15, - color: isDefault ? Colors.white : Colors.black, - loadingColor: isDefault ? yellowC : orangeC), + Opacity( + opacity: 0.7, + child: Balance( + address: address, + size: 16, + color: isDefault ? Colors.white : Colors.black, + loadingColor: isDefault ? yellowC : orangeC), + ) ], )), ); } - Widget nameBuilder(BuildContext context, WalletData repository, - WalletData defaultWallet, int currentChestNumber) { - final walletOptions = - Provider.of(context, listen: false); - - return ListTile( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))), - tileColor: repository.address == defaultWallet.address - ? orangeC - : const Color(0xffFFD58D), - title: Center( - child: Padding( - padding: const EdgeInsets.only(left: 5, right: 5, bottom: 35, top: 5), - child: NameByAddress( - address: repository.address, - wallet: repository, - size: 20, - canEdit: false, - color: repository.id()[1] == defaultWallet.id()[1] - ? const Color(0xffF9F9F1) - : Colors.black), - ), - ), - onTap: () { - walletOptions.getAddress(currentChestNumber, repository.derivation!); - Navigator.push( - context, - SmoothTransition( - page: WalletOptions( - wallet: repository, - ), - ), - ); - }, - ); - } - Widget addNewDerivation(context) { final myWalletProvider = Provider.of(context); diff --git a/lib/screens/my_contacts.dart b/lib/screens/my_contacts.dart index 8479ce4..0b59572 100644 --- a/lib/screens/my_contacts.dart +++ b/lib/screens/my_contacts.dart @@ -7,12 +7,12 @@ import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/providers/duniter_indexer.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/balance.dart'; +import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:provider/provider.dart'; @@ -23,8 +23,6 @@ class ContactsScreen extends StatelessWidget { Widget build(BuildContext context) { WalletsProfilesProvider walletsProfilesClass = Provider.of(context, listen: true); - HomeProvider homeProvider = - Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); double avatarSize = 55; @@ -51,7 +49,7 @@ class ContactsScreen extends StatelessWidget { 'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])), ), ), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Stack(children: [ Padding( @@ -104,7 +102,6 @@ class ContactsScreen extends StatelessWidget { ]), subtitle: Row(children: [ NameByAddress( - address: g1Wallet.address, wallet: WalletData(address: g1Wallet.address)) ]), diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index e0432fc..a37825b 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -34,6 +34,7 @@ class OnboardingStepTen extends StatelessWidget { final generateWalletProvider = Provider.of(context); final walletOptions = Provider.of(context); + final sub = Provider.of(context); final myWalletProvider = Provider.of(context, listen: false); CommonElements common = CommonElements(); @@ -126,7 +127,8 @@ class OnboardingStepTen extends StatelessWidget { ), ]); }), - Consumer(builder: (context, sub, _) { + Consumer( + builder: (context, walletOptions, _) { return sub.nodeConnected ? InkWell( key: keyCachePassword, @@ -188,7 +190,7 @@ class OnboardingStepTen extends StatelessWidget { obscureText: true, obscuringCharacter: '*', animationType: AnimationType.slide, - animationDuration: const Duration(milliseconds: 80), + animationDuration: const Duration(milliseconds: 40), validator: (v) { if (v!.length < pinLenght) { return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]); @@ -240,14 +242,14 @@ class OnboardingStepTen extends StatelessWidget { derivePath: '//2', password: generateWalletProvider.pin.text); WalletData myWallet = WalletData( - version: dataVersion, chest: configBox.get('currentChest'), address: address, number: 0, name: 'currentWallet'.tr(), derivation: 2, - imageDefaultPath: '0.png'); - await walletBox.add(myWallet); + imageDefaultPath: '0.png', + isOwned: true); + await walletBox.put(myWallet.address, myWallet); } myWalletProvider.readAllWallets(currentChest); myWalletProvider.reload(); diff --git a/lib/screens/search.dart b/lib/screens/search.dart index 3ccc490..c9281e3 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -41,7 +41,6 @@ class SearchScreen extends StatelessWidget { Navigator.of(context).pop(); }), ), - // bottomNavigationBar: _homeProvider.bottomAppBar(context), body: SafeArea( child: Stack(children: [ Column(children: [ diff --git a/lib/screens/search_result.dart b/lib/screens/search_result.dart index e4b3a71..d2ecaaa 100644 --- a/lib/screens/search_result.dart +++ b/lib/screens/search_result.dart @@ -7,13 +7,13 @@ import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/providers/duniter_indexer.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/search.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/balance.dart'; +import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:provider/provider.dart'; @@ -25,8 +25,6 @@ class SearchResultScreen extends StatelessWidget { final searchProvider = Provider.of(context, listen: false); WalletsProfilesProvider walletsProfilesClass = Provider.of(context, listen: false); - HomeProvider homeProvider = - Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); double avatarSize = 55; @@ -41,7 +39,7 @@ class SearchResultScreen extends StatelessWidget { child: Text('researchResults'.tr()), ), ), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Stack(children: [ Padding( @@ -127,7 +125,6 @@ class SearchResultScreen extends StatelessWidget { ]), subtitle: Row(children: [ NameByAddress( - address: g1Wallet.address, wallet: WalletData( address: g1Wallet.address), ), diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 52f87b4..4c8e1cf 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -9,7 +9,6 @@ import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/duniter_indexer.dart'; -import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; @@ -22,6 +21,7 @@ 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:provider/provider.dart'; @@ -43,8 +43,6 @@ class WalletViewScreen extends StatelessWidget { Provider.of(context, listen: false); walletProfile.address = address; final sub = Provider.of(context, listen: false); - HomeProvider homeProvider = - Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); @@ -115,7 +113,7 @@ class WalletViewScreen extends StatelessWidget { '?' ]))), ), - bottomNavigationBar: homeProvider.bottomAppBar(context), + bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Column(children: [ HeaderProfile(address: address, username: username), diff --git a/lib/widgets/bottom_app_bar.dart b/lib/widgets/bottom_app_bar.dart new file mode 100644 index 0000000..4b2737c --- /dev/null +++ b/lib/widgets/bottom_app_bar.dart @@ -0,0 +1,117 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.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/wallets_profiles.dart'; +import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/screens/myWallets/wallets_home.dart'; +import 'package:gecko/screens/search.dart'; +import 'package:provider/provider.dart'; + +class GeckoBottomAppBar extends StatelessWidget { + const GeckoBottomAppBar({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final myWalletProvider = + Provider.of(context, listen: false); + WalletsProfilesProvider historyProvider = + Provider.of(context, listen: false); + + final size = MediaQuery.of(context).size; + + const bool showBottomBar = true; + + return Visibility( + visible: showBottomBar, + child: Container( + color: yellowC, + width: size.width, + height: 80, + child: + // Stack( + // children: [ + // // CustomPaint( + // // size: Size(size.width, 110), + // // painter: CustomRoundedButton(), + // // ), + Row(mainAxisAlignment: MainAxisAlignment.start, children: [ + // SizedBox(width: 0), + const Spacer(), + const SizedBox(width: 11), + IconButton( + key: keyAppBarSearch, + iconSize: 40, + icon: const Image(image: AssetImage('assets/loupe-noire.png')), + onPressed: () { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + Navigator.push( + context, + MaterialPageRoute(builder: (homeContext) { + return const SearchScreen(); + }), + ); + }, + ), + const SizedBox(width: 22), + const Spacer(), + IconButton( + key: keyAppBarQrcode, + iconSize: 70, + icon: const Image(image: AssetImage('assets/qrcode-scan.png')), + onPressed: () async { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + historyProvider.scan(homeContext); + }, + ), + const Spacer(), + const SizedBox(width: 15), + IconButton( + key: keyAppBarChest, + iconSize: 60, + icon: const Image(image: AssetImage('assets/wallet.png')), + onPressed: () async { + WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); + String? pin; + if (myWalletProvider.pinCode == '') { + pin = await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + } + + if (pin != null || myWalletProvider.pinCode != '') { + Navigator.popUntil( + context, + ModalRoute.withName('/'), + ); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const WalletsHome(); + }), + ); + } + }, + ), + const Spacer(), + ]), + ), + ); + } +} diff --git a/lib/widgets/idty_status.dart b/lib/widgets/idty_status.dart index 51d0078..a5cda45 100644 --- a/lib/widgets/idty_status.dart +++ b/lib/widgets/idty_status.dart @@ -22,23 +22,6 @@ class IdentityStatus extends StatelessWidget { Widget build(BuildContext context) { final duniterIndexer = Provider.of(context, listen: false); - showText(String text, - [double size = 18, bool bold = false, bool smooth = true]) { - // log.d('$address $text'); - return AnimatedFadeOutIn( - data: text, - duration: Duration(milliseconds: smooth ? 200 : 0), - builder: (value) => Text( - value, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: size, - color: bold ? color : Colors.black, - fontWeight: bold ? FontWeight.w500 : FontWeight.w400), - ), - ); - } - return Consumer(builder: (context, sub, _) { return FutureBuilder( future: sub.idtyStatus(address), @@ -59,10 +42,8 @@ class IdentityStatus extends StatelessWidget { return isOwner ? showText('identityConfirmed'.tr()) : NameByAddress( - address: address, wallet: WalletData(address: address), size: 20, - canEdit: true, color: Colors.grey[700]!, fontWeight: FontWeight.w500, fontStyle: FontStyle.italic); @@ -72,10 +53,8 @@ class IdentityStatus extends StatelessWidget { return isOwner ? showText('memberValidated'.tr(), 18, true) : NameByAddress( - address: address, wallet: WalletData(address: address), size: 20, - canEdit: true, color: Colors.black, fontWeight: FontWeight.w600, fontStyle: FontStyle.normal); @@ -91,4 +70,21 @@ class IdentityStatus extends StatelessWidget { }); }); } + + AnimatedFadeOutIn showText(String text, + [double size = 18, bool bold = false, bool smooth = true]) { + // log.d('$address $text'); + return AnimatedFadeOutIn( + data: text, + duration: Duration(milliseconds: smooth ? 200 : 0), + builder: (value) => Text( + value, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: size, + color: bold ? color : Colors.black, + fontWeight: bold ? FontWeight.w500 : FontWeight.w400), + ), + ); + } } diff --git a/lib/widgets/name_by_address.dart b/lib/widgets/name_by_address.dart index bdaf32a..dd26abc 100644 --- a/lib/widgets/name_by_address.dart +++ b/lib/widgets/name_by_address.dart @@ -5,7 +5,6 @@ import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/widgets/wallet_name.dart'; -import 'package:gecko/widgets/wallet_name_controller.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:provider/provider.dart'; import 'package:truncate/truncate.dart'; @@ -13,19 +12,15 @@ import 'package:truncate/truncate.dart'; class NameByAddress extends StatelessWidget { const NameByAddress( {Key? key, - required this.address, required this.wallet, this.size = 20, - this.canEdit = false, this.color = Colors.black, this.fontWeight = FontWeight.w400, this.fontStyle = FontStyle.italic}) : super(key: key); - final String address; final WalletData wallet; final Color color; final double size; - final bool canEdit; final FontWeight fontWeight; final FontStyle fontStyle; @@ -34,12 +29,9 @@ class NameByAddress extends StatelessWidget { final duniterIndexer = Provider.of(context, listen: false); if (indexerEndpoint == '') { - if (canEdit) { - return WalletNameController(wallet: wallet, size: size); - } else { - return WalletName(wallet: wallet, size: size, color: color); - } + return WalletName(wallet: wallet, size: size, color: color); } + final httpLink = HttpLink( '$indexerEndpoint/v1/graphql', ); @@ -57,7 +49,7 @@ class NameByAddress extends StatelessWidget { document: gql( getNameByAddressQ), // this is the query string you just created variables: { - 'address': address, + 'address': wallet.address, }, // pollInterval: const Duration(seconds: 10), ), @@ -71,29 +63,27 @@ class NameByAddress extends StatelessWidget { return const Text('Loading'); } - duniterIndexer.walletNameIndexer[address] = + duniterIndexer.walletNameIndexer[wallet.address] = result.data?['account_by_pk']?['identity']?['name']; g1WalletsBox.put( - address, + wallet.address, G1WalletsList( - address: address, - username: duniterIndexer.walletNameIndexer[address])); + address: wallet.address, + username: + duniterIndexer.walletNameIndexer[wallet.address])); // log.d(g1WalletsBox.toMap().values.first.username); - if (duniterIndexer.walletNameIndexer[address] == null) { - if (canEdit) { - return WalletNameController(wallet: wallet, size: size); - } else { - return WalletName(wallet: wallet, size: size, color: color); - } + if (duniterIndexer.walletNameIndexer[wallet.address] == null) { + return WalletName(wallet: wallet, size: size, color: color); } return Text( color == Colors.grey[700]! - ? '(${duniterIndexer.walletNameIndexer[address]!})' - : truncate(duniterIndexer.walletNameIndexer[address]!, 20), + ? '(${duniterIndexer.walletNameIndexer[wallet.address]!})' + : truncate( + duniterIndexer.walletNameIndexer[wallet.address]!, 20), style: TextStyle( fontSize: size, color: color, diff --git a/lib/widgets/wallet_name_controller.dart b/lib/widgets/wallet_name_controller.dart deleted file mode 100644 index e5bf0ba..0000000 --- a/lib/widgets/wallet_name_controller.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; -import 'package:gecko/models/wallet_data.dart'; -import 'package:gecko/models/widgets_keys.dart'; -import 'package:gecko/providers/wallet_options.dart'; -import 'package:provider/provider.dart'; - -class WalletNameController extends StatelessWidget { - const WalletNameController({Key? key, required this.wallet, this.size = 20}) - : super(key: key); - final WalletData wallet; - final double size; - - @override - Widget build(BuildContext context) { - final walletOptions = - Provider.of(context, listen: false); - walletOptions.nameController.text = wallet.name ?? ''; - final walletNameFocus = FocusNode(); - - return SizedBox( - width: 260, - child: Stack(children: [ - TextField( - key: keyWalletName, - autofocus: false, - focusNode: walletNameFocus, - enabled: walletOptions.isEditing, - controller: walletOptions.nameController, - minLines: 1, - maxLines: 3, - textAlign: TextAlign.center, - decoration: const InputDecoration( - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - disabledBorder: InputBorder.none, - contentPadding: EdgeInsets.all(15.0), - ), - style: TextStyle( - fontSize: isTall ? size : size * 0.9, - color: Colors.black, - fontWeight: FontWeight.w400, - ), - ), - Positioned( - right: 0, - child: InkWell( - key: keyRenameWallet, - onTap: () async { - await walletOptions.editWalletName(context, wallet.id()); - await Future.delayed(const Duration(milliseconds: 30)); - walletNameFocus.requestFocus(); - }, - child: ClipRRect( - child: Image.asset( - walletOptions.isEditing - ? 'assets/walletOptions/android-checkmark.png' - : 'assets/walletOptions/edit.png', - width: 25, - height: 25), - ), - ), - ), - ]), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index aafc483..320ac0b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -287,7 +287,7 @@ packages: name: decimal url: "https://pub.dartlang.org" source: hosted - version: "2.3.1" + version: "2.3.2" dio: dependency: "direct main" description: @@ -1075,7 +1075,7 @@ packages: name: rational url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "2.2.2" responsive_framework: dependency: "direct main" description: @@ -1110,14 +1110,14 @@ packages: name: sentry url: "https://pub.dartlang.org" source: hosted - version: "6.17.0" + version: "6.18.0" sentry_flutter: dependency: "direct main" description: name: sentry_flutter url: "https://pub.dartlang.org" source: hosted - version: "6.17.0" + version: "6.18.0" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index cbd0b16..cfa10c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,11 +23,11 @@ dependencies: image_picker: ^0.8.4 jdenticon_dart: ^2.0.0 logger: ^1.1.0 - path_provider: ^2.0.9 + path_provider: ^2.0.11 pdf: ^3.7.1 permission_handler: ^10.0.0 pin_code_fields: ^7.4.0 - printing: ^5.9.1 + printing: ^5.9.3 provider: ^6.0.1 barcode_scan2: ^4.2.1 qr_flutter: #^4.0.0 @@ -35,7 +35,7 @@ dependencies: url: https://github.com/insinfo/qr.flutter.git ref: master responsive_framework: ^0.2.0 - sentry_flutter: ^6.5.1 + sentry_flutter: ^6.18.0 shared_preferences: ^2.0.7 truncate: ^3.0.1 unorm_dart: ^0.2.0