diff --git a/assets/avatars/0.png b/assets/avatars/0.png index 47e563e..98804aa 100755 Binary files a/assets/avatars/0.png and b/assets/avatars/0.png differ diff --git a/assets/avatars/1.png b/assets/avatars/1.png index 26b5786..8e3ce19 100755 Binary files a/assets/avatars/1.png and b/assets/avatars/1.png differ diff --git a/assets/avatars/2.png b/assets/avatars/2.png index 9271e58..19dfa74 100755 Binary files a/assets/avatars/2.png and b/assets/avatars/2.png differ diff --git a/assets/avatars/3.png b/assets/avatars/3.png index 452efff..605b620 100755 Binary files a/assets/avatars/3.png and b/assets/avatars/3.png differ diff --git a/assets/translations/en.json b/assets/translations/en.json index f49029c..cbecb40 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -159,8 +159,8 @@ "days": "{} days", "months": "{} months", "certify": "Certify this\nidentity", - "from": "From:", - "to": "To:", + "from": "From:{}", + "to": "To:{}", "amount": "Amount:", "choiceOfSourceWallet": "Choose a source wallet", "extrinsicInProgress": "{} in progress", @@ -171,16 +171,18 @@ "cancel": "Cancel", "inBlockchainResult": "In {} blockchain", "search": "Search an identity\nor an address", - "currencyNode": "{} node :", + "currencyNode": "node", "contactsManagementWithNbr": "My contacts ({})", "contactsManagement": "My contacts", "noContacts": "You don't have any contact", "addContact": "Add\nto contacts", "removeContact": "Remove\nthis contact", - "derivationsScanProgress": "Scan address {}/{}", + "scanRootDerivationInProgress": "Scan root address", + "derivationsScanProgress": "Scan {} firsts addresses", + "importDerivationsInProgress": "Import address {}/{}", "youAreOffline": "You are offline...", "importG1v1": "Import old G1v1 account", - "selectDestWallet": "Select a target wallet:", + "migrateToThisWallet": "Migrate to this wallet:", "youMustWaitBeforeCashoutThisAccount": "You have to wait a few moment before migrate this account", "thisAccountIsEmpty": "This account is empty", "youCannotMigrateIdentityToExistingIdentity": "You cannot migrate an identity\nto an account that already has an identity", diff --git a/assets/translations/es.json b/assets/translations/es.json index bb7a1d4..466a36a 100644 --- a/assets/translations/es.json +++ b/assets/translations/es.json @@ -160,8 +160,8 @@ "days": "{} dias", "months": "{} meses", "certify": "Certificar esta\nidentidad", - "from": "De:", - "to": "A:", + "from": "De:{}", + "to": "A:{}", "amount": "Importe:", "choiceOfSourceWallet": "Elige un monedero de origen", "extrinsicInProgress": "{} en progreso", @@ -172,16 +172,18 @@ "cancel": "Cancelar", "inBlockchainResult": "En la blockchain {}", "search": "Buscar una identidad\no una dirección", - "currencyNode": "Nodo {} :", + "currencyNode": "Nodo", "contactsManagementWithNbr": "Mis contactos ({})", "contactsManagement": "Mis contactos", "noContacts": "No tienes ningún contacto", "addContact": "Añadir\na contactos", "removeContact": "Eliminar\neste contacto", - "derivationsScanProgress": "Escaneado de la dirección {}/{}", + "scanRootDerivationInProgress": "Scan root address", + "derivationsScanProgress": "Scan {} firsts addresses", + "importDerivationsInProgress": "Import address {}/{}", "youAreOffline": "Estás desconectado...", "importG1v1": "Importar la cuenta antigua de G1v1", - "selectDestWallet": "Selecciona un monedero destino:", + "migrateToThisWallet": "Migrate to this wallet:", "youMustWaitBeforeCashoutThisAccount": "Tienes que esperar unos minutos antes de migrar esta cuenta", "thisAccountIsEmpty": "Esta cuenta está vacía", "youCannotMigrateIdentityToExistingIdentity": "No se puede migrar una identidad\na una cuenta que ya tiene una identidad", diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 445e827..3286cce 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -159,8 +159,8 @@ "days": "{} jours", "months": "{} mois", "certify": "Certifier cette\nidentité", - "from": "Depuis:", - "to": "Vers:", + "from": "Depuis:{}", + "to": "Vers:{}", "amount": "Montant:", "choiceOfSourceWallet": "Choix du portefeuille source", "extrinsicInProgress": "{} en cours", @@ -171,16 +171,18 @@ "cancel": "Annuler", "inBlockchainResult": "Dans la blockchain {}", "search": "Rechercher une identité\nou une adresse", - "currencyNode": "Noeud {} :", + "currencyNode": "Noeud", "contactsManagementWithNbr": "Mes contacts ({})", "contactsManagement": "Mes contacts", "noContacts": "Vous n'avez aucun contact", "addContact": "Ajouter\naux contacts", "removeContact": "Supprimer\nce contact", - "derivationsScanProgress": "Scan de l'adresse {}/{}", + "scanRootDerivationInProgress": "Scan de l'adresse racine", + "derivationsScanProgress": "Scan des {} premières adresses", + "importDerivationsInProgress": "Importation de l'adresse {}/{}", "youAreOffline": "Vous êtes hors ligne...", "importG1v1": "Importer un ancien compte G1v1", - "selectDestWallet": "Sélectionnez un portefeuille cible:", + "migrateToThisWallet": "Migrer vers ce portefeuille:", "youMustWaitBeforeCashoutThisAccount": "Vous devez attendre quelques minutes\navant de pouvoir migrer ce compte", "thisAccountIsEmpty": "Ce compte est vide", "youCannotMigrateIdentityToExistingIdentity": "Vous ne pouvez pas migrer une identité\nvers un compte disposant déjà d'une identité", diff --git a/assets/translations/it.json b/assets/translations/it.json index b2fa492..876b688 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -172,7 +172,7 @@ "cancel": "Annulla", "inBlockchainResult": "Nella blockchain {}", "search": "Cerca una identitá\no un indirizzo", - "currencyNode": "Nodo {} :", + "currencyNode": "Nodo", "contactsManagementWithNbr": "I miei contatti ({})", "contactsManagement": "I miei contatti", "noContacts": "Non ci sono contatti salvati", @@ -181,7 +181,7 @@ "derivationsScanProgress": "Scannerizzando l'indirizzo {}/{}", "youAreOffline": "Disconnesso...", "importG1v1": "Importa il conto antico da G1v1, versione precedente", - "selectDestWallet": "Seleziona un portafoglio di destinazione:", + "migrateToThisWallet": "Seleziona un portafoglio di destinazione:", "youMustWaitBeforeCashoutThisAccount": "Devi aspettare qualche minuto prima di migrare questo conto", "thisAccountIsEmpty": "Questo conto é vuoto", "youCannotMigrateIdentityToExistingIdentity": "Non si puó migrare un'identitá\na un conto che ne ha giá una", diff --git a/config/indexer_endpoints.json b/config/indexer_endpoints.json index d283564..b5e967e 100644 --- a/config/indexer_endpoints.json +++ b/config/indexer_endpoints.json @@ -1,4 +1,3 @@ [ - "https://gdev-indexer.p2p.legal", "https://hasura.gdev.coinduf.eu" ] diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..7e7e7f6 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/integration_test/scenarios/gecko_complete.dart b/integration_test/scenarios/gecko_complete.dart index 0671b08..b5f87a5 100644 --- a/integration_test/scenarios/gecko_complete.dart +++ b/integration_test/scenarios/gecko_complete.dart @@ -100,7 +100,7 @@ Future certifyTest5() async { await waitFor('thisWalletIsDefault'.tr()); // Search Wallet 5 again - await tapKey(keyAppBarSearch); + await tapKey(keyAppBarHome); final addressToSearch = await clipPaste(); final endAddress = addressToSearch.substring(addressToSearch.length - 6); expect(addressToSearch, test5.address); diff --git a/integration_test/utility/general_actions.dart b/integration_test/utility/general_actions.dart index a92f7a2..3da4198 100644 --- a/integration_test/utility/general_actions.dart +++ b/integration_test/utility/general_actions.dart @@ -11,7 +11,6 @@ import 'tests_utility.dart'; Future changeNode() async { const ipAddress = '10.0.2.2'; - log.d('ip address: $ipAddress'); await tapKey(keyDrawerMenu); await tapKey(keyParameters); diff --git a/integration_test/utility/tests_utility.dart b/integration_test/utility/tests_utility.dart index d9357d7..9a24d6e 100644 --- a/integration_test/utility/tests_utility.dart +++ b/integration_test/utility/tests_utility.dart @@ -11,9 +11,7 @@ import 'package:provider/provider.dart'; import 'dart:io' as io; import 'package:gecko/main.dart' as app; -const bool isHumanReading = false; -// final bool isHumanReading = -// dotenv.env['isHumanReading'] == 'true' ? true : false; +const isHumanReading = false; Timeout testTimeout([int seconds = 120]) => Timeout(Duration(seconds: isHumanReading ? 600 : seconds)); final sub = Provider.of(homeContext, listen: false); @@ -57,7 +55,7 @@ Future pump( {Duration duration = const Duration(milliseconds: 300), int number = 1}) async { for (int i = 0; i < number; i++) { - log.d("pump $i"); + log.i("pump $i"); await tester.pump(duration = duration); } } @@ -78,7 +76,7 @@ Future tapKey(Key buttonKey, await tester.pumpAndSettle(Duration(milliseconds: duration)); } final Finder finder = customFinder ?? find.byKey(buttonKey); - log.d('INTEGRATION TEST: Tap on ${finder.describeMatch(Plurality.zero)}}'); + log.i('INTEGRATION TEST: Tap on ${finder.describeMatch(Plurality.zero)}}'); await tester.tap(selectLast ? finder.last : finder); humanRead(); } @@ -106,7 +104,7 @@ Future waitForButtonEnabled(Key key, bool reverse = false}) async { final end = DateTime.now().add(timeout); - log.d('INTEGRATION TEST: Wait for $key to be enabled'); + log.i('INTEGRATION TEST: Wait for $key to be enabled'); do { if (DateTime.now().isAfter(end)) { @@ -121,7 +119,7 @@ Future waitForButtonEnabled(Key key, Future goBack() async { final NavigatorState navigator = tester.state(find.byType(Navigator)); - log.d('INTEGRATION TEST: Go back'); + log.i('INTEGRATION TEST: Go back'); navigator.pop(); await tester.pumpAndSettle(); humanRead(); @@ -131,7 +129,7 @@ Future enterText(Key fieldKey, String textIn, [int duration = 200]) async { if (duration != 0) { await tester.pumpAndSettle(Duration(milliseconds: duration)); } - log.d('INTEGRATION TEST: Enter text: $textIn'); + log.i('INTEGRATION TEST: Enter text: $textIn'); await tester.enterText(find.byKey(fieldKey), textIn); humanRead(); } @@ -145,7 +143,7 @@ Future waitFor(String text, final end = DateTime.now().add(timeout); Finder finder = exactMatch ? find.text(text) : find.textContaining(text); - log.d('INTEGRATION TEST: Wait for: $text'); + log.i('INTEGRATION TEST: Wait for: $text'); final searchType = reverse ? 'reversed text' : 'text'; @@ -182,7 +180,7 @@ Future isIconPresent(IconData icon, await tester.pumpAndSettle(); final finder = find.byIcon(icon); humanRead(); - return finder.evaluate().isEmpty ? false : true; + return finder.evaluate().isNotEmpty; } Future spawnBlock({int number = 1, int duration = 200, int? until}) async { @@ -240,7 +238,7 @@ Future bkSetNode([String? endpoint]) async { endpoint = 'ws://$ipAddress:9944'; } configBox.put('customEndpoint', endpoint); - sub.connectNode(homeContext); + sub.connectNode(); } // Restore chest in background diff --git a/lib/globals.dart b/lib/globals.dart index ac34913..7621851 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -8,7 +8,7 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:logger/logger.dart'; // Version of box data -const int dataVersion = 7; +const int dataVersion = 8; late String appVersion; const int pinLength = 5; @@ -21,15 +21,16 @@ late Box configBox; late Box g1WalletsBox; late Box contactsBox; // late Box keystoreBox; -late Directory imageDirectory; +late Directory avatarsDirectory; +late Directory avatarsCacheDirectory; +late bool isTall; -// String cesiumPod = "https://g1.data.le-sou.org"; -String cesiumPod = "https://g1.data.presles.fr"; +const cesiumPod = "https://g1.data.le-sou.org"; +// String cesiumPod = "https://g1.data.presles.fr"; // String cesiumPod = "https://g1.data.e-is.pro"; -// Responsive ratios -late bool isTall; -late double ratio; +const datapodEndpoint = 'https://gdev-datapod.p2p.legal'; +// const v2sDatapod = 'http://10.0.2.2:8080'; // Contexts late BuildContext homeContext; diff --git a/lib/main.dart b/lib/main.dart index be1d63a..79bb836 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,12 +20,12 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.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'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -54,7 +54,7 @@ Future main() async { // await dotenv.load(); // } - HomeProvider homeProvider = HomeProvider(); + final homeProvider = HomeProvider(); // DuniterIndexer _duniterIndexer = DuniterIndexer(); await initHiveForFlutter(); @@ -130,26 +130,23 @@ class Gecko extends StatelessWidget { ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()), ChangeNotifierProvider(create: (_) => WalletOptionsProvider()), ChangeNotifierProvider(create: (_) => SearchProvider()), - ChangeNotifierProvider(create: (_) => CesiumPlusProvider()), ChangeNotifierProvider(create: (_) => SubstrateSdk()), ChangeNotifierProvider(create: (_) => DuniterIndexer()), - ChangeNotifierProvider(create: (_) => SettingsProvider()) + ChangeNotifierProvider(create: (_) => SettingsProvider()), + ChangeNotifierProvider(create: (_) => V2sDatapodProvider()) ], child: MaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, - builder: (context, widget) => ResponsiveWrapper.builder( - BouncingScrollWrapper.builder(context, widget!), - maxWidth: 1200, - minWidth: 480, - defaultScale: true, - breakpoints: [ - const ResponsiveBreakpoint.resize(480, name: MOBILE), - const ResponsiveBreakpoint.autoScale(800, name: TABLET), - const ResponsiveBreakpoint.resize(1000, name: DESKTOP), - ], - background: Container(color: backgroundColor)), + builder: (context, child) => ResponsiveBreakpoints.builder( + child: child!, + breakpoints: [ + const Breakpoint(start: 0, end: 450, name: MOBILE), + const Breakpoint(start: 451, end: 800, name: TABLET), + const Breakpoint(start: 801, end: double.infinity, name: DESKTOP), + ], + ), title: 'Ğecko', theme: ThemeData( appBarTheme: const AppBarTheme( @@ -159,6 +156,7 @@ class Gecko extends StatelessWidget { primaryColor: const Color(0xffFFD58D), scaffoldBackgroundColor: backgroundColor, canvasColor: backgroundColor, + dialogBackgroundColor: backgroundColor, textTheme: const TextTheme( bodyLarge: TextStyle(fontSize: 16), bodyMedium: TextStyle(fontSize: 18), diff --git a/lib/models/g1_wallets_list.dart b/lib/models/g1_wallets_list.dart index 3fce1b3..3fe0695 100644 --- a/lib/models/g1_wallets_list.dart +++ b/lib/models/g1_wallets_list.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; part 'g1_wallets_list.g.dart'; @@ -15,22 +14,18 @@ class G1WalletsList { Id? id; @HiveField(3) - Image? avatar; - - @HiveField(4) String? username; - @HiveField(5) + @HiveField(4) String? csName; - @HiveField(6) + @HiveField(5) bool? isMembre; G1WalletsList({ required this.address, this.balance, this.id, - this.avatar, this.username, this.csName, this.isMembre, diff --git a/lib/models/g1_wallets_list.g.dart b/lib/models/g1_wallets_list.g.dart index 8b84c23..9a800f8 100644 --- a/lib/models/g1_wallets_list.g.dart +++ b/lib/models/g1_wallets_list.g.dart @@ -20,17 +20,16 @@ class G1WalletsListAdapter extends TypeAdapter { address: fields[0] as String, balance: fields[1] as double?, id: fields[2] as Id?, - avatar: fields[3] as Image?, - username: fields[4] as String?, - csName: fields[5] as String?, - isMembre: fields[6] as bool?, + username: fields[3] as String?, + csName: fields[4] as String?, + isMembre: fields[5] as bool?, ); } @override void write(BinaryWriter writer, G1WalletsList obj) { writer - ..writeByte(7) + ..writeByte(6) ..writeByte(0) ..write(obj.address) ..writeByte(1) @@ -38,12 +37,10 @@ class G1WalletsListAdapter extends TypeAdapter { ..writeByte(2) ..write(obj.id) ..writeByte(3) - ..write(obj.avatar) - ..writeByte(4) ..write(obj.username) - ..writeByte(5) + ..writeByte(4) ..write(obj.csName) - ..writeByte(6) + ..writeByte(5) ..write(obj.isMembre); } diff --git a/lib/models/migrate_wallet_checks.dart b/lib/models/migrate_wallet_checks.dart new file mode 100644 index 0000000..4b491fc --- /dev/null +++ b/lib/models/migrate_wallet_checks.dart @@ -0,0 +1,16 @@ +import 'package:gecko/models/wallet_data.dart'; + +class MigrateWalletChecks { + final Map balance; + final IdtyStatus idtyStatus; + final bool isSmith; + final String validationStatus; + final bool canValidate; + + const MigrateWalletChecks( + {required this.balance, + required this.idtyStatus, + required this.isSmith, + required this.validationStatus, + required this.canValidate}); +} diff --git a/lib/models/queries_datapod.dart b/lib/models/queries_datapod.dart new file mode 100644 index 0000000..8832f0c --- /dev/null +++ b/lib/models/queries_datapod.dart @@ -0,0 +1,42 @@ +const String updateProfileQ = r''' +mutation ($address: String!, $hash: String!, $signature: String!, $title: String, $description: String, $avatar: String, $geoloc: GeolocInput, $city: String, $socials: [SocialInput!]) { + updateProfile(address: $address, hash: $hash, signature: $signature, title: $title, description: $description, avatarBase64: $avatar, geoloc: $geoloc, city: $city, socials: $socials) { + message + success + } +} +'''; + +const String deleteProfileQ = r''' +mutation ($address: String!, $hash: String!, $signature: String!) { + deleteProfile(address: $address, hash: $hash, signature: $signature) { + message + success + } +} +'''; + +const String migrateProfileQ = r''' +mutation ($addressOld: String!, $addressNew: String!, $hash: String!, $signature: String!) { + migrateProfile(addressOld: $addressOld, addressNew: $addressNew, hash: $hash, signature: $signature) { + message + success + } +} +'''; + +const String getAvatarQ = r''' +query ($address: String!) { + profiles_by_pk(address: $address) { + avatar64 + } +} +'''; + +const String profileEditedAtQ = r''' +query ($address: String!) { + profiles_by_pk(address: $address) { + updated_at + } +} +'''; diff --git a/lib/models/scale_functions.dart b/lib/models/scale_functions.dart new file mode 100644 index 0000000..55c6458 --- /dev/null +++ b/lib/models/scale_functions.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; + +double scaleSize(double size) { + final scale = MediaQuery.of(homeContext).size.width / 375; + return size * scale; +} + +TextStyle scaledTextStyle({ + double fontSize = 16, + double? height, + FontStyle? fontStyle, + FontWeight? fontWeight, + Color? color, + List? shadows, + String? fontFamily, + double? letterSpacing, +}) { + return TextStyle( + fontSize: scaleSize(fontSize), + height: height, + fontWeight: fontWeight, + fontStyle: fontStyle, + color: color, + shadows: shadows, + fontFamily: fontFamily, + letterSpacing: letterSpacing, + ); +} + +class ScaledSizedBox extends SizedBox { + ScaledSizedBox({ + Key? key, + double? width, + double? height, + Widget? child, + }) : super( + key: key, + width: width != null ? scaleSize(width) : null, + height: height != null ? scaleSize(height) : null, + child: child, + ); +} diff --git a/lib/models/wallet_data.dart b/lib/models/wallet_data.dart index 428ad0f..431b807 100644 --- a/lib/models/wallet_data.dart +++ b/lib/models/wallet_data.dart @@ -1,4 +1,12 @@ +// ignore_for_file: use_build_context_synchronously + +import 'dart:io'; + +import 'package:gecko/globals.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:uuid/uuid.dart'; part 'wallet_data.g.dart'; @HiveType(typeId: 0) @@ -36,6 +44,9 @@ class WalletData extends HiveObject { @HiveField(10) List? certs; + @HiveField(11) + DateTime? profileUpdatedTime; + WalletData({ required this.address, this.chest, @@ -44,6 +55,7 @@ class WalletData extends HiveObject { this.derivation, this.imageDefaultPath, this.imageCustomPath, + this.profileUpdatedTime, this.isOwned = false, this.identityStatus = IdtyStatus.unknown, this.balance = 0, @@ -75,11 +87,47 @@ class WalletData extends HiveObject { return balance != 0; } + Future getUpdatedTime() async { + final datapod = Provider.of(homeContext, listen: false); + return await datapod.profileEditedAt(address); + } + + Future shouldUpdateProfile() async { + final remoteUpdatedProfile = await getUpdatedTime(); + late Duration difference; + if (profileUpdatedTime != null && remoteUpdatedProfile != null) { + difference = profileUpdatedTime!.difference(remoteUpdatedProfile); + } else if (remoteUpdatedProfile != null) { + return true; + } else { + difference = Duration.zero; + } + return difference.inSeconds.abs() >= 30; + } + + /// This method get the remote avatar on v2s-datapod only if needed, and store it on disk + Future getDatapodAvatar() async { + if (!await shouldUpdateProfile()) return; + + final datapod = Provider.of(homeContext, listen: false); + final avatarUuid = const Uuid().v4(); + + await datapod.getAvatar(address, saveOnDisk: true, uuid: avatarUuid); + + final avatarPath = '${avatarsDirectory.path}/$address-$avatarUuid'; + if (!await File(avatarPath).exists()) return; + + profileUpdatedTime = await getUpdatedTime(); + imageCustomPath = avatarPath; + + walletBox.put(address, this); + datapod.reload(); + } + bool hasCustomImage() { return imageCustomPath != null; } - // returns only the id part of the ':'-separated string List id() { return [chest, number]; } diff --git a/lib/models/wallet_data.g.dart b/lib/models/wallet_data.g.dart index bbd78a0..14c85c3 100644 --- a/lib/models/wallet_data.g.dart +++ b/lib/models/wallet_data.g.dart @@ -24,6 +24,7 @@ class WalletDataAdapter extends TypeAdapter { derivation: fields[4] as int?, imageDefaultPath: fields[5] as String?, imageCustomPath: fields[6] as String?, + profileUpdatedTime: fields[11] as DateTime?, isOwned: fields[7] as bool, identityStatus: fields[8] as IdtyStatus, balance: fields[9] as double, @@ -34,7 +35,7 @@ class WalletDataAdapter extends TypeAdapter { @override void write(BinaryWriter writer, WalletData obj) { writer - ..writeByte(11) + ..writeByte(12) ..writeByte(0) ..write(obj.address) ..writeByte(1) @@ -56,7 +57,9 @@ class WalletDataAdapter extends TypeAdapter { ..writeByte(9) ..write(obj.balance) ..writeByte(10) - ..write(obj.certs); + ..write(obj.certs) + ..writeByte(11) + ..write(obj.profileUpdatedTime); } @override diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index 88883a5..38bdfdf 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -5,7 +5,7 @@ const keyInfoPopup = Key('keyInfoPopup'); const keyGoNext = Key('keyGoNext'); const keyCancel = Key('keyCancel'); const keyConfirm = Key('keyConfirm'); -const keyAppBarSearch = Key('keyAppBarSearch'); +const keyAppBarHome = Key('keyAppBarSearch'); const keyAppBarQrcode = Key('keyAppBarQrcode'); const keyAppBarChest = Key('keyAppBarChest'); @@ -28,6 +28,7 @@ final keyDragAndDrop = GlobalKey(debugLabel: 'keyDragAndDrop'); // Wallet options const keyCopyAddress = Key('keyCopyAddress'); +const keyCopyPubkey = Key('keyCopyPubkey'); const keyOpenActivity = Key('keyOpenActivity'); const keyManageMembership = Key('keyManageMembership'); const keySetDefaultWallet = Key('keySetDefaultWallet'); diff --git a/lib/providers/cesium_plus.dart b/lib/providers/cesium_plus.dart deleted file mode 100644 index bfc630b..0000000 --- a/lib/providers/cesium_plus.dart +++ /dev/null @@ -1,159 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'package:dio/dio.dart'; -import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; -import 'package:path_provider/path_provider.dart'; -// import 'package:http/http.dart' as http; - -class CesiumPlusProvider with ChangeNotifier { - TextEditingController cesiumName = TextEditingController(); - - CancelToken avatarCancelToken = CancelToken(); - - Future _buildQuery(pubkey) async { - var queryGetAvatar = json.encode({ - "query": { - "bool": { - "should": [ - { - "match": { - '_id': {"query": pubkey, "boost": 2} - } - }, - { - "prefix": {'_id': pubkey} - } - ] - } - }, - "highlight": { - "fields": {"title": {}, "tags": {}} - }, - "from": 0, - "size": 100, - "_source": [ - "title", - "avatar", - "avatar._content_type", - "description", - "city", - "address", - "socials.url", - "creationTime", - "membersCount", - "type" - ], - "indices_boost": {"user": 100, "page": 1, "group": 0.01} - }); - - String requestUrl = "/user,page,group/profile,record/_search"; - String podRequest = cesiumPod + requestUrl; - - Map headers = { - 'Content-type': 'application/json', - 'Accept': 'application/json', - }; - - return [podRequest, queryGetAvatar, headers]; - } - - Future getName(String? pubkey) async { - String? name; - - if (g1WalletsBox.get(pubkey)?.csName != null) { - return g1WalletsBox.get(pubkey)!.csName!; - } - - List queryOptions = await _buildQuery(pubkey); - - var dio = Dio(); - late Response response; - try { - response = await dio.post( - queryOptions[0], - data: queryOptions[1], - options: Options( - headers: queryOptions[2], - sendTimeout: const Duration(seconds: 3), - receiveTimeout: const Duration(seconds: 5), - ), - ); - // response = await http.post((Uri.parse(queryOptions[0])), - // body: queryOptions[1], headers: queryOptions[2]); - } catch (e) { - log.e(e); - } - - if (response.data['hits']['hits'].toString() == '[]') { - return ''; - } - final bool nameExist = - response.data['hits']['hits'][0]['_source'].containsKey("title"); - if (!nameExist) { - return ''; - } - name = response.data['hits']['hits'][0]['_source']['title']; - - name ??= ''; - g1WalletsBox.get(pubkey)!.csName = name; - - return name; - } - - Future getAvatar(String? pubkey, double size) async { - if (g1WalletsBox.get(pubkey)?.avatar != null) { - return g1WalletsBox.get(pubkey)!.avatar; - } - var dio = Dio(); - - // log.d(_pubkey); - - List queryOptions = await _buildQuery(pubkey); - - late Response response; - try { - response = await dio - .post(queryOptions[0], - data: queryOptions[1], - options: Options( - headers: queryOptions[2], - sendTimeout: const Duration(seconds: 4), - receiveTimeout: const Duration(seconds: 15), - ), - cancelToken: avatarCancelToken) - .timeout( - const Duration(seconds: 15), - ); - // response = await http.post((Uri.parse(queryOptions[0])), - // body: queryOptions[1], headers: queryOptions[2]); - } catch (e) { - log.e(e); - } - - if (response.data['hits']['hits'].toString() == '[]' || - !response.data['hits']['hits'][0]['_source'].containsKey("avatar")) { - return defaultAvatar(size); - } - - final avatar = - response.data['hits']['hits'][0]['_source']['avatar']['_content']; - - var avatarFile = - File('${(await getTemporaryDirectory()).path}/avatar_$pubkey.png'); - await avatarFile.writeAsBytes(base64.decode(avatar)); - - final finalAvatar = Image.file( - avatarFile, - height: size, - fit: BoxFit.fitWidth, - ); - - g1WalletsBox.get(pubkey)!.avatar = finalAvatar; - - return finalAvatar; - } -} - -Image defaultAvatar(double size) => - Image.asset(('assets/icon_user.png'), height: size); diff --git a/lib/providers/chest_provider.dart b/lib/providers/chest_provider.dart index b15a7b8..b80e7b3 100644 --- a/lib/providers/chest_provider.dart +++ b/lib/providers/chest_provider.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -42,7 +43,6 @@ class ChestProvider with ChangeNotifier { List getChestWallets(ChestData chest) { List toDelete = []; - log.d(chest.key); walletBox.toMap().forEach((key, WalletData value) { if (value.chest == chest.key) { toDelete.add(value.address); @@ -54,19 +54,27 @@ class ChestProvider with ChangeNotifier { Future _confirmDeletingChest(context, String? walletName) async { return showDialog( context: context, - barrierDismissible: true, // user must tap button! + barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( - title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])), + title: Text( + 'areYouSureToDeleteWallet'.tr(args: [walletName!]), + style: scaledTextStyle(fontSize: 17), + ), actions: [ TextButton( - child: Text("no".tr(), key: keyCancel), + child: Text("no".tr(), + style: + scaledTextStyle(fontSize: 17, color: Colors.blueAccent), + key: keyCancel), onPressed: () { Navigator.pop(context, false); }, ), TextButton( - child: Text("yes".tr(), key: keyConfirm), + child: Text("yes".tr(), + style: scaledTextStyle(fontSize: 17, color: Colors.red), + key: keyConfirm), onPressed: () { Navigator.pop(context, true); }, diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index 365b018..bd1f98d 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -30,7 +30,7 @@ class DuniterIndexer with ChangeNotifier { final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql')); final response = await request.close(); if (response.statusCode != 200) { - log.d('INDEXER IS OFFLINE'); + log.w('INDEXER IS OFFLINE'); indexerEndpoint = ''; isLoadingIndexer = false; notifyListeners(); @@ -46,7 +46,7 @@ class DuniterIndexer with ChangeNotifier { return true; } } catch (e) { - log.d('INDEXER IS OFFLINE'); + log.w('INDEXER IS OFFLINE'); indexerEndpoint = ''; isLoadingIndexer = false; notifyListeners(); @@ -54,21 +54,6 @@ class DuniterIndexer with ChangeNotifier { } } - // Future checkIndexerEndpointBackground() async { - // final oldEndpoint = indexerEndpoint; - // while (true) { - // await Future.delayed(const Duration(seconds: 30)); - // final isValid = await checkIndexerEndpoint(oldEndpoint); - // if (!isValid) { - // log.d('INDEXER IS OFFILINE'); - // indexerEndpoint = ''; - // } else { - // // log.d('Indexer is online'); - // indexerEndpoint = oldEndpoint; - // } - // } - // } - Future getValidIndexerEndpoint() async { // await configBox.delete('indexerEndpoint'); @@ -77,14 +62,14 @@ class DuniterIndexer with ChangeNotifier { .then((jsonStr) => jsonDecode(jsonStr)); // _listEndpoints.shuffle(); - log.d(listIndexerEndpoints); listIndexerEndpoints.add('Personnalisé'); if (configBox.containsKey('customIndexer')) { return configBox.get('customIndexer'); } - if (configBox.containsKey('indexerEndpoint')) { + if (configBox.containsKey('indexerEndpoint') && + listIndexerEndpoints.contains(configBox.get('indexerEndpoint'))) { if (await checkIndexerEndpoint(configBox.get('indexerEndpoint'))) { return configBox.get('indexerEndpoint'); } @@ -98,7 +83,7 @@ class DuniterIndexer with ChangeNotifier { client.connectionTimeout = const Duration(milliseconds: 3000); do { - int listLenght = listIndexerEndpoints.length - 1; + final listLenght = listIndexerEndpoints.length - 1; if (i >= listLenght) { log.e('NO VALID INDEXER ENDPOINT FOUND'); indexerEndpoint = ''; @@ -111,7 +96,7 @@ class DuniterIndexer with ChangeNotifier { } try { - String endpointPath = '${listIndexerEndpoints[i]}/v1/graphql'; + final endpointPath = '${listIndexerEndpoints[i]}/v1/graphql'; final request = await client.postUrl(Uri.parse(endpointPath)); final response = await request.close(); @@ -139,7 +124,7 @@ class DuniterIndexer with ChangeNotifier { } } while (statusCode != 200); - log.i('INDEXER: $indexerEndpoint'); + log.i('Indexer: $indexerEndpoint'); return indexerEndpoint; } @@ -202,7 +187,7 @@ class DuniterIndexer with ChangeNotifier { if (fetchMoreCursor != null) { transBC = parseHistory(blockchainTX, pubkey); } else { - log.i("###### DEBUG H - Début de l'historique"); + log.d("Activity start of $pubkey"); } return opts; @@ -221,7 +206,7 @@ Future isIdtyExist(String name) async { 'name': name, }; final result = await _execQuery(isIdtyExistQ, variables); - return result.data!['identity']?.isEmpty ?? false ? false : true; + return result.data!['identity']?.isNotEmpty ?? false; } Future getBlockStart() async { @@ -310,12 +295,6 @@ Map computeHistoryView(repository, String address) { bool isMigrationTime = startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0; - //TODO: Migration date and transaction migration doesn't match, add this event to v2s indexer. - - // log.d('debug date transaction: $date'); - // log.d('debug date identity migration: ${sub.oldOwnerKeys[address]?[1]}'); - // isChangeOwnerkeyTime = date.compareTo(sub.oldOwnerKeys[address]?[1] ?? DateTime(2000)) < 0; - return { 'finalAmount': finalAmount, 'isMigrationTime': isMigrationTime, diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index 8ac8834..ec283af 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -9,6 +9,7 @@ import 'package:gecko/models/bip39_words.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/widgets/scan_derivations_info.dart'; import 'package:polkawallet_sdk/api/apiKeyring.dart'; import 'package:provider/provider.dart'; import "package:unorm_dart/unorm_dart.dart" as unorm; @@ -19,6 +20,7 @@ class GenerateWalletsProvider with ChangeNotifier { final walletNameFocus = FocusNode(); Color? askedWordColor = Colors.black; bool isAskedWordValid = false; + var scanStatus = ScanDerivationsStatus.none; int scanedValidWalletNumber = -1; int scanedWalletNumber = -1; int numberScan = 60; @@ -33,27 +35,27 @@ class GenerateWalletsProvider with ChangeNotifier { final pin = TextEditingController(); // Import wallet - TextEditingController cesiumID = TextEditingController(); - TextEditingController cesiumPWD = TextEditingController(); - TextEditingController cesiumPubkey = TextEditingController(); + final cesiumID = TextEditingController(); + final cesiumPWD = TextEditingController(); + final cesiumPubkey = TextEditingController(); bool isCesiumIDVisible = false; bool isCesiumPWDVisible = false; bool canImport = false; late durt.CesiumWallet cesiumWallet; // Import Chest - TextEditingController cellController0 = TextEditingController(); - TextEditingController cellController1 = TextEditingController(); - TextEditingController cellController2 = TextEditingController(); - TextEditingController cellController3 = TextEditingController(); - TextEditingController cellController4 = TextEditingController(); - TextEditingController cellController5 = TextEditingController(); - TextEditingController cellController6 = TextEditingController(); - TextEditingController cellController7 = TextEditingController(); - TextEditingController cellController8 = TextEditingController(); - TextEditingController cellController9 = TextEditingController(); - TextEditingController cellController10 = TextEditingController(); - TextEditingController cellController11 = TextEditingController(); + final cellController0 = TextEditingController(); + final cellController1 = TextEditingController(); + final cellController2 = TextEditingController(); + final cellController3 = TextEditingController(); + final cellController4 = TextEditingController(); + final cellController5 = TextEditingController(); + final cellController6 = TextEditingController(); + final cellController7 = TextEditingController(); + final cellController8 = TextEditingController(); + final cellController9 = TextEditingController(); + final cellController10 = TextEditingController(); + final cellController11 = TextEditingController(); bool isFirstTimeSentenceComplete = true; Future storeHDWChest(BuildContext context) async { @@ -83,18 +85,14 @@ class GenerateWalletsProvider with ChangeNotifier { final expectedWord = mnemo.split(' ')[nbrWord]; final normInputWord = unorm.nfkd(inputWord); - log.i("Is $expectedWord equal to input $normInputWord ?"); if (expectedWord == normInputWord || (kDebugMode && inputWord == 'triche')) { - log.d('Word is OK'); isAskedWordValid = true; askedWordColor = Colors.green[600]; - // walletNameFocus.nextFocus(); notifyListeners(); } else { isAskedWordValid = false; } - // notifyListeners(); } String removeDiacritics(String str) { @@ -153,7 +151,6 @@ class GenerateWalletsProvider with ChangeNotifier { String walletPubkey = cesiumWallet.pubkey; cesiumPubkey.text = walletPubkey; - log.d(walletPubkey); } void cesiumIDisVisible() { @@ -200,7 +197,7 @@ class GenerateWalletsProvider with ChangeNotifier { if (bip39Words(appLang).contains(word.toLowerCase())) { for (var bipWord in bip39Words(appLang)) { if (bipWord.startsWith(word)) { - isValid = nbrMatch == 0 ? true : false; + isValid = nbrMatch == 0; if (checkRedondance) nbrMatch = nbrMatch + 1; } } @@ -296,7 +293,6 @@ class GenerateWalletsProvider with ChangeNotifier { final sub = Provider.of(context, listen: false); final currentChestNumber = configBox.get('currentChest'); bool isAlive = false; - scanedValidWalletNumber = 0; scanedWalletNumber = 0; Map addressToScan = {}; notifyListeners(); @@ -305,14 +301,14 @@ class GenerateWalletsProvider with ChangeNotifier { return false; } + scanStatus = ScanDerivationsStatus.rootScanning; final hasRoot = await scanRootBalance(sub, currentChestNumber); - scanedWalletNumber = 1; notifyListeners(); if (hasRoot) { - scanedValidWalletNumber = 1; isAlive = true; } + scanStatus = ScanDerivationsStatus.scanning; for (int derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) { final addressData = await sub.sdk.api.keyring.addressFromMnemonic( sub.currencyParameters['ss58']!, @@ -328,35 +324,36 @@ class GenerateWalletsProvider with ChangeNotifier { onTimeout: () => {}, ); - for (String scannedWallet in balanceList.keys) { - if (balanceList[scannedWallet]!['transferableBalance'] != 0) { - isAlive = true; - String walletName = scanedValidWalletNumber == 0 - ? 'currentWallet'.tr() - : '${'wallet'.tr()} ${scanedValidWalletNumber + 1}'; - await sub.importAccount( - mnemonic: generatedMnemonic!, - derivePath: "//${addressToScan[scannedWallet]}", - password: pin.text); + // Remove unused wallets + balanceList.removeWhere((key, value) => value['transferableBalance'] == 0); + scanedValidWalletNumber = balanceList.length + scanedWalletNumber; - WalletData myWallet = WalletData( - chest: currentChestNumber, - address: scannedWallet, - number: scanedValidWalletNumber, - name: walletName, - derivation: addressToScan[scannedWallet], - imageDefaultPath: '${scanedValidWalletNumber % 4}.png', - isOwned: true); - await walletBox.put(myWallet.address, myWallet); - scanedValidWalletNumber = scanedValidWalletNumber + 1; - } - scanedWalletNumber = scanedWalletNumber + 1; + scanStatus = ScanDerivationsStatus.import; + for (String scannedWallet in balanceList.keys) { + isAlive = true; + String walletName = scanedWalletNumber == 0 + ? 'currentWallet'.tr() + : '${'wallet'.tr()} ${scanedWalletNumber + 1}'; + await sub.importAccount( + mnemonic: generatedMnemonic!, + derivePath: "//${addressToScan[scannedWallet]}", + password: pin.text); + + WalletData myWallet = WalletData( + chest: currentChestNumber, + address: scannedWallet, + number: scanedWalletNumber, + name: walletName, + derivation: addressToScan[scannedWallet], + imageDefaultPath: '${scanedWalletNumber % 4}.png', + isOwned: true); + await walletBox.put(myWallet.address, myWallet); + scanedWalletNumber++; notifyListeners(); } - log.d(scanedWalletNumber); - scanedWalletNumber = -1; - scanedValidWalletNumber = -1; + scanStatus = ScanDerivationsStatus.none; + scanedWalletNumber = scanedValidWalletNumber = -1; notifyListeners(); return isAlive; } @@ -372,8 +369,6 @@ class GenerateWalletsProvider with ChangeNotifier { onTimeout: () => {}, ); - log.d( - "${addressData.address!}: ${balance['transferableBalance']} $currencyName"); if (balance['transferableBalance'] != 0) { String walletName = 'myRootWallet'.tr(); await sub.importAccount(mnemonic: generatedMnemonic!, password: pin.text); @@ -387,6 +382,7 @@ class GenerateWalletsProvider with ChangeNotifier { imageDefaultPath: '0.png', isOwned: true); await walletBox.put(myWallet.address, myWallet); + scanedWalletNumber++; return true; } else { return false; diff --git a/lib/providers/home.dart b/lib/providers/home.dart index 6535845..54bdcc1 100644 --- a/lib/providers/home.dart +++ b/lib/providers/home.dart @@ -1,14 +1,9 @@ -// ignore_for_file: use_build_context_synchronously - import 'dart:convert'; import 'dart:io'; import 'dart:math'; -// import 'package:audioplayers/audio_cache.dart'; -// import 'package:audioplayers/audioplayers.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - import 'dart:async'; import 'package:gecko/globals.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -23,7 +18,7 @@ import 'package:provider/provider.dart'; class HomeProvider with ChangeNotifier { bool? isSearching; Icon searchIcon = const Icon(Icons.search); - final TextEditingController searchQuery = TextEditingController(); + final searchQuery = TextEditingController(); Widget appBarTitle = Text('Ğecko', style: TextStyle(color: Colors.grey[850])); String homeMessage = "loading".tr(); String defaultMessage = "noLizard".tr(); @@ -53,10 +48,11 @@ class HomeProvider with ChangeNotifier { // Init app folders final documentDir = await getApplicationDocumentsDirectory(); - imageDirectory = Directory('${documentDir.path}/images'); + avatarsDirectory = Directory('${documentDir.path}/avatars'); + avatarsCacheDirectory = Directory('${documentDir.path}/avatarsCache'); - if (!await imageDirectory.exists()) { - await imageDirectory.create(); + if (!await avatarsDirectory.exists()) { + await avatarsDirectory.create(); } } @@ -109,7 +105,6 @@ class HomeProvider with ChangeNotifier { configBox.put('endpoint', listEndpoints); } - log.i('ENDPOINT: $listEndpoints'); return listEndpoints; } diff --git a/lib/providers/my_wallets.dart b/lib/providers/my_wallets.dart index 2e4e683..28469e0 100644 --- a/lib/providers/my_wallets.dart +++ b/lib/providers/my_wallets.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'dart:async'; @@ -5,6 +7,7 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/widgets/commons/common_elements.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; class MyWalletsProvider with ChangeNotifier { @@ -26,29 +29,22 @@ class MyWalletsProvider with ChangeNotifier { return configBox.get('currentChest'); } - bool checkIfWalletExist() { - if (chestBox.isEmpty) { - // log.i('No wallets detected'); - return false; - } else { - return true; - } - } + bool isWalletsExists() => chestBox.isNotEmpty; Future> readAllWallets([int? chest]) async { final sub = Provider.of(homeContext, listen: false); - chest = chest ?? configBox.get('currentChest') ?? 0; + chest = chest ?? getCurrentChest(); listWallets.clear(); final wallets = walletBox.toMap().values.toList(); Map walletsToScan = {}; for (var walletFromBox in wallets) { - if (walletFromBox.chest == chest) { - if (walletFromBox.identityStatus == IdtyStatus.unknown) { - walletsToScan.putIfAbsent( - walletFromBox.address, (() => walletFromBox)); - } else { - listWallets.add(walletFromBox); - } + if (walletFromBox.chest != chest) { + continue; + } + if (walletFromBox.identityStatus == IdtyStatus.unknown) { + walletsToScan.putIfAbsent(walletFromBox.address, (() => walletFromBox)); + } else { + listWallets.add(walletFromBox); } } @@ -61,7 +57,6 @@ class MyWalletsProvider with ChangeNotifier { listWallets.add(wallet); n++; } - return listWallets; } @@ -120,6 +115,12 @@ class MyWalletsProvider with ChangeNotifier { await configBox.delete('defaultWallet'); await sub.deleteAllAccounts(); + final directory = await getApplicationDocumentsDirectory(); + final avatarFolder = Directory('${directory.path}/avatars/'); + if (await avatarFolder.exists()) { + await avatarFolder.delete(recursive: true); + } + myWalletProvider.pinCode = ''; await Navigator.of(context) @@ -201,6 +202,7 @@ class MyWalletsProvider with ChangeNotifier { isOwned: true); await walletBox.put(newWallet.address, newWallet); + await readAllWallets(); isNewDerivationLoading = false; notifyListeners(); @@ -220,7 +222,7 @@ class MyWalletsProvider with ChangeNotifier { if (listWallets.isEmpty) { newDerivationNbr = 2; } else { - WalletData lastWallet = listWallets.reduce( + final lastWallet = listWallets.reduce( (curr, next) => curr.derivation! > next.derivation! ? curr : next); if (lastWallet.derivation == -1) { @@ -236,7 +238,7 @@ class MyWalletsProvider with ChangeNotifier { } int lockPin = 0; - Future resetPinCode([int minutes = 15]) async { + Future debounceResetPinCode([int minutes = 15]) async { lockPin++; final actualLock = lockPin; await Future.delayed( diff --git a/lib/providers/search.dart b/lib/providers/search.dart index aed638a..7f914dc 100644 --- a/lib/providers/search.dart +++ b/lib/providers/search.dart @@ -3,75 +3,16 @@ import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/providers/wallets_profiles.dart'; class SearchProvider with ChangeNotifier { - TextEditingController searchController = TextEditingController(); + final searchController = TextEditingController(); List searchResult = []; - final cacheDuring = 20 * 60 * 1000; //First number is minutes - int cacheTime = 0; int resultLenght = 0; void reload() { notifyListeners(); } - // Future searchBlockchain() async { - // searchResult.clear(); - // int searchTime = DateTime.now().millisecondsSinceEpoch; - // WalletsProfilesProvider _walletProfiles = WalletsProfilesProvider('pubkey'); - - // if (cacheTime + cacheDuring <= searchTime) { - // g1WalletsBox.clear(); - // // final url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json'); - // // final response = await http.get(url); - - // var dio = Dio(); - // late Response response; - // try { - // response = await dio.get( - // 'https://g1-stats.axiom-team.fr/data/forbes.json', - // options: Options( - // sendTimeout: 5000, - // receiveTimeout: 10000, - // ), - // ); - // // response = await http.post((Uri.parse(queryOptions[0])), - // // body: queryOptions[1], headers: queryOptions[2]); - // } catch (e) { - // log.e(e); - // } - - // List _listWallets = _parseG1Wallets(response.data)!; - // Map _mapWallets = { - // for (var e in _listWallets) e.pubkey: e - // }; - - // await g1WalletsBox.putAll(_mapWallets); - // cacheTime = DateTime.now().millisecondsSinceEpoch; - // } - - // g1WalletsBox.toMap().forEach((key, value) { - // if ((value.id != null && - // value.id!.username != null && - // value.id!.username! - // .toLowerCase() - // .contains(searchController.text)) || - // value.pubkey!.contains(searchController.text)) { - // searchResult.add(value); - // return; - // } - // }); - - // if (searchResult.isEmpty && - // _walletProfiles.isPubkey(searchController.text)) { - // searchResult = [G1WalletsList(pubkey: searchController.text)]; - // } - - // return searchResult; - // } - Future> searchAddress() async { - final walletProfiles = WalletsProfilesProvider('pubkey'); - - if (walletProfiles.isAddress(searchController.text)) { + if (isAddress(searchController.text)) { G1WalletsList wallet = G1WalletsList(address: searchController.text); return [wallet]; } else { @@ -79,11 +20,3 @@ class SearchProvider with ChangeNotifier { } } } - -// List? _parseG1Wallets(var responseBody) { -// final parsed = responseBody.cast>(); - -// return parsed -// .map((json) => G1WalletsList.fromJson(json)) -// .toList(); -// } diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index b54e0ab..2caa502 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -1,13 +1,11 @@ -// ignore_for_file: use_build_context_synchronously, body_might_complete_normally_catch_error - import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; import 'package:fast_base58/fast_base58.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/migrate_wallet_checks.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; @@ -26,6 +24,7 @@ import 'package:provider/provider.dart'; import 'package:truncate/truncate.dart'; import 'package:pointycastle/pointycastle.dart' as pc; import "package:hex/hex.dart"; +import 'package:uuid/uuid.dart' show Uuid; class SubstrateSdk with ChangeNotifier { final WalletSDK sdk = WalletSDK(); @@ -37,11 +36,11 @@ class SubstrateSdk with ChangeNotifier { bool importIsLoading = false; int blocNumber = 0; bool isLoadingEndpoint = false; - String transactionStatus = ''; - final int initSs58 = 42; + Map transactionStatus = {}; + static const int initSs58 = 42; Map currencyParameters = {}; - TextEditingController csSalt = TextEditingController(); - TextEditingController csPassword = TextEditingController(); + final csSalt = TextEditingController(); + final csPassword = TextEditingController(); String g1V1NewAddress = ''; String g1V1OldPubkey = ''; bool isCesiumIDVisible = false; @@ -52,18 +51,23 @@ class SubstrateSdk with ChangeNotifier { ///////////////////////////////////// ////////// 1: API METHODS /////////// - /////////////////////////////////////3 + ///////////////////////////////////// - Future _executeCall(TxInfoData txInfo, txOptions, String password, + Future _executeCall(String currentTransactionId, TxInfoData txInfo, + txOptions, String password, [String? rawParams]) async { final walletOptions = Provider.of(homeContext, listen: false); final walletProfiles = Provider.of(homeContext, listen: false); + transactionStatus.putIfAbsent(currentTransactionId, () => 'sending'); + notifyListeners(); + try { final hash = await sdk.api.tx.signAndSend(txInfo, txOptions, password, rawParam: rawParams, onStatusChange: (p0) { - transactionStatus = p0; + transactionStatus.update(currentTransactionId, (_) => p0, + ifAbsent: () => p0); notifyListeners(); }).timeout( const Duration(seconds: 18), @@ -71,20 +75,23 @@ class SubstrateSdk with ChangeNotifier { ); log.d(hash); if (hash.isEmpty) { - transactionStatus = 'Exception: timeout'; + transactionStatus.update( + currentTransactionId, (_) => 'Exception: timeout'); notifyListeners(); return 'Exception: timeout'; } else { // Success ! - transactionStatus = hash.toString(); + transactionStatus.update(currentTransactionId, (_) => hash.toString(), + ifAbsent: () => hash.toString()); notifyListeners(); walletOptions.reload(); walletProfiles.reload(); return hash.toString(); } } catch (e) { - transactionStatus = e.toString(); + transactionStatus.update(currentTransactionId, (_) => e.toString(), + ifAbsent: () => e.toString()); notifyListeners(); return e.toString(); } @@ -136,6 +143,19 @@ class SubstrateSdk with ChangeNotifier { return res?.signature ?? ''; } + Future signDatapod(String document, String address) async { + final myWallets = + Provider.of(homeContext, listen: false); + final messageToSign = Uint8List.fromList(document.codeUnits); + + final signatureString = + await _signMessage(messageToSign, address, myWallets.pinCode); + final signatureInt = HEX.decode(signatureString.substring(2)); + final signature64 = base64Encode(signatureInt); + + return signature64; + } + //////////////////////////////////////////// ////////// 2: GET ONCHAIN STORAGE ////////// //////////////////////////////////////////// @@ -196,7 +216,7 @@ class SubstrateSdk with ChangeNotifier { Future hasAccountConsumers(String address) async { final accountInfo = await _getStorage('system.account("$address")'); final consumers = accountInfo['consumers']; - return consumers == 0 ? false : true; + return !(consumers == 0); } Future getUdValue() async { @@ -219,7 +239,7 @@ class SubstrateSdk with ChangeNotifier { } // Get onchain storage values - final List balanceGlobalMulti = + final List accountMulti = (await _getStorage('system.account.multi($stringifyAddresses)') as List) .map((dynamic e) => e as Map) .toList(); @@ -240,14 +260,10 @@ class SubstrateSdk with ChangeNotifier { .map((dynamic e) => e as Map?) .toList(); - final List pastReevals = - await _getStorage('universalDividend.pastReevals()'); - int nbr = 0; Map> finalBalancesList = {}; - for (Map balanceGlobal in balanceGlobalMulti) { - final computedBalance = - await _computeBalance(idtyDataList[nbr], pastReevals, balanceGlobal); + for (Map account in accountMulti) { + final computedBalance = await _computeBalance(idtyDataList[nbr], account); finalBalancesList.putIfAbsent(addresses[nbr], () => computedBalance); nbr++; } @@ -266,35 +282,33 @@ class SubstrateSdk with ChangeNotifier { } // Get onchain storage values - final Map balanceGlobal = await _getStorage('system.account("$address")'); + final Map account = await _getStorage('system.account("$address")'); final int? idtyIndex = await _getStorage('identity.identityIndexOf("$address")'); final Map? idtyData = idtyIndex == null ? null : await _getStorage('identity.identities($idtyIndex)'); - final List pastReevals = - await _getStorage('universalDividend.pastReevals()'); - return _computeBalance(idtyData, pastReevals, balanceGlobal); + return _computeBalance(idtyData, account); } Future> _computeBalance( - Map? idtyData, List pastReevals, Map balanceGlobal) async { + Map? idtyData, Map account) async { + final List pastReevals = + await _getStorage('universalDividend.pastReevals()'); // Compute amount of claimable UDs currentUdIndex = await getCurrentUdIndex(); final int unclaimedUds = _computeUnclaimUds( idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); // Calculate transferable and potential balance - final int transferableBalance = - (balanceGlobal['data']['free'] + unclaimedUds); + final int transferableBalance = (account['data']['free'] + unclaimedUds); return { 'transferableBalance': round((transferableBalance / balanceRatio) / 100), - 'free': round((balanceGlobal['data']['free'] / balanceRatio) / 100), + 'free': round((account['data']['free'] / balanceRatio) / 100), 'unclaimedUds': round((unclaimedUds / balanceRatio) / 100), - 'reserved': - round((balanceGlobal['data']['reserved'] / balanceRatio) / 100), + 'reserved': round((account['data']['reserved'] / balanceRatio) / 100), }; } @@ -319,9 +333,6 @@ class SubstrateSdk with ChangeNotifier { } } - // log.d( - // "debug computeUnclaimUds: ${pastReevals.reversed} --- $firstEligibleUd --- $currentUdIndex"); - return totalAmount; } @@ -426,7 +437,7 @@ class SubstrateSdk with ChangeNotifier { if (idtyIndex == -1) return false; final isSmith = await _getStorage('smithMembership.membership($idtyIndex)'); - return isSmith == null ? false : true; + return !(isSmith == null); } Future getGenesisHash() async { @@ -435,8 +446,6 @@ class SubstrateSdk with ChangeNotifier { wrapPromise: false, ) ?? []; - // log.d('genesisHash: $genesisHash'); - // log.d('genesisHash: ${HEX.decode(genesisHash.substring(2))}'); return genesisHash; } @@ -449,28 +458,35 @@ class SubstrateSdk with ChangeNotifier { return pubkeyByte; } - // Future pubkeyToAddress(String pubkey) async { - // await sdk.api.account.encodeAddress([pubkey]); - // } + Future addressToPubkeyB58(String address) async { + return Base58Encode(await addressToPubkey(address)); + } + + Future pubkeyV1ToAddress(String pubkey) async { + final pubkeyByte = Base58Decode(pubkey); + final String pubkeyHex = '0x${HEX.encode(pubkeyByte)}'; + final address = await sdk.api.account.encodeAddress([pubkeyHex]); + return address!.keys.first; + } Future initCurrencyParameters() async { - try { - currencyParameters['ss58'] = - await _getStorageConst('system.ss58Prefix.words'); - currencyParameters['minCertForMembership'] = - await _getStorageConst('wot.minCertForMembership.words'); - currencyParameters['newAccountPrice'] = - await _getStorageConst('account.newAccountPrice.words'); - currencyParameters['existentialDeposit'] = - await _getStorageConst('balances.existentialDeposit.words'); - currencyParameters['certPeriod'] = - await _getStorageConst('cert.certPeriod.words'); - currencyParameters['certMaxByIssuer'] = - await _getStorageConst('cert.maxByIssuer.words'); - currencyParameters['certValidityPeriod'] = - await _getStorageConst('cert.validityPeriod.words'); - } catch (e) { - log.i('error while getting storageVals (network?) :: $e'); + const currencyParametersNames = { + 'ss58': 'system.ss58Prefix.words', + 'minCertForMembership': 'wot.minCertForMembership.words', + 'newAccountPrice': 'account.newAccountPrice.words', + 'existentialDeposit': 'balances.existentialDeposit.words', + 'certPeriod': 'cert.certPeriod.words', + 'certMaxByIssuer': 'cert.maxByIssuer.words', + 'certValidityPeriod': 'cert.validityPeriod.words', + }; + + for (var param in currencyParametersNames.keys) { + try { + currencyParameters[param] = + await _getStorageConst(currencyParametersNames[param]!); + } catch (e) { + log.e('error while getting param $param :: $e'); + } } log.i('currencyParameters: $currencyParameters'); } @@ -560,7 +576,7 @@ class SubstrateSdk with ChangeNotifier { // final dateText = await sdk.webView! // .evalJavascript('api.tx($dateTextByte)', wrapPromise: false); - // log.d('aaaaaaaaaaaaaaaaaaaaa: $dateText'); + // log.d('Blockchain start: $dateText'); return DateFormat(); } @@ -583,9 +599,10 @@ class SubstrateSdk with ChangeNotifier { return sdk.api.connectedNode?.endpoint; } - Future connectNode(BuildContext ctx) async { - final homeProvider = Provider.of(ctx, listen: false); - final myWalletProvider = Provider.of(ctx, listen: false); + Future connectNode() async { + final homeProvider = Provider.of(homeContext, listen: false); + final myWalletProvider = + Provider.of(homeContext, listen: false); homeProvider.changeMessage("connectionPending".tr(), 0); @@ -611,12 +628,10 @@ class SubstrateSdk with ChangeNotifier { notifyListeners(); if (resNode != null) { nodeConnected = true; - // await getSs58Prefix(); // Subscribe bloc number sdk.api.setting.subscribeBestNumber((res) { blocNumber = int.parse(res.toString()); - // log.d(sdk.api.connectedNode?.endpoint); if (sdk.api.connectedNode?.endpoint == null) { nodeConnected = false; homeProvider.changeMessage("networkLost".tr(), 0); @@ -630,6 +645,7 @@ class SubstrateSdk with ChangeNotifier { // Currency parameters await initCurrencyParameters(); + // Indexer Blockchain start getBlockStart(); @@ -638,15 +654,14 @@ class SubstrateSdk with ChangeNotifier { "wellConnectedToNode" .tr(args: [getConnectedEndpoint()!.split('/')[2]]), 5); - // snackNode(ctx, true); } else { nodeConnected = false; notifyListeners(); homeProvider.changeMessage("noDuniterEndointAvailable".tr(), 0); - if (!myWalletProvider.checkIfWalletExist()) snackNode(homeContext, false); + if (!myWalletProvider.isWalletsExists()) snackNode(false); } - log.d(sdk.api.connectedNode?.endpoint); + log.i('Connected to node: ${sdk.api.connectedNode?.endpoint}'); } List getDuniterBootstrap() { @@ -677,7 +692,8 @@ class SubstrateSdk with ChangeNotifier { Future importAccount( {String mnemonic = '', String derivePath = '', - required String password}) async { + required String password, + CryptoType cryptoType = CryptoType.sr25519}) async { const keytype = KeyType.mnemonic; if (mnemonic != '') generatedMnemonic = mnemonic; @@ -691,13 +707,13 @@ class SubstrateSdk with ChangeNotifier { name: derivePath, password: password, derivePath: derivePath, - cryptoType: CryptoType.sr25519) + cryptoType: cryptoType) .catchError((e) { importIsLoading = false; notifyListeners(); + return e; }); if (json == null) return ''; - // log.d(json); try { await sdk.api.keyring.addAccount( keyring, @@ -748,19 +764,13 @@ class SubstrateSdk with ChangeNotifier { return seedText; } - int getDerivationNumber(String address) { - final account = getKeypair(address); - final deriveNbr = account.name!.split('//')[1]; - return int.parse(deriveNbr); - } - Future changePassword(BuildContext context, String address, String passOld, String passNew) async { final account = getKeypair(address); final myWalletProvider = Provider.of(context, listen: false); keyring.setCurrent(account); - myWalletProvider.resetPinCode(); + myWalletProvider.debounceResetPinCode(); return await sdk.api.keyring.changePassword(keyring, passOld, passNew); } @@ -877,12 +887,18 @@ class SubstrateSdk with ChangeNotifier { return g1V1NewAddress; } - Future getBalanceAndIdtyStatus( + Future getBalanceAndIdtyStatus( String fromAddress, String toAddress) async { + final sub = Provider.of(homeContext, listen: false); + bool canValidate = false; + String validationStatus = ''; + final fromBalance = fromAddress == '' ? {'transferableBalance': 0} : await getBalance(fromAddress); + final transferableBalance = fromBalance['transferableBalance']; + final statusList = await idtyStatus([fromAddress, toAddress]); final fromIdtyStatus = statusList[0]; final fromHasConsumer = @@ -890,13 +906,31 @@ class SubstrateSdk with ChangeNotifier { final toIdtyStatus = statusList[1]; final isSmithData = await isSmith(fromAddress); - return [ - fromBalance, - fromIdtyStatus, - toIdtyStatus, - fromHasConsumer, - isSmithData - ]; + // Check conditions to set 'canValidate' and 'validationStatus' + if (transferableBalance != 0 && !fromHasConsumer) { + canValidate = true; + } else if (toIdtyStatus != IdtyStatus.none && + fromIdtyStatus != IdtyStatus.none) { + validationStatus = 'youCannotMigrateIdentityToExistingIdentity'.tr(); + } else if (isSmithData) { + validationStatus = 'smithCantMigrateIdentity'.tr(); + } else if (fromHasConsumer) { + validationStatus = 'youMustWaitBeforeCashoutThisAccount'.tr(); + } else if (transferableBalance == 0) { + validationStatus = 'thisAccountIsEmpty'.tr(); + } + + if (sub.g1V1NewAddress == '') { + validationStatus = ''; + } + + return MigrateWalletChecks( + balance: fromBalance, + idtyStatus: toIdtyStatus, + isSmith: isSmithData, + validationStatus: validationStatus, + canValidate: canValidate, + ); } ////////////////////////////////////// @@ -908,8 +942,6 @@ class SubstrateSdk with ChangeNotifier { required String destAddress, required double amount, required String password}) async { - transactionStatus = ''; - final sender = await _setSender(fromAddress); final globalBalance = await getBalance(fromAddress); @@ -955,13 +987,13 @@ class SubstrateSdk with ChangeNotifier { rawParams = '[[$tx1, $tx2]]'; } - return await _executeCall(txInfo, txOptions, password, rawParams); + final transactionId = const Uuid().v4(); + _executeCall(transactionId, txInfo, txOptions, password, rawParams); + return transactionId; } Future certify( String fromAddress, String destAddress, String password) async { - transactionStatus = ''; - final statusList = await idtyStatus([fromAddress, destAddress]); final myIdtyStatus = statusList[0]; final toIdtyStatus = statusList[1]; @@ -972,8 +1004,6 @@ class SubstrateSdk with ChangeNotifier { final toIndex = idtyIndexList[1]; if (myIdtyStatus != IdtyStatus.validated) { - transactionStatus = 'notMember'; - notifyListeners(); return 'notMember'; } @@ -998,16 +1028,20 @@ class SubstrateSdk with ChangeNotifier { toIdtyStatus == IdtyStatus.confirmed) { if (toCerts![0] >= currencyParameters['minCertForMembership']! - 1 && toIdtyStatus != IdtyStatus.validated) { - log.i('Batch cert and membership validation'); + log.d('Batch cert and membership validation'); txInfo = TxInfoData( 'utility', 'batchAll', sender, ); final tx1 = 'api.tx.cert.addCert($fromIndex, $toIndex)'; - final tx2 = 'api.tx.identity.validateIdentity($toIndex)'; - rawParams = '[[$tx1, $tx2]]'; + //TODO: add requestDistanceEvaluation tx when available + + // final tx2 = 'api.tx.distance.requestDistanceEvaluation($toIndex)'; + // final tx2 = 'api.tx.identity.validateIdentity($toIndex)'; + + rawParams = '[[$tx1]]'; } else { txInfo = TxInfoData( 'cert', @@ -1017,13 +1051,13 @@ class SubstrateSdk with ChangeNotifier { txOptions = [fromIndex, toIndex]; } } else { - transactionStatus = 'cantBeCert'; - notifyListeners(); return 'cantBeCert'; } log.d('Cert action: ${txInfo.call!}'); - return await _executeCall(txInfo, txOptions, password, rawParams); + final transactionId = const Uuid().v4(); + _executeCall(transactionId, txInfo, txOptions, password, rawParams); + return transactionId; } Future confirmIdentity( @@ -1037,7 +1071,11 @@ class SubstrateSdk with ChangeNotifier { ); final txOptions = [name]; - return await _executeCall(txInfo, txOptions, password); + final transactionId = const Uuid().v4(); + + _executeCall(transactionId, txInfo, txOptions, password); + + return transactionId; } Future migrateIdentity( @@ -1047,7 +1085,6 @@ class SubstrateSdk with ChangeNotifier { required String destPassword, required Map fromBalance, bool withBalance = false}) async { - transactionStatus = ''; final sender = await _setSender(fromAddress); TxInfoData txInfo; @@ -1066,8 +1103,6 @@ class SubstrateSdk with ChangeNotifier { await _signMessage(messageToSign, destAddress, destPassword); final newKeySigType = '{"Sr25519": "$newKeySig"}'; - // messageToSign: [105, 99, 111, 107, 7, 193, 18, 255, 106, 185, 215, 208, 213, 49, 235, 229, 159, 152, 179, 83, 24, 178, 129, 59, 22, 85, 87, 115, 128, 129, 157, 56, 214, 24, 45, 153, 21, 0, 0, 0, 181, 82, 178, 99, 198, 4, 156, 190, 78, 35, 102, 137, 255, 7, 162, 31, 16, 79, 255, 132, 130, 237, 230, 222, 176, 88, 245, 217, 237, 78, 196, 239] - log.d(""" fromAddress: $fromAddress destAddress: $destAddress @@ -1107,7 +1142,9 @@ newKeySig: $newKeySigType"""); txOptions = [destAddress, newKeySigType]; } - return await _executeCall(txInfo, txOptions, fromPassword, rawParams); + final transactionId = const Uuid().v4(); + _executeCall(transactionId, txInfo, txOptions, fromPassword, rawParams); + return transactionId; } Future revokeIdentity(String address, String password) async { @@ -1131,10 +1168,12 @@ newKeySig: $newKeySigType"""); ); final txOptions = [idtyIndex, address, revocationSigTyped]; - return await _executeCall(txInfo, txOptions, password); + final transactionId = const Uuid().v4(); + _executeCall(transactionId, txInfo, txOptions, password); + return transactionId; } - Future migrateCsToV2(String salt, String password, String destAddress, + Future migrateCsToV2(String salt, String password, String destAddress, {required destPassword, required Map balance, IdtyStatus idtyStatus = IdtyStatus.none}) async { @@ -1167,9 +1206,10 @@ newKeySig: $newKeySigType"""); password: password, ); - log.d('g1migration idtyStatus: $idtyStatus'); + late String transactionId; + if (idtyStatus != IdtyStatus.none) { - await migrateIdentity( + transactionId = await migrateIdentity( fromAddress: keypair.address!, destAddress: destAddress, fromPassword: 'password', @@ -1177,14 +1217,17 @@ newKeySig: $newKeySigType"""); withBalance: true, fromBalance: balance); } else if (balance['transferableBalance'] != 0) { - await pay( + transactionId = await pay( fromAddress: keypair.address!, destAddress: destAddress, amount: -1, password: 'password'); + } else { + transactionId = ''; } await sdk.api.keyring.deleteAccount(keyring, keypair); + return transactionId; } Future spawnBlock([int number = 1, int until = 0]) async { @@ -1201,18 +1244,22 @@ newKeySig: $newKeySigType"""); void reload() { notifyListeners(); } + + void resetTransactionStatus() { + transactionStatus.clear(); + } } //////////////////////////////////////////// /////// 6: UI ELEMENTS (off class) ///////// //////////////////////////////////////////// -void snackNode(BuildContext context, bool isConnected) { +void snackNode(bool isConnected) { String message; if (!isConnected) { message = "noDuniterNodeAvailableTryLater".tr(); } else { - final sub = Provider.of(context, listen: false); + final sub = Provider.of(homeContext, listen: false); message = "${"youAreConnectedToNode".tr()}\n${sub.getConnectedEndpoint()!.split('//')[1]}"; @@ -1222,7 +1269,7 @@ void snackNode(BuildContext context, bool isConnected) { padding: const EdgeInsets.all(20), content: Text(message, style: const TextStyle(fontSize: 16)), duration: const Duration(seconds: 4)); - ScaffoldMessenger.of(context).showSnackBar(snackBar); + ScaffoldMessenger.of(homeContext).showSnackBar(snackBar); } String getShortPubkey(String pubkey) { diff --git a/lib/providers/v2s_datapod.dart b/lib/providers/v2s_datapod.dart new file mode 100644 index 0000000..bb1ef6a --- /dev/null +++ b/lib/providers/v2s_datapod.dart @@ -0,0 +1,220 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/queries_datapod.dart'; +import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/providers/my_wallets.dart'; +import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:uuid/uuid.dart'; + +class V2sDatapodProvider with ChangeNotifier { + Future _execQuery( + String query, Map variables) async { + final httpLink = HttpLink('$datapodEndpoint/v1/graphql'); + + final GraphQLClient client = GraphQLClient( + cache: GraphQLCache(), + link: httpLink, + ); + + final QueryOptions options = + QueryOptions(document: gql(query), variables: variables); + + return await client.query(options); + } + + Future updateProfile( + {required String address, + String? title, + String? description, + String? avatar, + String? city, + List>? socials, + Map? geoloc}) async { + final sub = Provider.of(homeContext, listen: false); + final myWallets = + Provider.of(homeContext, listen: false); + final walletData = myWallets.getWalletDataByAddress(address); + + final messageToSign = jsonEncode({ + 'address': address, + 'description': description, + 'avatarBase64': avatar, + 'geoloc': geoloc, + 'title': title, + 'city': city, + 'socials': socials + }); + final hashDocBytes = utf8.encode(messageToSign); + final hashDoc = sha256.convert(hashDocBytes).toString().toUpperCase(); + final signature = await sub.signDatapod(hashDoc, address); + + final variables = { + 'address': address, + 'hash': hashDoc, + 'signature': signature, + 'title': title, + 'description': description, + 'avatar': avatar, + 'city': city, + 'socials': socials, + 'geoloc': geoloc, + }; + final result = await _execQuery(updateProfileQ, variables); + if (result.hasException) { + log.e(result.exception.toString()); + return false; + } + log.d(result.data!['updateProfile']['message']); + walletData!.profileUpdatedTime = DateTime.now(); + walletBox.put(address, walletData); + + return true; + } + + Future deleteProfile({required String address}) async { + final sub = Provider.of(homeContext, listen: false); + + final messageToSign = jsonEncode({'address': address}); + final hashDocBytes = utf8.encode(messageToSign); + final hashDoc = sha256.convert(hashDocBytes).toString().toUpperCase(); + final signature = await sub.signDatapod(hashDoc, address); + + final variables = { + 'address': address, + 'hash': hashDoc, + 'signature': signature + }; + final result = await _execQuery(deleteProfileQ, variables); + if (result.hasException) { + log.e(result.exception.toString()); + return false; + } + log.d(result.data!['deleteProfile']['message']); + return true; + } + + Future migrateProfile( + {required String addressOld, required String addressNew}) async { + final sub = Provider.of(homeContext, listen: false); + + final messageToSign = + jsonEncode({'addressOld': addressOld, 'addressNew': addressNew}); + final hashDocBytes = utf8.encode(messageToSign); + final hashDoc = sha256.convert(hashDocBytes).toString().toUpperCase(); + final signature = await sub.signDatapod(hashDoc, addressOld); + + final variables = { + 'addressOld': addressOld, + 'addressNew': addressNew, + 'hash': hashDoc, + 'signature': signature + }; + final result = await _execQuery(migrateProfileQ, variables); + if (result.hasException) { + log.e(result.exception.toString()); + return false; + } + log.d(result.data!['migrateProfile']['message']); + return true; + } + + Future setAvatar(String address, String avatarPath) async { + final avatarBytes = await File(avatarPath).readAsBytes(); + final avatarString = base64Encode(avatarBytes); + return await updateProfile(address: address, avatar: avatarString); + } + + Future profileEditedAt(String address) async { + final variables = { + 'address': address, + }; + final result = await _execQuery(profileEditedAtQ, variables); + if (result.hasException) { + log.e(result.exception.toString()); + return null; + } + final String? profileDateData = + result.data!['profiles_by_pk']?['updated_at']; + final profileDate = + profileDateData == null ? null : DateTime.tryParse(profileDateData); + return profileDate; + } + + Future getAvatar(String address, + {double size = 20, bool saveOnDisk = false, String? uuid}) async { + final variables = { + 'address': address, + }; + final result = await _execQuery(getAvatarQ, variables); + if (result.hasException) { + log.e(result.exception.toString()); + return defaultAvatar(size); + } + final String? avatar64 = result.data!['profiles_by_pk']?['avatar64']; + + if (avatar64 == null) { + return defaultAvatar(size); + } + + final sanitizedAvatar64 = + avatar64.replaceAll('\n', '').replaceAll('\r', '').replaceAll(' ', ''); + + if (saveOnDisk) { + log.d('We save avatar for $address'); + await saveAvatar(address, sanitizedAvatar64, uuid); + } else { + await cacheAvatar(address, sanitizedAvatar64); + } + + return Image.memory( + base64.decode(sanitizedAvatar64), + height: size, + fit: BoxFit.fitWidth, + ); + } + + Future saveAvatar(String address, String data, String? uuid) async { + uuid = uuid ?? const Uuid().v4(); + final file = File('${avatarsDirectory.path}/$address-$uuid'); + return await file.writeAsBytes(base64.decode(data)); + } + + Future cacheAvatar(String address, String data) async { + final file = File('${avatarsCacheDirectory.path}/$address'); + return await file.writeAsBytes(base64.decode(data)); + } + + Image getAvatarLocal(String address, double size) { + final avatarFile = File('${avatarsCacheDirectory.path}/$address'); + return Image.file( + avatarFile, + height: size, + fit: BoxFit.fitWidth, + ); + } + + Image defaultAvatar(double size) => + Image.asset(('assets/icon_user.png'), height: scaleSize(size)); + + Future deleteAvatarsCacheDirectory() async { + if (await avatarsCacheDirectory.exists()) { + await avatarsCacheDirectory.delete(recursive: true); + } + } + + Future deleteAvatarsDirectory() async { + if (await avatarsDirectory.exists()) { + await avatarsDirectory.delete(recursive: true); + } + } + + + reload() { + notifyListeners(); + } +} diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index ff5bc28..fd1f4cf 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -11,6 +11,7 @@ import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/widgets/commons/common_elements.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/transaction_in_progress.dart'; @@ -19,14 +20,14 @@ import 'package:provider/provider.dart'; import 'package:image_cropper/image_cropper.dart'; class WalletOptionsProvider with ChangeNotifier { - TextEditingController address = TextEditingController(); - final TextEditingController _newWalletName = TextEditingController(); + final address = TextEditingController(); + final _newWalletName = TextEditingController(); bool isWalletUnlock = false; bool ischangedPin = false; - TextEditingController newPin = TextEditingController(); + final newPin = TextEditingController(); bool isEditing = false; bool isBalanceBlur = false; - TextEditingController nameController = TextEditingController(); + final nameController = TextEditingController(); late bool isDefaultWallet; bool canValidateNameBool = false; Map balanceCache = {}; @@ -48,17 +49,16 @@ class WalletOptionsProvider with ChangeNotifier { Future deleteWallet(context, WalletData wallet) async { final sub = Provider.of(context, listen: false); + final datapod = Provider.of(context, listen: false); final bool? answer = await (confirmPopup( context, 'areYouSureToForgetWallet'.tr(args: [wallet.name!]))); if (answer ?? false) { //Check if balance is null - final balance = await sub.getBalance(wallet.address); - if (balance != {}) { + if (balanceCache[wallet.address] != 0) { final myWalletProvider = Provider.of(context, listen: false); final defaultWallet = myWalletProvider.getDefaultWallet(); - log.d(defaultWallet.address); sub.pay( fromAddress: wallet.address, destAddress: defaultWallet.address, @@ -67,6 +67,11 @@ class WalletOptionsProvider with ChangeNotifier { } await walletBox.delete(wallet.key); + if (wallet.imageCustomPath != null) { + final avatarFile = File(wallet.imageCustomPath!); + await avatarFile.delete(); + } + datapod.deleteProfile(address: wallet.address); await sub.deleteAccounts([wallet.address]); Navigator.pop(context); @@ -80,14 +85,15 @@ class WalletOptionsProvider with ChangeNotifier { } Future changeAvatar() async { - // File _image; + final datapod = Provider.of(homeContext, listen: false); + final picker = ImagePicker(); XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { File imageFile = File(pickedFile.path); - if (!await imageDirectory.exists()) { + if (!await avatarsDirectory.exists()) { log.e("Image folder doesn't exist"); return ''; } @@ -110,7 +116,7 @@ class WalletOptionsProvider with ChangeNotifier { ], ); - final newPath = "${imageDirectory.path}/${pickedFile.name}"; + final newPath = "${avatarsDirectory.path}/${address.text}"; if (croppedFile != null) { await File(croppedFile.path).rename(newPath); @@ -118,9 +124,7 @@ class WalletOptionsProvider with ChangeNotifier { log.w('No image selected.'); return ''; } - // await imageFile.copy(newPath); - - log.i(newPath); + datapod.setAvatar(address.text, newPath); return newPath; } else { log.w('No image selected.'); @@ -129,7 +133,7 @@ class WalletOptionsProvider with ChangeNotifier { } Future confirmIdentityPopup(BuildContext context) async { - TextEditingController idtyName = TextEditingController(); + final idtyName = TextEditingController(); final sub = Provider.of(context, listen: false); final walletOptions = Provider.of(context, listen: false); @@ -141,7 +145,7 @@ class WalletOptionsProvider with ChangeNotifier { return showDialog( context: context, - barrierDismissible: true, // user must tap button! + barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( title: Text( @@ -194,45 +198,47 @@ class WalletOptionsProvider with ChangeNotifier { idtyName.text = idtyName.text.trim().replaceAll(' ', ''); - if (idtyName.text.length.clamp(3, 32) == + if (idtyName.text.length.clamp(3, 32) != idtyName.text.length) { - 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 != '') { - final wallet = myWalletProvider - .getWalletDataByAddress(address.text); - await sub.setCurrentWallet(wallet!); - sub.confirmIdentity(walletOptions.address.text, - idtyName.text, myWalletProvider.pinCode); - Navigator.pop(context); - - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return TransactionInProgress( - transType: 'comfirmIdty', - fromAddress: - getShortPubkey(wallet.address), - toAddress: getShortPubkey(wallet.address), - ); - }), - ); - } + return; } + + WalletData? defaultWallet = + myWalletProvider.getDefaultWallet(); + + if (myWalletProvider.pinCode == '') { + await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); + } + if (myWalletProvider.pinCode == '') return; + + final wallet = myWalletProvider + .getWalletDataByAddress(address.text); + await sub.setCurrentWallet(wallet!); + final transactionId = await sub.confirmIdentity( + walletOptions.address.text, + idtyName.text, + myWalletProvider.pinCode); + Navigator.pop(context); + + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transactionId: transactionId, + transType: 'comfirmIdty', + fromAddress: getShortPubkey(wallet.address), + toAddress: getShortPubkey(wallet.address), + ); + }), + ); } : null, child: Text( @@ -255,7 +261,7 @@ class WalletOptionsProvider with ChangeNotifier { } Future editWalletName(BuildContext context, List wID) async { - TextEditingController walletName = TextEditingController(); + final walletName = TextEditingController(); canValidateNameBool = false; return showDialog( @@ -336,7 +342,7 @@ class WalletOptionsProvider with ChangeNotifier { ); } - bool canValidateName(BuildContext context, TextEditingController walletName) { + bool canValidateName(BuildContext context, final walletName) { final myWalletProvider = Provider.of(context, listen: false); diff --git a/lib/providers/wallets_profiles.dart b/lib/providers/wallets_profiles.dart index 55726f8..b69771e 100644 --- a/lib/providers/wallets_profiles.dart +++ b/lib/providers/wallets_profiles.dart @@ -5,10 +5,10 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/screens/wallet_view.dart'; 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'; class WalletsProfilesProvider with ChangeNotifier { @@ -20,8 +20,8 @@ class WalletsProfilesProvider with ChangeNotifier { bool isHistoryScreen = false; String historySwitchButtun = "Voir l'historique"; String? rawSvg; - TextEditingController payAmount = TextEditingController(); - TextEditingController payComment = TextEditingController(); + final payAmount = TextEditingController(); + final payComment = TextEditingController(); num? _balance; Future scan(context) async { @@ -36,6 +36,7 @@ class WalletsProfilesProvider with ChangeNotifier { return 'false'; } if (isAddress(barcode.rawContent)) { + address = barcode.rawContent; Navigator.popUntil( context, ModalRoute.withName('/'), @@ -55,51 +56,6 @@ class WalletsProfilesProvider with ChangeNotifier { return barcode.rawContent; } - // Future pay(BuildContext context, {int? derivation}) async { - // MyWalletsProvider _myWalletProvider = - // Provider.of(context, listen: false); - // int? currentChest = configBox.get('currentChest'); - // String result; - - // derivation ??= - // _myWalletProvider.getDefaultWallet(currentChest)!.derivation!; - // result = await Gva(node: endPointGVA).pay( - // recipient: pubkey!, - // amount: double.parse(payAmount.text), - // mnemonic: _myWalletProvider.mnemonic, - // comment: payComment.text, - // derivation: derivation, - // lang: appLang); - - // return result; - // } - - bool isAddress(address) { - final RegExp regExp = RegExp( - r'^[a-zA-Z0-9]+$', - caseSensitive: false, - multiLine: false, - ); - - if (regExp.hasMatch(address) == true && - address.length > 45 && - address.length < 52) { - log.d("C'est une adresse !"); - - this.address = address; - - return true; - } else { - return false; - } - } - -// poka: Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P -// Pi: D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU // For debug -// Boris: JE6mkuzSpT3ePciCPRTpuMT9fqPUVVLJz2618d33p7tn -// Matograine portefeuille: 9p5nHsES6xujFR7pw2yGy4PLKKHgWsMvsDHaHF64Uj25. -// Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f - void resetdHistory() { notifyListeners(); } @@ -108,21 +64,6 @@ class WalletsProfilesProvider with ChangeNotifier { return Jdenticon.toSvg(pubkey); } - // Future getBalance(String _pubkey) async { - // final url = Uri.parse( - // '$endPointGVA?query={%20balance(script:%20%22$_pubkey%22)%20{%20amount%20base%20}%20}'); - // final response = await http.get(url); - // final result = json.decode(response.body); - - // if (result['data']['balance'] == null) { - // balance = 0.0; - // } else { - // balance = removeDecimalZero(result['data']['balance']['amount'] / 100); - // } - - // return balance; - // } - Future getBalance(String? pubkey) async { while (_balance == null) { await Future.delayed(const Duration(milliseconds: 50)); @@ -136,14 +77,12 @@ class WalletsProfilesProvider with ChangeNotifier { } Future addContact(G1WalletsList profile) async { - // log.d(profile.username); if (isContact(profile.address)) { await contactsBox.delete(profile.address); snackMessage(homeContext, message: 'removedFromcontacts'.tr(), duration: 4); } else { await contactsBox.put(profile.address, profile); - // drawStar(Size(50, 50)); snackMessage(homeContext, message: 'addedToContacts'.tr(), duration: 4); } notifyListeners(); @@ -154,12 +93,28 @@ class WalletsProfilesProvider with ChangeNotifier { } } +bool isAddress(address) { + final RegExp regExp = RegExp( + r'^[a-zA-Z0-9]+$', + caseSensitive: false, + multiLine: false, + ); + + if (regExp.hasMatch(address) == true && + address.length > 45 && + address.length < 52) { + return true; + } else { + return false; + } +} + snackMessage(context, {required String message, int duration = 2, double fontSize = 16}) { final snackBar = SnackBar( backgroundColor: Colors.grey[900], - padding: const EdgeInsets.all(20), - content: Text(message, style: TextStyle(fontSize: fontSize)), + padding: EdgeInsets.all(scaleSize(19)), + content: Text(message, style: scaledTextStyle(fontSize: fontSize)), duration: Duration(seconds: duration)); ScaffoldMessenger.of(context).showSnackBar(snackBar); } @@ -167,9 +122,9 @@ snackMessage(context, snackCopyKey(context) { final snackBar = SnackBar( backgroundColor: Colors.grey[900], - padding: const EdgeInsets.all(20), + padding: EdgeInsets.all(scaleSize(19)), content: Text("thisAddressHasBeenCopiedToClipboard".tr(), - style: const TextStyle(fontSize: 16)), + style: scaledTextStyle(fontSize: 16)), duration: const Duration(seconds: 2)); ScaffoldMessenger.of(context).showSnackBar(snackBar); } @@ -177,9 +132,9 @@ snackCopyKey(context) { snackCopySeed(context) { final snackBar = SnackBar( backgroundColor: Colors.grey[900], - padding: const EdgeInsets.all(20), + padding: EdgeInsets.all(scaleSize(19)), content: Text("thisMnemonicHasBeenCopiedToClipboard".tr(), - style: const TextStyle(fontSize: 17)), + style: scaledTextStyle(fontSize: 16)), duration: const Duration(seconds: 4)); ScaffoldMessenger.of(context).showSnackBar(snackBar); } diff --git a/lib/screens/activity.dart b/lib/screens/activity.dart index 9435d87..ba62888 100644 --- a/lib/screens/activity.dart +++ b/lib/screens/activity.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:flutter/material.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -12,12 +13,10 @@ import 'package:gecko/widgets/history_query.dart'; import 'package:provider/provider.dart'; class ActivityScreen extends StatefulWidget { - const ActivityScreen( - {required this.address, required this.avatar, this.username}) + const ActivityScreen({required this.address, this.username}) : super(key: keyActivityScreen); final String address; final String? username; - final Image avatar; @override State createState() => _ActivityScreenState(); @@ -43,10 +42,10 @@ class _ActivityScreenState extends State { child: Scaffold( appBar: AppBar( elevation: 0, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('accountActivity'.tr()), + toolbarHeight: scaleSize(57), + title: Text( + 'accountActivity'.tr(), + style: scaledTextStyle(fontSize: 20), ), ), bottomNavigationBar: const GeckoBottomAppBar(), diff --git a/lib/screens/certifications.dart b/lib/screens/certifications.dart index 4502563..278d61d 100644 --- a/lib/screens/certifications.dart +++ b/lib/screens/certifications.dart @@ -2,10 +2,11 @@ import 'package:accordion/controllers.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; -import 'package:gecko/widgets/certs_received.dart'; +import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/widgets/certs_list.dart'; import 'package:gecko/widgets/certs_counter.dart'; -import 'package:gecko/widgets/certs_sent.dart'; import 'package:accordion/accordion.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class CertificationsScreen extends StatelessWidget { const CertificationsScreen( @@ -18,41 +19,39 @@ class CertificationsScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - elevation: 0, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('certificationsOf'.tr(args: [username])), - )), + appBar: GeckoAppBar('certificationsOf'.tr(args: [username])), body: SafeArea( child: Accordion( - paddingListTop: 10, + paddingListTop: 7, paddingListBottom: 10, maxOpenSections: 1, headerBackgroundColorOpened: orangeC, scaleWhenAnimating: true, openAndCloseAnimation: true, - headerPadding: - const EdgeInsets.symmetric(vertical: 7, horizontal: 15), + headerPadding: EdgeInsets.symmetric( + vertical: scaleSize(6), horizontal: scaleSize(14)), sectionOpeningHapticFeedback: SectionHapticFeedback.heavy, sectionClosingHapticFeedback: SectionHapticFeedback.light, children: [ AccordionSection( isOpen: true, - leftIcon: - const Icon(Icons.insights_rounded, color: Colors.black), + leftIcon: Icon( + Icons.insights_rounded, + color: Colors.black, + size: scaleSize(20), + ), headerBackgroundColor: yellowC, headerBackgroundColorOpened: orangeC, header: Row(children: [ Text( 'received'.tr(), - style: const TextStyle(fontSize: 20), + style: scaledTextStyle(fontSize: 17), ), - const SizedBox(width: 5), + ScaledSizedBox(width: 5), CertsCounter(address: address) ]), - content: CertsReceived(address: address), + content: CertsList( + address: address, direction: CertDirection.sent), contentHorizontalPadding: 0, contentBorderWidth: 1, ), @@ -65,13 +64,16 @@ class CertificationsScreen extends StatelessWidget { header: Row(children: [ Text( 'sent'.tr(), - style: const TextStyle(fontSize: 20), + style: scaledTextStyle(fontSize: 17), ), - const SizedBox(width: 5), + ScaledSizedBox(width: 5), CertsCounter(address: address, isSent: true) ]), - content: CertsSent(address: address), - contentHorizontalPadding: 20, + content: CertsList( + address: address, + direction: CertDirection.sent, + ), + contentHorizontalPadding: 0, contentBorderWidth: 1, // onOpenSection: () => print('onOpenSection ...'), // onCloseSection: () => print('onCloseSection ...'), diff --git a/lib/screens/debug_screen.dart b/lib/screens/debug_screen.dart index 4dbe27f..413ca9b 100644 --- a/lib/screens/debug_screen.dart +++ b/lib/screens/debug_screen.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -14,11 +15,7 @@ class DebugScreen extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( - toolbarHeight: 60 * ratio, - title: const SizedBox( - height: 22, - child: Text('Debug screen'), - )), + toolbarHeight: scaleSize(57), title: const Text('Debug screen')), body: SafeArea( child: Column(children: [ const SizedBox(height: 40), @@ -42,8 +39,9 @@ class DebugScreen extends StatelessWidget { width: 250, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () async => await sub.spawnBlock(), child: const Text( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index df22b2e..acbd6ba 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -1,10 +1,9 @@ -// ignore_for_file: use_build_context_synchronously - import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -13,6 +12,7 @@ import 'package:gecko/providers/substrate_sdk.dart'; import 'package:flutter/material.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/widgets/bubble_speak.dart'; import 'package:gecko/widgets/commons/animated_text.dart'; import 'package:gecko/widgets/commons/common_elements.dart'; @@ -34,15 +34,15 @@ class _HomeScreenState extends State { @override void initState() { WidgetsBinding.instance.addPostFrameCallback((_) async { - final homeProviderInit = - Provider.of(context, listen: false); + final homeProvider = 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); + final datapod = Provider.of(context, listen: false); - final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); + final bool isWalletsExists = myWalletProvider.isWalletsExists(); // Check if versionData non compatible, drop everything if (configBox.get('dataVersion') == null) { @@ -53,6 +53,8 @@ class _HomeScreenState extends State { await infoPopup(context, "chestNotCompatibleMustReinstallGecko".tr()); await Hive.deleteBoxFromDisk('walletBox'); await Hive.deleteBoxFromDisk('chestBox'); + await datapod.deleteAvatarsDirectory(); + await avatarsDirectory.create(); chestBox = await Hive.openBox("chestBox"); await configBox.delete('defaultWallet'); if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi(); @@ -66,25 +68,25 @@ class _HomeScreenState extends State { if (sub.sdkReady && !sub.nodeConnected) { walletBox = await Hive.openBox("walletBox"); await Hive.deleteBoxFromDisk('g1WalletsBox'); + await datapod.deleteAvatarsCacheDirectory(); + await avatarsCacheDirectory.create(); g1WalletsBox = await Hive.openBox("g1WalletsBox"); contactsBox = await Hive.openBox("contactsBox"); - homeProviderInit.isWalletBoxInit = true; + homeProvider.isWalletBoxInit = true; myWalletProvider.reload(); duniterIndexer.getValidIndexerEndpoint(); - await homeProviderInit.getValidEndpoints(); + await homeProvider.getValidEndpoints(); if (configBox.get('isCacheChecked') == null) { configBox.put('isCacheChecked', false); } - HomeProvider homeProvider = - Provider.of(context, listen: false); Connectivity() .onConnectivityChanged .listen((ConnectivityResult result) async { - log.d('Network changed: $result'); + log.i('Network changed: $result'); if (result == ConnectivityResult.none) { sub.nodeConnected = false; await sub.sdk.api.setting.unsubscribeBestNumber(); @@ -94,7 +96,7 @@ class _HomeScreenState extends State { // Check if the phone is actually connected to the internet var connectivityResult = await (Connectivity().checkConnectivity()); if (connectivityResult != ConnectivityResult.none) { - await sub.connectNode(context); + await sub.connectNode(); } } }); @@ -110,19 +112,16 @@ class _HomeScreenState extends State { final myWalletProvider = Provider.of(context); Provider.of(context); - final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); + final isWalletsExists = myWalletProvider.isWalletsExists(); - isTall = false; - ratio = 1; - if (MediaQuery.of(context).size.height >= 930) { - isTall = true; - ratio = 1.125; - } + isTall = (MediaQuery.of(context).size.height / + MediaQuery.of(context).size.width) > + 1.75; return Scaffold( resizeToAvoidBottomInset: false, drawer: MainDrawer(isWalletsExists: isWalletsExists), - backgroundColor: const Color(0xffF9F9F1), + backgroundColor: yellowC, body: isWalletsExists ? geckHome(context) : welcomeHome(context)); } } @@ -142,42 +141,43 @@ Widget geckHome(context) { Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack(children: [ Positioned( - top: statusBarHeight + 10, - left: 15, + top: statusBarHeight + scaleSize(10), + left: scaleSize(15), child: Builder( builder: (context) => IconButton( key: keyDrawerMenu, - icon: const Icon( + icon: Icon( Icons.menu, - color: Colors.white, - size: 35, + color: Colors.black, + size: scaleSize(35), ), onPressed: () => Scaffold.of(context).openDrawer(), ), ), ), - const Align( - child: - Image(image: AssetImage('assets/home/header.png'), height: 210), + Align( + child: Image( + image: const AssetImage('assets/home/header.png'), + height: scaleSize(165)), ), ]), Padding( - padding: EdgeInsets.only(top: 15 * ratio), + padding: const EdgeInsets.only(top: 15), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ DefaultTextStyle( textAlign: TextAlign.center, - style: const TextStyle( + style: scaledTextStyle( color: Colors.white, - fontSize: 24, + fontSize: 19, fontWeight: FontWeight.w700, shadows: [ - Shadow( + const Shadow( offset: Offset(0, 0), blurRadius: 20, color: Colors.black, ), - Shadow( + const Shadow( offset: Offset(0, 0), blurRadius: 20, color: Colors.black, @@ -194,7 +194,7 @@ Widget geckHome(context) { ), ]), ), - const SizedBox(height: 15), + ScaledSizedBox(height: 15), Expanded( flex: 1, child: Container( @@ -229,37 +229,38 @@ Widget welcomeHome(context) { Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack(children: [ Positioned( - top: statusBarHeight + 10, - left: 15, + top: statusBarHeight + scaleSize(10), + left: scaleSize(15), child: Builder( builder: (context) => IconButton( key: keyDrawerMenu, - icon: const Icon( + icon: Icon( Icons.menu, - color: Colors.white, - size: 35, + color: Colors.black, + size: scaleSize(35), ), onPressed: () => Scaffold.of(context).openDrawer(), ), ), ), - const Align( - child: - Image(image: AssetImage('assets/home/header.png'), height: 210), + Align( + child: Image( + image: const AssetImage('assets/home/header.png'), + height: scaleSize(165)), ), ]), Padding( - padding: EdgeInsets.only(top: 1 * ratio), + padding: const EdgeInsets.only(top: 1), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "fastAppDescription".tr(args: [currencyName]), textAlign: TextAlign.center, - style: const TextStyle( + style: scaledTextStyle( color: Colors.white, - fontSize: 24, + fontSize: 20, fontWeight: FontWeight.w700, - shadows: [ + shadows: const [ Shadow( offset: Offset(0, 0), blurRadius: 20, @@ -292,39 +293,35 @@ Widget welcomeHome(context) { child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 480), child: Column(children: [ - const Spacer(), + const Spacer(flex: 4), Row(children: [ Expanded( child: Stack(children: [ - const Padding( - padding: EdgeInsets.only(top: 55), + Padding( + padding: EdgeInsets.only(top: scaleSize(55)), child: Image( - image: AssetImage('assets/home/gecko-bienvenue.png'), - height: 220, + image: const AssetImage( + 'assets/home/gecko-bienvenue.png'), + height: scaleSize(180), ), ), Positioned( - left: 180, - child: BubbleSpeak(text: "noLizard".tr()), - ), - const Positioned( - left: 200, - top: 60, - child: Image( - image: AssetImage('assets/home/bout_de_bulle.png'), - ), + left: scaleSize(160), + top: 10, + child: BubbleSpeakWithTail(text: "noLizard".tr()), ), ]), ), ]), - SizedBox( - width: 410, - height: 70, + ScaledSizedBox( + width: 330, + height: 60, child: ElevatedButton( key: keyOnboardingNewChest, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () { Navigator.push( @@ -338,19 +335,21 @@ Widget welcomeHome(context) { }, child: Text( 'createWallet'.tr(), - style: const TextStyle( - fontSize: 24, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 21, + fontWeight: FontWeight.w600, + color: Colors.white), ), ), ), - SizedBox(height: 25 * ratio), - SizedBox( - width: 410, - height: 70, + ScaledSizedBox(height: scaleSize(25)), + ScaledSizedBox( + width: 330, + height: 60, child: OutlinedButton( key: keyRestoreChest, style: OutlinedButton.styleFrom( - side: const BorderSide(width: 4, color: orangeC)), + side: BorderSide(width: scaleSize(4), color: orangeC)), onPressed: () { Navigator.push( context, @@ -363,14 +362,14 @@ Widget welcomeHome(context) { }, child: Text( "restoreWallet".tr(), - style: const TextStyle( - fontSize: 24, + style: scaledTextStyle( + fontSize: 21, color: orangeC, fontWeight: FontWeight.w600), ), ), ), - SizedBox(height: isTall ? 100 : 50) + const Spacer(flex: 3), ]), ), ), diff --git a/lib/screens/myWallets/change_pin.dart b/lib/screens/myWallets/change_pin.dart index c469393..e30dcdf 100644 --- a/lib/screens/myWallets/change_pin.dart +++ b/lib/screens/myWallets/change_pin.dart @@ -3,13 +3,12 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:durt/durt.dart'; - import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; - import 'package:provider/provider.dart'; class ChangePinScreen extends StatefulWidget with ChangeNotifier { @@ -26,7 +25,7 @@ class ChangePinScreen extends StatefulWidget with ChangeNotifier { } class _ChangePinScreenState extends State { - final TextEditingController newPin = TextEditingController(); + final newPin = TextEditingController(); @override void initState() { @@ -48,11 +47,8 @@ class _ChangePinScreenState extends State { resizeToAvoidBottomInset: false, appBar: AppBar( elevation: 1, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text(widget.walletName!), - ), + toolbarHeight: scaleSize(57), + title: Text(widget.walletName!), ), body: Center( child: SafeArea( @@ -95,16 +91,16 @@ class _ChangePinScreenState extends State { height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 12, - backgroundColor: Colors.green[400], // foreground + foregroundColor: Colors.black, + elevation: 12, + backgroundColor: Colors.green[400], ), onPressed: () async { WalletData defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -113,13 +109,13 @@ class _ChangePinScreenState extends State { ), ); } - if (pin != null || myWalletProvider.pinCode != '') { - await sub.changePassword(context, defaultWallet.address, - widget.walletProvider.pinCode, newPin.text); - widget.walletProvider.pinCode = newPin.text; - newPin.text = ''; - Navigator.pop(context); - } + if (myWalletProvider.pinCode == '') return; + + await sub.changePassword(context, defaultWallet.address, + widget.walletProvider.pinCode, newPin.text); + widget.walletProvider.pinCode = newPin.text; + newPin.text = ''; + Navigator.pop(context); }, child: Text( 'confirm'.tr(), diff --git a/lib/screens/myWallets/chest_options.dart b/lib/screens/myWallets/chest_options.dart index f44730c..4a8f581 100644 --- a/lib/screens/myWallets/chest_options.dart +++ b/lib/screens/myWallets/chest_options.dart @@ -4,7 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; - +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; @@ -15,6 +15,7 @@ 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:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class ChestOptions extends StatelessWidget { @@ -31,28 +32,13 @@ class ChestOptions extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, resizeToAvoidBottomInset: false, - appBar: AppBar( - elevation: 1, - toolbarHeight: 60 * ratio, - // leading: IconButton( - // icon: const Icon(Icons.arrow_back, color: Colors.black), - // onPressed: () { - // // Navigator.popUntil( - // // context, - // // ModalRoute.withName('/mywallets'), - // // ); - // Navigator.pop(context); - // }), - title: SizedBox( - height: 22, - child: Text(currentChest.name!), - )), + appBar: GeckoAppBar(currentChest.name!), bottomNavigationBar: const GeckoBottomAppBar(), body: Stack(children: [ Builder( builder: (ctx) => SafeArea( child: Column(children: [ - SizedBox(height: 30 * ratio), + ScaledSizedBox(height: 20), InkWell( key: keyShowSeed, onTap: () async { @@ -60,8 +46,7 @@ class ChestOptions extends StatelessWidget { Provider.of(context, listen: false); WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; - pin = await Navigator.push( + final String? pin = await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -70,38 +55,40 @@ class ChestOptions extends StatelessWidget { ), ); - if (pin != null) { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return ShowSeed( - walletName: currentChest.name, - walletProvider: walletProvider, - ); - }), - ); - } + if (pin == null) return; + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return ShowSeed( + walletName: currentChest.name, + walletProvider: walletProvider, + ); + }), + ); }, - child: SizedBox( - height: 50, + child: ScaledSizedBox( + height: 60, child: Row(children: [ - const SizedBox(width: 20), + ScaledSizedBox(width: 20), Image.asset( 'assets/onBoarding/phrase_de_restauration_flou.png', - width: 60, + width: scaleSize(60), ), - const SizedBox(width: 15), - Text( - 'displayMnemonic'.tr(), - style: const TextStyle( - fontSize: 20, - color: orangeC, + ScaledSizedBox(width: 13), + ScaledSizedBox( + width: 270, + child: Text( + 'displayMnemonic'.tr(), + style: scaledTextStyle( + fontSize: 17, + color: orangeC, + ), ), ), ]), ), ), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: 2), Consumer(builder: (context, sub, _) { return InkWell( key: keyChangePin, @@ -126,19 +113,19 @@ class ChestOptions extends StatelessWidget { // } // } // : null, - child: SizedBox( - height: 50, + child: ScaledSizedBox( + height: 60, child: Row(children: [ - const SizedBox(width: 26), + ScaledSizedBox(width: 30), Image.asset( 'assets/chests/secret_code.png', - height: 25, + height: scaleSize(22), ), - const SizedBox(width: 18), + ScaledSizedBox(width: 18), Text( 'changePassword'.tr(), - style: TextStyle( - fontSize: 20, + style: scaledTextStyle( + fontSize: 17, color: sub.nodeConnected ? Colors.grey[500] : Colors.grey[500]), @@ -146,7 +133,7 @@ class ChestOptions extends StatelessWidget { ])), ); }), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: 2), Consumer(builder: (context, sub, _) { return InkWell( key: keycreateRootDerivation, @@ -162,19 +149,19 @@ class ChestOptions extends StatelessWidget { ); } : null, - child: SizedBox( - height: 50, + child: ScaledSizedBox( + height: 60, child: Row(children: [ - const SizedBox(width: 35), - const Icon( + ScaledSizedBox(width: 37), + Icon( Icons.manage_accounts, - size: 33, + size: scaleSize(31), ), - const SizedBox(width: 25), + ScaledSizedBox(width: 23), Text( 'createDerivation'.tr(), - style: TextStyle( - fontSize: 20, + style: scaledTextStyle( + fontSize: 17, color: sub.nodeConnected ? Colors.black : Colors.grey[500]), @@ -183,26 +170,26 @@ class ChestOptions extends StatelessWidget { ), ); }), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: 2), InkWell( key: keyDeleteChest, onTap: () async { await chestProvider.deleteChest(context, currentChest); }, - child: SizedBox( - height: 50, + child: ScaledSizedBox( + height: 60, child: Row(children: [ - const SizedBox(width: 28), + ScaledSizedBox(width: 32), Image.asset( 'assets/walletOptions/trash.png', - height: 45, + height: scaleSize(38), ), - const SizedBox(width: 20), + ScaledSizedBox(width: 22), Text( 'deleteChest'.tr(), - style: const TextStyle( - fontSize: 20, - color: Color(0xffD80000), + style: scaledTextStyle( + fontSize: 17, + color: const Color(0xffD80000), ), ), ]), diff --git a/lib/screens/myWallets/choose_chest.dart b/lib/screens/myWallets/choose_chest.dart index 377c5f8..0285e12 100644 --- a/lib/screens/myWallets/choose_chest.dart +++ b/lib/screens/myWallets/choose_chest.dart @@ -1,8 +1,8 @@ // ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; @@ -23,7 +23,7 @@ class ChooseChest extends StatefulWidget { } class _ChooseChestState extends State { - TextEditingController tplController = TextEditingController(); + final tplController = TextEditingController(); CarouselController buttonCarouselController = CarouselController(); int? currentChest = configBox.get('currentChest'); @@ -34,14 +34,10 @@ class _ChooseChestState extends State { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('selectMyChest'.tr()), - )), + toolbarHeight: scaleSize(57), title: Text('selectMyChest'.tr())), body: SafeArea( child: Column(children: [ - SizedBox(height: 160 * ratio), + const SizedBox(height: 160), CarouselSlider( carouselController: buttonCarouselController, options: CarouselOptions( @@ -102,14 +98,14 @@ class _ChooseChestState extends State { ); }).toList(), ), - SizedBox(height: 80 * ratio), + const SizedBox(height: 80), SizedBox( width: 400, height: 70, child: ElevatedButton( style: ElevatedButton.styleFrom( foregroundColor: Colors.black, - backgroundColor: orangeC, // foreground + backgroundColor: orangeC, ), onPressed: () async { await configBox.put('currentChest', currentChest); diff --git a/lib/screens/myWallets/custom_derivations.dart b/lib/screens/myWallets/custom_derivations.dart index 0d2efaa..a2e9ef9 100644 --- a/lib/screens/myWallets/custom_derivations.dart +++ b/lib/screens/myWallets/custom_derivations.dart @@ -1,12 +1,13 @@ // ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class CustomDerivation extends StatefulWidget { @@ -48,28 +49,27 @@ class _CustomDerivationState extends State { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('createCustomDerivation'.tr()), - )), + appBar: GeckoAppBar('createCustomDerivation'.tr()), body: Center( child: SafeArea( child: Column(children: [ const Spacer(), Text( 'chooseDerivation'.tr(), + style: scaledTextStyle(fontSize: 17), ), - const SizedBox(height: 20), - SizedBox( + ScaledSizedBox(height: 20), + ScaledSizedBox( width: 100, child: DropdownButton( value: dropdownValue, menuMaxHeight: 300, - icon: const Icon(Icons.arrow_downward), + icon: Icon( + Icons.arrow_downward, + size: scaleSize(20), + ), elevation: 16, - style: const TextStyle(color: orangeC), + style: scaledTextStyle(color: orangeC), underline: Container( height: 2, color: orangeC, @@ -83,14 +83,14 @@ class _CustomDerivationState extends State { .map>((String value) { return DropdownMenuItem( value: value, - child: SizedBox( + child: ScaledSizedBox( width: 75, child: Row(children: [ const Spacer(), Text( value, - style: const TextStyle( - fontSize: 20, color: Colors.black), + style: scaledTextStyle( + fontSize: 17, color: Colors.black), ), const Spacer(), ]), @@ -99,20 +99,20 @@ class _CustomDerivationState extends State { ), ), const Spacer(flex: 1), - SizedBox( - width: 410, - height: 70, + ScaledSizedBox( + width: 240, + height: 55, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () async { WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -122,27 +122,28 @@ class _CustomDerivationState extends State { ); } - if (pin != null || myWalletProvider.pinCode != '') { - String newDerivationName = - '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; - if (dropdownValue == 'root') { - await myWalletProvider.generateRootWallet( - context, 'rootWallet'.tr()); - } else { - await myWalletProvider.generateNewDerivation( - context, - newDerivationName, - int.parse(dropdownValue!), - ); - } - Navigator.pop(context); - Navigator.pop(context); + if (myWalletProvider.pinCode != '') return; + String newDerivationName = + '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; + if (dropdownValue == 'root') { + await myWalletProvider.generateRootWallet( + context, 'rootWallet'.tr()); + } else { + await myWalletProvider.generateNewDerivation( + context, + newDerivationName, + int.parse(dropdownValue!), + ); } + Navigator.popUntil( + context, ModalRoute.withName('/mywallets')); }, child: Text( 'validate'.tr(), - style: const TextStyle( - fontSize: 24, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 19, + fontWeight: FontWeight.w600, + color: Colors.white), ), ), ), diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index 82f957b..f6b5f0a 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -1,12 +1,12 @@ // ignore_for_file: use_build_context_synchronously import 'dart:async'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/migrate_wallet_checks.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -15,11 +15,13 @@ 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/certifications.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:gecko/widgets/idty_status.dart'; import 'package:provider/provider.dart'; class ImportG1v1 extends StatelessWidget { const ImportG1v1({Key? key}) : super(key: key); + static const int debouneTime = 600; @override Widget build(BuildContext context) { @@ -27,12 +29,7 @@ class ImportG1v1 extends StatelessWidget { Provider.of(context, listen: false); Timer? debounce; - const int debouneTime = 600; WalletData selectedWallet = myWalletProvider.getDefaultWallet(); - bool canValidate = false; - String validationStatus = ''; - - log.d(myWalletProvider.listWallets); return PopScope( onPopInvoked: (_) { @@ -40,28 +37,24 @@ class ImportG1v1 extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('importOldAccount'.tr()), - )), + appBar: GeckoAppBar('importOldAccount'.tr()), body: SafeArea( child: Consumer(builder: (context, sub, _) { return FutureBuilder( future: sub.getBalanceAndIdtyStatus( sub.g1V1NewAddress, selectedWallet.address), - builder: (BuildContext context, AsyncSnapshot status) { + builder: (BuildContext context, + AsyncSnapshot status) { if (status.data == null) { - return const Column(children: [ - SizedBox(height: 80), + return Column(children: [ + ScaledSizedBox(height: 80), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( + ScaledSizedBox( height: 35, width: 35, - child: CircularProgressIndicator( + child: const CircularProgressIndicator( color: orangeC, strokeWidth: 4, ), @@ -70,43 +63,13 @@ class ImportG1v1 extends StatelessWidget { ]); } - final Map balance = status.data?[0] ?? {}; - final IdtyStatus idtyStatus = status.data?[1]; - final IdtyStatus myIdtyStatus = status.data?[2]; - final bool hasConsumer = status.data?[3] ?? false; - final bool isSmith = status.data?[4] ?? false; - - if (balance['transferableBalance'] != 0 && !hasConsumer) { - canValidate = true; - validationStatus = ''; - } else { - canValidate = false; - validationStatus = hasConsumer - ? 'youMustWaitBeforeCashoutThisAccount'.tr() - : 'thisAccountIsEmpty'.tr(); - } - - if (idtyStatus != IdtyStatus.none && - myIdtyStatus != IdtyStatus.none) { - canValidate = false; - validationStatus = - 'youCannotMigrateIdentityToExistingIdentity'.tr(); - } - - if (isSmith) { - canValidate = false; - validationStatus = 'smithCantMigrateIdentity'.tr(); - } - - if (sub.g1V1NewAddress == '') { - validationStatus = ''; - } + final statusData = status.data!; final bool isUdUnit = configBox.get('isUdUnit') ?? false; final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName; return Column(children: [ - const SizedBox(height: 20), + ScaledSizedBox(height: 10), TextFormField( key: keyCesiumId, autofocus: true, @@ -117,15 +80,18 @@ class ImportG1v1 extends StatelessWidget { } debounce = Timer( const Duration(milliseconds: debouneTime), () { - sub.reload(); - sub.csToV2Address( - sub.csSalt.text, sub.csPassword.text); + if (sub.csSalt.text != '' && + sub.csPassword.text != '') { + sub.reload(); + sub.csToV2Address( + sub.csSalt.text, sub.csPassword.text); + } }); }, keyboardType: TextInputType.text, controller: sub.csSalt, - obscureText: !sub - .isCesiumIDVisible, //This will obscure text dynamically + obscureText: !sub.isCesiumIDVisible, + style: scaledTextStyle(fontSize: 16), decoration: InputDecoration( hintText: 'enterCesiumId'.tr(), suffixIcon: IconButton( @@ -135,6 +101,7 @@ class ImportG1v1 extends StatelessWidget { ? Icons.visibility_off : Icons.visibility, color: Colors.black, + size: scaleSize(22), ), onPressed: () { sub.cesiumIDisVisible(); @@ -142,7 +109,7 @@ class ImportG1v1 extends StatelessWidget { ), ), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 7), TextFormField( key: keyCesiumPassword, autofocus: true, @@ -154,15 +121,18 @@ class ImportG1v1 extends StatelessWidget { debounce = Timer( const Duration(milliseconds: debouneTime), () { sub.g1V1NewAddress = ''; - sub.reload(); - sub.csToV2Address( - sub.csSalt.text, sub.csPassword.text); + if (sub.csSalt.text != '' && + sub.csPassword.text != '') { + sub.reload(); + sub.csToV2Address( + sub.csSalt.text, sub.csPassword.text); + } }); }, keyboardType: TextInputType.text, controller: sub.csPassword, - obscureText: !sub - .isCesiumIDVisible, //This will obscure text dynamically + obscureText: !sub.isCesiumIDVisible, + style: scaledTextStyle(fontSize: 16), decoration: InputDecoration( hintText: 'enterCesiumPassword'.tr(), suffixIcon: IconButton( @@ -171,6 +141,7 @@ class ImportG1v1 extends StatelessWidget { ? Icons.visibility_off : Icons.visibility, color: Colors.black, + size: scaleSize(22), ), onPressed: () { sub.cesiumIDisVisible(); @@ -178,45 +149,75 @@ class ImportG1v1 extends StatelessWidget { ), ), ), - const SizedBox(height: 20), - GestureDetector( - key: keyCopyAddress, - onTap: () { - Clipboard.setData( - ClipboardData(text: sub.g1V1OldPubkey)); - snackCopyKey(context); - }, - child: Text( - sub.g1V1OldPubkey, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), + ScaledSizedBox(height: 20), + Visibility( + visible: sub.g1V1OldPubkey != '', + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + children: [ + GestureDetector( + key: keyCopyPubkey, + onTap: () { + Clipboard.setData( + ClipboardData(text: sub.g1V1OldPubkey)); + snackCopyKey(context); + }, + child: Text( + 'v1: ${getShortPubkey(sub.g1V1OldPubkey)}', + style: scaledTextStyle( + fontSize: 17, + fontWeight: FontWeight.w600, + fontFamily: 'Monospace'), + ), + ), + ScaledSizedBox(height: 5), + GestureDetector( + key: keyCopyAddress, + onTap: () { + Clipboard.setData( + ClipboardData(text: sub.g1V1OldPubkey)); + snackCopyKey(context); + }, + child: Text( + 'v2: ${getShortPubkey(sub.g1V1NewAddress)}', + style: scaledTextStyle( + fontSize: 17, + fontWeight: FontWeight.w600, + fontFamily: 'Monospace'), + ), + ), + ], + ), + ScaledSizedBox(width: 30), + Column( + children: [ + Text( + '${statusData.balance['transferableBalance']} $unit', + style: scaledTextStyle(fontSize: 16), + ), + IdentityStatus( + address: sub.g1V1NewAddress, + isOwner: false, + color: Colors.black), + ScaledSizedBox(width: 10), + Certifications( + address: sub.g1V1NewAddress, size: 14) + ], + ), + ], ), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), Text( - '${balance['transferableBalance']} $unit', - style: const TextStyle(fontSize: 17), + 'migrateToThisWallet'.tr(), + style: scaledTextStyle(fontSize: 17), ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IdentityStatus( - address: sub.g1V1NewAddress, - isOwner: false, - color: Colors.black), - const SizedBox(width: 10), - Certifications(address: sub.g1V1NewAddress, size: 14) - ], - ), - const SizedBox(height: 30), - Text('selectDestWallet'.tr()), - const SizedBox(height: 5), + ScaledSizedBox(height: 5), DropdownButtonHideUnderline( key: keySelectWallet, child: DropdownButton( - // alignment: AlignmentDirectional.topStart, value: selectedWallet, icon: const Icon(Icons.keyboard_arrow_down), items: myWalletProvider.listWallets.map((wallet) { @@ -225,7 +226,7 @@ class ImportG1v1 extends StatelessWidget { value: wallet, child: Text( wallet.name!, - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 17), ), ); }).toList(), @@ -235,17 +236,18 @@ class ImportG1v1 extends StatelessWidget { }, ), ), - const SizedBox(height: 30), - SizedBox( - width: 380 * ratio, - height: 60 * ratio, + ScaledSizedBox(height: 10), + ScaledSizedBox( + width: 320, + height: 50, child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), - onPressed: canValidate + onPressed: statusData.canValidate ? () async { WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); @@ -263,17 +265,20 @@ class ImportG1v1 extends StatelessWidget { ); } - sub.migrateCsToV2(sub.csSalt.text, - sub.csPassword.text, selectedWallet.address, + final transactionId = await sub.migrateCsToV2( + sub.csSalt.text, + sub.csPassword.text, + selectedWallet.address, destPassword: pin ?? myWalletProvider.pinCode, - balance: balance, - idtyStatus: idtyStatus); + balance: statusData.balance, + idtyStatus: statusData.idtyStatus); Navigator.pop(context); - Navigator.push( + await Navigator.push( context, MaterialPageRoute(builder: (context) { return TransactionInProgress( + transactionId: transactionId, transType: 'identityMigration', fromAddress: getShortPubkey(sub.g1V1NewAddress), @@ -286,17 +291,17 @@ class ImportG1v1 extends StatelessWidget { : null, child: Text( 'migrateAccount'.tr(), - style: TextStyle( - fontSize: 23 * ratio, - fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 20, fontWeight: FontWeight.w600), ), ), ), - const SizedBox(height: 10), + ScaledSizedBox(height: 10), Text( - validationStatus, + statusData.validationStatus, textAlign: TextAlign.center, - style: TextStyle(fontSize: 15, color: Colors.grey[600]), + style: scaledTextStyle( + fontSize: 14, color: Colors.grey[600]), ) ]); }); @@ -312,5 +317,6 @@ class ImportG1v1 extends StatelessWidget { sub.csSalt.text = ''; sub.csPassword.text = ''; sub.g1V1NewAddress = ''; + sub.g1V1OldPubkey = ''; } } diff --git a/lib/screens/myWallets/manage_membership.dart b/lib/screens/myWallets/manage_membership.dart index 8b7af18..03f3c36 100644 --- a/lib/screens/myWallets/manage_membership.dart +++ b/lib/screens/myWallets/manage_membership.dart @@ -1,9 +1,9 @@ // ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -12,6 +12,7 @@ import 'package:gecko/widgets/commons/common_elements.dart'; import 'package:gecko/screens/myWallets/migrate_identity.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/transaction_in_progress.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; // import 'package:gecko/models/wallet_data.dart'; // import 'package:gecko/providers/my_wallets.dart'; @@ -31,44 +32,39 @@ class ManageMembership extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: const Text('manageMembership').tr(), - )), + appBar: GeckoAppBar('manageMembership'.tr()), body: SafeArea( child: Column(children: [ - const SizedBox(height: 20), + ScaledSizedBox(height: 20), migrateIdentity(context), - const SizedBox(height: 10), + ScaledSizedBox(height: 10), FutureBuilder( future: sub.isSmith(address), builder: (BuildContext context, AsyncSnapshot isSmith) { if (isSmith.data ?? false) { - return SizedBox( + return ScaledSizedBox( height: 75, child: Row( children: [ - const SizedBox(width: 20), + ScaledSizedBox(width: 17), Image.asset( 'assets/skull_Icon.png', color: Colors.grey[500], - height: 30, + height: scaleSize(28), ), - const SizedBox(width: 16), + ScaledSizedBox(width: 12), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('revokeMyIdentity'.tr(), - style: TextStyle( - fontSize: 20, + style: scaledTextStyle( + fontSize: 18, color: Colors.grey[500])), - const SizedBox(height: 2), + ScaledSizedBox(height: 2), Text("youCannotRevokeThisIdentity".tr(), - style: TextStyle( - fontSize: 14, + style: scaledTextStyle( + fontSize: 13, color: Colors.grey[500])), ]), ], @@ -77,7 +73,6 @@ class ManageMembership extends StatelessWidget { return revokeMyIdentity(context); } }) - // const SizedBox(height: 20), ]), )); } @@ -93,13 +88,13 @@ class ManageMembership extends StatelessWidget { }), ); }, - child: const SizedBox( - height: 60, + child: ScaledSizedBox( + height: 55, child: Row(children: [ - SizedBox(width: 16), - Icon(Icons.change_circle_outlined, size: 35), - SizedBox(width: 11.5), - Text('Migrer mon identité', style: TextStyle(fontSize: 20)), + ScaledSizedBox(width: 16), + Icon(Icons.change_circle_outlined, size: scaleSize(32)), + ScaledSizedBox(width: 11.5), + Text('Migrer mon identité', style: scaledTextStyle(fontSize: 18)), ]), ), ); @@ -109,58 +104,56 @@ class ManageMembership extends StatelessWidget { return InkWell( key: keyRevokeIdty, onTap: () async { - // TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options final answer = await confirmPopup(context, 'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ?? false; - if (answer) { - final myWalletProvider = - Provider.of(context, listen: false); - final sub = Provider.of(context, listen: false); + if (!answer) return; + final myWalletProvider = + Provider.of(context, listen: false); + final sub = Provider.of(context, listen: false); - // MyWalletsProvider mw = MyWalletsProvider(); - // final wallet = mw.getWalletDataByAddress(address); - // await sub.setCurrentWallet(wallet!); - - 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 != '') { - sub.revokeIdentity(address, myWalletProvider.pinCode); - } - Navigator.pop(context); - - Navigator.push( + WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); + String? pin; + if (myWalletProvider.pinCode == '') { + pin = await Navigator.push( context, - MaterialPageRoute(builder: (context) { - return TransactionInProgress( - transType: 'revokeIdty', - fromAddress: getShortPubkey(address), - toAddress: getShortPubkey(address)); - }), + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), ); } + + if (pin == null || myWalletProvider.pinCode == '') return; + + final transactionId = + await sub.revokeIdentity(address, myWalletProvider.pinCode); + + Navigator.pop(context); + + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transactionId: transactionId, + transType: 'revokeIdty', + fromAddress: getShortPubkey(address), + toAddress: getShortPubkey(address)); + }), + ); }, - child: SizedBox( - height: 60, + child: ScaledSizedBox( + height: 55, child: Row(children: [ - const SizedBox(width: 20), + ScaledSizedBox(width: 20), Image.asset( 'assets/skull_Icon.png', - height: 30, + height: scaleSize(28), ), - const SizedBox(width: 16), - const Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)), + ScaledSizedBox(width: 16), + Text('Révoquer mon adhésion', style: scaledTextStyle(fontSize: 18)), ]), ), ); diff --git a/lib/screens/myWallets/migrate_identity.dart b/lib/screens/myWallets/migrate_identity.dart index 31660b7..ced07f1 100644 --- a/lib/screens/myWallets/migrate_identity.dart +++ b/lib/screens/myWallets/migrate_identity.dart @@ -1,10 +1,11 @@ // ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/migrate_wallet_checks.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -13,6 +14,7 @@ import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/transaction_in_progress.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class MigrateIdentityScreen extends StatelessWidget { @@ -38,24 +40,22 @@ class MigrateIdentityScreen extends StatelessWidget { } else { selectedWallet = defaultWallet; } - bool canValidate = false; - String validationStatus = ''; final mdStyle = MarkdownStyleSheet( - p: const TextStyle(fontSize: 18, color: Colors.black, letterSpacing: 0.3), + p: scaledTextStyle(fontSize: 17, color: Colors.black, letterSpacing: 0.3), textAlign: WrapAlignment.center, ); if (walletsList.length < 2) { - return const Column( + return Column( children: [ - SizedBox(height: 80), + ScaledSizedBox(height: 80), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération', - style: TextStyle(fontSize: 20), + style: scaledTextStyle(fontSize: 17), ) ], ) @@ -65,113 +65,59 @@ class MigrateIdentityScreen extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('importOldAccount'.tr()), - )), + appBar: GeckoAppBar('migrateIdentity'.tr()), body: SafeArea( child: Consumer(builder: (context, sub, _) { return FutureBuilder( future: sub.getBalanceAndIdtyStatus( fromAddress, selectedWallet.address), - builder: (BuildContext context, AsyncSnapshot status) { + builder: (BuildContext context, + AsyncSnapshot status) { if (status.data == null) { - return const Column(children: [ - SizedBox(height: 80), + return Column(children: [ + ScaledSizedBox(height: 80), Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: 35, - width: 35, + ScaledSizedBox( + height: scaleSize(32), + width: scaleSize(32), child: CircularProgressIndicator( color: orangeC, - strokeWidth: 4, + strokeWidth: scaleSize(4), ), ), ]), ]); } - // log.d('statusData: ${status.data}'); - - final Map balance = status.data?[0] ?? {}; - final IdtyStatus idtyStatus = status.data?[1]; - final IdtyStatus myIdtyStatus = status.data?[2]; - final bool hasConsumer = status.data?[3] ?? false; - final bool isSmith = status.data?[4] ?? false; - - // log.d('hasconsumer: $hasConsumer'); - - if (isSmith) { - canValidate = false; - validationStatus = 'smithCantMigrateIdentity'.tr(); - } else if (balance['transferableBalance'] != 0 && - !hasConsumer) { - canValidate = true; - validationStatus = ''; - } else if (idtyStatus != IdtyStatus.none && - myIdtyStatus != IdtyStatus.none) { - canValidate = false; - validationStatus = - 'youCannotMigrateIdentityToExistingIdentity'.tr(); - } else { - canValidate = false; - validationStatus = hasConsumer - ? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X']) - : 'thisAccountIsEmpty'.tr(); - } - - log.d( - 'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address}, $balance, $idtyStatus, $myIdtyStatus'); - + final statusData = status.data!; final walletsList = myWalletProvider.listWallets.toList(); walletsList .removeWhere((element) => element.address == fromAddress); - // walletsList.add(WalletData(address: 'custom', name: 'custom')); final bool isUdUnit = configBox.get('isUdUnit') ?? false; final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName; return Column(children: [ const Row(children: []), - const SizedBox(height: 20), - - SizedBox( - width: 400, + ScaledSizedBox(height: 18), + ScaledSizedBox( + width: 320, child: MarkdownBody( data: 'areYouSureMigrateIdentity'.tr(args: [ duniterIndexer.walletNameIndexer[fromAddress] ?? '???', - '${balance['transferableBalance']} $unit' + '${statusData.balance['transferableBalance']} $unit' ]), styleSheet: mdStyle), ), - // Text( - // 'areYouSureMigrateIdentity'.tr(args: [ - // duniterIndexer - // .walletNameIndexer[fromAddress]!, - // '$balance $currencyName' - // ]), - // textAlign: TextAlign.center, - // ), - const SizedBox(height: 20), - Text( - sub.g1V1NewAddress, - style: const TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: FontWeight.bold, - fontFamily: 'Monospace'), - ), - const SizedBox(height: 30), - Text('selectDestWallet'.tr()), - const SizedBox(height: 5), + ScaledSizedBox(height: 55), + Text('migrateToThisWallet'.tr(), + style: scaledTextStyle(fontSize: 17)), + ScaledSizedBox(height: 5), DropdownButtonHideUnderline( key: keySelectWallet, child: DropdownButton( - // alignment: AlignmentDirectional.topStart, value: selectedWallet, icon: const Icon(Icons.keyboard_arrow_down), items: walletsList.map((wallet) { @@ -180,7 +126,7 @@ class MigrateIdentityScreen extends StatelessWidget { value: wallet, child: Text( wallet.name!, - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 17), ), ); }).toList(), @@ -190,19 +136,19 @@ class MigrateIdentityScreen extends StatelessWidget { }, ), ), - const SizedBox(height: 30), - SizedBox( - width: 380 * ratio, - height: 60 * ratio, + const Spacer(flex: 2), + ScaledSizedBox( + width: 320, + height: 55, child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), - onPressed: canValidate + onPressed: statusData.canValidate ? () async { - log.d('GOOO'); WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); @@ -219,17 +165,19 @@ class MigrateIdentityScreen extends StatelessWidget { ); } - sub.migrateIdentity( + if (myWalletProvider.pinCode == '') return; + final transactionId = await sub.migrateIdentity( fromAddress: fromAddress, destAddress: selectedWallet.address, fromPassword: pin ?? myWalletProvider.pinCode, destPassword: pin ?? myWalletProvider.pinCode, withBalance: true, - fromBalance: balance); + fromBalance: statusData.balance); Navigator.push( context, MaterialPageRoute(builder: (context) { return TransactionInProgress( + transactionId: transactionId, transType: 'identityMigration', fromAddress: getShortPubkey(fromAddress), toAddress: getShortPubkey( @@ -240,17 +188,21 @@ class MigrateIdentityScreen extends StatelessWidget { : null, child: Text( 'migrateIdentity'.tr(), - style: TextStyle( - fontSize: 23 * ratio, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: Colors.white), ), ), ), - const SizedBox(height: 10), + ScaledSizedBox(height: 10), Text( - validationStatus, + statusData.validationStatus, textAlign: TextAlign.center, - style: TextStyle(fontSize: 15, color: Colors.grey[600]), - ) + style: + scaledTextStyle(fontSize: 15, color: Colors.grey[600]), + ), + const Spacer(), ]); }); }), diff --git a/lib/screens/myWallets/restore_chest.dart b/lib/screens/myWallets/restore_chest.dart index ee4301f..83974f2 100644 --- a/lib/screens/myWallets/restore_chest.dart +++ b/lib/screens/myWallets/restore_chest.dart @@ -2,9 +2,9 @@ import 'package:bubble/bubble.dart'; import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -12,6 +12,7 @@ import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/widgets/commons/fader_transition.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; // import 'package:gecko/models/home.dart'; // import 'package:provider/provider.dart'; @@ -36,18 +37,13 @@ class RestoreChest extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('restoreAChest'.tr()), - )), + appBar: GeckoAppBar('restoreAChest'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - SizedBox(height: isTall ? 30 : 15), + ScaledSizedBox(height: isTall ? 20 : 3), bubbleSpeak('toRestoreEnterMnemonic'.tr()), - SizedBox(height: isTall ? 30 : 15), + ScaledSizedBox(height: isTall ? 20 : 5), Column(children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, @@ -57,7 +53,7 @@ class RestoreChest extends StatelessWidget { arrayCell(context, genW.cellController2), arrayCell(context, genW.cellController3), ]), - const SizedBox(height: 15), + ScaledSizedBox(height: isTall ? 10 : 3), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -66,7 +62,7 @@ class RestoreChest extends StatelessWidget { arrayCell(context, genW.cellController6), arrayCell(context, genW.cellController7), ]), - const SizedBox(height: 15), + ScaledSizedBox(height: isTall ? 10 : 3), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -81,14 +77,15 @@ class RestoreChest extends StatelessWidget { Expanded( child: Align( alignment: Alignment.center, - child: SizedBox( - width: 410, - height: 70, + child: ScaledSizedBox( + width: 340, + height: 55, child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () async { if (await sub @@ -110,8 +107,10 @@ class RestoreChest extends StatelessWidget { }, child: Text( 'restoreThisChest'.tr(), - style: const TextStyle( - fontSize: 24, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: Colors.white), ), ), ), @@ -119,15 +118,16 @@ class RestoreChest extends StatelessWidget { )) else Column(children: [ - const SizedBox(height: 20), - SizedBox( - width: 190, - height: 60, + ScaledSizedBox(height: 20), + ScaledSizedBox( + width: 210, + height: 55, child: ElevatedButton( key: keyPastMnemonic, style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 4, - backgroundColor: yellowC, // foreground + foregroundColor: Colors.black, + elevation: 4, + backgroundColor: yellowC, ), onPressed: () { genW.pasteMnemonic(context); @@ -135,16 +135,15 @@ class RestoreChest extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - const Icon( + Icon( Icons.content_paste_go, - size: 27, + size: scaleSize(28), ), - // const SizedBox(width: 10), Text( 'pasteFromClipboard'.tr(), textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 17, fontWeight: FontWeight.w400), + style: scaledTextStyle( + fontSize: 16, fontWeight: FontWeight.w400), ), ], )), @@ -161,7 +160,7 @@ class RestoreChest extends StatelessWidget { Widget bubbleSpeak(String text) { return Bubble( margin: const BubbleEdges.symmetric(horizontal: 20), - padding: BubbleEdges.all(isTall ? 25 : 15), + padding: BubbleEdges.all(scaleSize(15)), borderWidth: 1, borderColor: Colors.black, radius: Radius.zero, @@ -170,19 +169,19 @@ class RestoreChest extends StatelessWidget { text, key: keyBubbleSpeak, textAlign: TextAlign.justify, - style: const TextStyle( - color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400), + style: scaledTextStyle( + color: Colors.black, fontSize: 17, fontWeight: FontWeight.w400), ), ); } - Widget arrayCell(BuildContext context, TextEditingController cellCtl) { + Widget arrayCell(BuildContext context, final cellCtl) { final generateWalletProvider = Provider.of(context); return Container( - width: 102, - height: 40 * ratio, + width: scaleSize(87), + height: scaleSize(37), // ), decoration: BoxDecoration( border: Border.all(color: Colors.grey), @@ -213,7 +212,7 @@ class RestoreChest extends StatelessWidget { } }, textAlign: TextAlign.center, - style: const TextStyle(fontSize: 20), + style: scaledTextStyle(fontSize: 17), ), ); } @@ -221,7 +220,7 @@ class RestoreChest extends StatelessWidget { Future badMnemonicPopup(BuildContext context) async { return showDialog( context: context, - barrierDismissible: true, // user must tap button! + barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( title: const Text('Phrase incorrecte'), diff --git a/lib/screens/myWallets/show_seed.dart b/lib/screens/myWallets/show_seed.dart index 0a146c3..767ce57 100644 --- a/lib/screens/myWallets/show_seed.dart +++ b/lib/screens/myWallets/show_seed.dart @@ -1,14 +1,15 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.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/wallets_profiles.dart'; import 'package:gecko/widgets/commons/build_text.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:pdf/pdf.dart'; import 'package:printing/printing.dart'; import 'package:provider/provider.dart'; @@ -33,12 +34,7 @@ class ShowSeed extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('myMnemonic'.tr()), - )), + appBar: GeckoAppBar('myMnemonic'.tr()), body: SafeArea( child: Column(children: [ const Spacer(flex: 1), @@ -48,10 +44,10 @@ class ShowSeed extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot seed) { if (seed.connectionState != ConnectionState.done || seed.hasError) { - return const SizedBox( + return ScaledSizedBox( height: 15, width: 15, - child: CircularProgressIndicator( + child: const CircularProgressIndicator( color: orangeC, strokeWidth: 2, ), @@ -64,74 +60,82 @@ class ShowSeed extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Column(children: [ - BuildText(text: 'keepYourMnemonicSecret'.tr()), - SizedBox(height: 35 * ratio), + BuildText( + text: 'keepYourMnemonicSecret'.tr(), size: 16), + ScaledSizedBox(height: 35), sentanceArray(context, seed.data!.split(' ')), - const SizedBox(height: 20), - SizedBox( - height: 40, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), + ScaledSizedBox(height: 20), + Row( + children: [ + ScaledSizedBox( + height: 39, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Colors.black, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + backgroundColor: orangeC, + elevation: 1, + ), + onPressed: () { + Clipboard.setData( + ClipboardData(text: seed.data!)); + snackCopySeed(context); + }, + child: Row(children: [ + Image.asset( + 'assets/walletOptions/copy-white.png', + height: scaleSize(24), + ), + ScaledSizedBox(width: 7), + Text( + 'copy'.tr(), + style: scaledTextStyle( + fontSize: 14, color: Colors.grey[50]), + ) + ]), ), - backgroundColor: orangeC, - elevation: 1, // foreground ), - onPressed: () { - Clipboard.setData( - ClipboardData(text: seed.data!)); - snackCopySeed(context); - }, - child: Row(children: [ - Image.asset( - 'assets/walletOptions/copy-white.png', - height: 25, + ScaledSizedBox(width: 50), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return PrintWallet(seed.data); + }), + ); + }, + child: Image.asset( + 'assets/printer.png', + height: scaleSize(38), ), - const SizedBox(width: 7), - Text( - 'copy'.tr(), - style: TextStyle( - fontSize: 15, color: Colors.grey[50]), - ) - ]), - ), - ), - const SizedBox(height: 30), - GestureDetector( - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return PrintWallet(seed.data); - }), - ); - }, - child: Image.asset( - 'assets/printer.png', - height: 42 * ratio, - ), + ), + ], ), ]), ]); }), - const Spacer(flex: 2), - SizedBox( - width: 380 * ratio, - height: 60 * ratio, + const Spacer(flex: 3), + ScaledSizedBox( + width: 240, + height: 55, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () { Navigator.pop(context); }, child: Text( 'close'.tr(), - style: TextStyle( - fontSize: 23 * ratio, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 19, + fontWeight: FontWeight.w600, + color: Colors.white), ), ), ), @@ -141,61 +145,55 @@ class ShowSeed extends StatelessWidget { } Widget sentanceArray(BuildContext context, List mnemonic) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 3), - child: Container( - constraints: const BoxConstraints(maxWidth: 450), - decoration: BoxDecoration( - border: Border.all(color: Colors.black), - color: const Color(0xffeeeedd), - borderRadius: const BorderRadius.all( - Radius.circular(10), - )), - padding: const EdgeInsets.all(20), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row(children: [ - arrayCell(mnemonic[0], 1), - arrayCell(mnemonic[1], 2), - arrayCell(mnemonic[2], 3), - arrayCell(mnemonic[3], 4), - ]), - const SizedBox(height: 15), - Row(children: [ - arrayCell(mnemonic[4], 5), - arrayCell(mnemonic[5], 6), - arrayCell(mnemonic[6], 7), - arrayCell(mnemonic[7], 8), - ]), - const SizedBox(height: 15), - Row(children: [ - arrayCell(mnemonic[8], 9), - arrayCell(mnemonic[9], 10), - arrayCell(mnemonic[10], 11), - arrayCell(mnemonic[11], 12), - ]), - ])), - ); + return Container( + constraints: BoxConstraints(maxWidth: scaleSize(360)), + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + color: const Color(0xffeeeedd), + borderRadius: const BorderRadius.all( + Radius.circular(10), + )), + padding: EdgeInsets.all(scaleSize(14)), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row(children: [ + arrayCell(mnemonic[0], 1), + arrayCell(mnemonic[1], 2), + arrayCell(mnemonic[2], 3), + arrayCell(mnemonic[3], 4), + ]), + ScaledSizedBox(height: 15), + Row(children: [ + arrayCell(mnemonic[4], 5), + arrayCell(mnemonic[5], 6), + arrayCell(mnemonic[6], 7), + arrayCell(mnemonic[7], 8), + ]), + ScaledSizedBox(height: 15), + Row(children: [ + arrayCell(mnemonic[8], 9), + arrayCell(mnemonic[9], 10), + arrayCell(mnemonic[10], 11), + arrayCell(mnemonic[11], 12), + ]), + ])); } Widget arrayCell(dataWord, int nbr) { - log.d(nbr); - - return SizedBox( - width: 100, + return ScaledSizedBox( + width: 82, child: Column(children: [ Text( nbr.toString(), - style: - TextStyle(fontSize: 13 * ratio, color: const Color(0xff6b6b52)), + style: scaledTextStyle(fontSize: 11, color: const Color(0xff6b6b52)), ), Text( dataWord, key: keyMnemonicWord(dataWord), - style: TextStyle(fontSize: 17 * ratio, color: Colors.black), + style: scaledTextStyle(fontSize: 16, color: Colors.black), ), ]), ); @@ -219,13 +217,10 @@ class PrintWallet extends StatelessWidget { }), backgroundColor: yellowC, foregroundColor: Colors.black, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'printMyMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), + toolbarHeight: scaleSize(57), + title: Text( + 'printMyMnemonic'.tr(), + style: scaledTextStyle(fontWeight: FontWeight.w600), ), ), body: PdfPreview( diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index 02b51d5..3bbac91 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -3,8 +3,8 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; - import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -22,7 +22,7 @@ class UnlockingWallet extends StatelessWidget { late int currentChestNumber; late ChestData currentChest; bool canUnlock = true; - TextEditingController enterPin = TextEditingController(); + final enterPin = TextEditingController(); FocusNode pinFocus = FocusNode(debugLabel: 'pinFocusNode'); // ignore: close_sinks @@ -58,15 +58,15 @@ class UnlockingWallet extends StatelessWidget { children: [ Stack(children: [ Positioned( - top: 10, //statusBarHeight + 10, + top: 10, left: 15, child: Builder( builder: (context) => IconButton( key: keyPopButton, - icon: const Icon( + icon: Icon( Icons.arrow_back, color: Colors.black, - size: 30, + size: scaleSize(28), ), onPressed: () { myWalletProvider.isPinValid = false; @@ -77,52 +77,55 @@ class UnlockingWallet extends StatelessWidget { ), ), Column(children: [ - SizedBox(height: isTall ? 100 : 20), + ScaledSizedBox(height: isTall ? 80 : 65), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ currentChest.imageFile == null ? Image.asset( 'assets/chests/${currentChest.imageName}', - width: isTall ? 130 : 100, + width: scaleSize(95), ) : Image.file( currentChest.imageFile!, - width: isTall ? 130 : 100, + width: scaleSize(127), ), - const SizedBox(width: 5), - SizedBox( + ScaledSizedBox(width: 5), + ScaledSizedBox( width: 250, child: Text( currentChest.name!, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 25, + style: scaledTextStyle( + fontSize: 22, color: Colors.black, fontWeight: FontWeight.w700), )), ]), - SizedBox(height: 30 * ratio), - SizedBox( - width: 400, + ScaledSizedBox(height: isTall ? 30 : 15), + ScaledSizedBox( + width: 350, child: Text( 'toUnlockEnterPassword'.tr(), - style: const TextStyle( - fontSize: 19, + textAlign: TextAlign.center, + style: scaledTextStyle( + fontSize: 16, color: Colors.black, fontWeight: FontWeight.w400), )), - SizedBox(height: 30 * ratio), + ScaledSizedBox(height: isTall ? 30 : 15), if (!myWalletProvider.isPinValid && !myWalletProvider.isPinLoading) Text( "thisIsNotAGoodCode".tr(), - style: const TextStyle( - color: Colors.red, fontWeight: FontWeight.w500), + style: scaledTextStyle( + color: Colors.red, + fontWeight: FontWeight.w500, + fontSize: 16), ), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: isTall ? 8 : 0), pinForm(context, pinLenght), - SizedBox(height: 3 * ratio), + ScaledSizedBox(height: 8), if (canUnlock) Consumer( builder: (context, sub, _) { @@ -132,49 +135,50 @@ class UnlockingWallet extends StatelessWidget { walletOptions.changePinCacheChoice(); }, child: Row(children: [ - const SizedBox(height: 30), + ScaledSizedBox(height: 30), const Spacer(), Icon( configBox.get('isCacheChecked') ? Icons.check_box : Icons.check_box_outline_blank, color: orangeC, + size: scaleSize(22), ), - const SizedBox(width: 8), + ScaledSizedBox(width: 8), Text( 'rememberPassword'.tr(), - style: TextStyle( - fontSize: 16, color: Colors.grey[700]), + style: scaledTextStyle( + fontSize: 15, color: Colors.grey[700]), ), const Spacer() ]), ); }), - const SizedBox(height: 10), + // const ScaledSizedBox(height: 10), // if (canUnlock) - InkWell( - key: keyChangeChest, - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) { - // return const ChooseChest(); - // }), - // ); - }, - child: SizedBox( - width: 400, - height: 50, - child: Center( - child: Text( - 'changeChest'.tr(), - style: const TextStyle( - fontSize: 22, - color: Colors.grey, // orangeC - fontWeight: FontWeight.w600), - ), - ), - )), + // InkWell( + // key: keyChangeChest, + // onTap: () { + // // Navigator.push( + // // context, + // // MaterialPageRoute(builder: (context) { + // // return const ChooseChest(); + // // }), + // // ); + // }, + // child: ScaledSizedBox( + // width: 400, + // height: 50, + // child: Center( + // child: Text( + // 'changeChest'.tr(), + // style: const scaledTextStyle( + // fontSize: 22, + // color: Colors.grey, // orangeC + // fontWeight: FontWeight.w600), + // ), + // ), + // )), ]), ]), ]), @@ -193,21 +197,22 @@ class UnlockingWallet extends StatelessWidget { // return Text( // 'Impossible de retrouver votre\nportefeuille par défaut.\nID: ${defaultWallet.id()}', // textAlign: TextAlign.center, - // style: const TextStyle( + // style: const scaledTextStyle( // color: Colors.redAccent, fontWeight: FontWeight.w500), // ); // } return Form( child: Padding( - padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30), + padding: EdgeInsets.symmetric( + vertical: scaleSize(3), horizontal: scaleSize(isTall ? 30 : 15)), child: PinCodeTextField( key: keyPinForm, textCapitalization: TextCapitalization.characters, focusNode: pinFocus, autoFocus: true, appContext: context, - pastedTextStyle: TextStyle( + pastedTextStyle: scaledTextStyle( color: Colors.green.shade600, fontWeight: FontWeight.bold, ), @@ -216,6 +221,7 @@ class UnlockingWallet extends StatelessWidget { obscuringCharacter: '*', animationType: AnimationType.slide, animationDuration: const Duration(milliseconds: 40), + useHapticFeedback: true, validator: (v) { if (v!.length < pinLenght) { return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]); @@ -228,13 +234,13 @@ class UnlockingWallet extends StatelessWidget { borderWidth: 4, shape: PinCodeFieldShape.box, borderRadius: BorderRadius.circular(5), - fieldHeight: 50 * ratio, - fieldWidth: 50, + fieldHeight: scaleSize(47), + fieldWidth: scaleSize(47), activeFillColor: Colors.black, ), - showCursor: kDebugMode ? false : true, + showCursor: !kDebugMode, cursorColor: Colors.black, - textStyle: const TextStyle(fontSize: 27, height: 1.6), + textStyle: scaledTextStyle(fontSize: 25, height: 1.6), backgroundColor: const Color(0xffF9F9F1), enableActiveFill: false, controller: enterPin, @@ -263,7 +269,7 @@ class UnlockingWallet extends StatelessWidget { myWalletProvider.isPinValid = true; myWalletProvider.isPinLoading = false; pinColor = Colors.green[400]; - myWalletProvider.resetPinCode(); + myWalletProvider.debounceResetPinCode(); Navigator.pop(context, pin.toUpperCase()); } }, diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 8633669..e3a3a98 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -4,11 +4,13 @@ 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/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/certifications.dart'; @@ -23,7 +25,6 @@ import 'package:gecko/widgets/idty_status.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:gecko/widgets/page_route_no_transition.dart'; import 'package:provider/provider.dart'; - import 'package:qr_flutter/qr_flutter.dart'; class WalletOptions extends StatelessWidget { @@ -49,8 +50,6 @@ class WalletOptions extends StatelessWidget { final isWalletNameIndexed = duniterIndexer.walletNameIndexer[walletOptions.address.text] != null; - log.d("Wallet options: $currentChest:${wallet.derivation}"); - return PopScope( onPopInvoked: (_) { walletOptions.isEditing = false; @@ -61,18 +60,18 @@ class WalletOptions extends StatelessWidget { backgroundColor: backgroundColor, resizeToAvoidBottomInset: false, appBar: AppBar( - toolbarHeight: 60 * ratio, + toolbarHeight: scaleSize(57), elevation: 0, - title: SizedBox( - height: 22, - child: Consumer( - builder: (context, walletProvider, _) { - return Text(isWalletNameIndexed + title: Consumer( + builder: (context, walletProvider, _) { + return Text( + isWalletNameIndexed ? duniterIndexer .walletNameIndexer[walletOptions.address.text]! - : wallet.name!); - }), - ), + : wallet.name!, + style: scaledTextStyle(fontSize: 20), + ); + }), actions: [ InkWell( onTap: () { @@ -85,10 +84,10 @@ class WalletOptions extends StatelessWidget { }), ); }, - child: QrImageWidget( + child: QrImageView( data: walletOptions.address.text, version: QrVersions.auto, - size: 80, + size: scaleSize(70), ), ), ], @@ -99,7 +98,7 @@ class WalletOptions extends StatelessWidget { builder: (ctx) => SafeArea( child: Column(children: [ Container( - height: isTall ? 5 : 0, + height: 5, color: yellowC, ), Consumer( @@ -116,14 +115,15 @@ class WalletOptions extends StatelessWidget { )), child: Row(children: [ const Spacer(flex: 1), + ScaledSizedBox(width: 15), avatar(walletProvider), const Spacer(flex: 1), Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Stack(children: [ - SizedBox( - width: 250, + ScaledSizedBox( + width: 230, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -131,7 +131,7 @@ class WalletOptions extends StatelessWidget { builder: (context, walletProvider, _) { return NameByAddress( wallet: wallet, - size: 29, + size: 24, color: Colors.black, fontWeight: wallet.identityStatus == IdtyStatus.validated @@ -142,7 +142,7 @@ class WalletOptions extends StatelessWidget { ], ), ), - const SizedBox(width: 10), + ScaledSizedBox(width: 10), if (duniterIndexer .walletNameIndexer[wallet.address] == null) @@ -161,16 +161,16 @@ class WalletOptions extends StatelessWidget { walletOptions.isEditing ? 'assets/walletOptions/android-checkmark.png' : 'assets/walletOptions/edit.png', - width: 25, - height: 25), + width: scaleSize(23), + height: scaleSize(23)), ), ), ), ]), - SizedBox(height: isTall ? 5 : 0), + ScaledSizedBox(height: 5), Balance( - address: walletProvider.address.text, size: 24), - const SizedBox(width: 30), + address: walletProvider.address.text, size: 20), + ScaledSizedBox(width: 30), InkWell( onTap: () => sub.certsCounterCache[ walletProvider.address.text] != @@ -200,10 +200,10 @@ class WalletOptions extends StatelessWidget { color: orangeC), Certifications( address: walletProvider.address.text, - size: 20) + size: 17) ]), ), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: 10), ]), const Spacer(flex: 2), ]), @@ -214,24 +214,7 @@ class WalletOptions extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - // InkWell( - // onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) { - // return QrCodeFullscreen( - // _walletOptions.address.text, - // ); - // }), - // ); - // }, - // child: QrImageWidget( - // data: _walletOptions.address.text, - // version: QrVersions.auto, - // size: isTall ? 150 : 80, - // ), - // ), - SizedBox(height: 30 * ratio), + ScaledSizedBox(height: 25), Consumer( builder: (context, walletProvider, _) { final defaultWallet = @@ -242,24 +225,22 @@ class WalletOptions extends StatelessWidget { return Column(children: [ confirmIdentityButton(walletProvider), pubkeyWidget(walletProvider, ctx), - SizedBox(height: 10 * ratio), + ScaledSizedBox(height: 11), activityWidget( context, historyProvider, walletProvider), - SizedBox(height: 12 * ratio), + ScaledSizedBox(height: 11), setDefaultWalletWidget( context, walletProvider, myWalletProvider, walletOptions, currentChest), - SizedBox(height: 17 * ratio), + ScaledSizedBox(height: 11), Column(children: [ if (!walletProvider.isDefaultWallet && !wallet.isMembre()) deleteWallet( - context, walletProvider, currentChest) - else - const SizedBox(), + context, walletProvider, currentChest), if (wallet.isMembre()) const ManageMembershipButton() ]) @@ -278,53 +259,58 @@ class WalletOptions extends StatelessWidget { } Widget avatar(WalletOptionsProvider walletProvider) { - return Stack( - children: [ - InkWell( - onTap: () async { - final newPath = await (walletProvider.changeAvatar()); - if (newPath != '') { - wallet.imageCustomPath = newPath; - walletBox.put(wallet.key, wallet); - } - walletProvider.reload(); - }, - child: wallet.imageCustomPath == null || wallet.imageCustomPath == '' - ? Image.asset( - 'assets/avatars/${wallet.imageDefaultPath}', - width: 110, - ) - : Container( - width: 150, - height: 150, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.transparent, - image: DecorationImage( - fit: BoxFit.cover, - image: FileImage( - File(wallet.imageCustomPath!), - ), - ), - ), - ), - ), - Positioned( - right: 0, - top: 0, - child: InkWell( + return Consumer(builder: (context, datapod, _) { + return Stack( + children: [ + InkWell( onTap: () async { - wallet.imageCustomPath = await (walletProvider.changeAvatar()); + final newPath = await (walletProvider.changeAvatar()); + if (newPath != '') { + wallet.imageCustomPath = newPath; + walletBox.put(wallet.key, wallet); + // Uncomment to enable Cs+ avatar storage + // CesiumPlusProvider().setAvatar(wallet.address, newPath); + } walletProvider.reload(); }, - child: Image.asset( - 'assets/walletOptions/camera.png', - height: 40, + child: + wallet.imageCustomPath == null || wallet.imageCustomPath == '' + ? Image.asset( + 'assets/avatars/${wallet.imageDefaultPath}', + width: scaleSize(122), + ) + : Container( + width: scaleSize(122), + height: scaleSize(122), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.transparent, + image: DecorationImage( + fit: BoxFit.cover, + image: FileImage( + File(wallet.imageCustomPath!), + ), + ), + ), + ), + ), + Positioned( + right: 0, + top: 0, + child: InkWell( + onTap: () async { + wallet.imageCustomPath = await (walletProvider.changeAvatar()); + walletProvider.reload(); + }, + child: Image.asset( + 'assets/walletOptions/camera.png', + height: scaleSize(38), + ), ), ), - ), - ], - ); + ], + ); + }); } Widget confirmIdentityButton(WalletOptionsProvider walletProvider) { @@ -336,44 +322,39 @@ class WalletOptions extends StatelessWidget { (BuildContext context, AsyncSnapshot> snapshot) { if (snapshot.data!.first == IdtyStatus.created) { return Column(children: [ - SizedBox( - width: 320, - height: 60, + ScaledSizedBox( + width: 310, + height: 55, child: ElevatedButton( key: keyConfirmIdentity, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), - onPressed: () async { + onPressed: () { walletProvider.confirmIdentityPopup(context); - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) { - // return const SearchResultScreen(); - // }), - // ); }, child: Text( 'confirmMyIdentity'.tr(), - style: const TextStyle( + style: scaledTextStyle( fontSize: 21, fontWeight: FontWeight.w600), ), ), ), - const SizedBox(height: 7), + ScaledSizedBox(height: 7), Text( "someoneCreatedYourIdentity".tr(args: [currencyName]), - style: TextStyle( + style: scaledTextStyle( fontSize: 16, color: Colors.grey[600], fontStyle: FontStyle.italic, ), ), - const SizedBox(height: 40), + ScaledSizedBox(height: 40), ]); } else { - return const SizedBox(); + return ScaledSizedBox(); } }); }); @@ -387,24 +368,24 @@ class WalletOptions extends StatelessWidget { Clipboard.setData(ClipboardData(text: walletProvider.address.text)); snackCopyKey(ctx); }, - child: SizedBox( + child: ScaledSizedBox( height: 50, child: Row(children: [ - const SizedBox(width: 30), + ScaledSizedBox(width: 26), Image.asset( 'assets/walletOptions/key.png', - height: 45, + height: scaleSize(42), ), - const SizedBox(width: 20), + ScaledSizedBox(width: 19), Text(shortPubkey, - style: const TextStyle( - fontSize: 22, + style: scaledTextStyle( + fontSize: 19, fontWeight: FontWeight.w800, fontFamily: 'Monospace', color: Colors.black)), - const SizedBox(width: 15), - SizedBox( - height: 40, + const Spacer(), + ScaledSizedBox( + height: 35, child: ElevatedButton( style: ElevatedButton.styleFrom( foregroundColor: Colors.black, @@ -412,7 +393,7 @@ class WalletOptions extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), backgroundColor: orangeC, - elevation: 1, // foreground + elevation: 1, ), onPressed: () { Clipboard.setData( @@ -422,16 +403,12 @@ class WalletOptions extends StatelessWidget { child: Row(children: [ Image.asset( 'assets/walletOptions/copy-white.png', - height: 25, + height: scaleSize(23), ), - const SizedBox(width: 7), - Text( - 'copy'.tr(), - style: TextStyle(fontSize: 15, color: Colors.grey[50]), - ) ]), ), ), + const Spacer(), ]), ), ); @@ -444,36 +421,23 @@ class WalletOptions extends StatelessWidget { return InkWell( key: keyOpenActivity, onTap: () { - // _historyProvider.nPage = 1; Navigator.push( context, PageNoTransit(builder: (context) { - return ActivityScreen( - address: walletProvider.address.text, - avatar: wallet.imageCustomPath == null - ? Image.asset( - 'assets/avatars/${wallet.imageDefaultPath}', - width: 110, - ) - : Image.asset( - wallet.imageCustomPath!, - width: 110, - )); + return ActivityScreen(address: walletProvider.address.text); }), ); }, - child: SizedBox( + child: ScaledSizedBox( height: 50, child: Row(children: [ - const SizedBox(width: 30), + ScaledSizedBox(width: 26), Image.asset( 'assets/walletOptions/clock.png', - height: 45, + height: scaleSize(42), ), - const SizedBox(width: 22), - Text("displayActivity".tr(), - style: - const TextStyle(fontSize: 20, fontWeight: FontWeight.w500)), + ScaledSizedBox(width: 20), + Text("displayActivity".tr(), style: scaledTextStyle(fontSize: 18)), ]), ), ); @@ -495,28 +459,34 @@ class WalletOptions extends StatelessWidget { await setDefaultWallet(context, currentChest); } : null, - child: SizedBox( - height: 50, + child: ScaledSizedBox( + height: 60, child: Row(children: [ - const SizedBox(width: 31), - CircleAvatar( - backgroundColor: - Colors.grey[walletProvider.isDefaultWallet ? 300 : 500], - child: Image.asset( - 'assets/walletOptions/android-checkmark.png', - height: 25, + ScaledSizedBox(width: isTall ? 28 : 23), + ScaledSizedBox( + height: 42, + child: CircleAvatar( + backgroundColor: + Colors.grey[walletProvider.isDefaultWallet ? 300 : 500], + child: Image.asset( + 'assets/walletOptions/android-checkmark.png', + height: scaleSize(23), + ), ), ), - const SizedBox(width: 22), - Text( - walletProvider.isDefaultWallet - ? 'thisWalletIsDefault'.tr() - : 'defineWalletAsDefault'.tr(), - style: TextStyle( - fontSize: 20, - color: walletProvider.isDefaultWallet - ? Colors.grey[500] - : Colors.black)), + ScaledSizedBox(width: isTall ? 21 : 18), + ScaledSizedBox( + width: 250, + child: Text( + walletProvider.isDefaultWallet + ? 'thisWalletIsDefault'.tr() + : 'defineWalletAsDefault'.tr(), + style: scaledTextStyle( + fontSize: 18, + color: walletProvider.isDefaultWallet + ? Colors.grey[500] + : Colors.black)), + ), ]), ), ); @@ -530,8 +500,6 @@ class WalletOptions extends StatelessWidget { final walletOptions = Provider.of(context, listen: false); - // WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!; - // defaultWallet = wallet; await sub.setCurrentWallet(wallet); await myWalletProvider.readAllWallets(currentChest); myWalletProvider.reload(); @@ -547,8 +515,6 @@ class WalletOptions extends StatelessWidget { final defaultWallet = myWalletProvider.getDefaultWallet(); final bool isDefaultWallet = walletOptions.address.text == defaultWallet.address; - // return Consumer( - // builder: (context, _myWalletProvider, _) { return FutureBuilder( future: sub.hasAccountConsumers(wallet.address), builder: (BuildContext context, AsyncSnapshot hasConsumers) { @@ -560,7 +526,8 @@ class WalletOptions extends StatelessWidget { walletOptions.balanceCache[walletOptions.address.text] ?? -1; final bool canDelete = !isDefaultWallet && !hasConsumers.data! && - (balance > 2 || balance == 0); + (balance > 2 || balance == 0) && + !wallet.hasIdentity(); return InkWell( key: keyDeleteWallet, onTap: canDelete @@ -575,17 +542,17 @@ class WalletOptions extends StatelessWidget { : null, child: canDelete ? Row(children: [ - const SizedBox(width: 30), + ScaledSizedBox(width: 27), Image.asset( 'assets/walletOptions/trash.png', - height: 45, + height: scaleSize(42), ), - const SizedBox(width: 19), + ScaledSizedBox(width: 19), Text('deleteThisWallet'.tr(), - style: const TextStyle( - fontSize: 20, color: Color(0xffD80000))), + style: scaledTextStyle( + fontSize: 18, color: const Color(0xffD80000))), ]) - : const SizedBox(width: 30), + : ScaledSizedBox(width: 30), ); }); } diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 5f7aa73..d5b3bd5 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; @@ -44,15 +45,21 @@ class _WalletsHomeState extends State { backgroundColor: backgroundColor, appBar: AppBar( elevation: 1, - toolbarHeight: 60 * ratio, + toolbarHeight: scaleSize(57), title: Row( children: [ Image.asset( 'assets/chests/${currentChest.imageName}', height: 32, ), - const SizedBox(width: 17), - Text(currentChest.name!, style: TextStyle(color: Colors.grey[850])), + ScaledSizedBox(width: 17), + Text( + currentChest.name!, + style: scaledTextStyle( + color: Colors.grey[850], + fontSize: 17, + fontWeight: FontWeight.w500), + ), ], ), backgroundColor: const Color(0xffFFD58D), @@ -73,11 +80,11 @@ class _WalletsHomeState extends State { builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done || snapshot.hasError) { - return const Center( - child: SizedBox( + return Center( + child: ScaledSizedBox( height: 50, width: 50, - child: CircularProgressIndicator( + child: const CircularProgressIndicator( color: orangeC, strokeWidth: 3, ), @@ -96,19 +103,19 @@ class _WalletsHomeState extends State { Widget myWalletsTiles(BuildContext context, int currentChestNumber) { final myWalletProvider = Provider.of(context); - final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); + final bool isWalletsExists = myWalletProvider.isWalletsExists(); if (!isWalletsExists) { return const Text(''); } if (myWalletProvider.listWallets.isEmpty) { - return const Expanded( + return Expanded( child: Column(children: [ Center( child: Text( 'Veuillez générer votre premier portefeuille', - style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500), + style: scaledTextStyle(fontSize: 17, fontWeight: FontWeight.w500), )), ])); } @@ -131,9 +138,9 @@ class _WalletsHomeState extends State { final screenWidth = MediaQuery.of(context).size.width; int nTule; - if (screenWidth >= 900) { + if (screenWidth >= 700) { nTule = 4; - } else if (screenWidth >= 650) { + } else if (screenWidth >= 450) { nTule = 3; } else { nTule = 2; @@ -148,13 +155,13 @@ class _WalletsHomeState extends State { TargetContent( child: Column( children: [ - Image.asset('assets/drag-and-drop.png', height: 140), - const SizedBox(height: 15), + Image.asset('assets/drag-and-drop.png', height: scaleSize(115)), + ScaledSizedBox(height: 15), Text( 'explainDraggableWallet'.tr(), textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 22, fontWeight: FontWeight.w500), + style: scaledTextStyle( + fontSize: 20, fontWeight: FontWeight.w500), ), ], )) @@ -178,35 +185,38 @@ class _WalletsHomeState extends State { configBox.put('showDraggableTutorial', false); } - return CustomScrollView(slivers: [ - const SliverToBoxAdapter(child: SizedBox(height: 20)), - if (idtyWallet.address != '') - SliverToBoxAdapter( - child: DragTuleAction( - wallet: idtyWallet, - child: WalletTileMembre(repository: idtyWallet), + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: CustomScrollView(slivers: [ + SliverToBoxAdapter(child: ScaledSizedBox(height: 12)), + if (idtyWallet.address != '') + SliverToBoxAdapter( + child: DragTuleAction( + wallet: idtyWallet, + child: WalletTileMembre(repository: idtyWallet), + ), ), - ), - SliverGrid.count( - key: keyListWallets, - crossAxisCount: nTule, - childAspectRatio: 1, - crossAxisSpacing: 0, - mainAxisSpacing: 0, - children: [ - for (WalletData repository in listWalletsWithoutIdty) - DragTuleAction( - wallet: repository, - child: WalletTile(repository: repository), - ), - Consumer(builder: (context, sub, _) { - return sub.nodeConnected && - myWalletProvider.listWallets.length < maxWalletsInSafe - ? const AddNewDerivationButton() - : const Text(''); - }), - ]), - const SliverToBoxAdapter(child: ChestOptionsButtons()), - ]); + SliverGrid.count( + key: keyListWallets, + crossAxisCount: nTule, + childAspectRatio: 1, + crossAxisSpacing: 0, + mainAxisSpacing: 0, + children: [ + for (WalletData repository in listWalletsWithoutIdty) + DragTuleAction( + wallet: repository, + child: WalletTile(repository: repository), + ), + Consumer(builder: (context, sub, _) { + return sub.nodeConnected && + myWalletProvider.listWallets.length < maxWalletsInSafe + ? const AddNewDerivationButton() + : const Text(''); + }), + ]), + const SliverToBoxAdapter(child: ChestOptionsButtons()), + ]), + ); } } diff --git a/lib/screens/my_contacts.dart b/lib/screens/my_contacts.dart index 75872bb..0288524 100644 --- a/lib/screens/my_contacts.dart +++ b/lib/screens/my_contacts.dart @@ -1,10 +1,10 @@ import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:gecko/widgets/contacts_list.dart'; import 'package:provider/provider.dart'; @@ -14,7 +14,6 @@ class ContactsScreen extends StatelessWidget { @override Widget build(BuildContext context) { Provider.of(context, listen: true); - double avatarSize = 55; final myContacts = contactsBox.toMap().values.toList(); // Order contacts by username @@ -25,19 +24,12 @@ class ContactsScreen extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - elevation: 1, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])), - ), - ), + appBar: GeckoAppBar( + 'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])), bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Stack(children: [ - ContactsList(myContacts: myContacts, avatarSize: avatarSize), + ContactsList(myContacts: myContacts), const OfflineInfo(), ]), ), diff --git a/lib/screens/onBoarding/1.dart b/lib/screens/onBoarding/1.dart index 795db64..a65b4e9 100644 --- a/lib/screens/onBoarding/1.dart +++ b/lib/screens/onBoarding/1.dart @@ -1,11 +1,11 @@ // ignore_for_file: file_names import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/2.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepOne extends StatelessWidget { const OnboardingStepOne({Key? key}) : super(key: key); @@ -14,17 +14,7 @@ class OnboardingStepOne extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'newWallet'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('newWallet'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index 29a595c..75724c7 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; @@ -16,6 +17,8 @@ import 'package:gecko/widgets/commons/build_text.dart'; import 'package:gecko/screens/onBoarding/11_congratulations.dart'; import 'package:gecko/widgets/commons/fader_transition.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; +import 'package:gecko/widgets/scan_derivations_info.dart'; import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:provider/provider.dart'; @@ -27,7 +30,7 @@ class OnboardingStepTen extends StatelessWidget { final formKey = GlobalKey(); Color? pinColor = const Color(0xFFA4B600); bool hasError = false; - TextEditingController enterPin = TextEditingController(); + final enterPin = TextEditingController(); FocusNode pinFocus = FocusNode(debugLabel: 'pinFocusNode'); @override @@ -47,61 +50,30 @@ class OnboardingStepTen extends StatelessWidget { }, child: Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'myPassword'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('myPassword'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), const BuildProgressBar(pagePosition: 9), - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), BuildText(text: "geckoWillCheckPassword".tr()), - SizedBox(height: isTall ? 60 : 10), - Visibility( - visible: generateWalletProvider.scanedValidWalletNumber != -1, - child: Padding( - padding: const EdgeInsets.only(bottom: 15), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text("derivationsScanProgress".tr(args: [ - '${generateWalletProvider.scanedWalletNumber}', - '${generateWalletProvider.numberScan + 1}' - ])), - const SizedBox(width: 10), - const SizedBox( - height: 22, - width: 22, - child: CircularProgressIndicator( - color: orangeC, - strokeWidth: 3, - ), - ), - ], - ), - ), - ), + ScaledSizedBox(height: isTall ? 25 : 0), + const ScanDerivationsInfo(), Consumer(builder: (context, mw, _) { return Visibility( visible: !myWalletProvider.isPinValid && !myWalletProvider.isPinLoading, child: Text( "thisIsNotAGoodCode".tr(), - style: const TextStyle( - color: Colors.red, fontWeight: FontWeight.w500), + style: scaledTextStyle( + fontSize: 16, + color: Colors.red, + fontWeight: FontWeight.w500), ), ); }), - SizedBox(height: isTall ? 20 : 10), + ScaledSizedBox(height: isTall ? 20 : 0), Consumer(builder: (context, sub, _) { return sub.nodeConnected ? pinForm(context, walletOptions, pinLenght, 1, 2) @@ -110,7 +82,7 @@ class OnboardingStepTen extends StatelessWidget { children: [ Text( "youHaveToBeConnectedToValidateChest".tr(), - style: const TextStyle( + style: scaledTextStyle( fontSize: 20, color: Colors.redAccent, fontWeight: FontWeight.w500, @@ -128,25 +100,25 @@ class OnboardingStepTen extends StatelessWidget { walletOptions.changePinCacheChoice(); }, child: Row(children: [ - const SizedBox(height: 30), + ScaledSizedBox(height: isTall ? 30 : 0), const Spacer(), Icon( configBox.get('isCacheChecked') ?? false ? Icons.check_box : Icons.check_box_outline_blank, color: orangeC, + size: scaleSize(22), ), - const SizedBox(width: 8), + ScaledSizedBox(width: 8), Text( 'rememberPassword'.tr(), - style: TextStyle( - fontSize: 16, color: Colors.grey[700]), + style: scaledTextStyle( + fontSize: 15, color: Colors.grey[700]), ), const Spacer() ])) : const Text(''); }), - const SizedBox(height: 10), ]), const OfflineInfo(), ]), @@ -181,6 +153,7 @@ class OnboardingStepTen extends StatelessWidget { length: pinLenght, obscureText: true, obscuringCharacter: '*', + useHapticFeedback: true, animationType: AnimationType.slide, animationDuration: const Duration(milliseconds: 40), validator: (v) { @@ -195,13 +168,13 @@ class OnboardingStepTen extends StatelessWidget { borderWidth: 4, shape: PinCodeFieldShape.box, borderRadius: BorderRadius.circular(5), - fieldHeight: 50 * ratio, - fieldWidth: 50, + fieldHeight: scaleSize(47), + fieldWidth: scaleSize(47), activeFillColor: Colors.black, ), - showCursor: kDebugMode ? false : true, + showCursor: !kDebugMode, cursorColor: Colors.black, - textStyle: const TextStyle(fontSize: 27, height: 1.6), + textStyle: const TextStyle(fontSize: 25, height: 1.6), backgroundColor: const Color(0xffF9F9F1), enableActiveFill: false, controller: enterPin, @@ -216,7 +189,6 @@ class OnboardingStepTen extends StatelessWidget { onCompleted: (pin) async { myWalletProvider.pinCode = pin.toUpperCase(); myWalletProvider.pinLenght = pinLenght; - log.d('$pin || ${generateWalletProvider.pin.text}'); if (pin.toUpperCase() == generateWalletProvider.pin.text) { pinColor = Colors.green[500]; myWalletProvider.isPinLoading = false; @@ -247,8 +219,7 @@ class OnboardingStepTen extends StatelessWidget { myWalletProvider.reload(); generateWalletProvider.generatedMnemonic = ''; - myWalletProvider.resetPinCode(); - // sleep(const Duration(milliseconds: 500)); + myWalletProvider.debounceResetPinCode(); Navigator.push( context, FaderTransition( @@ -260,7 +231,6 @@ class OnboardingStepTen extends StatelessWidget { myWalletProvider.isPinValid = false; pinColor = Colors.red[600]; enterPin.text = ''; - // myWalletProvider.reload(); pinFocus.requestFocus(); } }, diff --git a/lib/screens/onBoarding/11_congratulations.dart b/lib/screens/onBoarding/11_congratulations.dart index 9480295..293d308 100644 --- a/lib/screens/onBoarding/11_congratulations.dart +++ b/lib/screens/onBoarding/11_congratulations.dart @@ -5,8 +5,10 @@ import 'package:confetti/confetti.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/widgets/commons/build_text.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepEleven extends StatelessWidget { const OnboardingStepEleven({Key? key}) : super(key: key); @@ -20,35 +22,24 @@ class OnboardingStepEleven extends StatelessWidget { canPop: false, child: Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - leading: const Icon(Icons.check), - title: SizedBox( - height: 22, - child: Text( - 'allGood'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('allGood'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - const SizedBox(height: 40), + ScaledSizedBox(height: isTall ? 25 : 5), BuildText( text: "yourChestAndWalletWereCreatedSuccessfully".tr()), - SizedBox(height: isTall ? 20 : 10), + ScaledSizedBox(height: isTall ? 15 : 5), Image.asset( 'assets/onBoarding/gecko-clin.gif', - height: isTall ? 400 : 300, + height: scaleSize(isTall ? 330 : 280), ), Expanded( child: Align( alignment: Alignment.bottomCenter, child: finishButton(context)), ), - const SizedBox(height: 40), + ScaledSizedBox(height: isTall ? 40 : 5), ]), Align( alignment: Alignment.topLeft, @@ -83,9 +74,9 @@ class OnboardingStepEleven extends StatelessWidget { } Widget finishButton(BuildContext context) { - return SizedBox( - width: 380 * ratio, - height: 60 * ratio, + return ScaledSizedBox( + width: 340, + height: 55, child: ElevatedButton( key: keyGoWalletsHome, style: ElevatedButton.styleFrom( @@ -99,7 +90,8 @@ Widget finishButton(BuildContext context) { }, child: Text( "accessMyChest".tr(), - style: TextStyle(fontSize: 22 * ratio, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 21, fontWeight: FontWeight.w600, color: Colors.white), ), ), ); diff --git a/lib/screens/onBoarding/2.dart b/lib/screens/onBoarding/2.dart index 67a9896..a068f36 100644 --- a/lib/screens/onBoarding/2.dart +++ b/lib/screens/onBoarding/2.dart @@ -1,12 +1,12 @@ // ignore_for_file: file_names import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/3.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepTwo extends StatelessWidget { const OnboardingStepTwo({Key? key}) : super(key: key); @@ -15,17 +15,7 @@ class OnboardingStepTwo extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'yourMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('yourMnemonic'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( diff --git a/lib/screens/onBoarding/3.dart b/lib/screens/onBoarding/3.dart index f92d3cc..ecb521b 100644 --- a/lib/screens/onBoarding/3.dart +++ b/lib/screens/onBoarding/3.dart @@ -1,12 +1,12 @@ // ignore_for_file: file_names import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/4.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepThree extends StatelessWidget { const OnboardingStepThree({Key? key}) : super(key: key); @@ -15,25 +15,17 @@ class OnboardingStepThree extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'yourMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('yourMnemonic'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( - text: 'warningForgotPassword'.tr(), - assetName: 'forgot_password.png'.tr(), - buttonText: '>', - nextScreen: const OnboardingStepFor(), - pagePosition: 2), + text: 'warningForgotPassword'.tr(), + assetName: 'forgot_password.png'.tr(), + buttonText: '>', + nextScreen: const OnboardingStepFor(), + pagePosition: 2, + boxHeight: 316, + ), const OfflineInfo(), ]), ), diff --git a/lib/screens/onBoarding/4.dart b/lib/screens/onBoarding/4.dart index 339ee7f..9820c8e 100644 --- a/lib/screens/onBoarding/4.dart +++ b/lib/screens/onBoarding/4.dart @@ -1,12 +1,12 @@ // ignore_for_file: file_names import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/5.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepFor extends StatelessWidget { const OnboardingStepFor({Key? key}) : super(key: key); @@ -15,17 +15,7 @@ class OnboardingStepFor extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'yourMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('yourMnemonic'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( diff --git a/lib/screens/onBoarding/5.dart b/lib/screens/onBoarding/5.dart index a258f36..bb1bc04 100644 --- a/lib/screens/onBoarding/5.dart +++ b/lib/screens/onBoarding/5.dart @@ -1,10 +1,10 @@ // ignore_for_file: file_names 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/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -15,6 +15,7 @@ import 'package:gecko/widgets/commons/build_text.dart'; import 'package:gecko/screens/onBoarding/6.dart'; import 'package:gecko/widgets/commons/fader_transition.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; AsyncSnapshot? mnemoList; @@ -39,30 +40,53 @@ class _ChooseChestState extends State { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'yourMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('yourMnemonic'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), const BuildProgressBar(pagePosition: 4), - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), BuildText(text: 'geckoGeneratedYourMnemonicKeepItSecret'.tr()), - SizedBox(height: 35 * ratio), + ScaledSizedBox(height: isTall ? 15 : 5), sentanceArray(context), - SizedBox(height: 17 * ratio), + ScaledSizedBox(height: isTall ? 17 : 5), Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.center, children: [ + ScaledSizedBox( + height: 40, + width: 132, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Colors.black, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + backgroundColor: orangeC, + elevation: 1, + ), + onPressed: () { + Clipboard.setData(ClipboardData( + text: generateWalletProvider.generatedMnemonic!)); + snackCopySeed(context); + }, + child: Row(children: [ + Image.asset( + 'assets/walletOptions/copy-white.png', + height: scaleSize(23), + ), + const Spacer(), + Text( + 'copy'.tr(), + style: scaledTextStyle( + fontSize: 15, color: Colors.grey[50]), + ), + const Spacer(), + ]), + ), + ), + ScaledSizedBox(width: 70), GestureDetector( onTap: () { Navigator.push( @@ -75,71 +99,39 @@ class _ChooseChestState extends State { }, child: Image.asset( 'assets/printer.png', - height: 42 * ratio, - ), - ), - SizedBox( - height: 40, - width: 120, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - backgroundColor: orangeC, - elevation: 1, // foreground - ), - onPressed: () { - Clipboard.setData(ClipboardData( - text: generateWalletProvider.generatedMnemonic!)); - snackCopySeed(context); - }, - child: Row(children: [ - Image.asset( - 'assets/walletOptions/copy-white.png', - height: 25, - ), - const SizedBox(width: 7), - Text( - 'copy'.tr(), - style: TextStyle(fontSize: 15, color: Colors.grey[50]), - ) - ]), + height: scaleSize(42), ), ), ], ), - const SizedBox(height: 40), + ScaledSizedBox(height: isTall ? 17 : 5), Expanded( child: Align( alignment: Alignment.bottomCenter, - child: SizedBox( - width: 380 * ratio, - height: 60 * ratio, + child: ScaledSizedBox( + width: 350, + height: 55, child: ElevatedButton( key: keyGenerateMnemonic, style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 4, - backgroundColor: const Color(0xffFFD58D), // foreground + foregroundColor: Colors.black, + elevation: 4, + backgroundColor: const Color(0xffFFD58D), ), onPressed: () { - // _generateWalletProvider.reloadBuild(); setState(() {}); }, child: Text("chooseAnotherMnemonic".tr(), textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22 * ratio, - fontWeight: FontWeight.w600))), + style: scaledTextStyle( + fontSize: 22, fontWeight: FontWeight.w600))), ), ), ), - SizedBox(height: 22 * ratio), + ScaledSizedBox(height: isTall ? 20 : 10), nextButton( context, "iNotedMyMnemonic".tr(), false, widget.skipIntro), - const Spacer(), - // SizedBox(height: 35 * ratio), + isTall ? const Spacer() : const SizedBox(height: 5), ]), const OfflineInfo(), ]), @@ -152,68 +144,65 @@ Widget sentanceArray(BuildContext context) { final generateWalletProvider = Provider.of(context, listen: false); - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 3), - child: Container( - constraints: const BoxConstraints(maxWidth: 450), - decoration: BoxDecoration( - border: Border.all(color: Colors.black), - color: const Color(0xffeeeedd), - borderRadius: const BorderRadius.all( - Radius.circular(10), - )), - padding: const EdgeInsets.all(20), - child: FutureBuilder( - future: generateWalletProvider.generateWordList(context), - builder: (BuildContext context, AsyncSnapshot data) { - if (!data.hasData) { - return const Text(''); - } else { - mnemoList = data; - return Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row(children: [ - arrayCell(data.data![0]), - arrayCell(data.data![1]), - arrayCell(data.data![2]), - arrayCell(data.data![3]), - ]), - const SizedBox(height: 15), - Row(children: [ - arrayCell(data.data![4]), - arrayCell(data.data![5]), - arrayCell(data.data![6]), - arrayCell(data.data![7]), - ]), - const SizedBox(height: 15), - Row(children: [ - arrayCell(data.data![8]), - arrayCell(data.data![9]), - arrayCell(data.data![10]), - arrayCell(data.data![11]), - ]), - ]); - } - }), - ), + return Container( + constraints: BoxConstraints(maxWidth: scaleSize(isTall ? 355 : 340)), + decoration: BoxDecoration( + border: Border.all(color: Colors.black), + color: const Color(0xffeeeedd), + borderRadius: const BorderRadius.all( + Radius.circular(10), + )), + padding: EdgeInsets.all(scaleSize(11)), + child: FutureBuilder( + future: generateWalletProvider.generateWordList(context), + builder: (BuildContext context, AsyncSnapshot data) { + if (!data.hasData) { + return const Text(''); + } else { + mnemoList = data; + return Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row(children: [ + arrayCell(data.data![0]), + arrayCell(data.data![1]), + arrayCell(data.data![2]), + arrayCell(data.data![3]), + ]), + ScaledSizedBox(height: 12), + Row(children: [ + arrayCell(data.data![4]), + arrayCell(data.data![5]), + arrayCell(data.data![6]), + arrayCell(data.data![7]), + ]), + ScaledSizedBox(height: 12), + Row(children: [ + arrayCell(data.data![8]), + arrayCell(data.data![9]), + arrayCell(data.data![10]), + arrayCell(data.data![11]), + ]), + ]); + } + }), ); } Widget arrayCell(dataWord) { - return SizedBox( - width: 100, + return ScaledSizedBox( + width: scaleSize(isTall ? 78 : 91), child: Column(children: [ Text( dataWord.split(':')[0], - style: TextStyle(fontSize: 13 * ratio, color: const Color(0xff6b6b52)), + style: scaledTextStyle(fontSize: 12, color: const Color(0xff6b6b52)), ), Text( dataWord.split(':')[1], key: keyMnemonicWord(dataWord.split(':')[0]), - style: TextStyle(fontSize: 17 * ratio, color: Colors.black), + style: scaledTextStyle(fontSize: 16, color: Colors.black), ), ]), ); @@ -225,14 +214,15 @@ Widget nextButton( Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); - return SizedBox( - width: 380 * ratio, - height: 60 * ratio, + return ScaledSizedBox( + width: 350, + height: 55, child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () { generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt(); @@ -251,7 +241,8 @@ Widget nextButton( }, child: Text( text, - style: TextStyle(fontSize: 22 * ratio, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 22, fontWeight: FontWeight.w600, color: Colors.white), ), ), ); diff --git a/lib/screens/onBoarding/6.dart b/lib/screens/onBoarding/6.dart index 55dfa62..1061bde 100644 --- a/lib/screens/onBoarding/6.dart +++ b/lib/screens/onBoarding/6.dart @@ -2,9 +2,9 @@ // ignore_for_file: must_be_immutable import 'package:easy_localization/easy_localization.dart'; - import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart'; @@ -13,6 +13,7 @@ import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/widgets/commons/fader_transition.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class OnboardingStepSix extends StatelessWidget { @@ -22,8 +23,8 @@ class OnboardingStepSix extends StatelessWidget { final bool skipIntro; String? generatedMnemonic; - TextEditingController wordController = TextEditingController(); - final TextEditingController _mnemonicController = TextEditingController(); + final wordController = TextEditingController(); + final _mnemonicController = TextEditingController(); @override Widget build(BuildContext context) { @@ -40,47 +41,37 @@ class OnboardingStepSix extends StatelessWidget { child: Scaffold( backgroundColor: backgroundColor, resizeToAvoidBottomInset: false, - extendBodyBehindAppBar: true, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'yourMnemonic'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), + appBar: GeckoAppBar('yourMnemonic'.tr()), body: SafeArea( child: Stack(children: [ Align( alignment: Alignment.topCenter, child: Column(children: [ - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), const BuildProgressBar(pagePosition: 5), - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), BuildText( text: "didYouNoteMnemonicToBeSureTypeWord".tr(args: [ (generateWalletProvider.nbrWord + 1).toString() ]), - size: 20, isMd: true), - SizedBox(height: isTall ? 70 : 20), - Text('${generateWalletProvider.nbrWord + 1}', - key: keyAskedWord, - style: TextStyle( - fontSize: isTall ? 17 : 15, - color: orangeC, - fontWeight: FontWeight.w400)), - const SizedBox(height: 10), + ScaledSizedBox(height: isTall ? 40 : 5), + if (isTall) + Text('${generateWalletProvider.nbrWord + 1}', + key: keyAskedWord, + style: scaledTextStyle( + fontSize: 20, + color: orangeC, + fontWeight: FontWeight.w500)), + if (isTall) ScaledSizedBox(height: 5), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(7), border: Border.all( color: Colors.grey[600]!, - width: 3, + width: scaleSize(3), )), - width: 430, + width: scaleSize(340), child: TextFormField( key: keyInputWord, autofocus: true, @@ -94,8 +85,8 @@ class OnboardingStepSix extends StatelessWidget { maxLines: 1, textAlign: TextAlign.center, decoration: InputDecoration( - labelStyle: TextStyle( - fontSize: 22.0, + labelStyle: scaledTextStyle( + fontSize: 19, color: Colors.grey[500], fontWeight: FontWeight.w500), labelText: generateWalletProvider.isAskedWordValid @@ -103,10 +94,10 @@ class OnboardingStepSix extends StatelessWidget { : "${generateWalletProvider.nbrWordAlpha} ${"nthMnemonicWord".tr()}", fillColor: const Color(0xffeeeedd), filled: true, - contentPadding: const EdgeInsets.all(12), + contentPadding: const EdgeInsets.all(10), ), - style: TextStyle( - fontSize: 40.0, + style: scaledTextStyle( + fontSize: 26, color: generateWalletProvider.askedWordColor, fontWeight: FontWeight.w500))), Visibility( @@ -133,7 +124,7 @@ class OnboardingStepSix extends StatelessWidget { // ), // ), // ), - SizedBox(height: 35 * ratio), + ScaledSizedBox(height: 40), ]), ), const OfflineInfo(), @@ -151,14 +142,15 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) { generateWalletProvider.isAskedWordValid = false; generateWalletProvider.askedWordColor = Colors.black; - return SizedBox( - width: 380 * ratio, - height: 60 * ratio, + return ScaledSizedBox( + width: 340, + height: 55, child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: () { Navigator.push( @@ -166,7 +158,8 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) { }, child: Text( text, - style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 22, fontWeight: FontWeight.w600, color: Colors.white), ), ), ); diff --git a/lib/screens/onBoarding/7.dart b/lib/screens/onBoarding/7.dart index ba427e4..7c3edf3 100644 --- a/lib/screens/onBoarding/7.dart +++ b/lib/screens/onBoarding/7.dart @@ -1,11 +1,12 @@ // ignore_for_file: file_names -import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/8.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepSeven extends StatelessWidget { const OnboardingStepSeven({Key? key, this.scanDerivation = false}) @@ -16,17 +17,7 @@ class OnboardingStepSeven extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'myPassword'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('myPassword'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( @@ -35,7 +26,7 @@ class OnboardingStepSeven extends StatelessWidget { buttonText: '>', nextScreen: OnboardingStepEight(scanDerivation: scanDerivation), pagePosition: 6, - boxHeight: 400), + boxHeight: 320), const OfflineInfo(), ]), ), diff --git a/lib/screens/onBoarding/8.dart b/lib/screens/onBoarding/8.dart index 7650cf5..74be139 100644 --- a/lib/screens/onBoarding/8.dart +++ b/lib/screens/onBoarding/8.dart @@ -1,11 +1,12 @@ // ignore_for_file: file_names -import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/widgets/commons/intro_info.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; class OnboardingStepEight extends StatelessWidget { const OnboardingStepEight({Key? key, this.scanDerivation = false}) @@ -16,17 +17,7 @@ class OnboardingStepEight extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'myPassword'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('myPassword'.tr()), body: SafeArea( child: Stack(children: [ InfoIntro( @@ -35,7 +26,8 @@ class OnboardingStepEight extends StatelessWidget { buttonText: '>', nextScreen: OnboardingStepNine(scanDerivation: scanDerivation), pagePosition: 7, - isMd: true), + isMd: true, + boxHeight: 320), const OfflineInfo(), ]), ), diff --git a/lib/screens/onBoarding/9.dart b/lib/screens/onBoarding/9.dart index 176ece3..0b3c9ad 100644 --- a/lib/screens/onBoarding/9.dart +++ b/lib/screens/onBoarding/9.dart @@ -1,8 +1,9 @@ // ignore_for_file: file_names -import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart'; @@ -10,6 +11,7 @@ import 'package:gecko/widgets/commons/build_text.dart'; import 'package:gecko/screens/onBoarding/10.dart'; import 'package:gecko/widgets/commons/next_button.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class OnboardingStepNine extends StatelessWidget { @@ -21,8 +23,6 @@ class OnboardingStepNine extends StatelessWidget { Widget build(BuildContext context) { final generateWalletProvider = Provider.of(context); - // final myWalletProvider = - // Provider.of(context); generateWalletProvider.pin.text = debugPin // kDebugMode && ? 'AAAAA' @@ -30,25 +30,15 @@ class OnboardingStepNine extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text( - 'myPassword'.tr(), - style: const TextStyle(fontWeight: FontWeight.w600), - ), - ), - ), - extendBodyBehindAppBar: true, + appBar: GeckoAppBar('myPassword'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), const BuildProgressBar(pagePosition: 8), - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), BuildText(text: "hereIsThePasswordKeepIt".tr()), - const SizedBox(height: 100), + ScaledSizedBox(height: isTall ? 60 : 10), Stack( alignment: Alignment.centerRight, children: [ @@ -60,9 +50,9 @@ class OnboardingStepNine extends StatelessWidget { maxLines: 1, textAlign: TextAlign.center, decoration: const InputDecoration(), - style: const TextStyle( + style: scaledTextStyle( letterSpacing: 5, - fontSize: 35.0, + fontSize: 33, color: Colors.black, fontWeight: FontWeight.bold)), IconButton( @@ -74,41 +64,40 @@ class OnboardingStepNine extends StatelessWidget { ), ], ), - const SizedBox(height: 30), + ScaledSizedBox(height: isTall ? 30 : 15), Text( 'Pendant la phase de test de Ğecko,\nles codes secrets\nsont systématiquement AAAAA.' .tr(), - style: TextStyle(color: Colors.grey[700], fontSize: 15), + style: scaledTextStyle(color: Colors.grey[700], fontSize: 14), textAlign: TextAlign.center), Expanded( child: Align( alignment: Alignment.bottomCenter, - child: SizedBox( - width: 380 * ratio, - height: 60 * ratio, + child: ScaledSizedBox( + width: 340, + height: 55, child: ElevatedButton( key: keyChangePin, style: ElevatedButton.styleFrom( foregroundColor: Colors.black, elevation: 4, - backgroundColor: - const Color(0xffFFD58D), // foreground + backgroundColor: const Color(0xffFFD58D), ), onPressed: () { generateWalletProvider.changePinCode( reload: true); }, child: Text("chooseAnotherPassword".tr(), - style: TextStyle( - fontSize: 22 * ratio, + style: scaledTextStyle( + fontSize: 22, fontWeight: FontWeight.w600))), ))), - SizedBox(height: 22 * ratio), + ScaledSizedBox(height: 20), NextButton( text: "iNotedMyPassword".tr(), nextScreen: OnboardingStepTen(scanDerivation: scanDerivation), isFast: false), - SizedBox(height: 35 * ratio), + ScaledSizedBox(height: 40), ]), const OfflineInfo(), ]), diff --git a/lib/screens/qrcode_fullscreen.dart b/lib/screens/qrcode_fullscreen.dart index 8726bcd..1d4cda0 100644 --- a/lib/screens/qrcode_fullscreen.dart +++ b/lib/screens/qrcode_fullscreen.dart @@ -2,52 +2,85 @@ import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:qr_flutter/qr_flutter.dart'; -// import 'package:gecko/models/home.dart'; -// import 'package:provider/provider.dart'; +import 'package:screen_brightness/screen_brightness.dart'; -class QrCodeFullscreen extends StatelessWidget { - TextEditingController tplController = TextEditingController(); +class QrCodeFullscreen extends StatefulWidget { + const QrCodeFullscreen(this.address, {this.color, Key? key}) + : super(key: key); - QrCodeFullscreen(this.address, {this.color, Key? key}) : super(key: key); final String address; final Color? color; + @override + State createState() => _QrCodeFullscreenState(); +} + +class _QrCodeFullscreenState extends State { + final tplController = TextEditingController(); + + Future setBrightness(double brightness) async { + try { + await ScreenBrightness().setScreenBrightness(brightness); + } catch (e) { + log.e(e.toString()); + throw 'Failed to set brightness'; + } + } + + Future resetBrightness() async { + try { + await ScreenBrightness().resetScreenBrightness(); + } catch (e) { + log.e(e.toString()); + throw 'Failed to reset brightness'; + } + } + + @override + void initState() { + super.initState(); + setBrightness(1); + } + @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - elevation: 0, - backgroundColor: color ?? Colors.black, - toolbarHeight: 60 * ratio, - leading: IconButton( - icon: const Icon(Icons.arrow_back, color: orangeC), - onPressed: () { - Navigator.pop(context); - }), - title: SizedBox( - height: 22, - child: Text( - 'QR Code de ${getShortPubkey(address)}', - style: const TextStyle(color: orangeC), - ), - )), - body: SafeArea( - child: SizedBox.expand( - child: Container( - color: color ?? backgroundColor, - child: Column( - children: [ - const Spacer(), - QrImageWidget( - data: address, - version: QrVersions.auto, - size: 350, - ), - const Spacer(flex: 2), - ], - )), + return PopScope( + onPopInvoked: (_) { + resetBrightness(); + }, + child: Scaffold( + appBar: AppBar( + elevation: 0, + backgroundColor: widget.color ?? Colors.black, + toolbarHeight: scaleSize(57), + leading: IconButton( + icon: const Icon(Icons.arrow_back, color: orangeC), + onPressed: () { + Navigator.pop(context); + }), + title: Text( + 'QR Code de ${getShortPubkey(widget.address)}', + style: scaledTextStyle(color: orangeC, fontSize: 20), + )), + body: SafeArea( + child: SizedBox.expand( + child: Container( + color: widget.color ?? backgroundColor, + child: Column( + children: [ + const Spacer(), + QrImageView( + data: widget.address, + version: QrVersions.auto, + size: scaleSize(320), + ), + const Spacer(flex: 2), + ], + )), + ), ), ), ); diff --git a/lib/screens/search.dart b/lib/screens/search.dart index 3b316fe..cc984c0 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -1,17 +1,18 @@ // ignore_for_file: use_build_context_synchronously import 'dart:async'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/search.dart'; -import 'package:gecko/widgets/commons/common_elements.dart'; +import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/search_result.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:provider/provider.dart'; class SearchScreen extends StatefulWidget { @@ -28,9 +29,11 @@ class _SearchScreenState extends State { final int debouneTime = 50; Future getClipBoard() async { + final searchProvider = Provider.of(context, listen: false); final clipboard = await Clipboard.getData('text/plain'); pastedAddress = clipboard?.text ?? ''; canPasteAddress = isAddress(pastedAddress); + searchProvider.reload(); } @override @@ -44,10 +47,7 @@ class _SearchScreenState extends State { @override Widget build(BuildContext context) { final searchProvider = Provider.of(context); - final screenHeight = MediaQuery.of(context).size.height; - final canValidate = searchProvider.searchController.text.length >= 2; - // final canPasteAddress = false; return PopScope( onPopInvoked: (_) { @@ -55,18 +55,11 @@ class _SearchScreenState extends State { }, child: Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - elevation: 1, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('search'.tr()), - ), - ), + appBar: GeckoAppBar('search'.tr()), body: SafeArea( child: Stack(children: [ Column(children: [ - SizedBox(height: isTall ? 200 : 100), + ScaledSizedBox(height: isTall ? 165 : 60), Padding( padding: const EdgeInsets.symmetric(horizontal: 17), child: TextField( @@ -102,7 +95,7 @@ class _SearchScreenState extends State { suffixIcon: searchProvider.searchController.text == '' ? null : Padding( - padding: const EdgeInsets.symmetric(horizontal: 17), + padding: const EdgeInsets.symmetric(horizontal: 10), child: IconButton( onPressed: (() async => { searchProvider.searchController.text = '', @@ -112,15 +105,16 @@ class _SearchScreenState extends State { icon: Icon( Icons.close, color: Colors.grey[600], - size: 30, + size: scaleSize(28), ), ), ), - prefixIcon: const Padding( - padding: EdgeInsets.symmetric(horizontal: 17), - child: Image( - image: AssetImage('assets/loupe-noire.png'), - height: 35), + prefixIcon: Padding( + padding: const EdgeInsets.symmetric(horizontal: 13), + child: Image.asset( + 'assets/loupe-noire.png', + height: scaleSize(10), + ), ), border: OutlineInputBorder( borderSide: @@ -131,24 +125,25 @@ class _SearchScreenState extends State { BorderSide(color: Colors.grey[500]!, width: 2.5), borderRadius: BorderRadius.circular(8), ), - contentPadding: const EdgeInsets.all(20), + contentPadding: const EdgeInsets.all(13), ), - style: const TextStyle( - fontSize: 20, + style: scaledTextStyle( + fontSize: 17, color: Colors.black, fontWeight: FontWeight.w400, ), ), ), - const Spacer(flex: 1), - SizedBox( - width: 320, - height: 90, + const Spacer(), + ScaledSizedBox( + width: 270, + height: 70, child: ElevatedButton( key: keyConfirmSearch, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: canValidate ? () { @@ -177,12 +172,14 @@ class _SearchScreenState extends State { ? 'pasteAddress'.tr() : 'search'.tr(), textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 21, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: Colors.white), ), ), ), - Spacer(flex: screenHeight <= 800 ? 1 : 2), + const Spacer(), ]), const OfflineInfo(), ]), diff --git a/lib/screens/search_result.dart b/lib/screens/search_result.dart index 7f1b617..e61fb1c 100644 --- a/lib/screens/search_result.dart +++ b/lib/screens/search_result.dart @@ -1,12 +1,13 @@ import 'package:easy_localization/easy_localization.dart'; - import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/search.dart'; import 'package:gecko/widgets/bottom_app_bar.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; +import 'package:gecko/widgets/commons/top_appbar.dart'; import 'package:gecko/widgets/search_result_list.dart'; import 'package:provider/provider.dart'; @@ -16,29 +17,15 @@ class SearchResultScreen extends StatelessWidget { @override Widget build(BuildContext context) { final searchProvider = Provider.of(context, listen: false); - WalletsProfilesProvider walletsProfilesClass = + final walletsProfilesClass = Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); - double avatarSize = 55; - // List myContacts = contactsBox.toMap().values.toList(); - // myContacts = myContacts - // .where((map) => - // (map.username ?? '').contains(searchProvider.searchController.text)) - // .toList(); - - // final searchProvider.resultLenght.toString(); + final avatarSize = scaleSize(37); return Scaffold( backgroundColor: backgroundColor, - appBar: AppBar( - elevation: 1, - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('researchResults'.tr()), - ), - ), + appBar: GeckoAppBar('researchResults'.tr()), bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Stack(children: [ @@ -47,38 +34,39 @@ class SearchResultScreen extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 30), + ScaledSizedBox(height: 20), Center( child: Column( children: [ Text( "resultsFor".tr(), - style: TextStyle(color: Colors.grey[600]), + style: scaledTextStyle( + color: Colors.grey[600], fontSize: 16), ), Text( '"${searchProvider.searchController.text}"', - style: const TextStyle( - fontStyle: FontStyle.italic, fontSize: 21), + style: scaledTextStyle( + fontStyle: FontStyle.italic, fontSize: 18), ) ], ), ), - // const SizedBox(height: 40), + // ScaledSizedBox(height: 40), // Text( // 'Dans mes contacts'.tr(args: [currencyName]), - // style: const TextStyle(fontSize: 20), + // style: scaledTextStyle(fontSize: 20), // ), // ContactsList( // myContacts: myContacts, // avatarSize: avatarSize, // walletsProfilesClass: walletsProfilesClass, // duniterIndexer: duniterIndexer), - const SizedBox(height: 40), + ScaledSizedBox(height: 22), Text( 'inBlockchainResult'.tr(args: [currencyName]), - style: const TextStyle(fontSize: 20), + style: scaledTextStyle(fontSize: 16), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 13), SearchResult( searchProvider: searchProvider, duniterIndexer: duniterIndexer, diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 45be251..0afd48f 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,6 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; - +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; @@ -8,6 +8,7 @@ import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/settings_provider.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/widgets/commons/loading.dart'; import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:provider/provider.dart'; @@ -18,89 +19,85 @@ class SettingsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - const double buttonHigh = 50; - const double buttonWidth = 240; - const double fontSize = 16; - return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( - toolbarHeight: 60 * ratio, - title: SizedBox( - height: 22, - child: Text('parameters'.tr()), + toolbarHeight: scaleSize(57), + title: Text( + 'parameters'.tr(), + style: scaledTextStyle(fontSize: 21), )), body: Column(children: [ - const SizedBox(height: 30), + ScaledSizedBox(height: 30), Text( 'networkSettings'.tr(), - style: TextStyle(color: Colors.grey[500], fontSize: 22), + style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), duniterEndpointSelection(context), - const SizedBox(height: 30), + ScaledSizedBox(height: 30), indexerEndpointSelection(context), - const SizedBox(height: 40), + ScaledSizedBox(height: 35), Text( 'displaySettings'.tr(), - style: TextStyle(color: Colors.grey[500], fontSize: 22), + style: scaledTextStyle(color: Colors.grey[500]!, fontSize: 20), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), chooseCurrencyUnit(context), - // SizedBox(height: isTall ? 80 : 120), const Spacer(), - SizedBox( - height: buttonHigh, - width: buttonWidth, - child: Center( - child: InkWell( - key: keyDeleteAllWallets, - onTap: () async { - log.i('Oublier tous mes coffres'); - await _myWallets.deleteAllWallet(context); - }, - child: Text( - 'forgetAllMyChests'.tr(), - style: const TextStyle( - fontSize: fontSize + 4, - color: Color(0xffD80000), - fontWeight: FontWeight.w600, + Center( + child: InkWell( + key: keyDeleteAllWallets, + onTap: () async { + log.w('Oublier tous mes coffres'); + await _myWallets.deleteAllWallet(context); + }, + child: ScaledSizedBox( + height: scaleSize(40), + width: 220, + child: Center( + child: Text( + 'forgetAllMyChests'.tr(), + style: scaledTextStyle( + fontSize: 18, + color: const Color(0xffD80000), + fontWeight: FontWeight.w600, + ), ), ), ), ), ), // const Spacer(), - SizedBox(height: isTall ? 90 : 60), + ScaledSizedBox(height: 70), ]), ); } Widget chooseCurrencyUnit(BuildContext context) { - HomeProvider homeProvider = - Provider.of(context, listen: false); + final homeProvider = Provider.of(context, listen: false); return InkWell( key: keyUdUnit, onTap: () async { await homeProvider.changeCurrencyUnit(context); }, - child: SizedBox( + child: ScaledSizedBox( height: 50, child: Row( children: [ - const SizedBox(width: 12), - Text('showUdAmounts'.tr()), + ScaledSizedBox(width: 12), + Text('showUdAmounts'.tr(), style: scaledTextStyle(fontSize: 16)), const Spacer(), Consumer(builder: (context, homeProvider, _) { final bool isUdUnit = configBox.get('isUdUnit') ?? false; return Icon( isUdUnit ? Icons.check_box : Icons.check_box_outline_blank, color: orangeC, - size: 32, + size: scaleSize(30), ); }), - const SizedBox(width: 30), + ScaledSizedBox(width: 30), ], ), ), @@ -133,7 +130,7 @@ class SettingsScreen extends StatelessWidget { selectedDuniterEndpoint = customEndpoint.endpoint; } - TextEditingController endpointController = TextEditingController( + final endpointController = TextEditingController( text: configBox.containsKey('customEndpoint') ? configBox.get('customEndpoint') : 'wss://'); @@ -141,30 +138,34 @@ class SettingsScreen extends StatelessWidget { return Column(children: [ Row(children: [ Consumer(builder: (context, sub, _) { - log.d(sub.sdk.api.connectedNode?.endpoint); return Expanded( child: Row(children: [ - const SizedBox(width: 10), - SizedBox( - width: 80, + ScaledSizedBox(width: 2), + ScaledSizedBox( + width: 55, child: Text( - 'currencyNode'.tr(args: ['']), + 'currencyNode'.tr(), + style: scaledTextStyle(fontSize: 16), ), ), const Spacer(), - Icon(sub.nodeConnected && !sub.isLoadingEndpoint - ? Icons.check - : Icons.close), + ScaledSizedBox( + width: 30, + child: Icon(sub.nodeConnected && !sub.isLoadingEndpoint + ? Icons.check + : Icons.close), + ), if (sub.nodeConnected && !sub.isLoadingEndpoint) const Icon(Icons.add_card_sharp, size: 0.01), const Spacer(), - SizedBox( - width: 280, + ScaledSizedBox( + height: 52, + width: 230, child: Consumer(builder: (context, set, _) { return DropdownButtonHideUnderline( key: keySelectDuniterNodeDropDown, child: DropdownButton( - // alignment: AlignmentDirectional.topStart, + style: scaledTextStyle(fontSize: 16, color: Colors.black), value: selectedDuniterEndpoint, icon: const Icon(Icons.keyboard_arrow_down), items: duniterBootstrapNodes @@ -176,7 +177,6 @@ class SettingsScreen extends StatelessWidget { ); }).toList(), onChanged: (String? newEndpoint) { - log.d(newEndpoint!); selectedDuniterEndpoint = newEndpoint; set.reload(); }, @@ -184,9 +184,9 @@ class SettingsScreen extends StatelessWidget { ); }), ), - const Spacer(flex: 5), + const Spacer(flex: 3), sub.isLoadingEndpoint - ? const CircularProgressIndicator(color: orangeC) + ? Loading(size: scaleSize(32), stroke: 2.5) : Consumer(builder: (context, set, _) { return IconButton( key: keyConnectToEndpoint, @@ -196,7 +196,7 @@ class SettingsScreen extends StatelessWidget { sub.getConnectedEndpoint() ? orangeC : Colors.grey[500], - size: 40, + size: scaleSize(35), ), onPressed: selectedDuniterEndpoint != sub.getConnectedEndpoint() @@ -214,7 +214,7 @@ class SettingsScreen extends StatelessWidget { configBox.put( 'customEndpoint', finalEndpoint); } - await sub.connectNode(context); + await sub.connectNode(); } : null); }), @@ -226,13 +226,14 @@ class SettingsScreen extends StatelessWidget { Consumer(builder: (context, set, _) { return Visibility( visible: selectedDuniterEndpoint == 'Personnalisé', - child: SizedBox( + child: ScaledSizedBox( width: 200, height: 50, child: TextField( key: keyCustomDuniterEndpoint, controller: endpointController, autocorrect: false, + style: scaledTextStyle(fontSize: 16), ), ), ); @@ -244,17 +245,15 @@ class SettingsScreen extends StatelessWidget { Consumer(builder: (context, set, _) { return Visibility( visible: selectedDuniterEndpoint == 'Auto', - child: SizedBox( + child: ScaledSizedBox( width: 250, height: sub.getConnectedEndpoint() == null ? 60 : 20, child: Text( - sub.getConnectedEndpoint() ?? - "anAutoNodeChoosed" - .tr(), //"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.", - style: TextStyle( + sub.getConnectedEndpoint() ?? "anAutoNodeChoosed".tr(), + style: scaledTextStyle( fontSize: 15, fontStyle: FontStyle.italic, - color: Colors.grey[700]), + color: Colors.grey[700]!), ), ), ); @@ -263,7 +262,7 @@ class SettingsScreen extends StatelessWidget { 'blockN'.tr(args: [ sub.blocNumber.toString() ]), //'bloc N°${sub.blocNumber}', - style: TextStyle(fontSize: 14, color: Colors.grey[700]), + style: scaledTextStyle(fontSize: 14, color: Colors.grey[700]), ) ], ); @@ -285,7 +284,7 @@ class SettingsScreen extends StatelessWidget { selectedIndexerEndpoint = duniterIndexer.listIndexerEndpoints[0]; } - TextEditingController indexerEndpointController = TextEditingController( + final indexerEndpointController = TextEditingController( text: configBox.containsKey('customIndexer') ? configBox.get('customIndexer') : 'https://'); @@ -293,25 +292,22 @@ class SettingsScreen extends StatelessWidget { return Column(children: [ Row(children: [ Consumer(builder: (context, indexer, _) { - log.d(selectedIndexerEndpoint); - log.d(indexer.listIndexerEndpoints); return Expanded( child: Row(children: [ - const SizedBox(width: 10), - const SizedBox( - width: 80, - // child: Text('indexer'.tr()), // why translation does not work?? - child: Text('Indexer'), + ScaledSizedBox(width: 5), + ScaledSizedBox( + width: 55, + child: Text('Indexer', style: scaledTextStyle(fontSize: 16)), ), const Spacer(), Icon(indexerEndpoint != '' ? Icons.check : Icons.close), const Spacer(), - SizedBox( - width: 280, + ScaledSizedBox( + width: 230, child: Consumer(builder: (context, set, _) { return DropdownButtonHideUnderline( child: DropdownButton( - // alignment: AlignmentDirectional.topStart, + style: scaledTextStyle(fontSize: 16, color: Colors.black), value: selectedIndexerEndpoint, icon: const Icon(Icons.keyboard_arrow_down), items: @@ -322,7 +318,6 @@ class SettingsScreen extends StatelessWidget { ); }).toList(), onChanged: (newEndpoint) { - log.d(newEndpoint!); selectedIndexerEndpoint = newEndpoint.toString(); set.reload(); }, @@ -332,7 +327,7 @@ class SettingsScreen extends StatelessWidget { ), const Spacer(flex: 5), indexer.isLoadingIndexer - ? const CircularProgressIndicator(color: orangeC) + ? Loading(size: scaleSize(32), stroke: 2.5) : Consumer(builder: (context, set, _) { return IconButton( icon: Icon( @@ -340,7 +335,7 @@ class SettingsScreen extends StatelessWidget { color: selectedIndexerEndpoint != indexerEndpoint ? orangeC : Colors.grey[500], - size: 40, + size: scaleSize(35), ), onPressed: selectedIndexerEndpoint != indexerEndpoint ? () async { @@ -356,7 +351,6 @@ class SettingsScreen extends StatelessWidget { } else { configBox.delete('customIndexer'); } - log.d('connection to indexer $finalEndpoint'); await indexer .checkIndexerEndpoint(finalEndpoint); } @@ -370,12 +364,13 @@ class SettingsScreen extends StatelessWidget { Consumer(builder: (context, set, _) { return Visibility( visible: selectedIndexerEndpoint == 'Personnalisé', - child: SizedBox( + child: ScaledSizedBox( width: 200, height: 50, child: TextField( controller: indexerEndpointController, autocorrect: false, + style: scaledTextStyle(fontSize: 16), ), ), ); @@ -384,14 +379,12 @@ class SettingsScreen extends StatelessWidget { return Consumer(builder: (context, set, _) { return Visibility( visible: selectedIndexerEndpoint == 'Auto', - child: SizedBox( + child: ScaledSizedBox( width: 250, height: 60, child: Text( - sub.getConnectedEndpoint() ?? - "anAutoNodeChoosed" - .tr(), //"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.", - style: TextStyle( + sub.getConnectedEndpoint() ?? "anAutoNodeChoosed".tr(), + style: scaledTextStyle( fontSize: 15, fontStyle: FontStyle.italic, color: Colors.grey[700]), diff --git a/lib/screens/template_screen.dart b/lib/screens/template_screen.dart index 185a2da..b00aac4 100644 --- a/lib/screens/template_screen.dart +++ b/lib/screens/template_screen.dart @@ -1,5 +1,6 @@ import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; class TemplateScreen extends StatelessWidget { const TemplateScreen({Key? key}) : super(key: key); @@ -11,11 +12,7 @@ class TemplateScreen extends StatelessWidget { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( - toolbarHeight: 60 * ratio, - title: const SizedBox( - height: 22, - child: Text('Template screen'), - )), + toolbarHeight: scaleSize(57), title: const Text('Template screen')), body: const SafeArea( child: Column(children: [ SizedBox(height: 20), diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 4ce8005..aa77a72 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -1,223 +1,281 @@ -import 'package:easy_localization/easy_localization.dart'; -import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.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/wallets_profiles.dart'; import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.dart'; class TransactionInProgress extends StatelessWidget { - const TransactionInProgress( - {Key? key, - this.transType = 'pay', - this.fromAddress, - this.toAddress, - this.toUsername}) - : super(key: key); + final String transactionId; final String transType; - final String? fromAddress; - final String? toAddress; - final String? toUsername; + final String? fromAddress, toAddress, toUsername; + + const TransactionInProgress({ + Key? key, + required this.transactionId, + this.transType = 'pay', + this.fromAddress, + this.toAddress, + this.toUsername, + }) : super(key: key); @override Widget build(BuildContext context) { final sub = Provider.of(context, listen: true); - final walletProfiles = - Provider.of(context, listen: false); - final myWalletProvider = - Provider.of(context, listen: false); - bool isValid = false; - bool isLoading = false; - final result = sub.transactionStatus; - final from = fromAddress ?? - g1WalletsBox - .get(myWalletProvider.getDefaultWallet().address) - ?.username ?? - myWalletProvider.getDefaultWallet().name!; + final transactionDetails = TransactionDetails( + transactionId: transactionId, + fromAddress: fromAddress, + toAddress: toAddress, + toUsername: toUsername, + sub: sub, + transType: transType, + ); - String to = toAddress ?? walletProfiles.address; - to = - myWalletProvider.getWalletDataByAddress(to)?.name ?? getShortPubkey(to); - - final amount = walletProfiles.payAmount.text; - final bool isUdUnit = configBox.get('isUdUnit') ?? false; - - final Map actionMap = { - 'pay': 'transaction'.tr(), - 'cert': 'certification'.tr(), - 'comfirmIdty': 'identityConfirm'.tr(), - 'revokeIdty': 'revokeAdhesion'.tr(), - 'identityMigration': 'identityMigration'.tr(), - }; - - String resultText = ''; - final Map resultMap = { - '': 'sending'.tr(), - 'Ready': 'propagating'.tr(), - 'Broadcast': 'validating'.tr(), - 'cert.NotRespectCertPeriod': '24hbetweenCerts'.tr(), - 'identity.CreatorNotAllowedToCreateIdty': '24hbetweenCerts'.tr(), - 'cert.CannotCertifySelf': 'canNotCertifySelf'.tr(), - 'identity.IdtyNameAlreadyExist': 'nameAlreadyExist'.tr(), - 'balances.KeepAlive': '2GDtoKeepAlive'.tr(), - '1010: Invalid Transaction: Inability to pay some fees , e.g. account balance too low': - 'youHaveToFeedThisAccountBeforeUsing'.tr(), - 'Token.FundsUnavailable': 'fundsUnavailable'.tr(), - 'Exception: timeout': 'execTimeoutOver'.tr(), - }; - - if (result.contains('blockHash: ')) { - isValid = true; - resultText = 'extrinsicValidated' - .tr(args: [actionMap[transType] ?? 'strangeTransaction'.tr()]); - log.i('Bloc of last transaction: ${sub.blocNumber} --- $result'); - } else if (result.contains('Exception: ')) { - resultText = "${"anErrorOccurred".tr()}:\n"; - final String exception = result.split('Exception: ')[1]; - resultText = resultMap[exception] ?? "$resultText\n$exception"; - log.d('Error: $exception'); - } else { - isLoading = true; - resultText = resultMap[result] ?? 'unknown status...'; + Widget getTransactionStatusIcon(TransactionDetails details) { + switch (details.txStatus) { + case TransactionStatus.loading: + return ScaledSizedBox( + height: 17, + width: 17, + child: const CircularProgressIndicator( + color: orangeC, + strokeWidth: 2, + ), + ); + case TransactionStatus.success: + return Icon( + Icons.done_all, + size: scaleSize(32), + color: Colors.greenAccent, + ); + case TransactionStatus.failed: + return Icon( + Icons.close, + size: scaleSize(32), + color: Colors.redAccent, + ); + case TransactionStatus.none: + default: + return const SizedBox.shrink(); + } } - log.d("$transType :: ${actionMap[transType]} :: $result"); + Widget buildTransactionStatus(TransactionDetails details) { + return Column( + children: [ + getTransactionStatusIcon(details), + ScaledSizedBox(height: 7), + if (details.txStatus != TransactionStatus.none) + Text( + transactionDetails.resultText, + textAlign: TextAlign.center, + style: scaledTextStyle(fontSize: 17), + ) + ], + ); + } return PopScope( onPopInvoked: (_) { - sub.transactionStatus = ''; + sub.resetTransactionStatus(); }, child: Scaffold( backgroundColor: backgroundColor, appBar: AppBar( - toolbarHeight: 60 * ratio, + toolbarHeight: scaleSize(57), elevation: 0, automaticallyImplyLeading: false, - title: SizedBox( - height: 22, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('extrinsicInProgress'.tr(args: [ - actionMap[transType] ?? 'strangeTransaction'.tr() - ])) - ]), - )), + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'extrinsicInProgress'.tr(args: [ + transactionDetails.actionMap[transType] ?? + 'strangeTransaction'.tr() + ]), + style: scaledTextStyle(fontSize: 20), + ) + ])), body: SafeArea( child: Align( - alignment: FractionalOffset.bottomCenter, - child: Column(children: [ - Container( - width: double.infinity, - decoration: const BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - yellowC, - backgroundColor, - ], - )), - child: Column(children: [ - const SizedBox(height: 10), - if (transType == 'pay') - Text( - isUdUnit - ? 'ud'.tr(args: ['$amount ']) - : '$amount $currencyName', - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w600), - ), - if (transType == 'pay') const SizedBox(height: 10), + alignment: FractionalOffset.bottomCenter, + child: Column(children: [ + Container( + width: double.infinity, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + yellowC, + backgroundColor, + ], + )), + child: Column(children: [ + ScaledSizedBox(height: 10), + if (transType == 'pay') Text( - 'fromMinus'.tr(), + transactionDetails.isUdUnit + ? 'ud'.tr(args: ['${transactionDetails.amount} ']) + : '${transactionDetails.amount} $currencyName', textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w500), ), - Text( - from, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w600), - ), - const SizedBox(height: 10), - Text( - 'toMinus'.tr(), - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), - ), - Text( - toUsername ?? to, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w600), - ), - const SizedBox(height: 20), - ]), - ), - // const SizedBox(height: 20, width: double.infinity), - const Spacer(), - Column(children: [ - Visibility( - visible: isLoading, - child: const SizedBox( - height: 18, - width: 18, - child: CircularProgressIndicator( - color: orangeC, - strokeWidth: 2, - ), - ), - ), - Visibility( - visible: !isLoading, - child: Icon( - isValid ? Icons.done_all : Icons.close, - size: 35, - color: isValid ? Colors.greenAccent : Colors.redAccent, - ), - ), - const SizedBox(height: 10), + if (transType == 'pay') ScaledSizedBox(height: 10), Text( - resultText, + 'fromMinus'.tr(), textAlign: TextAlign.center, - style: TextStyle(fontSize: 19 * ratio), + style: scaledTextStyle(fontSize: 16), ), + Text( + transactionDetails.fromAddress!, + textAlign: TextAlign.center, + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w500), + ), + Visibility( + visible: transactionDetails.fromAddress != + transactionDetails.toAddress, + child: Column( + children: [ + ScaledSizedBox(height: 10), + Text( + 'toMinus'.tr(), + textAlign: TextAlign.center, + style: scaledTextStyle(fontSize: 16), + ), + Text( + transactionDetails.toUsername!, + textAlign: TextAlign.center, + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w500), + ), + ], + ), + ), + ScaledSizedBox(height: 20), ]), - const Spacer(), - Expanded( - child: Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - width: 380 * ratio, - height: 60 * ratio, - child: ElevatedButton( - key: keyCloseTransactionScreen, - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground - ), - onPressed: () { - sub.transactionStatus = ''; - Navigator.pop(context); - }, - child: Text( - 'close'.tr(), - style: TextStyle( - fontSize: 23 * ratio, - fontWeight: FontWeight.w600), - ), + ), + const Spacer(), + buildTransactionStatus(transactionDetails), + const Spacer(), + Expanded( + child: Align( + alignment: Alignment.bottomCenter, + child: ScaledSizedBox( + width: 300, + height: 55, + child: ElevatedButton( + key: keyCloseTransactionScreen, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, + ), + onPressed: () { + sub.resetTransactionStatus(); + Navigator.pop(context); + }, + child: Text( + 'close'.tr(), + style: scaledTextStyle( + fontSize: 20, fontWeight: FontWeight.w600), ), ), ), ), - SizedBox(height: isTall ? 80 : 20) - ])), + ), + ScaledSizedBox(height: 80) + ]), + ), ), ), ); } } + +enum TransactionStatus { loading, failed, success, none } + +class TransactionDetails { + String? fromAddress, toAddress, toUsername, amount; + bool isUdUnit = false; + String resultText = ''; + TransactionStatus txStatus = TransactionStatus.none; + + TransactionDetails({ + required transactionId, + required this.fromAddress, + required this.toAddress, + required this.toUsername, + required SubstrateSdk sub, + required String transType, + }) { + final walletProfiles = + Provider.of(homeContext, listen: false); + final myWalletProvider = + Provider.of(homeContext, listen: false); + String defaultWalletAddress = myWalletProvider.getDefaultWallet().address; + String defaultWalletName = myWalletProvider.getDefaultWallet().name!; + String? walletDataName = + myWalletProvider.getWalletDataByAddress(toAddress ?? '')?.name; + + fromAddress = fromAddress ?? + g1WalletsBox.get(defaultWalletAddress)?.username ?? + defaultWalletName; + toAddress = toAddress ?? walletProfiles.address; + toUsername = toUsername ?? walletDataName ?? getShortPubkey(toAddress!); + + amount = walletProfiles.payAmount.text; + isUdUnit = configBox.get('isUdUnit') ?? false; + + if (sub.transactionStatus.containsKey(transactionId)) { + calculateTransactionStatus( + sub.transactionStatus[transactionId], transType); + } + } + + void calculateTransactionStatus(String? result, String transType) { + if (result == null) { + txStatus = TransactionStatus.none; + } else if (result.contains('blockHash: ')) { + txStatus = TransactionStatus.success; + resultText = 'extrinsicValidated' + .tr(args: [actionMap[transType] ?? 'strangeTransaction'.tr()]); + } else if (result.contains('Exception: ')) { + txStatus = TransactionStatus.failed; + String exception = result.split('Exception: ')[1]; + resultText = resultMap[exception] ?? exception; + } else { + txStatus = TransactionStatus.loading; + resultText = resultMap[result] ?? 'Unknown status: $result'; + } + } + + Map actionMap = { + 'pay': 'transaction'.tr(), + 'cert': 'certification'.tr(), + 'comfirmIdty': 'identityConfirm'.tr(), + 'revokeIdty': 'revokeAdhesion'.tr(), + 'identityMigration': 'identityMigration'.tr(), + }; + + Map resultMap = { + 'sending': 'sending'.tr(), + 'Ready': 'propagating'.tr(), + 'Broadcast': 'validating'.tr(), + 'cert.NotRespectCertPeriod': '24hbetweenCerts'.tr(), + 'identity.CreatorNotAllowedToCreateIdty': '24hbetweenCerts'.tr(), + 'cert.CannotCertifySelf': 'canNotCertifySelf'.tr(), + 'identity.IdtyNameAlreadyExist': 'nameAlreadyExist'.tr(), + 'balances.KeepAlive': '2GDtoKeepAlive'.tr(), + '1010: Invalid Transaction: Inability to pay some fees , e.g. account balance too low': + 'youHaveToFeedThisAccountBeforeUsing'.tr(), + 'Token.FundsUnavailable': 'fundsUnavailable'.tr(), + 'Exception: timeout': 'execTimeoutOver'.tr(), + }; +} diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 51b5ac3..6c5d205 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -1,13 +1,12 @@ -//FIXME: flutter upgrades should fix this... one day. -// ignore_for_file: use_build_context_synchronously, prefer_const_constructors +// ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/scale_functions.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/substrate_sdk.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -25,37 +24,36 @@ import 'package:gecko/widgets/payment_popup.dart'; import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; +const double buttonSize = 83; +const double buttonFontSize = 14; + class WalletViewScreen extends StatelessWidget { const WalletViewScreen( - {required this.address, required this.username, this.avatar, Key? key}) + {required this.address, required this.username, Key? key}) : super(key: key); final String address; final String? username; - final Image? avatar; - final double buttonSize = 100; - final double buttonFontSize = 18; @override Widget build(BuildContext context) { - WalletsProfilesProvider walletProfile = + final walletProfile = Provider.of(context, listen: false); final sub = Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); final duniterIndexer = Provider.of(context, listen: false); - WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); + final defaultWallet = myWalletProvider.getDefaultWallet(); walletProfile.address = address; sub.setCurrentWallet(defaultWallet); - log.d("username: $username"); - return Scaffold( backgroundColor: backgroundColor, resizeToAvoidBottomInset: true, appBar: AppBar( elevation: 0, - toolbarHeight: 60 * ratio, + toolbarHeight: scaleSize(57), + titleSpacing: 10, actions: [ Row( children: [ @@ -67,7 +65,6 @@ class WalletViewScreen extends StatelessWidget { g1WalletsBox.toMap().forEach((key, value) { if (key == address) newContact = value; }); - // G1WalletsList(pubkey: pubkey!, username: username); await walletProfile.addContact( newContact ?? G1WalletsList(address: address)); }, @@ -75,11 +72,11 @@ class WalletViewScreen extends StatelessWidget { walletProfile.isContact(address) ? Icons.add_reaction_rounded : Icons.add_reaction_outlined, - size: 35, + size: scaleSize(33), ), ); }), - const SizedBox(width: 10), + ScaledSizedBox(width: isTall ? 10 : 0), InkWell( onTap: () { Navigator.push( @@ -91,65 +88,61 @@ class WalletViewScreen extends StatelessWidget { }), ); }, - child: QrImageWidget( + child: QrImageView( data: walletProfile.address, version: QrVersions.auto, - size: 80, + size: scaleSize(65), ), ), ], ) ], - title: SizedBox( - height: 22, - child: Text(duniterIndexer - .walletNameIndexer[walletProfile.address] == - null - ? 'seeAWallet'.tr() - : 'memberAccountOf'.tr(args: [ - duniterIndexer.walletNameIndexer[walletProfile.address] ?? - '?' - ]))), + title: Text( + duniterIndexer.walletNameIndexer[walletProfile.address] == null + ? 'seeAWallet'.tr() + : 'memberAccountOf'.tr(args: [ + duniterIndexer.walletNameIndexer[walletProfile.address] ?? + '?' + ]), + style: scaledTextStyle(fontSize: 18), + ), ), bottomNavigationBar: const GeckoBottomAppBar(), body: SafeArea( child: Column(children: [ HeaderProfile(address: address, username: username), - SizedBox(height: isTall ? 30 : 15), + ScaledSizedBox(height: 25), Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Column(children: [ - SizedBox( + ScaledSizedBox( height: buttonSize, child: ClipOval( child: Material( color: yellowC, child: InkWell( key: keyViewActivity, - splashColor: orangeC, // inkwell color - child: const Padding( - padding: EdgeInsets.all(13), - child: Image( - image: AssetImage( - 'assets/walletOptions/clock.png'), - height: 90)), + splashColor: orangeC, + child: Padding( + padding: EdgeInsets.all(scaleSize(10)), + child: + Image.asset('assets/walletOptions/clock.png'), + ), onTap: () { Navigator.push( context, PageNoTransit(builder: (context) { - return ActivityScreen( - address: address, - avatar: defaultAvatar(50)); + return ActivityScreen(address: address); }), ); }), ), ), ), - const SizedBox(height: 9), + ScaledSizedBox(height: 6), Text( "displayNActivity".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( fontSize: buttonFontSize, fontWeight: FontWeight.w500), ), ]), @@ -158,10 +151,8 @@ class WalletViewScreen extends StatelessWidget { return FutureBuilder( future: sub.certState(defaultWallet.address, address), builder: (context, AsyncSnapshot> snapshot) { - if (snapshot.data == null) return const SizedBox(); + if (snapshot.data == null) return const SizedBox.shrink(); String duration = ''; - log.d( - '${getShortPubkey(address)} --- certDelay ${snapshot.data!['certDelay']} --- certRenewable ${snapshot.data!['certRenewable']}'); if (snapshot.data!['certDelay'] != null || snapshot.data!['certRenewable'] != null) { @@ -203,7 +194,7 @@ class WalletViewScreen extends StatelessWidget { if (snapshot.data!['canCert'] != null || duration == 'seconds'.tr(args: ['0'])) Column(children: [ - SizedBox( + ScaledSizedBox( height: buttonSize, child: ClipOval( child: Material( @@ -218,66 +209,64 @@ class WalletViewScreen extends StatelessWidget { 'assets/gecko_certify.png')), ), onTap: () async { - final bool? result = + final result = await confirmPopupCertification( - context, - 'areYouSureYouWantToCertify1' - .tr(), - duniterIndexer - .walletNameIndexer[ - address] ?? - "noIdentity".tr(), - 'areYouSureYouWantToCertify2' - .tr(), - getShortPubkey(address)); + context, + 'areYouSureYouWantToCertify1' + .tr(), + duniterIndexer + .walletNameIndexer[ + address] ?? + "noIdentity".tr(), + 'areYouSureYouWantToCertify2' + .tr(), + getShortPubkey(address)) ?? + false; - if (result ?? false) { - String? pin; - if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( - context, - MaterialPageRoute( - builder: (homeContext) { - return UnlockingWallet( - wallet: defaultWallet); - }, - ), - ); - } - if (pin != null || - myWalletProvider.pinCode != '') { - WalletsProfilesProvider - walletViewProvider = Provider - .of( - context, - listen: false); - final acc = sub.getCurrentWallet(); - sub.certify( - acc.address!, - walletViewProvider.address, - pin ?? - myWalletProvider.pinCode); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) { - return const TransactionInProgress( - transType: 'cert'); - }), - ); - } + if (!result) return; + if (myWalletProvider.pinCode == '') { + await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet( + wallet: defaultWallet); + }, + ), + ); } + if (myWalletProvider.pinCode == '') { + return; + } + WalletsProfilesProvider + walletViewProvider = Provider.of< + WalletsProfilesProvider>( + context, + listen: false); + final acc = sub.getCurrentWallet(); + final transactionId = await sub.certify( + acc.address!, + walletViewProvider.address, + myWalletProvider.pinCode); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transactionId: transactionId, + transType: 'cert'); + }), + ); }), ), ), ), - const SizedBox(height: 9), + ScaledSizedBox(height: 6), Text( toStatus == null ? "certify".tr() : "createIdentity".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( fontSize: buttonFontSize, fontWeight: FontWeight.w500), ), @@ -295,7 +284,7 @@ class WalletViewScreen extends StatelessWidget { ); }), Column(children: [ - SizedBox( + ScaledSizedBox( height: buttonSize, child: ClipOval( child: Material( @@ -303,11 +292,12 @@ class WalletViewScreen extends StatelessWidget { child: InkWell( key: keyCopyAddress, splashColor: orangeC, - child: const Padding( - padding: EdgeInsets.all(20), - child: Image( - image: AssetImage('assets/copy_key.png'), - height: 90)), + child: Padding( + padding: EdgeInsets.all(scaleSize(17)), + child: const Image( + image: AssetImage('assets/copy_key.png'), + ), + ), onTap: () { Clipboard.setData(ClipboardData(text: address)); snackCopyKey(context); @@ -315,11 +305,11 @@ class WalletViewScreen extends StatelessWidget { ), ), ), - const SizedBox(height: 9), + ScaledSizedBox(height: 6), Text( "copyAddress".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( fontSize: buttonFontSize, fontWeight: FontWeight.w500), ), ]), @@ -329,7 +319,7 @@ class WalletViewScreen extends StatelessWidget { return Opacity( opacity: sub.nodeConnected ? 1 : 0.5, child: Container( - height: buttonSize, + height: scaleSize(buttonSize), decoration: BoxDecoration( color: const Color(0xff7c94b6), borderRadius: const BorderRadius.all(Radius.circular(100)), @@ -346,9 +336,8 @@ class WalletViewScreen extends StatelessWidget { splashColor: yellowC, onTap: sub.nodeConnected ? () async { - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -358,15 +347,13 @@ class WalletViewScreen extends StatelessWidget { ), ); } - if (pin != null || - myWalletProvider.pinCode != '') { - paymentPopup(context, address, username); - } + if (myWalletProvider.pinCode == '') return; + paymentPopup(context, address, username); } : null, - child: const Padding( - padding: EdgeInsets.all(14), - child: Image( + child: Padding( + padding: EdgeInsets.all(scaleSize(10)), + child: const Image( image: AssetImage('assets/vector_white.png')), )), ), @@ -374,44 +361,41 @@ class WalletViewScreen extends StatelessWidget { ), ); }), - const SizedBox(height: 9), + ScaledSizedBox(height: 6), Consumer(builder: (context, sub, _) { return Text( 'doATransfer'.tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( color: sub.nodeConnected ? Colors.black : Colors.grey[500], fontSize: buttonFontSize, fontWeight: FontWeight.w500), ); }), - SizedBox(height: isTall ? 50 : 20) + ScaledSizedBox(height: isTall ? 50 : 7) ]), )); } Widget waitToCert(String status, String duration) { return Column(children: [ - SizedBox( + ScaledSizedBox( height: buttonSize, - child: Padding( - padding: const EdgeInsets.only(bottom: 0), - child: Container( - foregroundDecoration: const BoxDecoration( - color: Colors.grey, - backgroundBlendMode: BlendMode.saturation, - ), - child: const Opacity( - opacity: 0.5, - child: Image(image: AssetImage('assets/gecko_certify.png')), - ), + child: Container( + foregroundDecoration: const BoxDecoration( + color: Colors.grey, + backgroundBlendMode: BlendMode.saturation, + ), + child: const Opacity( + opacity: 0.5, + child: Image(image: AssetImage('assets/gecko_certify.png')), ), ), ), Text( status.tr(args: [duration]), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( fontSize: buttonFontSize - 4, fontWeight: FontWeight.w400, color: Colors.grey[600]), diff --git a/lib/widgets/balance.dart b/lib/widgets/balance.dart index 53517f0..4306d0d 100644 --- a/lib/widgets/balance.dart +++ b/lib/widgets/balance.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/widgets/ud_unit_display.dart'; @@ -22,54 +22,50 @@ class Balance extends StatelessWidget { Widget build(BuildContext context) { final walletOptions = Provider.of(context, listen: false); - return Column(children: [ - Consumer(builder: (context, sdk, _) { - return FutureBuilder( - future: sdk.getBalance(address), - builder: (BuildContext context, - AsyncSnapshot> globalBalance) { - if (globalBalance.connectionState != ConnectionState.done || - globalBalance.hasError) { - if (walletOptions.balanceCache[address] != null && - walletOptions.balanceCache[address] != -1) { - return Row(children: [ - Text(walletOptions.balanceCache[address]!.toString(), - style: TextStyle( - fontSize: isTall ? size : size * 0.9, - color: color)), - const SizedBox(width: 5), - UdUnitDisplay(size: size, color: color), - ]); - } else { - return SizedBox( - height: 15, - width: 15, - child: CircularProgressIndicator( - color: loadingColor, - strokeWidth: 2, - ), - ); - } - } - walletOptions.balanceCache[address] = - globalBalance.data!['transferableBalance']!; - if (walletOptions.balanceCache[address] != -1) { + return Consumer(builder: (context, sdk, _) { + return FutureBuilder( + future: sdk.getBalance(address), + builder: (BuildContext context, + AsyncSnapshot> globalBalance) { + if (globalBalance.connectionState != ConnectionState.done || + globalBalance.hasError) { + if (walletOptions.balanceCache[address] != null && + walletOptions.balanceCache[address] != -1) { return Row(children: [ - Text( - walletOptions.balanceCache[address]!.toString(), - style: TextStyle( - fontSize: isTall ? size : size * 0.9, - color: color, - ), - ), - const SizedBox(width: 5), - UdUnitDisplay(size: size, color: color), + Text(walletOptions.balanceCache[address]!.toString(), + style: scaledTextStyle(fontSize: size, color: color)), + ScaledSizedBox(width: 5), + UdUnitDisplay(size: scaleSize(size), color: color), ]); } else { - return const Text(''); + return ScaledSizedBox( + height: 15, + width: 15, + child: CircularProgressIndicator( + color: loadingColor, + strokeWidth: 2, + ), + ); } - }); - }), - ]); + } + walletOptions.balanceCache[address] = + globalBalance.data!['transferableBalance']!; + if (walletOptions.balanceCache[address] != -1) { + return Row(children: [ + Text( + walletOptions.balanceCache[address]!.toString(), + style: scaledTextStyle( + fontSize: size, + color: color, + ), + ), + ScaledSizedBox(width: 5), + UdUnitDisplay(size: scaleSize(size), color: color), + ]); + } else { + return const Text(''); + } + }); + }); } } diff --git a/lib/widgets/bottom_app_bar.dart b/lib/widgets/bottom_app_bar.dart index 3a5c031..b09eef2 100644 --- a/lib/widgets/bottom_app_bar.dart +++ b/lib/widgets/bottom_app_bar.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -32,13 +33,13 @@ class GeckoBottomAppBar extends StatelessWidget { child: Container( color: yellowC, width: size.width, - height: 80, + height: scaleSize(67), child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [ const Spacer(), - const SizedBox(width: 11), + ScaledSizedBox(width: 11), IconButton( - key: keyAppBarSearch, - iconSize: 55, + key: keyAppBarHome, + iconSize: scaleSize(53), icon: const Icon(Icons.home_outlined), onPressed: () { searchProvider.reload(); @@ -48,27 +49,27 @@ class GeckoBottomAppBar extends StatelessWidget { ); }, ), - const SizedBox(width: 12), + ScaledSizedBox(width: 12), const Spacer(), IconButton( key: keyAppBarQrcode, - iconSize: 70, icon: const Image(image: AssetImage('assets/qrcode-scan.png')), onPressed: () async { historyProvider.scan(homeContext); }, ), const Spacer(), - const SizedBox(width: 15), + ScaledSizedBox(width: 15), Stack( + alignment: AlignmentDirectional.center, children: [ if (lockAction) Center( child: Padding( padding: const EdgeInsets.only(left: 0), child: Container( - width: 75, - height: 75, + width: scaleSize(75), + height: scaleSize(75), decoration: BoxDecoration( shape: BoxShape.circle, border: @@ -84,37 +85,37 @@ class GeckoBottomAppBar extends StatelessWidget { ), ), ), - IconButton( - key: keyAppBarChest, - iconSize: 60, - icon: const Image(image: AssetImage('assets/wallet.png')), - onPressed: lockAction - ? 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 != '') { - // log.d( - // isRoutePresentInNavigator(context, '/mywallets')); - Navigator.popUntil(context, ModalRoute.withName('/')); - //FIXME: Should not have to wait 300 milliseconds when /mywallets exist in navigator... - sleep(const Duration(milliseconds: 300)); - Navigator.pushNamed(context, '/mywallets'); - // Navigator.pushNamedAndRemoveUntil( - // context, '/mywallets', ModalRoute.withName('/')); - } - }, + ScaledSizedBox( + height: 53, + child: IconButton( + key: keyAppBarChest, + icon: const Image(image: AssetImage('assets/wallet.png')), + onPressed: lockAction + ? null + : () async { + WalletData? defaultWallet = + myWalletProvider.getDefaultWallet(); + if (myWalletProvider.pinCode == '') { + await Navigator.push( + context, + MaterialPageRoute( + builder: (homeContext) { + return UnlockingWallet(wallet: defaultWallet); + }, + ), + ); + + if (myWalletProvider.pinCode == '') return; + Navigator.popUntil( + context, ModalRoute.withName('/')); + //FIXME: Should not have to wait 300 milliseconds when /mywallets exist in navigator... + sleep(const Duration(milliseconds: 300)); + Navigator.pushNamed(context, '/mywallets'); + // Navigator.pushNamedAndRemoveUntil( + // context, '/mywallets', ModalRoute.withName('/')); + } + }, + ), ), ], ), @@ -128,7 +129,6 @@ class GeckoBottomAppBar extends StatelessWidget { bool isRoutePresentInNavigator(BuildContext context, String routeName) { bool isPresent = false; Navigator.popUntil(context, (route) { - log.d(route.settings.name); if (route.settings.name == routeName) { isPresent = true; } diff --git a/lib/widgets/bubble_speak.dart b/lib/widgets/bubble_speak.dart index 1505db8..ed1979c 100644 --- a/lib/widgets/bubble_speak.dart +++ b/lib/widgets/bubble_speak.dart @@ -1,33 +1,73 @@ import 'package:bubble/bubble.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; class BubbleSpeak extends StatelessWidget { const BubbleSpeak({ required this.text, this.long, + this.fontSize = 18, this.textKey, Key? key, }) : super(key: key); final String text; final double? long; + final double fontSize; final Key? textKey; @override Widget build(BuildContext context) { return Bubble( padding: long == null - ? const BubbleEdges.all(20) + ? const BubbleEdges.all(18) : BubbleEdges.symmetric(horizontal: long, vertical: 30), elevation: 5, color: backgroundColor, child: Text( text, key: textKey, - style: const TextStyle( - color: Colors.black, fontSize: 21, fontWeight: FontWeight.w400), + style: scaledTextStyle( + color: Colors.black, + fontSize: fontSize, + fontWeight: FontWeight.w400), ), ); } } + +class BubbleSpeakWithTail extends StatelessWidget { + const BubbleSpeakWithTail({ + required this.text, + this.long, + this.fontSize = 18, + this.textKey, + Key? key, + }) : super(key: key); + + final String text; + final double? long; + final double fontSize; + final Key? textKey; + + @override + Widget build(BuildContext context) { + return Stack( + alignment: Alignment.bottomRight, + clipBehavior: Clip.none, + children: [ + BubbleSpeak( + text: text, fontSize: fontSize, textKey: textKey, long: long), + Positioned( + left: 15, + bottom: -scaleSize(28), + child: Image( + image: const AssetImage('assets/home/bout_de_bulle.png'), + height: scaleSize(30), + ), + ), + ], + ); + } +} diff --git a/lib/widgets/buttons/add_new_derivation_button.dart b/lib/widgets/buttons/add_new_derivation_button.dart index ed86d4e..b2c5f3e 100644 --- a/lib/widgets/buttons/add_new_derivation_button.dart +++ b/lib/widgets/buttons/add_new_derivation_button.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -21,7 +22,7 @@ class AddNewDerivationButton extends StatelessWidget { String newDerivationName = '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; return Padding( - padding: const EdgeInsets.all(16), + padding: EdgeInsets.all(scaleSize(11)), child: ClipRRect( borderRadius: const BorderRadius.all(Radius.circular(12)), child: Column(children: [ @@ -32,9 +33,8 @@ class AddNewDerivationButton extends StatelessWidget { if (!myWalletProvider.isNewDerivationLoading) { WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -43,10 +43,9 @@ class AddNewDerivationButton extends StatelessWidget { ), ); } - if (pin != null || myWalletProvider.pinCode != '') { - await myWalletProvider.generateNewDerivation( - context, newDerivationName); - } + if (myWalletProvider.pinCode == '') return; + await myWalletProvider.generateNewDerivation( + context, newDerivationName); } }, child: Container( @@ -55,20 +54,20 @@ class AddNewDerivationButton extends StatelessWidget { decoration: const BoxDecoration(color: floattingYellow), child: Center( child: myWalletProvider.isNewDerivationLoading - ? const SizedBox( - height: 60, - width: 60, - child: CircularProgressIndicator( + ? ScaledSizedBox( + height: 50, + width: 50, + child: const CircularProgressIndicator( color: orangeC, - strokeWidth: 7, + strokeWidth: 6, ), ) - : const Text( + : Text( '+', - style: TextStyle( - fontSize: 150, + style: scaledTextStyle( + fontSize: 110, fontWeight: FontWeight.w700, - color: Color(0xFFFCB437)), + color: const Color(0xFFFCB437)), )), )), ), diff --git a/lib/widgets/buttons/chest_options_buttons.dart b/lib/widgets/buttons/chest_options_buttons.dart index 91fa11d..4c31bdd 100644 --- a/lib/widgets/buttons/chest_options_buttons.dart +++ b/lib/widgets/buttons/chest_options_buttons.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/screens/myWallets/chest_options.dart'; @@ -17,18 +18,19 @@ class ChestOptionsButtons extends StatelessWidget { Widget build(BuildContext context) { final myWalletProvider = Provider.of(context); return Column(children: [ - const SizedBox(height: 50), - SizedBox( - height: 80, - width: 420, + ScaledSizedBox(height: 50), + ScaledSizedBox( + height: 60, + width: 300, child: ElevatedButton.icon( icon: Image.asset( 'assets/chests/config.png', - height: 60, + height: scaleSize(40), ), style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 2, - backgroundColor: floattingYellow, // foreground + foregroundColor: Colors.black, + elevation: 2, + backgroundColor: floattingYellow, ), onPressed: () => Navigator.push( context, @@ -38,69 +40,68 @@ class ChestOptionsButtons extends StatelessWidget { ), label: Text( " ${"manageChest".tr()}", - style: const TextStyle( - fontSize: 22, + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w700, - color: Color(0xff8a3c0f), + color: const Color(0xff8a3c0f), ), ), )), - const SizedBox(height: 30), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/cesium_bw2.svg', - semanticsLabel: 'CS', - height: 50, - ), - const SizedBox(width: 5), - InkWell( - key: keyImportG1v1, - onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const ImportG1v1(); - }), - ); - }, - child: SizedBox( - width: 350, + ScaledSizedBox(height: 20), + InkWell( + key: keyImportG1v1, + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const ImportG1v1(); + }), + ); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/cesium_bw2.svg', + semanticsLabel: 'CS', + height: scaleSize(40), + ), + ScaledSizedBox( + width: 275, height: 60, child: Center( child: Text('importG1v1'.tr(), - style: TextStyle( - fontSize: 22, + style: scaledTextStyle( + fontSize: 17, color: Colors.blue[900], fontWeight: FontWeight.w500))), ), - ), - ], - ), - const SizedBox(height: 20), - InkWell( - key: keyChangeChest, - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) { - // return const ChooseChest(); - // }), - // ); - }, - child: SizedBox( - width: 400, - height: 60, - child: Center( - child: Text('changeChest'.tr(), - style: const TextStyle( - fontSize: 22, - color: Colors.grey, //orangeC - fontWeight: FontWeight.w500))), + ], ), ), - const SizedBox(height: 30) + ScaledSizedBox(height: 20), + // InkWell( + // key: keyChangeChest, + // onTap: () { + // // Navigator.push( + // // context, + // // MaterialPageRoute(builder: (context) { + // // return const ChooseChest(); + // // }), + // // ); + // }, + // child: ScaledSizedBox( + // width: 270, + // height: 60, + // child: Center( + // child: Text('changeChest'.tr(), + // style: const scaledTextStyle( + // fontSize: 20, + // color: Colors.grey, //orangeC + // fontWeight: FontWeight.w500))), + // ), + // ), + ScaledSizedBox(height: 30) ]); } } diff --git a/lib/widgets/buttons/home_buttons.dart b/lib/widgets/buttons/home_buttons.dart index f8343ce..1fc218f 100644 --- a/lib/widgets/buttons/home_buttons.dart +++ b/lib/widgets/buttons/home_buttons.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/home.dart'; @@ -38,14 +39,14 @@ class HomeButtons extends StatelessWidget { ), child: ClipOval( child: Material( - color: orangeC, // button color + color: orangeC, child: InkWell( key: keyOpenSearch, child: Padding( - padding: const EdgeInsets.all(18), + padding: EdgeInsets.all(scaleSize(15)), child: Image( image: const AssetImage('assets/home/loupe.png'), - height: 62 * ratio), + height: scaleSize(58)), ), onTap: () { Navigator.push( @@ -58,17 +59,17 @@ class HomeButtons extends StatelessWidget { ), ), ), - const SizedBox(height: 12), + ScaledSizedBox(height: 10), Text( "searchWallet".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( color: Colors.white, - fontSize: 15 * ratio, + fontSize: 13.5, fontWeight: FontWeight.w500), ) ]), - const SizedBox(width: 120), + ScaledSizedBox(width: 95), Column(children: [ Container( decoration: const BoxDecoration( @@ -91,9 +92,8 @@ class HomeButtons extends StatelessWidget { : () async { WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -103,31 +103,30 @@ class HomeButtons extends StatelessWidget { ), ); } - if (pin != null || myWalletProvider.pinCode != '') { - Navigator.pushNamed(context, '/mywallets'); - } + if (myWalletProvider.pinCode == '') return; + Navigator.pushNamed(context, '/mywallets'); }, child: Padding( - padding: const EdgeInsets.all(18), + padding: EdgeInsets.all(scaleSize(14.5)), child: Image( image: const AssetImage('assets/home/wallet.png'), - height: 68 * ratio))), + height: scaleSize(61)))), ), ), ), - const SizedBox(height: 12), + ScaledSizedBox(height: 10), Text( "manageWallets".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( color: Colors.white, - fontSize: 15 * ratio, + fontSize: 13.5, fontWeight: FontWeight.w500), ) ]) ]), Padding( - padding: EdgeInsets.only(top: 35 * ratio), + padding: EdgeInsets.only(top: scaleSize(30)), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Column(children: [ @@ -145,29 +144,29 @@ class HomeButtons extends StatelessWidget { color: orangeC, // button color child: InkWell( child: Padding( - padding: const EdgeInsets.all(18), + padding: EdgeInsets.all(scaleSize(14)), child: Image( image: const AssetImage('assets/home/qrcode.png'), - height: 68 * ratio)), + height: scaleSize(62))), onTap: () async { await historyProvider.scan(context); }), ), ), ), - const SizedBox(height: 12), + ScaledSizedBox(height: 10), Text( "scanQRCode".tr(), textAlign: TextAlign.center, - style: TextStyle( + style: scaledTextStyle( color: Colors.white, - fontSize: 15 * ratio, + fontSize: 13.5, fontWeight: FontWeight.w500), ) ]) ]), ), - SizedBox(height: isTall ? 80 : 40) + ScaledSizedBox(height: isTall ? 60 : 30) ]); } } diff --git a/lib/widgets/buttons/manage_membership_button.dart b/lib/widgets/buttons/manage_membership_button.dart index 82f1f51..a3cdb95 100644 --- a/lib/widgets/buttons/manage_membership_button.dart +++ b/lib/widgets/buttons/manage_membership_button.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/screens/myWallets/manage_membership.dart'; @@ -26,16 +27,16 @@ class ManageMembershipButton extends StatelessWidget { }), ); }, - child: SizedBox( + child: ScaledSizedBox( height: 40, child: Row(children: [ - const SizedBox(width: 32), + ScaledSizedBox(width: 28), Image.asset( 'assets/medal.png', - height: 45, + height: scaleSize(42), ), - const SizedBox(width: 22), - Text('manageMembership'.tr(), style: const TextStyle(fontSize: 20)), + ScaledSizedBox(width: 20), + Text('manageMembership'.tr(), style: scaledTextStyle(fontSize: 18)), ]), ), ); diff --git a/lib/widgets/cert_tile.dart b/lib/widgets/cert_tile.dart index dc0e25b..0e7d7ea 100644 --- a/lib/widgets/cert_tile.dart +++ b/lib/widgets/cert_tile.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; -import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/screens/wallet_view.dart'; class CertTile extends StatelessWidget { @@ -16,7 +17,7 @@ class CertTile extends StatelessWidget { @override Widget build(BuildContext context) { int keyID = 0; - const double avatarSize = 200; + const double avatarSize = 40; return Column( children: listCerts.map((repository) { @@ -25,45 +26,49 @@ class CertTile extends StatelessWidget { padding: const EdgeInsets.only(right: 0), child: ListTile( key: keyTransaction(keyID++), - contentPadding: const EdgeInsets.only( - left: 20, right: 30, top: 15, bottom: 15), + contentPadding: EdgeInsets.only( + left: 10, right: 0, top: scaleSize(3), bottom: scaleSize(3)), leading: ClipOval( - child: defaultAvatar(avatarSize), + child: V2sDatapodProvider().defaultAvatar(avatarSize), ), title: Padding( - padding: const EdgeInsets.only(bottom: 5), - child: Text(repository['name'], - style: const TextStyle(fontSize: 22)), + padding: const EdgeInsets.only(bottom: 2), + child: Text( + repository['name'], + style: scaledTextStyle(fontSize: 16), + ), ), subtitle: RichText( text: TextSpan( - style: TextStyle( - fontSize: 18, + style: scaledTextStyle( + fontSize: 15, color: Colors.grey[700], ), children: [ TextSpan( text: repository['date'], + style: scaledTextStyle(fontSize: 15), ), if (repository[2] != '') TextSpan( text: ' · ', - style: TextStyle( - fontSize: 20, + style: scaledTextStyle( + fontSize: 19, color: Colors.grey[550], ), ), TextSpan( text: getShortPubkey(repository['address']), - style: TextStyle( + style: scaledTextStyle( fontStyle: FontStyle.italic, + fontFamily: 'Monospace', color: Colors.grey[600], - fontSize: 18), + fontSize: 15), ), ], ), ), - dense: false, + dense: !isTall, isThreeLine: false, onTap: () { Navigator.push( diff --git a/lib/widgets/certifications.dart b/lib/widgets/certifications.dart index ac7f342..18efd13 100644 --- a/lib/widgets/certifications.dart +++ b/lib/widgets/certifications.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -24,18 +25,20 @@ class Certifications extends StatelessWidget { ? Row( children: [ Image.asset('assets/medal.png', - color: color, height: 20), - const SizedBox(width: 1), + color: color, height: scaleSize(18)), + ScaledSizedBox(width: 1), Text(certs.data?[0].toString() ?? '0', - style: TextStyle(fontSize: size, color: color)), - const SizedBox(width: 5), + style: + scaledTextStyle(fontSize: size, color: color)), + ScaledSizedBox(width: 5), Text( "(${certs.data?[1].toString() ?? '0'})", - style: TextStyle(fontSize: size * 0.7, color: color), + style: scaledTextStyle( + fontSize: size * 0.7, color: color), ) ], ) - : const Text(''); + : const SizedBox(); }); }), ]); diff --git a/lib/widgets/certs_counter.dart b/lib/widgets/certs_counter.dart index 01c0a3b..10f9aa2 100644 --- a/lib/widgets/certs_counter.dart +++ b/lib/widgets/certs_counter.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -11,7 +12,10 @@ class CertsCounter extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer(builder: (context, sub, _) { - return Text('(${sub.certsCounterCache[address]![isSent ? 1 : 0]})'); + return Text( + '(${sub.certsCounterCache[address]![isSent ? 1 : 0]})', + style: scaledTextStyle(fontSize: 17), + ); }); } } diff --git a/lib/widgets/certs_list.dart b/lib/widgets/certs_list.dart new file mode 100644 index 0000000..3c06680 --- /dev/null +++ b/lib/widgets/certs_list.dart @@ -0,0 +1,123 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/queries_indexer.dart'; +import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:gecko/widgets/cert_tile.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; + +class CertsList extends StatelessWidget { + const CertsList( + {Key? key, + required this.address, + this.direction = CertDirection.received}) + : super(key: key); + final String address; + final CertDirection direction; + + @override + Widget build(BuildContext context) { + final screenHeight = MediaQuery.of(context).size.height; + final appBarHeight = AppBar().preferredSize.height; + final windowHeight = screenHeight - appBarHeight - (isTall ? 170 : 140); + + final httpLink = HttpLink( + '$indexerEndpoint/v1/graphql', + ); + + late String gertCertsReq; + late String certFrom; + + if (direction == CertDirection.received) { + gertCertsReq = getCertsReceived; + certFrom = 'issuer'; + } else { + gertCertsReq = getCertsSent; + certFrom = 'receiver'; + } + + final client = ValueNotifier( + GraphQLClient( + cache: GraphQLCache(store: HiveStore()), + link: httpLink, + ), + ); + return GraphQLProvider( + client: client, + child: Query( + options: QueryOptions( + document: gql(gertCertsReq), + variables: { + 'address': address, + }, + ), + builder: (QueryResult result, {fetchMore, refetch}) { + if (result.isLoading && result.data == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + if (result.hasException || result.data == null) { + log.e('Error Indexer: ${result.exception}'); + return Column(children: [ + ScaledSizedBox(height: 50), + Text( + "noNetworkNoHistory".tr(), + textAlign: TextAlign.center, + style: scaledTextStyle(fontSize: 18), + ) + ]); + } else if (result.data?['certification']?.isEmpty) { + return Column(children: [ + ScaledSizedBox(height: 50), + Text( + "noDataToDisplay".tr(), + style: scaledTextStyle(fontSize: 18), + ) + ]); + } + + final List certsData = result.data!['certification']; + List listCerts = []; + for (final cert in certsData) { + final String issuerAddress = cert[certFrom]['pubkey']; + final String issuerName = cert[certFrom]['name']; + final date = DateTime.parse(cert['created_at']); + final dp = DateTime(date.year, date.month, date.day); + final dateForm = '${dp.day}-${dp.month}-${dp.year}'; + listCerts.add({ + 'address': issuerAddress, + 'name': issuerName, + 'date': dateForm + }); + } + + // Build history list + return SizedBox( + height: windowHeight, + child: ListView( + key: keyListTransactions, + children: [ + result.data == null + ? Column(children: [ + ScaledSizedBox(height: 50), + Text( + "noTransactionToDisplay".tr(), + style: scaledTextStyle(fontSize: 18), + ) + ]) + : Column(children: [ + CertTile(listCerts: listCerts), + ]) + ], + ), + ); + }, + ), + ); + } +} + +enum CertDirection { received, sent } diff --git a/lib/widgets/certs_received.dart b/lib/widgets/certs_received.dart deleted file mode 100644 index 32c274e..0000000 --- a/lib/widgets/certs_received.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; -import 'package:gecko/models/queries_indexer.dart'; -import 'package:gecko/models/widgets_keys.dart'; -import 'package:gecko/widgets/cert_tile.dart'; -import 'package:graphql_flutter/graphql_flutter.dart'; - -class CertsReceived extends StatelessWidget { - const CertsReceived({Key? key, required this.address}) : super(key: key); - final String address; - - @override - Widget build(BuildContext context) { - final screenHeight = MediaQuery.of(context).size.height; - final appBarHeight = AppBar().preferredSize.height; - log.d(appBarHeight); - final windowHeight = screenHeight - appBarHeight - 200; - - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(store: HiveStore()), - link: httpLink, - ), - ); - return GraphQLProvider( - client: client, - child: Query( - options: QueryOptions( - document: gql(getCertsReceived), - variables: { - 'address': address, - }, - ), - builder: (QueryResult result, {fetchMore, refetch}) { - if (result.isLoading && result.data == null) { - return const Center( - child: CircularProgressIndicator(), - ); - } - - if (result.hasException || result.data == null) { - log.e('Error Indexer: ${result.exception}'); - return Column(children: [ - const SizedBox(height: 50), - Text( - "noNetworkNoHistory".tr(), - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), - ) - ]); - } else if (result.data?['certification']?.isEmpty) { - return Column(children: [ - const SizedBox(height: 50), - Text( - "noDataToDisplay".tr(), - style: const TextStyle(fontSize: 18), - ) - ]); - } - // Build history list - return SizedBox( - height: windowHeight, - child: ListView( - key: keyListTransactions, - children: [certsView(result)], - ), - ); - }, - ), - ); - } - - Widget certsView(QueryResult result) { - List listCerts = []; - final List certsData = result.data!['certification']; - - for (final cert in certsData) { - final String issuerAddress = cert['issuer']['pubkey']; - final String issuerName = cert['issuer']['name']; - final date = DateTime.parse(cert['created_at']); - final dp = DateTime(date.year, date.month, date.day); - final dateForm = '${dp.day}-${dp.month}-${dp.year}'; - listCerts.add( - {'address': issuerAddress, 'name': issuerName, 'date': dateForm}); - } - - return result.data == null - ? Column(children: [ - const SizedBox(height: 50), - Text( - "noTransactionToDisplay".tr(), - style: const TextStyle(fontSize: 18), - ) - ]) - : Column(children: [ - CertTile(listCerts: listCerts), - ]); - } -} diff --git a/lib/widgets/certs_sent.dart b/lib/widgets/certs_sent.dart deleted file mode 100644 index 689f7f5..0000000 --- a/lib/widgets/certs_sent.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; -import 'package:gecko/models/queries_indexer.dart'; -import 'package:gecko/models/widgets_keys.dart'; -import 'package:gecko/widgets/cert_tile.dart'; -import 'package:graphql_flutter/graphql_flutter.dart'; - -class CertsSent extends StatelessWidget { - const CertsSent({Key? key, required this.address}) : super(key: key); - final String address; - - @override - Widget build(BuildContext context) { - final screenHeight = MediaQuery.of(context).size.height; - final appBarHeight = AppBar().preferredSize.height; - log.d(appBarHeight); - final windowHeight = screenHeight - appBarHeight - 200; - - final httpLink = HttpLink( - '$indexerEndpoint/v1/graphql', - ); - - final client = ValueNotifier( - GraphQLClient( - cache: GraphQLCache(store: HiveStore()), - link: httpLink, - ), - ); - return GraphQLProvider( - client: client, - child: Query( - options: QueryOptions( - document: gql(getCertsSent), - variables: { - 'address': address, - }, - ), - builder: (QueryResult result, {fetchMore, refetch}) { - if (result.isLoading && result.data == null) { - return const Center( - child: CircularProgressIndicator(), - ); - } - - if (result.hasException || result.data == null) { - log.e('Error Indexer: ${result.exception}'); - return Column(children: [ - const SizedBox(height: 50), - Text( - "noNetworkNoHistory".tr(), - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), - ) - ]); - } else if (result.data?['certification']?.isEmpty) { - return Column(children: [ - const SizedBox(height: 50), - Text( - "noDataToDisplay".tr(), - style: const TextStyle(fontSize: 18), - ) - ]); - } - // Build history list - return SizedBox( - height: windowHeight, - child: ListView( - key: keyListTransactions, - children: [certsView(result)], - ), - ); - }, - ), - ); - } - - Widget certsView(QueryResult result) { - List listCerts = []; - final List certsData = result.data!['certification']; - - for (final cert in certsData) { - final String issuerAddress = cert['receiver']['pubkey']; - final String issuerName = cert['receiver']['name']; - final date = DateTime.parse(cert['created_at']); - final dp = DateTime(date.year, date.month, date.day); - final dateForm = '${dp.day}-${dp.month}-${dp.year}'; - - listCerts.add( - {'address': issuerAddress, 'name': issuerName, 'date': dateForm}); - } - - return result.data == null - ? Column(children: [ - const SizedBox(height: 50), - Text( - "noTransactionToDisplay".tr(), - style: const TextStyle(fontSize: 18), - ) - ]) - : Column(children: [ - CertTile(listCerts: listCerts), - ]); - } -} diff --git a/lib/widgets/commons/build_image.dart b/lib/widgets/commons/build_image.dart index d3b284a..b932f4a 100644 --- a/lib/widgets/commons/build_image.dart +++ b/lib/widgets/commons/build_image.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; class BuildImage extends StatelessWidget { const BuildImage({ @@ -15,10 +16,11 @@ class BuildImage extends StatelessWidget { @override Widget build(BuildContext context) { + final ratio = isTall ? 1 : 0.95; return Container( padding: const EdgeInsets.all(0), - width: 440, - height: isTall ? boxHeight : boxHeight * 0.9, + width: scaleSize(imageWidth * ratio), + height: scaleSize(boxHeight * ratio), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, @@ -29,6 +31,6 @@ class BuildImage extends StatelessWidget { ], ), border: Border.all(color: Colors.grey[900]!)), - child: Image.asset('assets/onBoarding/$assetName', width: imageWidth)); + child: Image.asset('assets/onBoarding/$assetName')); } } diff --git a/lib/widgets/commons/build_progress_bar.dart b/lib/widgets/commons/build_progress_bar.dart index 6436388..ebea0cb 100644 --- a/lib/widgets/commons/build_progress_bar.dart +++ b/lib/widgets/commons/build_progress_bar.dart @@ -1,6 +1,7 @@ import 'package:dots_indicator/dots_indicator.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; class BuildProgressBar extends StatelessWidget { const BuildProgressBar({ @@ -16,8 +17,10 @@ class BuildProgressBar extends StatelessWidget { dotsCount: 10, position: pagePosition, decorator: DotsDecorator( - spacing: const EdgeInsets.symmetric(horizontal: 10), - color: Colors.grey[300]!, // Inactive color + size: Size.square(scaleSize(7)), + activeSize: Size.square(scaleSize(10)), + spacing: EdgeInsets.symmetric(horizontal: scaleSize(10)), + color: Colors.grey[400]!, activeColor: orangeC, ), ); diff --git a/lib/widgets/commons/build_text.dart b/lib/widgets/commons/build_text.dart index eac00be..64f663c 100644 --- a/lib/widgets/commons/build_text.dart +++ b/lib/widgets/commons/build_text.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; class BuildText extends StatelessWidget { const BuildText({ Key? key, required this.text, - this.size = 20, + this.size = 17, this.isMd = true, }) : super(key: key); @@ -16,25 +17,24 @@ class BuildText extends StatelessWidget { @override Widget build(BuildContext context) { + final double ratio = isTall ? 1 : 0.95; final mdStyle = MarkdownStyleSheet( - p: TextStyle( - fontSize: isTall ? size : size * 0.9, - color: Colors.black, - letterSpacing: 0.3), + p: scaledTextStyle( + fontSize: size * ratio, color: Colors.black, letterSpacing: 0.3), textAlign: WrapAlignment.spaceBetween, ); return Container( padding: const EdgeInsets.all(12), - width: 440, + width: scaleSize(350 * ratio), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.grey[900]!)), child: isMd ? MarkdownBody(data: text, styleSheet: mdStyle) : Text(text, textAlign: TextAlign.justify, - style: TextStyle( - fontSize: isTall ? size : size * 0.9, + style: scaledTextStyle( + fontSize: size * ratio, color: Colors.black, letterSpacing: 0.3)), ); diff --git a/lib/widgets/commons/common_elements.dart b/lib/widgets/commons/common_elements.dart index 93f42fb..53164a8 100644 --- a/lib/widgets/commons/common_elements.dart +++ b/lib/widgets/commons/common_elements.dart @@ -1,19 +1,20 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; Future confirmPopup(BuildContext context, String title) async { return showDialog( context: context, - barrierDismissible: true, // user must tap button! + barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( backgroundColor: backgroundColor, content: Text( title, textAlign: TextAlign.center, - style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), + style: scaledTextStyle(fontSize: 19, fontWeight: FontWeight.w500), ), actions: [ Row( @@ -23,26 +24,27 @@ Future confirmPopup(BuildContext context, String title) async { key: keyConfirm, child: Text( "yes".tr(), - style: const TextStyle( - fontSize: 21, - color: Color(0xffD80000), + style: scaledTextStyle( + fontSize: 19, + color: const Color(0xffD80000), ), ), onPressed: () { Navigator.pop(context, true); }, ), - const SizedBox(width: 20), + ScaledSizedBox(width: 20), TextButton( child: Text( "no".tr(), - style: const TextStyle(fontSize: 21), + style: + scaledTextStyle(fontSize: 19, color: Colors.blueAccent), ), onPressed: () { Navigator.pop(context, false); }, ), - const SizedBox(height: 120) + ScaledSizedBox(height: 70) ], ) ], @@ -58,45 +60,45 @@ Future confirmPopupCertification(BuildContext context, String question1, barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( - // actionsPadding: const EdgeInsets.all(0.0), backgroundColor: backgroundColor, - content: SizedBox( - height: 240, + content: ScaledSizedBox( + height: 230, child: Column( children: [ - const SizedBox(height: 15), + ScaledSizedBox(height: 15), Text( question1, textAlign: TextAlign.center, style: - const TextStyle(fontSize: 20, fontWeight: FontWeight.w400), + scaledTextStyle(fontSize: 19, fontWeight: FontWeight.w400), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), Text( username, textAlign: TextAlign.center, style: - const TextStyle(fontSize: 24, fontWeight: FontWeight.w500), + scaledTextStyle(fontSize: 22, fontWeight: FontWeight.w500), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), Text( question2, textAlign: TextAlign.center, style: - const TextStyle(fontSize: 20, fontWeight: FontWeight.w400), + scaledTextStyle(fontSize: 19, fontWeight: FontWeight.w400), ), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), Text( address, textAlign: TextAlign.center, style: - const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), + scaledTextStyle(fontSize: 19, fontWeight: FontWeight.w500), ), - const SizedBox(height: 20), - const Text( + ScaledSizedBox(height: 20), + Text( '?', textAlign: TextAlign.center, - style: TextStyle(fontSize: 20, fontWeight: FontWeight.w400), + style: + scaledTextStyle(fontSize: 19, fontWeight: FontWeight.w400), ), ], ), @@ -109,26 +111,26 @@ Future confirmPopupCertification(BuildContext context, String question1, key: keyConfirm, child: Text( "yes".tr(), - style: const TextStyle( - fontSize: 25, - color: Color(0xffD80000), + style: scaledTextStyle( + fontSize: 20, + color: const Color(0xffD80000), ), ), onPressed: () { Navigator.pop(context, true); }, ), - const SizedBox(width: 35), + ScaledSizedBox(width: 32), TextButton( child: Text( "no".tr(), - style: const TextStyle(fontSize: 25), + style: scaledTextStyle(fontSize: 20), ), onPressed: () { Navigator.pop(context, false); }, ), - const SizedBox(height: 120) + ScaledSizedBox(height: 120) ], ) ], @@ -140,14 +142,14 @@ Future confirmPopupCertification(BuildContext context, String question1, Future infoPopup(BuildContext context, String title) async { return showDialog( context: context, - barrierDismissible: true, // user must tap button! + barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( backgroundColor: backgroundColor, content: Text( title, textAlign: TextAlign.center, - style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), + style: scaledTextStyle(fontSize: 17, fontWeight: FontWeight.w500), ), actions: [ Row( @@ -159,9 +161,9 @@ Future infoPopup(BuildContext context, String title) async { padding: const EdgeInsets.all(8), child: Text( "gotit".tr(), - style: const TextStyle( - fontSize: 21, - color: Color(0xffD80000), + style: scaledTextStyle( + fontSize: 19, + color: const Color(0xffD80000), ), ), ), @@ -176,42 +178,3 @@ Future infoPopup(BuildContext context, String title) async { }, ); } - -bool isAddress(address) { - final RegExp regExp = RegExp( - r'^[a-zA-Z0-9]+$', - caseSensitive: false, - multiLine: false, - ); - - if (regExp.hasMatch(address) == true && - address.length > 45 && - address.length < 52) { - log.d("C'est une adresse !"); - - return true; - } else { - return false; - } -} - -// Widget geckoAppBar() { -// return AppBar( -// toolbarHeight: 60 * ratio, -// elevation: 0, -// leading: IconButton( -// icon: const Icon(Icons.arrow_back, color: Colors.black), -// onPressed: () { -// _walletOptions.isEditing = false; -// _walletOptions.isBalanceBlur = false; -// Navigator.pop(context); -// }), -// title: SizedBox( -// height: 22, -// child: Consumer( -// builder: (context, walletProvider, _) { -// return Text(_walletOptions.nameController.text); -// }), -// ), -// ); -// } diff --git a/lib/widgets/commons/intro_info.dart b/lib/widgets/commons/intro_info.dart index 5169004..5a1f5ac 100644 --- a/lib/widgets/commons/intro_info.dart +++ b/lib/widgets/commons/intro_info.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/widgets/commons/build_image.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart'; import 'package:gecko/widgets/commons/build_text.dart'; @@ -15,9 +16,9 @@ class InfoIntro extends StatelessWidget { required this.pagePosition, this.isMd = false, this.isFast = false, - this.boxHeight = 440, + this.boxHeight = 340, this.imageWidth = 350, - this.textSize = 20, + this.textSize = 17, }) : super(key: key); final String text; @@ -34,12 +35,10 @@ class InfoIntro extends StatelessWidget { @override Widget build(BuildContext context) { return Column(children: [ - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 25 : 5), BuildProgressBar(pagePosition: pagePosition), - SizedBox(height: isTall ? 40 : 20), - + ScaledSizedBox(height: isTall ? 25 : 5), BuildText(text: text, size: textSize, isMd: isMd), - BuildImage( assetName: assetName, boxHeight: boxHeight, imageWidth: imageWidth), Expanded( @@ -49,8 +48,7 @@ class InfoIntro extends StatelessWidget { text: buttonText, nextScreen: nextScreen, isFast: false), ), ), - // const SizedBox(height: 40), - SizedBox(height: isTall ? 40 : 20), + ScaledSizedBox(height: isTall ? 40 : 5), ]); } } diff --git a/lib/widgets/commons/loading.dart b/lib/widgets/commons/loading.dart new file mode 100644 index 0000000..b969606 --- /dev/null +++ b/lib/widgets/commons/loading.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; + +class Loading extends StatelessWidget { + const Loading({ + Key? key, + this.size = 15, + this.stroke = 2, + }) : super(key: key); + + final double size; + final double stroke; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: size, + width: size, + child: CircularProgressIndicator( + color: orangeC, + strokeWidth: stroke, + ), + ); + } +} diff --git a/lib/widgets/commons/next_button.dart b/lib/widgets/commons/next_button.dart index 2a92142..dd31354 100644 --- a/lib/widgets/commons/next_button.dart +++ b/lib/widgets/commons/next_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/widgets/commons/fader_transition.dart'; @@ -17,14 +18,15 @@ class NextButton extends StatelessWidget { @override Widget build(BuildContext context) { - return SizedBox( - width: 380 * ratio, - height: 60 * ratio, + return ScaledSizedBox( + width: 340, + height: 55, child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, backgroundColor: orangeC, - elevation: 4, // foreground + foregroundColor: Colors.white, + backgroundColor: orangeC, + elevation: 4, ), onPressed: () { Navigator.push( @@ -32,7 +34,8 @@ class NextButton extends StatelessWidget { }, child: Text( text, - style: TextStyle(fontSize: 23 * ratio, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 23, fontWeight: FontWeight.w600, color: Colors.white), ), ), ); diff --git a/lib/widgets/commons/top_appbar.dart b/lib/widgets/commons/top_appbar.dart new file mode 100644 index 0000000..ea18611 --- /dev/null +++ b/lib/widgets/commons/top_appbar.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:gecko/models/scale_functions.dart'; + +class GeckoAppBar extends StatelessWidget implements PreferredSizeWidget { + const GeckoAppBar(this.text, {Key? key}) : super(key: key); + + final String text; + + @override + AppBar build(BuildContext context) { + return AppBar( + toolbarHeight: scaleSize(57), + titleSpacing: 10, + title: Text( + text, + style: scaledTextStyle(fontWeight: FontWeight.w600, fontSize: 18), + ), + ); + } + + @override + Size get preferredSize => Size.fromHeight(scaleSize(57)); +} diff --git a/lib/widgets/contacts_list.dart b/lib/widgets/contacts_list.dart index 2dd8aab..baaafc5 100644 --- a/lib/widgets/contacts_list.dart +++ b/lib/widgets/contacts_list.dart @@ -2,14 +2,15 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.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/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/balance.dart'; +import 'package:gecko/widgets/datapod_avatar.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:provider/provider.dart'; @@ -17,11 +18,9 @@ class ContactsList extends StatelessWidget { const ContactsList({ Key? key, required this.myContacts, - required this.avatarSize, }) : super(key: key); final List myContacts; - final double avatarSize; @override Widget build(BuildContext context) { @@ -30,11 +29,11 @@ class ContactsList extends StatelessWidget { final duniterIndexer = Provider.of(context, listen: false); return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 5), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 20, width: double.infinity), + ScaledSizedBox(height: 10, width: double.infinity), if (myContacts.isEmpty) Text('noContacts'.tr()) else @@ -45,13 +44,15 @@ class ContactsList extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( key: keySearchResult('keyID++'), - horizontalTitleGap: 40, + horizontalTitleGap: 7, contentPadding: const EdgeInsets.all(5), - leading: defaultAvatar(avatarSize), + dense: !isTall, + leading: DatapodAvatar( + address: g1Wallet.address, size: scaleSize(50)), title: Row(children: [ Text(getShortPubkey(g1Wallet.address), - style: const TextStyle( - fontSize: 18, + style: scaledTextStyle( + fontSize: 16, fontFamily: 'Monospace', fontWeight: FontWeight.w500), textAlign: TextAlign.center), @@ -59,7 +60,7 @@ class ContactsList extends StatelessWidget { trailing: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( + ScaledSizedBox( width: 110, child: Row( mainAxisAlignment: MainAxisAlignment.end, @@ -70,16 +71,16 @@ class ContactsList extends StatelessWidget { children: [ Balance( address: g1Wallet.address, - size: 16), + size: scaleSize(14)), ]), ]), ), ]), subtitle: Row(children: [ NameByAddress( + size: scaleSize(17), wallet: WalletData(address: g1Wallet.address)) ]), - dense: false, isThreeLine: false, onTap: () { Navigator.push( @@ -87,13 +88,9 @@ class ContactsList extends StatelessWidget { MaterialPageRoute(builder: (context) { walletsProfilesClass.address = g1Wallet.address; return WalletViewScreen( - address: g1Wallet.address, - username: duniterIndexer - .walletNameIndexer[g1Wallet.address], - avatar: g1WalletsBox - .get(g1Wallet.address) - ?.avatar, - ); + address: g1Wallet.address, + username: duniterIndexer + .walletNameIndexer[g1Wallet.address]); }), ); }), diff --git a/lib/widgets/datapod_avatar.dart b/lib/widgets/datapod_avatar.dart new file mode 100644 index 0000000..a87e20b --- /dev/null +++ b/lib/widgets/datapod_avatar.dart @@ -0,0 +1,86 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/queries_datapod.dart'; +import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; +import 'package:gecko/widgets/commons/loading.dart'; +import 'package:graphql_flutter/graphql_flutter.dart'; +import 'package:provider/provider.dart'; + +class DatapodAvatar extends StatelessWidget { + const DatapodAvatar({Key? key, required this.address, this.size = 15}) + : super(key: key); + final String address; + final double size; + + @override + Widget build(BuildContext context) { + final datapod = Provider.of(context, listen: false); + + final cachedImage = File('${avatarsCacheDirectory.path}/$address'); + if (cachedImage.existsSync()) { + return ScaledSizedBox( + width: size, + child: ClipOval( + child: datapod.getAvatarLocal(address, size), + ), + ); + } + + final httpLink = HttpLink( + '$datapodEndpoint/v1/graphql', + ); + + final client = ValueNotifier( + GraphQLClient( + cache: GraphQLCache(store: HiveStore()), + link: httpLink, + ), + ); + + return ScaledSizedBox( + width: size, + child: GraphQLProvider( + client: client, + child: Query( + options: QueryOptions( + document: gql(getAvatarQ), + variables: { + 'address': address, + }, + ), + builder: (QueryResult result, {fetchMore, refetch}) { + if (result.isLoading) { + return const Center( + child: Loading(), + ); + } + final String? avatar64 = + result.data!['profiles_by_pk']?['avatar64']; + + if (avatar64 == null || result.data == null) { + return ClipOval(child: datapod.defaultAvatar(size)); + } + + final sanitizedAvatar64 = avatar64 + .replaceAll('\n', '') + .replaceAll('\r', '') + .replaceAll(' ', ''); + + datapod.cacheAvatar(address, sanitizedAvatar64); + + return ClipOval( + child: Image.memory( + base64.decode(sanitizedAvatar64), + height: size, + fit: BoxFit.fitWidth, + ), + ); + }), + ), + ); + } +} diff --git a/lib/widgets/drag_tule_action.dart b/lib/widgets/drag_tule_action.dart index 1c3e640..9e09378 100644 --- a/lib/widgets/drag_tule_action.dart +++ b/lib/widgets/drag_tule_action.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -23,9 +24,7 @@ class DragTuleAction extends StatelessWidget { delay: const Duration(milliseconds: 200), data: wallet.address, dragAnchorStrategy: (Draggable _, BuildContext __, Offset ___) => - const Offset(0, 0), - // feedbackOffset: const Offset(-500, -500), - // dragAnchorStrategy: childDragAnchorStrategy, + const Offset(55, 55), onDragStarted: () => myWalletProvider.dragAddress = wallet, onDragEnd: (_) { myWalletProvider.lastFlyBy = null; @@ -37,17 +36,15 @@ class DragTuleAction extends StatelessWidget { style: ElevatedButton.styleFrom( backgroundColor: orangeC, shape: const CircleBorder(), - padding: const EdgeInsets.all(15), + padding: EdgeInsets.all(scaleSize(14)), ), - child: const SizedBox( - height: 35, - child: Image(image: AssetImage('assets/vector_white.png')), + child: SizedBox( + height: scaleSize(33), + child: const Image(image: AssetImage('assets/vector_white.png')), ), ), child: DragTarget( onAccept: (senderAddress) async { - log.d( - 'INTERPAY: sender: $senderAddress --- receiver: ${wallet.address}'); final walletData = myWalletProvider.getWalletDataByAddress(senderAddress); await sub.setCurrentWallet(walletData!); diff --git a/lib/widgets/drag_wallets_info.dart b/lib/widgets/drag_wallets_info.dart index 6428d4a..f89aac0 100644 --- a/lib/widgets/drag_wallets_info.dart +++ b/lib/widgets/drag_wallets_info.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:provider/provider.dart'; @@ -27,19 +28,35 @@ class DragWalletsInfo extends StatelessWidget { final toName = duniterIndexer.walletNameIndexer[lastFlyBy.address] ?? lastFlyBy.name; + final mdStyle = MarkdownStyleSheet( + p: scaledTextStyle(fontSize: 16, color: Colors.black, letterSpacing: 0.3), + textAlign: WrapAlignment.spaceBetween, + ); return Container( color: yellowC, width: screenWidth, - height: 80, + height: scaleSize(85), child: Center( child: Column( children: [ - const SizedBox(height: 2), - Text('${'executeATransfer'.tr()}:'), - MarkdownBody(data: '${'from'.tr()} **$fromName**'), - if (isSameAddress) Text('chooseATargetWallet'.tr()), - if (!isSameAddress) MarkdownBody(data: 'Vers: **$toName**'), + ScaledSizedBox(height: 2), + Text( + '${'executeATransfer'.tr()}:', + style: scaledTextStyle(fontSize: 16), + ), + MarkdownBody( + data: '${'from'.tr(args: [''])} **$fromName**', + styleSheet: mdStyle), + if (isSameAddress) + Text( + 'chooseATargetWallet'.tr(), + style: scaledTextStyle(fontSize: 16), + ), + if (!isSameAddress) + MarkdownBody( + data: '${'to'.tr(args: [''])} **$toName**', + styleSheet: mdStyle), ], )), ); diff --git a/lib/widgets/drawer.dart b/lib/widgets/drawer.dart index 68bc78b..85a1140 100644 --- a/lib/widgets/drawer.dart +++ b/lib/widgets/drawer.dart @@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/debug_screen.dart'; @@ -19,82 +20,122 @@ class MainDrawer extends StatelessWidget { @override Widget build(BuildContext context) { - return Drawer( - child: Column( - children: [ - Expanded( - child: ListView(padding: EdgeInsets.zero, children: [ - const DrawerHeader( - decoration: BoxDecoration( - color: orangeC, + final listStyle = scaledTextStyle(fontSize: 15); + + return SizedBox( + width: MediaQuery.of(context).size.width * 0.67, + child: Drawer( + child: Column( + children: [ + Expanded( + child: ListView(padding: EdgeInsets.zero, children: [ + DrawerHeader( + decoration: const BoxDecoration( + color: orangeC, + ), + child: Column(children: [ + Image( + image: const AssetImage('assets/icon/gecko_final.png'), + height: scaleSize(125)), + ]), ), - child: Column(children: [ - 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(); + ScaledSizedBox(height: scaleSize(10)), + Opacity( + opacity: 0.8, + child: ListTile( + key: keyParameters, + leading: Icon(Icons.settings, size: scaleSize(25)), + dense: !isTall, + // contentPadding: + // EdgeInsets.symmetric(horizontal: scaleSize(12)), + title: Text( + 'parameters'.tr(), + style: listStyle, + ), + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return SettingsScreen(); + }), + ); + }, + ), + ), + ScaledSizedBox(height: scaleSize(4)), + if (isWalletsExists) + Opacity( + opacity: 0.8, + child: ListTile( + key: keyContacts, + leading: Icon(Icons.contacts_rounded, size: scaleSize(25)), + dense: !isTall, + title: Text( + 'contactsManagement'.tr(), + style: listStyle, + ), + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const ContactsScreen(); + }), + ); + }, + ), + ), + if (isWalletsExists) ScaledSizedBox(height: scaleSize(4)), + if (kDebugMode) + Opacity( + opacity: 0.8, + child: ListTile( + key: keyDebugScreen, + leading: + Icon(Icons.developer_mode_rounded, size: scaleSize(25)), + dense: !isTall, + title: Text( + 'Debug screen'.tr(), + style: listStyle, + ), + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return const DebugScreen(); + }), + ); + }, + ), + ), + ])), + Align( + alignment: FractionalOffset.bottomCenter, + child: InkWell( + key: keyCopyAddress, + splashColor: orangeC, + child: Padding( + padding: const EdgeInsets.all(15), + child: Opacity( + opacity: 0.8, + child: Text('Ğecko v$appVersion', + style: scaledTextStyle(fontSize: 13)), + ), + ), + onTap: () { + Clipboard.setData( + ClipboardData(text: 'Ğecko v$appVersion')); + snackMessage(context, + message: + 'Le numéro de version de Ğecko a été copié dans votre presse papier', + duration: 4); }), - ); - }, ), - if (isWalletsExists) - ListTile( - key: keyContacts, - title: Text('contactsManagement'.tr()), - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const ContactsScreen(); - }), - ); - }, - ), - if (kDebugMode) - ListTile( - key: keyDebugScreen, - title: Text('Debug screen'.tr()), - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - return const DebugScreen(); - }), - ); - }, - ), - ])), - Align( - alignment: FractionalOffset.bottomCenter, - child: InkWell( - key: keyCopyAddress, - splashColor: orangeC, - child: Padding( - padding: const EdgeInsets.all(20), - child: Text('Ğecko v$appVersion')), - onTap: () { - Clipboard.setData(ClipboardData(text: 'Ğecko v$appVersion')); - snackMessage(context, - message: - 'Le numéro de version de Ğecko a été copié dans votre presse papier', - duration: 4); - }), - ), - const SizedBox(height: 20) - ], + ScaledSizedBox(height: 15) + ], + ), ), ); } diff --git a/lib/widgets/header_profile.dart b/lib/widgets/header_profile.dart index 1337e2d..48fa47d 100644 --- a/lib/widgets/header_profile.dart +++ b/lib/widgets/header_profile.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.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/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; @@ -10,6 +10,7 @@ import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/certifications.dart'; import 'package:gecko/widgets/balance.dart'; import 'package:gecko/widgets/certifications.dart'; +import 'package:gecko/widgets/datapod_avatar.dart'; import 'package:gecko/widgets/commons/offline_info.dart'; import 'package:gecko/widgets/idty_status.dart'; import 'package:gecko/widgets/page_route_no_transition.dart'; @@ -27,7 +28,7 @@ class HeaderProfile extends StatelessWidget { @override Widget build(BuildContext context) { - const double avatarSize = 140; + final avatarSize = scaleSize(110); final duniterIndexer = Provider.of(context, listen: false); final walletOptions = Provider.of(context, listen: false); @@ -37,7 +38,7 @@ class HeaderProfile extends StatelessWidget { Consumer(builder: (context, sub, _) { bool isAccountExist = walletOptions.balanceCache[address] != 0; return Container( - height: 185, + height: scaleSize(160), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, @@ -50,13 +51,13 @@ class HeaderProfile extends StatelessWidget { )); }), Padding( - padding: const EdgeInsets.only(left: 30, right: 40), + padding: EdgeInsets.only(left: scaleSize(19), right: scaleSize(19)), child: Row(children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - height: 10, + height: 5, color: yellowC, ), Row(children: [ @@ -68,16 +69,17 @@ class HeaderProfile extends StatelessWidget { }, child: Text( getShortPubkey(address), - style: const TextStyle( - fontSize: 30, - fontWeight: FontWeight.w800, + style: scaledTextStyle( + fontSize: 23, + fontFamily: 'Monospace', + fontWeight: FontWeight.w900, ), ), ), ]), - const SizedBox(height: 18), - Balance(address: address, size: 25), - const SizedBox(height: 5), + ScaledSizedBox(height: 15), + Balance(address: address, size: 20), + ScaledSizedBox(height: 5), InkWell( onTap: () => sub.certsCounterCache[address] != null ? { @@ -100,16 +102,16 @@ class HeaderProfile extends StatelessWidget { address: address, isOwner: false, color: Colors.black), - Certifications(address: address, size: 19) + Certifications(address: address, size: 18) ], ), ), ]), const Spacer(), + // ScaledSizedBox(width: 20), Column(children: [ - ClipOval( - child: defaultAvatar(avatarSize), - ), + ScaledSizedBox(height: 15), + DatapodAvatar(address: address, size: avatarSize), ]), ]), ), diff --git a/lib/widgets/history_query.dart b/lib/widgets/history_query.dart index f4ae02b..e13adb0 100644 --- a/lib/widgets/history_query.dart +++ b/lib/widgets/history_query.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/queries_indexer.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/widgets/history_view.dart'; @@ -24,11 +25,11 @@ class HistoryQuery extends StatelessWidget { if (indexerEndpoint == '') { return Column(children: [ - const SizedBox(height: 50), + ScaledSizedBox(height: 50), Text( "noNetworkNoHistory".tr(), textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 18), ) ]); } @@ -72,20 +73,20 @@ class HistoryQuery extends StatelessWidget { if (result.hasException) { log.e('Error Indexer: ${result.exception}'); return Column(children: [ - const SizedBox(height: 50), + ScaledSizedBox(height: 50), Text( "noNetworkNoHistory".tr(), textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 18), ) ]); } else if (result .data?['transaction_connection']?['edges'].isEmpty) { return Column(children: [ - const SizedBox(height: 50), + ScaledSizedBox(height: 50), Text( "noDataToDisplay".tr(), - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 18), ) ]); } @@ -93,8 +94,6 @@ class HistoryQuery extends StatelessWidget { if (result.isNotLoading) { if (duniterIndexer.fetchMoreCursor == null) nPage = 1; - // log.d('nPage: $nPage'); - if (nPage <= 3) { nRepositories = 20; } else if (nPage <= 6) { diff --git a/lib/widgets/history_view.dart b/lib/widgets/history_view.dart index b17a9d9..7b8fb6c 100644 --- a/lib/widgets/history_view.dart +++ b/lib/widgets/history_view.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/wallet_view.dart'; @@ -24,16 +25,16 @@ class HistoryView extends StatelessWidget { final sub = Provider.of(homeContext, listen: false); int keyID = 0; - const double avatarSize = 200; + const double avatarSize = 50; bool isMigrationPassed = false; List pastDelimiters = []; return duniterIndexer.transBC == null ? Column(children: [ - const SizedBox(height: 50), + ScaledSizedBox(height: 50), Text( "noTransactionToDisplay".tr(), - style: const TextStyle(fontSize: 18), + style: scaledTextStyle(fontSize: 18), ) ]) : Column(children: [ @@ -51,23 +52,23 @@ class HistoryView extends StatelessWidget { return Column(children: [ if (isMigrationTime) Padding( - padding: const EdgeInsets.symmetric(vertical: 30), + padding: EdgeInsets.symmetric(vertical: scaleSize(23)), child: Row( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - const Image( - image: AssetImage('assets/party.png'), height: 40), - const SizedBox(width: 40), + Image( + image: const AssetImage('assets/party.png'), + height: scaleSize(32)), Text( 'blockchainStart'.tr(), - style: const TextStyle( - fontSize: 25, + style: scaledTextStyle( + fontSize: 20, color: Colors.blueAccent, fontWeight: FontWeight.w500), ), - const SizedBox(width: 40), - const Image( - image: AssetImage('assets/party.png'), height: 40), + Image( + image: const AssetImage('assets/party.png'), + height: scaleSize(32)), ], ), ), @@ -76,11 +77,11 @@ class HistoryView extends StatelessWidget { !(pastDelimiters[pastDelimiters.length - 2] == answer['dateDelimiter'])) Padding( - padding: const EdgeInsets.symmetric(vertical: 30), + padding: const EdgeInsets.symmetric(vertical: 20), child: Text( answer['dateDelimiter'], - style: const TextStyle( - fontSize: 23, + style: scaledTextStyle( + fontSize: 20, color: orangeC, fontWeight: FontWeight.w300), ), @@ -117,30 +118,32 @@ class HistoryView extends StatelessWidget { }), ), child: Row( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - const Icon( + Icon( Icons.account_circle, size: 40, - color: Colors.blueAccent, + color: Colors.green[700], ), - const SizedBox(width: 40), Column(children: [ Text( 'Identité migré:'.tr(), - style: const TextStyle( - fontSize: 25, - color: Colors.blueAccent, + style: scaledTextStyle( + fontSize: 20, + color: Colors.green[700], fontWeight: FontWeight.w500), ), Text( - 'Ancienne adresse: ${getShortPubkey(sub.oldOwnerKeys[address]![0])}') + 'from'.tr(args: [ + ' ${getShortPubkey(sub.oldOwnerKeys[address]![0])}' + ]), + style: scaledTextStyle(fontSize: 17), + ), ]), - const SizedBox(width: 40), - const Icon( + Icon( Icons.account_circle, - size: 40, - color: Colors.blueAccent, + size: scaleSize(32), + color: Colors.green[700], ), ], ), @@ -149,11 +152,11 @@ class HistoryView extends StatelessWidget { if (!duniterIndexer.pageInfo!['hasNextPage']) Column( children: [ - const SizedBox(height: 15), + ScaledSizedBox(height: 15), Text("historyStart".tr(), textAlign: TextAlign.center, - style: const TextStyle(fontSize: 20)), - const SizedBox(height: 15) + style: scaledTextStyle(fontSize: 20)), + ScaledSizedBox(height: 15) ], ) ]); diff --git a/lib/widgets/idty_status.dart b/lib/widgets/idty_status.dart index 4e5339d..65dd65c 100644 --- a/lib/widgets/idty_status.dart +++ b/lib/widgets/idty_status.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/widgets/commons/animated_text.dart'; @@ -35,14 +36,14 @@ class IdentityStatus extends StatelessWidget { if (resStatus == IdtyStatus.confirmed) { return NameByAddress( wallet: WalletData(address: address), - size: 20, + size: 18, color: Colors.grey[700]!, fontWeight: FontWeight.w500, fontStyle: FontStyle.italic); } else if (resStatus == IdtyStatus.validated) { return NameByAddress( wallet: WalletData(address: address), - size: 22, + size: 20, color: Colors.black, fontWeight: FontWeight.w600, fontStyle: FontStyle.normal); @@ -60,7 +61,7 @@ class IdentityStatus extends StatelessWidget { return SizedBox( child: showText(statusText[resStatus]!, - bold: resStatus == IdtyStatus.validated ? true : false), + bold: resStatus == IdtyStatus.validated, size: scaleSize(17)), ); }); }); @@ -68,7 +69,6 @@ class IdentityStatus extends StatelessWidget { AnimatedFadeOutIn showText(String text, {double size = 18, bool bold = false}) { - // log.d('$address $text'); return AnimatedFadeOutIn( data: text, duration: const Duration(milliseconds: 150), diff --git a/lib/widgets/name_by_address.dart b/lib/widgets/name_by_address.dart index bf9c036..763c225 100644 --- a/lib/widgets/name_by_address.dart +++ b/lib/widgets/name_by_address.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/queries_indexer.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/widgets/wallet_name.dart'; @@ -87,7 +88,7 @@ class NameByAddress extends StatelessWidget { ? '(${duniterIndexer.walletNameIndexer[wallet.address]!})' : truncate( duniterIndexer.walletNameIndexer[wallet.address]!, 20), - style: TextStyle( + style: scaledTextStyle( fontSize: size, color: color, fontWeight: fontWeight, diff --git a/lib/widgets/payment_popup.dart b/lib/widgets/payment_popup.dart index b18fbf0..3945cac 100644 --- a/lib/widgets/payment_popup.dart +++ b/lib/widgets/payment_popup.dart @@ -4,6 +4,7 @@ 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/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -32,9 +33,8 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { walletViewProvider.payAmount.text = ''; Future executeTransfert() async { - String? pin; if (myWalletProvider.pinCode == '') { - pin = await Navigator.push( + await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { @@ -43,26 +43,26 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { ), ); } - log.d(pin); - if (pin != null || myWalletProvider.pinCode != '') { - // Payment workflow ! - final sub = Provider.of(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 TransactionInProgress( - toAddress: toAddress, toUsername: username); - }), - ); - } + if (myWalletProvider.pinCode == '') return; + // Payment workflow ! + final sub = Provider.of(context, listen: false); + final acc = sub.getCurrentWallet(); + log.d( + "fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}"); + final transactionId = await sub.pay( + fromAddress: acc.address!, + destAddress: toAddress, + amount: double.parse(walletViewProvider.payAmount.text), + password: myWalletProvider.pinCode); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + return TransactionInProgress( + transactionId: transactionId, + toAddress: toAddress, + toUsername: username); + }), + ); } myWalletProvider.readAllWallets().then((value) => myWalletProvider.listWallets @@ -105,7 +105,7 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom), child: Container( - height: 420, + height: scaleSize(400), decoration: const ShapeDecoration( color: Color(0xffffeed1), shape: RoundedRectangleBorder( @@ -116,8 +116,11 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { ), ), child: Padding( - padding: const EdgeInsets.only( - top: 24, bottom: 0, left: 24, right: 24), + padding: EdgeInsets.only( + top: scaleSize(14), + bottom: 0, + left: scaleSize(16), + right: scaleSize(16)), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -127,125 +130,137 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { children: [ Text( 'executeATransfer'.tr(), - style: const TextStyle( - fontSize: 26, fontWeight: FontWeight.w700), + style: scaledTextStyle( + fontSize: 20, fontWeight: FontWeight.w700), ), IconButton( key: keyPopButton, - iconSize: 40, + iconSize: scaleSize(32), icon: const Icon(Icons.cancel_outlined), onPressed: () { Navigator.pop(context); }, ), ]), - const SizedBox(height: 5), + ScaledSizedBox(height: 5), Text( - 'from'.tr(), - style: TextStyle( - fontSize: 19, + 'from'.tr(args: ['']), + style: scaledTextStyle( + fontSize: 16, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), - const SizedBox(height: 5), + ScaledSizedBox(height: 5), Consumer(builder: (context, sub, _) { - return DropdownButton( - dropdownColor: const Color(0xffffeed1), - elevation: 12, - key: keyDropdownWallets, - value: defaultWallet, - menuMaxHeight: 300, - onTap: () { - FocusScope.of(context).requestFocus(amountFocus); - }, - selectedItemBuilder: (_) { - return myWalletProvider.listWallets + return Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.blueAccent.shade200, width: 2), + borderRadius: + const BorderRadius.all(Radius.circular(10)), + ), + alignment: Alignment.center, + padding: const EdgeInsets.all(0), + child: DropdownButton( + dropdownColor: const Color(0xffffeed1), + elevation: 12, + key: keyDropdownWallets, + value: defaultWallet, + menuMaxHeight: scaleSize(270), + onTap: () { + FocusScope.of(context) + .requestFocus(amountFocus); + }, + selectedItemBuilder: (_) { + return myWalletProvider.listWallets + .map((WalletData wallet) { + return Container( + width: scaleSize(isTall ? 315 : 310), + padding: EdgeInsets.all(scaleSize(7)), + child: Visibility( + visible: wallet.address == + defaultWallet.address, + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + NameByAddress( + wallet: wallet, + fontStyle: FontStyle.normal, + size: 18, + ), + const Spacer(), + // const Text('data') + Balance( + address: wallet.address, + size: 18), + ]), + ), + ); + }).toList(); + }, + onChanged: (WalletData? newSelectedWallet) async { + defaultWallet = newSelectedWallet!; + await sub.setCurrentWallet(newSelectedWallet); + sub.reload(); + amountFocus.requestFocus(); + setState(() {}); + }, + items: 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(7), - child: Visibility( - visible: - wallet.address == defaultWallet.address, - child: Row(children: [ - NameByAddress( - wallet: wallet, - fontStyle: FontStyle.normal), - const Spacer(), - Balance( - address: wallet.address, size: 20), - ]), + return DropdownMenuItem( + value: wallet, + key: keySelectThisWallet(wallet.address), + child: Container( + color: const Color(0xffffeed1), + width: scaleSize(isTall ? 315 : 310), + padding: const EdgeInsets.all(10), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + NameByAddress( + wallet: wallet, + fontStyle: FontStyle.normal, + size: 18, + ), + const Spacer(), + Balance( + address: wallet.address, + size: 18), + ]), ), ); - }).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, - key: keySelectThisWallet(wallet.address), - child: Container( - color: const Color(0xffffeed1), - width: 408, - height: 80, - padding: const EdgeInsets.all(7), - child: Row(children: [ - NameByAddress( - wallet: wallet, - fontStyle: FontStyle.normal), - const Spacer(), - Balance(address: wallet.address, size: 20), - ]), - ), - ); - }).toList()); + }).toList()), + ); }), - const SizedBox(height: 12), + ScaledSizedBox(height: 12), Row( children: [ Text( - 'to'.tr(), - style: TextStyle( - fontSize: 19, + 'to'.tr(args: ['']), + style: scaledTextStyle( + fontSize: 16, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), - const SizedBox(width: 10), - Column( - children: [ - const SizedBox(height: 2), - Text( - username ?? getShortPubkey(toAddress), - style: const TextStyle( - fontSize: 21, - fontWeight: FontWeight.w600, - ), - ), - ], + ScaledSizedBox(width: 10), + Text( + username ?? getShortPubkey(toAddress), + style: scaledTextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), ), ], ), - const SizedBox(height: 7), + ScaledSizedBox(height: 7), Row( children: [ Text( 'amount'.tr(), - style: TextStyle( - fontSize: 19, + style: scaledTextStyle( + fontSize: 16, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), @@ -254,24 +269,25 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { onTap: () => infoFeesPopup(context), child: Row( children: [ - const Icon(Icons.info_outlined, color: orangeC), - const SizedBox(width: 5), + Icon(Icons.info_outlined, + color: orangeC, size: scaleSize(21)), + ScaledSizedBox(width: 5), Text( 'fees'.tr( args: [fees.toString(), currencyName]), - style: const TextStyle( + style: scaledTextStyle( color: orangeC, - fontSize: 17, + fontSize: 14, fontWeight: FontWeight.w500, ), ), ], ), ), - const SizedBox(width: 10), + ScaledSizedBox(width: 10), ], ), - const SizedBox(height: 10), + ScaledSizedBox(height: 10), Focus( onFocusChange: (focused) { setState(() { @@ -299,7 +315,6 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { walletViewProvider.payAmount.text == '' ? '0' : walletViewProvider.payAmount.text)); - log.d(fees); setState(() {}); }, inputFormatters: [ @@ -310,9 +325,8 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { ], decoration: InputDecoration( hintText: '0.00', - suffix: Text(isUdUnit - ? 'ud'.tr(args: ['']) - : currencyName), // udUnitDisplay(40), + suffix: Text( + isUdUnit ? 'ud'.tr(args: ['']) : currencyName), filled: true, fillColor: Colors.transparent, focusedBorder: OutlineInputBorder( @@ -320,24 +334,25 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { color: Colors.grey[500]!, width: 2), borderRadius: BorderRadius.circular(8), ), - contentPadding: const EdgeInsets.all(15), + contentPadding: EdgeInsets.all(scaleSize(9)), ), - style: const TextStyle( - fontSize: 33, + style: scaledTextStyle( + fontSize: 25, color: Colors.black, fontWeight: FontWeight.w600, ), ), ), const Spacer(), - SizedBox( + ScaledSizedBox( width: double.infinity, - height: 60, + height: 55, child: ElevatedButton( key: keyConfirmPayment, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, - backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, + elevation: 4, + backgroundColor: orangeC, ), onPressed: canValidate ? () async { @@ -347,8 +362,8 @@ void paymentPopup(BuildContext context, String toAddress, String? username) { : null, child: Text( 'executeTheTransfer'.tr(), - style: const TextStyle( - fontSize: 20, fontWeight: FontWeight.w600), + style: scaledTextStyle( + fontSize: 18, fontWeight: FontWeight.w600), ), ), ), @@ -373,19 +388,19 @@ Future infoFeesPopup(BuildContext context) async { mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.info_outlined, color: orangeC, size: 40), - const SizedBox(height: 20), + ScaledSizedBox(height: 20), Text( 'feesExplanation'.tr(), textAlign: TextAlign.center, - style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), + style: scaledTextStyle(fontSize: 20, fontWeight: FontWeight.w500), ), - const SizedBox(height: 30), + ScaledSizedBox(height: 30), Text( 'feesExplanationDetails'.tr(), textAlign: TextAlign.center, - style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w300), + style: scaledTextStyle(fontSize: 18, fontWeight: FontWeight.w300), ), - const SizedBox(height: 5), + ScaledSizedBox(height: 5), InkWell( onTap: () async => await _launchUrl('https://duniter.org'), child: Container( @@ -401,7 +416,7 @@ Future infoFeesPopup(BuildContext context) async { child: Text( 'moreInfo'.tr(), textAlign: TextAlign.center, - style: const TextStyle( + style: scaledTextStyle( fontSize: 18, fontWeight: FontWeight.w300, color: Colors.blueAccent, @@ -422,9 +437,9 @@ Future infoFeesPopup(BuildContext context) async { padding: const EdgeInsets.all(8), child: Text( 'gotit'.tr(), - style: const TextStyle( + style: scaledTextStyle( fontSize: 21, - color: Color(0xffD80000), + color: const Color(0xffD80000), ), ), ), diff --git a/lib/widgets/scan_derivations_info.dart b/lib/widgets/scan_derivations_info.dart new file mode 100644 index 0000000..daa0fcf --- /dev/null +++ b/lib/widgets/scan_derivations_info.dart @@ -0,0 +1,62 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; +import 'package:gecko/providers/generate_wallets.dart'; +import 'package:provider/provider.dart'; + +class ScanDerivationsInfo extends StatelessWidget { + const ScanDerivationsInfo({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final generateWalletProvider = + Provider.of(context); + return Visibility( + visible: generateWalletProvider.scanStatus != ScanDerivationsStatus.none, + child: Padding( + padding: const EdgeInsets.only(bottom: 15), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (generateWalletProvider.scanStatus == + ScanDerivationsStatus.rootScanning) + Text( + 'scanRootDerivationInProgress'.tr(), + style: scaledTextStyle(fontSize: 16), + ), + if (generateWalletProvider.scanStatus == + ScanDerivationsStatus.scanning) + Text( + 'derivationsScanProgress' + .tr(args: [generateWalletProvider.numberScan.toString()]), + style: scaledTextStyle(fontSize: 16), + ), + if (generateWalletProvider.scanStatus == + ScanDerivationsStatus.import) + Text( + "importDerivationsInProgress".tr(args: [ + '${generateWalletProvider.scanedWalletNumber}', + '${generateWalletProvider.scanedValidWalletNumber}' + ]), + style: scaledTextStyle(fontSize: 16), + ), + ScaledSizedBox(width: 10), + ScaledSizedBox( + height: 22, + width: 22, + child: CircularProgressIndicator( + color: orangeC, + strokeWidth: scaleSize(3), + ), + ), + ], + ), + ), + ); + } +} + +enum ScanDerivationsStatus { none, rootScanning, scanning, import } diff --git a/lib/widgets/search_identity_query.dart b/lib/widgets/search_identity_query.dart index 8e6ddb8..9403cac 100644 --- a/lib/widgets/search_identity_query.dart +++ b/lib/widgets/search_identity_query.dart @@ -3,14 +3,15 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/queries_indexer.dart'; +import 'package:gecko/models/scale_functions.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/search.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/balance.dart'; +import 'package:gecko/widgets/datapod_avatar.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:provider/provider.dart'; @@ -28,7 +29,6 @@ class SearchIdentityQuery extends StatelessWidget { return Text('noResult'.tr()); } - log.d(indexerEndpoint); final httpLink = HttpLink( '$indexerEndpoint/v1/graphql', ); @@ -44,12 +44,10 @@ class SearchIdentityQuery extends StatelessWidget { client: client, child: Query( options: QueryOptions( - document: gql( - searchAddressByNameQ), // this is the query string you just created + document: gql(searchAddressByNameQ), variables: { 'name': name, }, - // pollInterval: const Duration(seconds: 10), ), builder: (QueryResult result, {VoidCallback? refetch, FetchMore? fetchMore}) { @@ -76,62 +74,58 @@ class SearchIdentityQuery extends StatelessWidget { searchProvider.resultLenght = identities.length; - double avatarSize = 55; + final avatarSize = scaleSize(45); return Expanded( child: ListView(children: [ for (Map profile in identities) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 5), - child: ListTile( - key: keySearchResult(profile['pubkey']), - horizontalTitleGap: 40, - contentPadding: const EdgeInsets.all(5), - leading: defaultAvatar(avatarSize), - title: Row(children: [ - Text(getShortPubkey(profile['pubkey']), - style: const TextStyle( - fontSize: 18, - fontFamily: 'Monospace', - fontWeight: FontWeight.w500), - textAlign: TextAlign.center), - ]), - trailing: SizedBox( - width: 110, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Balance( - address: profile['pubkey'], size: 16), - ]), - ]), - ), - subtitle: Row(children: [ - Text(profile['name'] ?? '', - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w500), - textAlign: TextAlign.center), - ]), - dense: false, - isThreeLine: false, - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - walletsProfiles.address = profile['pubkey']; - return WalletViewScreen( - address: profile['pubkey'], - username: profile['name'], - avatar: - g1WalletsBox.get(profile['pubkey'])?.avatar, - ); - }), - ); - }), - ), + ListTile( + key: keySearchResult(profile['pubkey']), + horizontalTitleGap: 10, + contentPadding: const EdgeInsets.only(right: 2), + leading: DatapodAvatar( + address: profile['pubkey'], size: avatarSize), + title: Row(children: [ + Text(getShortPubkey(profile['pubkey']), + style: scaledTextStyle( + fontSize: 16, + fontFamily: 'Monospace', + fontWeight: FontWeight.w500), + textAlign: TextAlign.center), + ]), + trailing: ScaledSizedBox( + width: 120, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Balance( + address: profile['pubkey'], size: 15), + ]), + ]), + ), + subtitle: Row(children: [ + Text(profile['name'] ?? '', + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w500), + textAlign: TextAlign.center), + ]), + dense: !isTall, + isThreeLine: false, + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + walletsProfiles.address = profile['pubkey']; + return WalletViewScreen( + address: profile['pubkey'], + username: profile['name'], + ); + }), + ); + }), ]), ); }), diff --git a/lib/widgets/search_result_list.dart b/lib/widgets/search_result_list.dart index 9a09db8..0726605 100644 --- a/lib/widgets/search_result_list.dart +++ b/lib/widgets/search_result_list.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.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/search.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/balance.dart'; +import 'package:gecko/widgets/datapod_avatar.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:gecko/widgets/search_identity_query.dart'; @@ -36,12 +37,11 @@ class SearchResult extends StatelessWidget { if (snapshot.data?.isEmpty ?? true) { return SearchIdentityQuery( name: searchProvider.searchController.text); - // const Text('Aucun résultat'); } else { return Expanded( child: ListView(children: [ for (G1WalletsList g1Wallet in snapshot.data ?? []) - resultTile(g1Wallet, context), + resultTileAddressSearch(g1Wallet, context), ]), ); } @@ -58,54 +58,50 @@ class SearchResult extends StatelessWidget { ); } - Padding resultTile(G1WalletsList g1Wallet, BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 5), - child: ListTile( - key: keySearchResult(g1Wallet.address), - horizontalTitleGap: 40, - contentPadding: const EdgeInsets.all(5), - leading: defaultAvatar(avatarSize), - title: Row(children: [ - Text(getShortPubkey(g1Wallet.address), - style: const TextStyle( - fontSize: 18, - fontFamily: 'Monospace', - fontWeight: FontWeight.w500), - textAlign: TextAlign.center), - ]), - trailing: + Widget resultTileAddressSearch(G1WalletsList g1Wallet, BuildContext context) { + return ListTile( + key: keySearchResult(g1Wallet.address), + horizontalTitleGap: 10, + contentPadding: const EdgeInsets.all(5), + leading: DatapodAvatar(address: g1Wallet.address, size: avatarSize), + title: Row(children: [ + Text(getShortPubkey(g1Wallet.address), + style: scaledTextStyle( + fontSize: 18, + fontFamily: 'Monospace', + fontWeight: FontWeight.w500), + textAlign: TextAlign.center), + ]), + trailing: + Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + ScaledSizedBox( + width: 110, + child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [ Column(mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - width: 110, - child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [ - Column(mainAxisAlignment: MainAxisAlignment.center, children: [ - Balance(address: g1Wallet.address, size: 16), - ]), + Balance(address: g1Wallet.address, size: 15), ]), - ), - ]), - subtitle: Row(children: [ - NameByAddress( - wallet: WalletData(address: g1Wallet.address), - ), - ]), - dense: false, - isThreeLine: false, - onTap: () { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute(builder: (context) { - walletsProfilesClass.address = g1Wallet.address; - return WalletViewScreen( - address: g1Wallet.address, - username: g1Wallet.username, - avatar: g1Wallet.avatar, - ); - }), - ); - }), - ); + ]), + ), + ]), + subtitle: Row(children: [ + NameByAddress( + wallet: WalletData(address: g1Wallet.address), + ), + ]), + dense: false, + isThreeLine: false, + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) { + walletsProfilesClass.address = g1Wallet.address; + return WalletViewScreen( + address: g1Wallet.address, + username: g1Wallet.username, + ); + }), + ); + }); } } diff --git a/lib/widgets/transaction_tile.dart b/lib/widgets/transaction_tile.dart index 86b79c4..2c1ae91 100644 --- a/lib/widgets/transaction_tile.dart +++ b/lib/widgets/transaction_tile.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.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/substrate_sdk.dart'; +import 'package:gecko/providers/v2s_datapod.dart'; import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/page_route_no_transition.dart'; @@ -36,52 +38,50 @@ class TransactionTile extends StatelessWidget { child: ListTile( key: keyTransaction(newKey), contentPadding: - const EdgeInsets.only(left: 20, right: 30, top: 15, bottom: 15), + const EdgeInsets.symmetric(horizontal: 15, vertical: 5), leading: ClipOval( - child: defaultAvatar(avatarSize), + child: V2sDatapodProvider().defaultAvatar(avatarSize), ), title: Padding( padding: const EdgeInsets.only(bottom: 5), child: Text(getShortPubkey(repository[1]), - style: const TextStyle(fontSize: 18, fontFamily: 'Monospace')), + style: scaledTextStyle(fontSize: 17, fontFamily: 'Monospace')), ), subtitle: RichText( text: TextSpan( - style: TextStyle( + style: scaledTextStyle( fontSize: 17, color: Colors.grey[700], ), children: [ - TextSpan( - text: dateForm, - ), + TextSpan(text: dateForm, style: scaledTextStyle(fontSize: 16)), if (username != null) TextSpan( text: ' · ', - style: TextStyle( - fontSize: 25, + style: scaledTextStyle( + fontSize: 21, color: Colors.grey[550], ), ), TextSpan( text: username, - style: TextStyle( + style: scaledTextStyle( fontStyle: FontStyle.italic, color: Colors.grey[600], - fontSize: 19), + fontSize: 16), ), ], ), ), trailing: Text(finalAmount, - style: TextStyle( - fontSize: 18, + style: scaledTextStyle( + fontSize: 17, fontWeight: FontWeight.w500, color: repository[4] == 'RECEIVED' ? Colors.green[700] : Colors.blue[700]), textAlign: TextAlign.justify), - dense: false, + dense: !isTall, isThreeLine: false, onTap: () { Navigator.push( @@ -93,7 +93,6 @@ class TransactionTile extends StatelessWidget { ); }), ); - // Navigator.pop(context); }), ); } diff --git a/lib/widgets/ud_unit_display.dart b/lib/widgets/ud_unit_display.dart index 942b155..da0c375 100644 --- a/lib/widgets/ud_unit_display.dart +++ b/lib/widgets/ud_unit_display.dart @@ -21,15 +21,14 @@ class UdUnitDisplay extends StatelessWidget { children: [ Text( 'ud'.tr(args: ['']), - style: TextStyle( - fontSize: isTall ? size : size * 0.9, color: color), + style: TextStyle(fontSize: size, color: color), ), Column( children: [ Text( currencyName, style: TextStyle( - fontSize: (isTall ? size : size * 0.9) * 0.7, + fontSize: size * 0.7, fontWeight: FontWeight.w500, color: color), ), @@ -38,8 +37,6 @@ class UdUnitDisplay extends StatelessWidget { ) ], ) - : Text(currencyName, - style: - TextStyle(fontSize: isTall ? size : size * 0.9, color: color)); + : Text(currencyName, style: TextStyle(fontSize: size, color: color)); } } diff --git a/lib/widgets/wallet_name.dart b/lib/widgets/wallet_name.dart index b1a2b63..c5b0a23 100644 --- a/lib/widgets/wallet_name.dart +++ b/lib/widgets/wallet_name.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:truncate/truncate.dart'; @@ -16,14 +16,12 @@ class WalletName extends StatelessWidget { @override Widget build(BuildContext context) { - double newSize = (wallet.name?.length ?? 0) <= 15 ? size : size - 2; - return Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Text( truncate(wallet.name ?? '', 20), textAlign: TextAlign.center, - style: TextStyle( - fontSize: isTall ? newSize : newSize * 0.9, + style: scaledTextStyle( + fontSize: size, color: color, fontWeight: FontWeight.w400, fontStyle: FontStyle.italic, diff --git a/lib/widgets/wallet_tile.dart b/lib/widgets/wallet_tile.dart index a5f6a3b..be56ef8 100644 --- a/lib/widgets/wallet_tile.dart +++ b/lib/widgets/wallet_tile.dart @@ -1,9 +1,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.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/v2s_datapod.dart'; import 'package:gecko/screens/myWallets/wallet_options.dart'; import 'package:gecko/widgets/balance.dart'; import 'package:gecko/widgets/commons/smooth_transition.dart'; @@ -23,8 +25,10 @@ class WalletTile extends StatelessWidget { final myWalletProvider = Provider.of(context); final defaultWallet = myWalletProvider.getDefaultWallet(); + repository.getDatapodAvatar(); + return Padding( - padding: const EdgeInsets.all(16), + padding: EdgeInsets.all(scaleSize(11)), child: GestureDetector( key: keyOpenWallet(repository.address), onTap: () { @@ -37,7 +41,7 @@ class WalletTile extends StatelessWidget { ), ); }, - child: SizedBox( + child: ScaledSizedBox( key: repository.number == 1 ? keyDragAndDrop : const Key('nothing'), child: ClipOvalShadow( shadow: const Shadow( @@ -49,39 +53,41 @@ class WalletTile extends StatelessWidget { child: ClipRRect( borderRadius: const BorderRadius.all(Radius.circular(12)), child: Column(children: [ - 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, - ], + Expanded(child: Consumer( + builder: (context, datapod, _) { + return Container( + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + gradient: RadialGradient( + radius: 0.8, + colors: [ + Color.fromARGB(255, 255, 255, 211), + yellowC, + ], + ), ), - ), - child: 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: 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: [ BalanceBuilder( address: repository.address, @@ -91,12 +97,12 @@ class WalletTile extends StatelessWidget { children: [ Column( children: [ - const SizedBox(height: 7), + ScaledSizedBox(height: 5), Opacity( opacity: 0.7, child: NameByAddress( wallet: repository, - size: 20, + size: 16, color: defaultWallet.address == repository.address ? Colors.white @@ -135,7 +141,7 @@ class BalanceBuilder extends StatelessWidget { color: isDefault ? orangeC : yellowC, child: Padding( padding: - const EdgeInsets.only(left: 5, right: 5, top: 38, bottom: 10), + EdgeInsets.only(left: 5, right: 5, top: scaleSize(28), bottom: 6), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -143,7 +149,7 @@ class BalanceBuilder extends StatelessWidget { opacity: 0.7, child: Balance( address: address, - size: 16, + size: 14, color: isDefault ? Colors.white : Colors.black, loadingColor: isDefault ? yellowC : orangeC), ) diff --git a/lib/widgets/wallet_tile_membre.dart b/lib/widgets/wallet_tile_membre.dart index aebb95a..463aab3 100644 --- a/lib/widgets/wallet_tile_membre.dart +++ b/lib/widgets/wallet_tile_membre.dart @@ -1,9 +1,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/scale_functions.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/v2s_datapod.dart'; import 'package:gecko/screens/myWallets/wallet_options.dart'; import 'package:gecko/widgets/balance.dart'; import 'package:gecko/widgets/certifications.dart'; @@ -21,8 +23,12 @@ class WalletTileMembre extends StatelessWidget { Widget build(BuildContext context) { final myWalletProvider = Provider.of(context); final defaultWallet = myWalletProvider.getDefaultWallet(); + + repository.getDatapodAvatar(); + return Padding( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 20), + padding: EdgeInsets.symmetric( + horizontal: scaleSize(52), vertical: scaleSize(15)), child: GestureDetector( key: keyOpenWallet(repository.address), onTap: () { @@ -35,9 +41,9 @@ class WalletTileMembre extends StatelessWidget { ), ); }, - child: SizedBox( + child: ScaledSizedBox( key: repository.number == 1 ? keyDragAndDrop : const Key('nothing'), - height: 240, + height: 180, child: ClipOvalShadow( shadow: const Shadow( color: Colors.transparent, @@ -51,45 +57,48 @@ class WalletTileMembre extends StatelessWidget { Expanded( child: Stack( children: [ - Container( - width: double.infinity, - height: double.infinity, - decoration: const BoxDecoration( - gradient: RadialGradient( - radius: 0.8, - colors: [ - Color.fromARGB(255, 255, 255, 211), - yellowC, - ], + Consumer( + builder: (context, datapod, _) { + return Container( + width: double.infinity, + height: double.infinity, + decoration: const BoxDecoration( + gradient: RadialGradient( + radius: 0.8, + colors: [ + Color.fromARGB(255, 255, 255, 211), + yellowC, + ], + ), ), - ), - child: 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: 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!), + ), ), ), ), - ), - ), + ); + }), Positioned( - left: 25, - top: 25, + left: 20, + top: 20, child: Opacity( - opacity: 0.6, + opacity: 0.8, child: Image.asset('assets/medal.png', - color: Colors.black, height: 40), + color: orangeC, height: scaleSize(33)), ), ), ], @@ -101,12 +110,12 @@ class WalletTileMembre extends StatelessWidget { isDefault: repository.address == defaultWallet.address), Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Column(children: [ - const SizedBox(height: 10), + ScaledSizedBox(height: 5), Opacity( opacity: 0.7, child: NameByAddress( wallet: repository, - size: 20, + size: 18, color: defaultWallet.address == repository.address ? Colors.white : Colors.black, @@ -116,8 +125,8 @@ class WalletTileMembre extends StatelessWidget { ]), ]), Positioned( - right: 25, - top: 25, + right: scaleSize(12), + top: scaleSize(18), child: Opacity( opacity: 0.7, child: Certifications( @@ -125,7 +134,7 @@ class WalletTileMembre extends StatelessWidget { color: defaultWallet.address == repository.address ? Colors.white : Colors.black, - size: 18), + size: 15), ), ), ]), @@ -154,8 +163,8 @@ class BalanceBuilder extends StatelessWidget { width: double.infinity, color: isDefault ? orangeC : yellowC, child: Padding( - padding: - const EdgeInsets.only(left: 5, right: 5, top: 45, bottom: 15), + padding: EdgeInsets.only( + left: 5, right: 5, top: scaleSize(27), bottom: scaleSize(11)), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -163,7 +172,7 @@ class BalanceBuilder extends StatelessWidget { opacity: 0.7, child: Balance( address: address, - size: 16, + size: 15, color: isDefault ? Colors.white : Colors.black, loadingColor: isDefault ? yellowC : orangeC), ) diff --git a/pubspec.lock b/pubspec.lock index 749b434..8c5434f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: archive - sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" url: "https://pub.dev" source: hosted - version: "3.4.9" + version: "3.4.10" args: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: barcode - sha256: "789f898eef0bd88312470bdb2cc996f895ad7dd5f89e9adde84b204546a90b45" + sha256: "2a8b2ee065f419c2aeda141436cc556d91ae772d220fd80679f4d431d6c2ab43" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.5" barcode_scan2: dependency: "direct main" description: @@ -173,18 +173,18 @@ packages: dependency: transitive description: name: build_resolvers - sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.7" build_runner_core: dependency: transitive description: @@ -205,10 +205,10 @@ packages: dependency: transitive description: name: built_value - sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2" + sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 url: "https://pub.dev" source: hosted - version: "8.8.0" + version: "8.8.1" carousel_slider: dependency: "direct main" description: @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: code_builder - sha256: b2151ce26a06171005b379ecff6e08d34c470180ffe16b8e14b6d52be292b55f + sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.9.0" collection: dependency: transitive description: @@ -293,12 +293,12 @@ packages: dependency: transitive description: name: cross_file - sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.3+7" + version: "0.3.3+8" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab @@ -357,10 +357,10 @@ packages: dependency: "direct main" description: name: dio - sha256: "01870acd87986f768e0c09cc4d7a19a59d814af7b34cbeb0b437d2c33bdfea4c" + sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3" url: "https://pub.dev" source: hosted - version: "5.3.4" + version: "5.4.0" dots_indicator: dependency: "direct main" description: @@ -711,6 +711,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + hive_generator: + dependency: "direct dev" + description: + name: hive_generator + sha256: "06cb8f58ace74de61f63500564931f9505368f45f98958bd7a6c35ba24159db4" + url: "https://pub.dev" + source: hosted + version: "2.0.1" html: dependency: transitive description: @@ -747,10 +755,10 @@ packages: dependency: "direct dev" description: name: icons_launcher - sha256: "0c4a46dfbc1e9025745c1d28949149d601bdf56a892338e74c4b4dd9a7066987" + sha256: "3ed4560181f238e69ca5d55589d6946ef31e6a321c934251a26ce1d9e9867305" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" image: dependency: transitive description: @@ -787,18 +795,18 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "7d7f2768df2a8b0a3cefa5ef4f84636121987d403130e70b17ef7e2cf650ba84" + sha256: fc712337719239b0b6e41316aa133350b078fa39b6cbd706b61f3fd421b03c77 url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: d6a6e78821086b0b737009b09363018309bbc6de3fd88cc5c26bc2bb44a4957f + sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe url: "https://pub.dev" source: hosted - version: "0.8.8+2" + version: "0.8.9+1" image_picker_for_web: dependency: transitive description: @@ -811,10 +819,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: "76ec722aeea419d03aa915c2c96bf5b47214b053899088c9abb4086ceecf97a7" + sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf url: "https://pub.dev" source: hosted - version: "0.8.8+4" + version: "0.8.9" image_picker_linux: dependency: transitive description: @@ -968,10 +976,10 @@ packages: dependency: transitive description: name: mobx - sha256: "42ae7277ec5c36fa5ce02aa14551065babce3c38a35947330144ff47bc775c75" + sha256: "6b467f91bfc534922ea670db69a1972d28bd9754085892decb5bce19f2c8d0d5" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" nested: dependency: transitive description: @@ -1048,10 +1056,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_foundation: dependency: transitive description: @@ -1088,10 +1096,10 @@ packages: dependency: "direct main" description: name: pdf - sha256: aa8835fcb9cfaf57ab2f1970e8548ceed3d0cb53eda7da906648f8153eaf37c9 + sha256: "93cbb2c06de9bab91844550f19896b2373e7a5ce25173995e7e5ec5e1741429d" url: "https://pub.dev" source: hosted - version: "3.10.6" + version: "3.10.7" permission_handler: dependency: "direct main" description: @@ -1120,10 +1128,10 @@ packages: dependency: transitive description: name: permission_handler_html - sha256: d96ff56a757b7f04fa825c469d296c5aebc55f743e87bd639fef91a466a24da8 + sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df" url: "https://pub.dev" source: hosted - version: "0.1.0+1" + version: "0.1.0+2" permission_handler_platform_interface: dependency: transitive description: @@ -1144,10 +1152,10 @@ packages: dependency: transitive description: name: petitparser - sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.0.2" pin_code_fields: dependency: "direct main" description: @@ -1192,8 +1200,8 @@ packages: dependency: "direct main" description: path: "." - ref: gecko-fixes-3 - resolved-ref: ac7347e907ca30766eedb9e15583ebc20916d56c + ref: "8b254d9e98cb367b4a57d67f8c6f5bbe89a52552" + resolved-ref: "8b254d9e98cb367b4a57d67f8c6f5bbe89a52552" url: "https://github.com/poka-IT/sdk.git" source: git version: "0.5.4+4" @@ -1272,12 +1280,11 @@ packages: qr_flutter: dependency: "direct main" description: - path: "." - ref: master - resolved-ref: bd3fc334a87e0898bb0092036e74bb99cd7ad4e3 - url: "https://github.com/insinfo/qr.flutter.git" - source: git - version: "4.0.0" + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" rational: dependency: transitive description: @@ -1290,10 +1297,10 @@ packages: dependency: "direct main" description: name: responsive_framework - sha256: e083346029b008335b008274c4d3fac5b9e0ca8796f201ed20884f579101d584 + sha256: "23aa7be5d5136922df708f6ddccb5ec4e0eb8bc576c3f105f5093f31d6b68e50" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "1.1.1" rxdart: dependency: transitive description: @@ -1302,6 +1309,54 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" + screen_brightness: + dependency: "direct main" + description: + name: screen_brightness + sha256: ed8da4a4511e79422fc1aa88138e920e4008cd312b72cdaa15ccb426c0faaedd + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + screen_brightness_android: + dependency: transitive + description: + name: screen_brightness_android + sha256: "3df10961e3a9e968a5e076fe27e7f4741fa8a1d3950bdeb48cf121ed529d0caf" + url: "https://pub.dev" + source: hosted + version: "0.1.0+2" + screen_brightness_ios: + dependency: transitive + description: + name: screen_brightness_ios + sha256: "99adc3ca5490b8294284aad5fcc87f061ad685050e03cf45d3d018fe398fd9a2" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + screen_brightness_macos: + dependency: transitive + description: + name: screen_brightness_macos + sha256: "64b34e7e3f4900d7687c8e8fb514246845a73ecec05ab53483ed025bd4a899fd" + url: "https://pub.dev" + source: hosted + version: "0.1.0+1" + screen_brightness_platform_interface: + dependency: transitive + description: + name: screen_brightness_platform_interface + sha256: b211d07f0c96637a15fb06f6168617e18030d5d74ad03795dd8547a52717c171 + url: "https://pub.dev" + source: hosted + version: "0.1.0" + screen_brightness_windows: + dependency: transitive + description: + name: screen_brightness_windows + sha256: "9261bf33d0fc2707d8cf16339ce25768100a65e70af0fcabaf032fc12408ba86" + url: "https://pub.dev" + source: hosted + version: "0.1.3" scroll_to_index: dependency: transitive description: @@ -1322,18 +1377,18 @@ packages: dependency: transitive description: name: sentry - sha256: e7ded42974bac5f69e4ca4ddc57d30499dd79381838f24b7e8fd9aa4139e7b79 + sha256: "89e426587b0879e53c46a0aae0eb312696d9d2d803ba14b252a65cc24b1416a2" url: "https://pub.dev" source: hosted - version: "7.13.2" + version: "7.14.0" sentry_flutter: dependency: "direct main" description: name: sentry_flutter - sha256: d6f55ec7a1f681784165021f749007712a72ff57eadf91e963331b6ae326f089 + sha256: fd089ee4e75a927be037c56815a0a54af5a519f52b803a5ffecb589bb36e2401 url: "https://pub.dev" source: hosted - version: "7.13.2" + version: "7.14.0" shared_preferences: dependency: transitive description: @@ -1411,6 +1466,22 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + url: "https://pub.dev" + source: hosted + version: "1.3.4" source_span: dependency: transitive description: @@ -1527,10 +1598,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba + sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.2" url_launcher_android: dependency: transitive description: @@ -1551,10 +1622,10 @@ packages: dependency: transitive description: name: url_launcher_linux - sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" url_launcher_macos: dependency: transitive description: @@ -1575,20 +1646,20 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" + sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" uuid: - dependency: transitive + dependency: "direct main" description: name: uuid sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" @@ -1639,10 +1710,10 @@ packages: dependency: transitive description: name: wallet - sha256: "569c91c2af13a9e1119c001f9c09218eccf3f383eb8d15ba13a5b558010c1bc0" + sha256: "687fd89a16557649b26189e597792962f405797fc64113e8758eabc2c2605c32" url: "https://pub.dev" source: hosted - version: "0.0.12+1" + version: "0.0.13" watcher: dependency: transitive description: @@ -1695,34 +1766,34 @@ packages: dependency: transitive description: name: webview_flutter_android - sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf" + sha256: b54c89fe14a6d26a2a46e24880da0441cdd2bf1f6d01a5b3e1d39558feb1de0b url: "https://pub.dev" source: hosted - version: "3.12.1" + version: "3.13.1" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: adb8c03c2be231bea5a8ed0e9039e9d18dbb049603376beaefa15393ede468a5 + sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.9.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76 + sha256: eebfabfa8a115b535b52031b8b26f7a4b58ceceab378bc9db8762b0fb46f7b5d url: "https://pub.dev" source: hosted - version: "3.9.4" + version: "3.10.0" win32: dependency: transitive description: name: win32 - sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.1.1" xdg_directories: dependency: transitive description: @@ -1735,10 +1806,10 @@ packages: dependency: transitive description: name: xml - sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.4.2" + version: "6.5.0" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 493ad22..9ed91ae 100644 --- a/pubspec.yaml +++ b/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.2+59 +version: 0.1.3+63 environment: sdk: ">=2.12.0 <3.0.0" @@ -14,63 +14,64 @@ dependencies: flutter: sdk: flutter bubble: ^1.2.1 - carousel_slider: ^4.0.0 - graphql_flutter: ^5.1.1-beta.4 + carousel_slider: ^4.2.1 + graphql_flutter: ^5.1.2 hive_flutter: ^1.1.0 - image_picker: ^1.0.4 + image_picker: ^1.0.5 jdenticon_dart: ^2.0.0 logger: ^2.0.2+1 - path_provider: ^2.0.11 - pdf: ^3.7.1 - permission_handler: ^11.0.1 + path_provider: ^2.1.1 + pdf: ^3.10.7 + permission_handler: ^11.1.0 pin_code_fields: ^8.0.1 - printing: ^5.10.1 - provider: ^6.0.1 - barcode_scan2: ^4.2.1 - qr_flutter: #^4.0.0 - git: - url: https://github.com/insinfo/qr.flutter.git - ref: master - responsive_framework: 0.2.0 - sentry_flutter: ^7.4.1 + printing: ^5.11.1 + provider: ^6.1.1 + barcode_scan2: ^4.3.0 + qr_flutter: ^4.1.0 + responsive_framework: ^1.1.1 + sentry_flutter: ^7.14.0 truncate: ^3.0.1 unorm_dart: ^0.3.0 - dio: ^5.0.1 - durt: ^0.1.6 + dio: ^5.4.0 + durt: ^0.1.7 package_info_plus: ^5.0.1 polkawallet_sdk: #^0.5.2 git: # url: https://github.com/polkawallet-io/sdk.git # ref: develop url: https://github.com/poka-IT/sdk.git - ref: gecko-fixes-3 - # ref: ff98a117e86060a91113107f31355a17ccfb346c + # ref: gecko-fixes-3 + ref: 8b254d9e98cb367b4a57d67f8c6f5bbe89a52552 dots_indicator: ^3.0.0 - connectivity_plus: ^3.0.2 + connectivity_plus: ^3.0.6 image_cropper: ^4.0.1 - easy_localization: ^3.0.1 - flutter_markdown: ^0.6.10+2 - pointycastle: ^3.6.1 + easy_localization: ^3.0.3 + flutter_markdown: ^0.6.18+2 + pointycastle: ^3.7.3 hex: ^0.2.0 - accordion: ^2.5.1 - flutter_svg: ^2.0.2 - pinenacl: ^0.3.3 + accordion: ^2.6.0 + flutter_svg: ^2.0.9 + pinenacl: ^0.3.4 fast_base58: ^0.2.1 - tutorial_coach_mark: ^1.2.8 + tutorial_coach_mark: ^1.2.11 confetti: ^0.7.0 - url_launcher: ^6.1.11 + url_launcher: ^6.2.2 + crypto: ^3.0.3 + screen_brightness: ^0.2.2+1 + uuid: ^3.0.7 dev_dependencies: # flutter_launcher_icons: ^0.9.2 # flutter_launcher_icons_maker: ^^0.10.2 - icons_launcher: ^2.0.6 - build_runner: ^2.1.2 + icons_launcher: ^2.1.6 + build_runner: ^2.4.7 + hive_generator: ^2.0.1 flutter_lints: ^3.0.1 flutter_test: sdk: flutter integration_test: sdk: flutter - dart_code_metrics: ^5.0.1 + dart_code_metrics: ^5.7.6 icons_launcher: image_path: "assets/icon/gecko_flat.png" diff --git a/scripts/build-apk.sh b/scripts/build-apk.sh index f5ac9b2..3267def 100755 --- a/scripts/build-apk.sh +++ b/scripts/build-apk.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + fVersion=$(grep "version: " pubspec.yaml | awk '{ print $2 }') withPush=$1 @@ -19,7 +21,8 @@ echo "Nom du build final: ${APPNAME}-${VERSION}+${BUILD}.apk" flutter clean if [[ $1 == "bundle" ]]; then - flutter build appbundle --release --target-platform android-arm,android-arm64 --build-name $VERSION --build-number $BUILD + flutter build appbundle --release --build-name $VERSION --build-number $BUILD + exit 0 else # flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64 --build-name $VERSION --build-number $BUILD flutter build apk --release --split-per-abi --build-name $VERSION --build-number $BUILD diff --git a/scripts/update_pubsec_yaml_versions.py b/scripts/update_pubsec_yaml_versions.py new file mode 100644 index 0000000..968b590 --- /dev/null +++ b/scripts/update_pubsec_yaml_versions.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +from ruamel.yaml import YAML + +# Define the file paths +pubspec_yaml_path = "pubspec.yaml" +pubspec_lock_path = "pubspec.lock" + +# Initialize YAML parser/loader +yaml = YAML() +yaml.preserve_quotes = True +yaml.indent(mapping=2, sequence=4, offset=2) + +# Read the pubspec.lock file and extract the package versions +lock_versions = {} +with open(pubspec_lock_path, 'r') as lock_file: + lock_data = yaml.load(lock_file) + for package_name, package_info in lock_data['packages'].items(): + lock_versions[package_name] = package_info['version'] + +# Read the pubspec.yaml file +with open(pubspec_yaml_path, 'r') as yaml_file: + yaml_data = yaml.load(yaml_file) + +# Function to preserve formatting and update versions +def update_dependency_versions(dependencies_section): + if not dependencies_section: + return + + for package, details in dependencies_section.items(): + # Skip if it's an SDK or Git dependency + if isinstance(details, dict) and ('sdk' in details or 'git' in details): + continue + + # Update version if the package exists in lock_versions + if package in lock_versions: + dependencies_section[package] = "^" + lock_versions[package] + +# Update the dependency versions in pubspec.yaml +update_dependency_versions(yaml_data.get('dependencies', {})) +update_dependency_versions(yaml_data.get('dev_dependencies', {})) + +# Write the updated data back to pubspec.yaml +with open(pubspec_yaml_path, 'w') as yaml_file: + yaml.dump(yaml_data, yaml_file) + +print("pubspec.yaml has been updated with versions from pubspec.lock.")