Compare commits

..

4 Commits

143 changed files with 6985 additions and 6209 deletions

1
.env
View File

@ -1 +0,0 @@
ip_address=127.0.0.1

7
.gitignore vendored
View File

@ -55,9 +55,4 @@ scripts/private/
AppDir/
appimage-builder-cache/
AppImageBuilder.yml
android/app/build.gradle
integration_test/duniter/data/chains/
# Ignore PC deps
macos/
windows/
android/app/build.gradle

View File

@ -5,7 +5,7 @@ stages:
- package
.env:
image: axiomteam/gecko-ci:v0.0.11
image: axiomteam/gecko-ci:v0.0.9
tags:
- redshift

View File

@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 33
compileSdkVersion 31
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@ -46,7 +46,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "gecko.axiomteam.fr"
minSdkVersion 19
targetSdkVersion 33
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
@ -66,6 +66,7 @@ android {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.release //poka: comment this to build unsigned release, or set to signingConfigs.debug to sign with debug keys
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

View File

@ -19,6 +19,7 @@
<activity
android:requestLegacyExternalStorage="true"
android:name=".MainActivity"
android:resource="@style/NormalTheme"
android:icon="@mipmap/ic_launcher"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"

View File

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.7.10'
ext.kotlin_version = '1.6.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.enableJetifier=true
android.enableR8=true

View File

@ -3,5 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -51,6 +51,7 @@
"validate": "Validate",
"confirm": "Confirm",
"confirmPayment": "Confirm payment",
"clickHereToConfirmIdentity": "Click here to confirm\nyour new identity",
"geckoGenerateYourWalletFromMnemonic": "Ğecko builds your wallet from a **restoration sentence**. It is a bit like the blueprint that builds your wallet.",
"keepThisMnemonicSecure": "Keep this sentence carefully, because without it Ğecko will not be able to rebuild your wallets the day you change your phone.",
"geckoGeneratedYourMnemonicKeepItSecret": "Ğecko generated your mnemonic successfully! Keep it secret, because anyone who knows it can access all your wallets.",
@ -125,7 +126,7 @@
"yesterday": "Yesterday",
"thisWeek": "This week",
"chestNotCompatibleMustReinstallGecko": "The version of your safes is no longer compatible with this version of Ğecko.\nAll your safes will be forgotten, you must import them again.",
"notConnectedToInternet": "You are not connected to internet",
"notConnectedToInternet": "You are note connected to internet",
"researchResults": "Results of your research",
"resultsFor": "Results for ",
"forgetAllMyChests": "Forget all my chests",
@ -137,7 +138,7 @@
"sending": "Sending...",
"propagating": "Propagating...",
"validating": "Validating...",
"anErrorOccurred": "An error occurred",
"anErrorOccured": "An error occured",
"24hbetweenCerts": "You have to wait 24h between certs",
"canNotCertifySelf": "You can not certify yourself",
"nameAlreadyExist": "This name is already taken",
@ -146,7 +147,6 @@
"execTimeoutOver": "Execution timeout is over",
"seeAWallet": "See a wallet",
"mustWaitXBeforeCertify": "You have to wait\n{} before\ncertifying again",
"mustConfirmHisIdentity": "This person must confirm\nhis identity before can be\ncertified",
"canRenewCertInX": "You can renew\nthis certification\nin {}",
"executeATransfer": "Execute a transfer",
"executeTheTransfer": "Execute the transfer",
@ -158,7 +158,6 @@
"months": "{} months",
"certify": "Certify",
"from": "From:",
"to": "To:",
"amount": "Amount:",
"choiceOfSourceWallet": "Choose a source wallet",
"extrinsicInProgress": "{} in progress",
@ -170,30 +169,9 @@
"inBlockchainResult": "In {} blockchain",
"search": "Search",
"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 {}/{}",
"youAreOffline": "You are offline...",
"importG1v1": "Import old G1v1 account",
"selectDestWallet": "Select a target 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",
"importOldAccount": "Import your old account",
"enterCesiumId": "Enter your Cesium ID",
"enterCesiumPassword": "Enter your Cesium password",
"migrateAccount": "Migrate account",
"migrateIdentity": "Migrate identity",
"identityMigration": "Identity migration",
"areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?",
"someoneCreatedYourIdentity": "Someone created your {} identity !",
"confirmMyIdentity": "Confirm my identity",
"revokeMyIdentity": "Revoke my identity",
"youCannotRevokeThisIdentity": "You cannot revoke this identity while\nit is member of the blacksmiths web",
"showUdAmounts": "Show amounts in UD",
"ud": "{}UD",
"chooseATargetWallet": "Choose a target wallet"
"removeContact": "Remove\nthis contact"
}

View File

@ -1,6 +1,6 @@
{
"searchWallet": "Buscar\nbilletera",
"manageWallets": "Gestionar\nbilleteras",
"searchWallet": "Search\nwallet",
"manageWallets": "Manage\nwallets",
"scanQRCode": "Escanear un\ncódigo QR",
"wellConnectedToNode": "Estas bien conectada al nodo\n{}",
"networkLost": "Se ha perdido la red...",
@ -13,20 +13,20 @@
"fastAppDescription": "La aplicación de pago {}\nmás rápida que un reptil de Vietnam",
"createWallet": "Crear una billetera",
"restoreWallet": "Restaurar mis billeteras",
"parameters": "Parámetros",
"parameters": "Parameters",
"chooseAnotherMnemonic": "Choose an other\nmnemonic sentence",
"iNotedMyMnemonic": "He escrito mi frase",
"iNotedMyMnemonic": "I wrote down my sentence",
"printMyMnemonic": "Print my mnemonic sentence",
"manageChest": "Configure this chest",
"changeChest": "Change chest",
"geckoChest": "Ğecko chest",
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:",
"rememberPassword": "Keep this code in memory for 15 minutes",
"myRootWallet": "Mi billetera principal",
"myRootWallet": "My root wallet",
"currentWallet": "My current chest",
"wallet": "Billetera",
"wallet": "Wallet",
"displayMnemonic": "Display my mnemonic sentence",
"changePassword": "Cambiar mi contraseña",
"changePassword": "Change my password",
"createDerivation": "Create a new derivation",
"createCustomDerivation": "Create a new custom derivation",
"deleteChest": "Delete this chest",
@ -36,21 +36,22 @@
"selectMyChest": "Select my chest",
"accessMyChest": "Access my chest",
"manageMembership": "Manage my membership",
"chooseThisWallet": "Elegir esta billetera",
"chooseThisWallet": "Choose this wallet",
"thisWalletIsDefault": "This wallet is the default one",
"defineWalletAsDefault": "Define this as the default one",
"displayActivity": "Display activity",
"displayNActivity": "Display\nactivity",
"memberValidated": "Miembro validado!",
"copyAddress": "Copiar\ndirección",
"copy": "Copiar",
"thisAddressHasBeenCopiedToClipboard": "Esta dirección se ha copiado al cortapapeles",
"memberValidated": "Validated member!",
"copyAddress": "Copy\naddress",
"copy": "Copy",
"thisAddressHasBeenCopiedToClipboard": "This address has been copied to clipboard",
"chooseWalletName": "Choose a new name\nfor your wallet:",
"choosePassword": "Choose a random password:",
"chooseDerivation": "Choose a derivation:",
"validate": "Validar",
"confirm": "Confirmar",
"confirmPayment": "Confirmar pago",
"validate": "Validate",
"confirm": "Confirm",
"confirmPayment": "Confirm payment",
"clickHereToConfirmIdentity": "Click here to confirm\nyour new identity",
"geckoGenerateYourWalletFromMnemonic": "Ğecko builds your wallet from a **restoration sentence**. It is a bit like the blueprint that builds your wallet.",
"keepThisMnemonicSecure": "Keep this sentence carefully, because without it Ğecko will not be able to rebuild your wallets the day you change your phone.",
"geckoGeneratedYourMnemonicKeepItSecret": "Ğecko generated your mnemonic successfully! Keep it secret, because anyone who knows it can access all your wallets.",
@ -63,7 +64,7 @@
"myPassword": "My password",
"thisPasswordProtectsYourWalletsInASecureChest": "This secret code protects your wallets in a safe **which only you have the code for**, so that your wallets cannot be used by others.",
"hereIsThePasswordKeepIt": "And here is your password!\n\nMemorize it or write it down, because you will be asked **every time** you want to make a payment on this device.",
"chooseAnotherPassword": "Elige otra contraseña",
"chooseAnotherPassword": "Choose an other password",
"iNotedMyPassword": "I noted my password",
"geckoWillCheckPassword": "Gecko will check with you if you have remembered your secret code.\n\n Type your secret code in the field below to check that you have written it down correctly.",
"yourChestAndWalletWereCreatedSuccessfully": "Super!\n\nYour chest and your first portfolio have been created with great success.\n\nCongratulations!",
@ -72,7 +73,7 @@
"areYouSureForgetAllChests": "Are you sure you want to forget all your chests?",
"areYouSureToForgetWallet": "Are you sure you wan to forget the wallet \"{}\"?",
"areYouSureYouWantToCertify": "Are you sure you want to certify the address:\n\n{}",
"yes": "Si",
"yes": "Yes",
"no": "No",
"keepYourMnemonicSecret": "Try to keep this phrase a secret, as it allows anyone who knows it to access all your wallets.",
"iGeneratedYourMnemonicKeepItSecret": "I've generated your restoration phrase!\n Try to keep it a secret, as it allows anyone who knows it to access all your portfolios.",
@ -82,118 +83,94 @@
"pasteFromClipboard": "Paste from\nclipboard",
"restoreAChest": "Restore a chest",
"restoreThisChest": "Restore this chest",
"continue": "Continuar",
"continue": "Continue",
"itsTheGoodWord": "It's the good word!",
"nthMnemonicWord": "word of your mnemonic",
"1th": "Primera",
"2th": "Segunda",
"3th": "Tercera",
"4th": "Cuarta",
"5th": "Quinta",
"6th": "Sexta",
"7th": "Séptima",
"8th": "Octava",
"9th": "Novena",
"10th": "Décima",
"11th": "Undécima",
"12th": "Duodécima",
"yourPasswordLengthIsX": "La longitud de tu contraseña es {}",
"1th": "First",
"2th": "Second",
"3th": "Third",
"4th": "Fourth",
"5th": "Fifth",
"6th": "Sixth",
"7th": "Seventh",
"8th": "Eighth",
"9th": "Ninth",
"10th": "Tenth",
"11th": "Eleventh",
"12th": "Twelfth",
"yourPasswordLengthIsX": "Your password length is {}",
"noIdentity": "No identity",
"identityCreated": "Identidad creada",
"identityConfirmed": "Identidad confirmada",
"identityExpired": "Identitdad caducada",
"confirmYourIdentity": "Confirma tu identidad",
"identityCreated": "Identity created",
"identityConfirmed": "Identity confirmed",
"identityExpired": "Identity expired",
"confirmYourIdentity": "Confirm your identity",
"noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later",
"youAreConnectedToNode": "You are connected to node",
"accountActivity": "Actividad de la cuenta",
"accountActivity": "Account activity",
"noNetworkNoHistory": "Network state does not allow\nto display account history",
"noDataToDisplay": "No data to be displayed.",
"noTransactionToDisplay": "No transaction to display",
"month1": "Enero",
"month2": "Febrero",
"month3": "Marzo",
"month4": "Abril",
"month5": "Mayo",
"month6": "Junio",
"month7": "Julio",
"month8": "Agosto",
"month9": "Septiembre",
"month10": "Octubre",
"month11": "Noviembre",
"month12": "Diciembre",
"today": "Hoy",
"yesterday": "Ayer",
"thisWeek": "Esta semana",
"month1": "January",
"month2": "February",
"month3": "March",
"month4": "April",
"month5": "May",
"month6": "June",
"month7": "July",
"month8": "August",
"month9": "September",
"month10": "October",
"month11": "November",
"month12": "December",
"today": "Today",
"yesterday": "Yesterday",
"thisWeek": "This week",
"chestNotCompatibleMustReinstallGecko": "The version of your safes is no longer compatible with this version of Ğecko.\nAll your safes will be forgotten, you must import them again.",
"notConnectedToInternet": "No estas conectado a internet",
"notConnectedToInternet": "You are note connected to internet",
"researchResults": "Results of your research",
"resultsFor": "Results for ",
"forgetAllMyChests": "Forget all my chests",
"transaction": "Transaccion",
"certification": "Certificacion",
"transaction": "Transaction",
"certification": "Certification",
"identityConfirm": "Identity confirmation",
"revokeAdhesion": "Adhesion revocation",
"strangeTransaction": "Strange transaction",
"sending": "Enviando...",
"propagating": "Propagando...",
"validating": "Validando...",
"anErrorOccurred": "Ocurrió un error",
"sending": "Sending...",
"propagating": "Propagating...",
"validating": "Validating...",
"anErrorOccured": "An error occured",
"24hbetweenCerts": "You have to wait 24h between certs",
"canNotCertifySelf": "You can not certify yourself",
"nameAlreadyExist": "This name is already taken",
"2GDtoKeepAlive": "You have to keep at least 2ĞD to keep your account alive",
"youHaveToFeedThisAccountBeforeUsing": "You have to feed this account\nbefore using it.",
"execTimeoutOver": "Execution timeout is over",
"seeAWallet": "Ver una billetera",
"mustWaitXBeforeCertify": "Tienes que esperar\n{} antes de\nvolver a certificar",
"mustConfirmHisIdentity": "This person must confirm\nhis identity before can be\ncertified",
"seeAWallet": "See a wallet",
"mustWaitXBeforeCertify": "You have to wait\n{} before\ncertifying again",
"canRenewCertInX": "You can renew\nthis certification\nin {}",
"executeATransfer": "Execute a transfer",
"executeTheTransfer": "Execute the transfer",
"doATransfer" : "Execute a\ntransfer",
"seconds": "{} segundos",
"minutes": "{} minutos",
"hours": "{} horas {}",
"days": "{} dias",
"months": "{} meses",
"seconds": "{} seconds",
"minutes": "{} minutes",
"hours": "{} hours {}",
"days": "{} days",
"months": "{} months",
"certify": "Certify",
"from": "De:",
"to": "A:",
"amount": "Importe:",
"from": "From:",
"amount": "Amount:",
"choiceOfSourceWallet": "Choose a source wallet",
"extrinsicInProgress": "{} en progreso",
"extrinsicValidated": "{} validado !",
"fromMinus": "de",
"toMinus": "a",
"extrinsicInProgress": "{} in progress",
"extrinsicValidated": "{} validated !",
"fromMinus": "from",
"toMinus": "to",
"deleteThisWallet": "Delete this wallet",
"cancel": "Cancelar",
"cancel": "Cancel",
"inBlockchainResult": "In {} blockchain",
"search": "Buscar",
"currencyNode": "{} nodo :",
"contactsManagementWithNbr": "Mis contactos ({})",
"contactsManagement": "Mis contactos",
"search": "Search",
"currencyNode": "{} node :",
"contactsManagement": "My contacts",
"noContacts": "You don't have any contact",
"addContact": "Add\nto contacts",
"removeContact": "Remove\nthis contact",
"derivationsScanProgress": "Scan address {}/{}",
"youAreOffline": "You are offline...",
"importG1v1": "Import old G1v1 account",
"selectDestWallet": "Select a target 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",
"importOldAccount": "Import your old account",
"enterCesiumId": "Ingrese su ID de Cesium",
"enterCesiumPassword": "Ingrese su contraseña de Cesium",
"migrateAccount": "Migrate account",
"migrateIdentity": "Migrate identity",
"identityMigration": "Identity migration",
"areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?",
"someoneCreatedYourIdentity": "Someone created your {} identity !",
"confirmMyIdentity": "Confirmar mi identidad",
"revokeMyIdentity": "Revocar mi identidad",
"youCannotRevokeThisIdentity": "You cannot revoke this identity while\nit is member of the blacksmiths web",
"showUdAmounts": "Show amounts in UD",
"ud": "{}UD",
"chooseATargetWallet": "Elija una billetera de destino"
}
"removeContact": "Remove\nthis contact"
}

View File

@ -51,6 +51,7 @@
"validate": "Valider",
"confirm": "Confirmer",
"confirmPayment": "Confirmer le paiement",
"clickHereToConfirmIdentity": "Cliquez ici pour confirmer\nvotre nouvelle identité",
"geckoGenerateYourWalletFromMnemonic": "Ğecko fabrique votre portefeuille à partir dune **phrase de restauration**. Elle est un peu comme le plan qui permet de construire votre portefeuille.",
"keepThisMnemonicSecure": "Conservez cette phrase précieusement, car sans elle Ğecko ne pourra pas reconstruire vos portefeuilles le jour où vous changez de téléphone.",
"geckoGeneratedYourMnemonicKeepItSecret": "Gecko a généré votre phrase de restauration ! Tâchez de la garder bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.",
@ -138,7 +139,7 @@
"sending": "Envoi en cours...",
"propagating": "En cours de propagation...",
"validating": "En cours de validation...",
"anErrorOccurred": "Une erreur s'est produite",
"anErrorOccured": "Une erreur s'est produite",
"24hbetweenCerts": "Vous devez attendre 24h entre chaque certification",
"canNotCertifySelf": "Vous ne pouvez pas vous certifier\nvous même ...",
"nameAlreadyExist": "Ce nom est déjà pris",
@ -147,8 +148,7 @@
"execTimeoutOver": "Le délais d'éxecution est dépassé",
"seeAWallet": "Voir un portefeuille",
"mustWaitXBeforeCertify": "Vous devez attendre\n{} avant\nde pouvoir certifier",
"mustConfirmHisIdentity": "Cette personne doit confirmer\nson identité avant de pouvoir\nêtre certifié",
"canRenewCertInX": "Vous pourrez renouveler\ncette certification\ndans {}",
"canRenewCertInX": "Vous pourrez renouveller\ncette certification\ndans {}",
"executeATransfer": "Effectuer un virement",
"executeTheTransfer": "Effectuer le virement",
"doATransfer": "Faire un\nvirement",
@ -159,7 +159,6 @@
"months": "{} mois",
"certify": "Certifier",
"from": "Depuis:",
"to": "Vers:",
"amount": "Montant:",
"choiceOfSourceWallet": "Choix du portefeuille source",
"extrinsicInProgress": "{} en cours",
@ -171,30 +170,8 @@
"inBlockchainResult": "Dans la blockchain {}",
"search": "Rechercher",
"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 {}/{}",
"youAreOffline": "Vous êtes hors ligne...",
"importG1v1": "Importer un ancien compte G1v1",
"selectDestWallet": "Sélectionnez un portefeuille cible:",
"youMustWaitBeforeCashoutThisAccount": "Vous devez attendre quelques minutes avant 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é",
"importOldAccount": "Importer son ancien compte",
"enterCesiumId": "Entrez votre identifiant Cesium",
"enterCesiumPassword": "Entrez votre mot de passe Cesium",
"migrateAccount": "Migrer le compte",
"migrateIdentity": "Migrer l'identité",
"identityMigration": "Migration de l'identité",
"areYouSureMigrateIdentity": "Êtes-vous certain de vouloir migrer définitivement l'identité **{}** et son solde de **{}** ?",
"someoneCreatedYourIdentity": "Quelqu'un a créé votre identité {} !",
"confirmMyIdentity": "Confirmer mon identité",
"revokeMyIdentity": "Révoquer mon identité",
"youCannotRevokeThisIdentity": "Vous ne pouvez pas révoquer cette identité tant\nqu'elle fait partie de la toile forgerons",
"showUdAmounts": "Afficher les montants en DU",
"ud": "{}DU",
"chooseATargetWallet": "Choisissez un portefeuille cible"
"removeContact": "Supprimer\nce contact"
}

View File

@ -1,4 +1,5 @@
[
"wss://gdev.p2p.legal/ws",
"wss://gdev.librelois.fr/ws"
"wss://gdev.librelois.fr/ws",
"wss://gdev.1000i100.fr/ws",
"wss://gdev.komun.org/ws"
]

View File

@ -1,6 +1,4 @@
[
"https://gdev-indexer.p2p.legal",
"https://idx.gdev.cgeek.fr",
"https://duniter-indexer.coinduf.eu",
"http://192.168.1.72:8080"
]

View File

@ -1,128 +0,0 @@
# Context des tests
Chaque test est précédé par le lancement d'un noeud Duniter v2s en docker [dont voici le compose](https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/docker-compose.yml).
Voici le yaml de configuration de la monnaie de test éphémère: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/data/gecko_tests.json
Voici le mnemonic de test utilisé:
`pipe paddle ketchup filter life ice feel embody glide quantum ride usage`
Et les 5 premiers portefeuilles Gecko associés:
```
test1: 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa
test2: 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb
test3: 5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p
test4: 5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5
test5: 5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R
```
Seul les 4 premiers sont membres au démarrage.
Voici le scénario de test principal que j'ai réalisé pour le moment
Scénario 1
- Changer le noeud Duniter pour se connecter au nœud local (l'ip local est récupéré automatiquement, car le nœud est sur le host (votre pc), alors que l'app est dans son émulateur)
- Importer le coffre de test
- Effectuer une transaction du Portefeuille 1 (test1) vers le portefeuille 5 (test5)
- Vérifier que les frais de créations de compte ont bien été prélevés
- Certifier test5 avec test1, test2 et test3 et vérifier qu'il deviens bien membre
- Créer 10 blocs, puis encore 10, puis 30 de plus et vérifier à chaque fois si le compte génère bien ses DU à la bonne valeur, réévaluation comprise au bloc 50.
Des vérifications sur l'état du texte affiché à l'écran ou des widgets affichés ou non sont fait entre chaque étapes pour vérifier que tout ce passe toujours bien.
Si la moindre erreur intervient, le test s'arrête et vous informe de l'erreur en question.
Voici le code du test contenant ce scénario: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/gecko_complete.dart
Ce test dur environ 1 minutes et 15 seconds, compilation et lancement de nœud au démarrage inclus.
Voici le rendu (attention ça va assez vite ^^) :
https://tube.p2p.legal/w/kMc5c8KnLi9BpwJrM4EnKX
On remarque notamment que des blocs sont créés uniquement et directement après un extrinsic lancé depuis l'app
---
# Tuto contributeurs
**Il n'est nécessaire ni de connaître le code de Ğecko, ni de connaître Dart/flutter pour écrire un nouveau scénario de test !**
Il vous suffit de comprendre par exemple cet extrait de code:
```
// Copy test mnemonic in clipboard
await clipCopy(testMnemonic);
// Open screen import chest
await goKey(keyRestoreChest, duration: 0);
// Tap on button to paste mnemonic
await goKey(keyPastMnemonic);
// Tap on next button 4 times to skip 3 screen
await goKey(keyGoNext);
await goKey(keyGoNext);
await goKey(keyGoNext);
await goKey(keyGoNext);
// Check if cached password checkbox is checked
final isCached = await isIconPresent(Icons.check_box);
// If not, tap on to cache password
if (!isCached) await goKey(keyCachePassword, duration: 0);
// Enter password
await enterText(keyPinForm, 'AAAAA', 0);
// Check if string "Accéder à mon coffre" is present in screen
await waitFor('Accéder à mon coffre');
// Go to wallets home
await goKey(keyGoWalletsHome, duration: 0);
// Check if string "ĞD" is present in screen
await waitFor('ĞD');
// Tap on add a new derivation button
await addDerivation();
// Tap on Wallet 5
await goKey(keyOpenWallet(test5.address));
// Copy address of Wallet 5
await goKey(keyCopyAddress);
// Check if string "Cette adresse a été copié" is present in screen
await waitFor('Cette adresse a été copié');
// Pop screen 2 time to go back home
await goBack();
await goBack();
// Create a new bloc (useless here, just to show you the method)
await spawnBlock();
// Check if string "y'a pas de lézard" is present in screen
await waitFor("y'a pas de lézard");
```
Vous avez dans ce bout de code commenté tous ce dont vous avez besoin pour effectuer un test d'intégration dans Ğecko :slight_smile:
Vous trouverez toutes les clés de widgets disponibles dans l'app dans ce fichier: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/lib/models/widgets_keys.dart
Ce sont ces clés qui vous permette dinteragir avec les widgets de l'app depuis votre test.
Pour créer un nouveau test **à partir de zero**, voici la marche à suivre:
- Suivez [le readme](https://git.duniter.org/clients/gecko/-/blob/master/README.md) pour configurer votre environnement de développement et ainsi pouvoir lancer Ğecko en mode debug dans un émulateur.
- Créer un nouveau fichier pour votre test dans le dossier `integration_test` (ici nous lappellerons `mon_test.dart`)
- Prenez exemple sur le fichier `gecko_complete.dart` pour écrire votre test
- Lancer un émulateur android (1 seul)
- Exécutez votre test ainsi: `./integration_test/launch_test.sh mon_test`
Créer toute sorte de tests imaginable dans Ğecko est très utile pour éviter un maximum les régressions de bugs entre les différentes versions.
Si vous avez envie de nous aider, que vous ne savez presque pas coder mais que vous êtes prêt à mettre un peu les mains dans la sauce, et que vous avez une idée de scénario à tester, alors n'hésitez pas, je répondrais à toutes vos questions :slight_smile:
A noter que ces tests permettent de tester Gecko mais aussi partiellement Duniter et l'indexer d'une même pierre.

View File

@ -0,0 +1,447 @@
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:gecko/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
int globalTimeout = 2;
group(
'Gecko end-to-end tests',
() {
// First, define the Finders and use them to locate widgets from the
// test suite. Note: the Strings provided to the `byValueKey` method must
// be the same as the Strings we used for the Keys in step 1.
// final manageWalletsFinder = find.byKey(Key('manageWallets'));
// final buttonFinder = find.byValueKey('increment');
// FlutterDriver driver;
WidgetTester tester;
String pinCode;
// *** Global functions *** //
// Easy get text
Future<String> getText(String text) async {
Text resultText = tester.firstWidget(find.byKey(Key(text)));
// Text pinCodeText = generatedPinFinder.evaluate().single.widget as Text;
return resultText.data;
}
// Function to tap the widget by key
Future tapOn(String key) async {
await tester.tap(find.byKey(Key(key)));
}
// Function to go back to previous screen
Future goBack() async {
await Process.run(
'adb',
<String>['shell', 'input', 'keyevent', 'KEYCODE_BACK'],
runInShell: true,
);
}
// Easy sleep
Future sleep(int _time) async {
await Future.delayed(Duration(milliseconds: _time));
}
// Test if widget exist on screen, return a boolean
Future<bool> isPresent(String text,
{Duration timeout = const Duration(seconds: 1)}) async {
try {
expect(text, findsOneWidget);
return true;
} catch (exception) {
return false;
}
}
// Create a derivation
Future createDerivation(String _name) async {
await tapOn('addDerivation');
await sleep(100);
await tester.enterText(find.byKey(Key('DerivationNameKey')), _name);
await tapOn('validDerivation');
await sleep(300);
}
// Delete a derivation
Future deleteWallet(bool _confirm) async {
await tapOn('deleteWallet');
await sleep(100);
_confirm
? await tapOn('confirmDeleting')
: await tapOn('cancelDeleting');
await sleep(300);
}
// Delete all wallets
Future deleteAllWallets() async {
await tester.tap(find.byKey(Key('drawerMenu')));
await sleep(300);
await tester.tap(find.byKey(Key('parameters')));
await sleep(300);
await tester.tap(find.byKey(Key('deleteAllWallets')));
await sleep(300);
await tester.tap(find.byKey(Key('confirmDeletingAllWallets')));
await sleep(300);
}
// Fast creation of new Keychain
Future<String> createNewKeychain(String name) async {
await tapOn('drawerMenu');
await sleep(300);
await tapOn('parameters');
await sleep(300);
await tapOn('generateKeychain');
expect(find.text(''), findsOneWidget);
pinCode = await getText('generatedPin');
await tapOn('storeKeychain');
await sleep(100);
await tester.enterText(find.byKey(Key('askedWord')), 'triche');
await tapOn('walletName');
await tester.enterText(find.byKey(Key('walletName')), 'name');
await tapOn('confirmStorage');
await sleep(300);
return pinCode;
}
// *** Begin of tests *** //
testWidgets('OnBoarding - Open wallets management', (
WidgetTester tester, {
timeout: Timeout.none,
}) async {
app.main();
await tester.pumpAndSettle();
// expect("y'a pas de lézard !", findsOneWidget);
await tester.tap(find.byKey(Key('manageWallets')));
print(
'####################################################################');
// If a wallet exist, go to delete theme all
await tester.pumpAndSettle();
if (!await isPresent(
"Je ne connais pour linstant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.")) {
await tester.pumpAndSettle();
// await tester.pageBack();
await goBack();
await sleep(500);
await deleteAllWallets();
await sleep(300);
await tester.tap(find.byKey(Key('manageWallets')));
}
await tester.pumpAndSettle();
// Verify onboarding is starting, with text
expect(
"Je ne connais pour linstant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.",
findsOneWidget);
});
// test('OnBoarding - Go to create restore sentance', (
// {timeout: Timeout.none}) async {
// await tapOn('goStep1');
// await tapOn('goStep2');
// await tapOn('goStep3');
// await tapOn('goStep4');
// await tapOn('goStep5');
// await tapOn('goStep6');
// expect(
// "Jai généré votre phrase de restauration !\nTâchez de la garder bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.",
// findsOneWidget);
// });
// test('OnBoarding - Generate sentance and confirme it', (
// {timeout: Timeout.none}) async {
// await tapOn('goStep7');
// await tester.pumpAndSettle();
// Future selectWord() async {
// List words = [for (var i = 1; i <= 13; i += 1) i];
// for (var j = 1; j < 13; j++) {
// words[j] = await getText('word$j');
// }
// expect(await getText('step7'),
// "C'est le moment de noter votre phrase !");
// await tapOn('goStep8');
// await sleep(200);
// String goodWord = words[int.parse(
// await getText('askedWord'),
// )];
// // Enter the expected word
// await tester.enterText(find.byKey(Key('inputWord')), goodWord);
// // Check if word is valid
// expect(find.text("C'est le bon mot !"), findsOneWidget);
// // Continue onboarding workflow
// await tapOn('goStep9');
// }
// await selectWord();
// //Go back 2 times to mnemonic generation screen
// await goBack();
// await goBack();
// await sleep(100);
// // Generate 3 times mnemonic
// await tapOn('generateMnemonic');
// await tapOn('generateMnemonic');
// await tapOn('generateMnemonic');
// await sleep(500);
// await selectWord();
// });
// test('OnBoarding - Generate secret code and confirm it', (
// {timeout: Timeout.none}) async {
// expect(await getText('step9'),
// "Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre trousseau de clefs, ce qui le rend inutilisable par dautres, par exemple si vous perdez votre téléphone ou si on vous le vole.");
// await tapOn('goStep10');
// await tapOn('goStep11');
// while (await getText('generatedPin') == '') {
// print('Waiting for pin code generation...');
// await sleep(100);
// }
// // Change secret code 4 times
// for (int i = 0; i < 4; i++) await tapOn('changeSecretCode');
// await sleep(500);
// pinCode = await getText('generatedPin');
// await tapOn('goStep12');
// await sleep(300);
// // //Enter bad secret code
// // await tester.enterText('abcde');
// // await tapOn('formKey');
// // await sleep(1500);
// // await tapOn('formKey2');
// //Enter good secret code
// await tester.enterText(find.byKey(Key('formKey2')), pinCode);
// expect(await getText('step13'),
// "Top !\n\nVotre trousseau de clef et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !");
// });
// test('My wallets - Rename first derivation', (
// {timeout: const Duration(seconds: 2)}) async {
// await tapOn('goWalletHome');
// expect(await getText('myWallets'), "Mes portefeuilles");
// await sleep(300);
// // Go to first derivation and rename it
// await tester.tap(find.text('Mon portefeuille courant'));
// await sleep(300);
// await tapOn('renameWallet');
// await sleep(100);
// await tapOn('walletName');
// await sleep(100);
// await tester.enterText(
// find.byKey(Key('walletName')), 'Renommage wallet 1');
// await sleep(300);
// await tapOn('renameWallet');
// await sleep(400);
// expect('Renommage wallet 1', findsOneWidget);
// await goBack();
// });
// test('My wallets - Create a derivations, open thems, tap all buttons', (
// {timeout: const Duration(seconds: 2)}) async {
// expect('Renommage wallet 1', findsOneWidget);
// // Add a second derivation
// await createDerivation('Derivation 2');
// // Go to second derivation options
// await tester.tap(find.text('Derivation 2'));
// await sleep(100);
// // Test options
// await tapOn('displayBalance');
// await tapOn('displayHistory');
// await sleep(300);
// await goBack();
// await tapOn('displayBalance');
// await sleep(100);
// await tapOn('displayBalance');
// await sleep(100);
// await tapOn('displayBalance');
// await tapOn('setDefaultWallet');
// await sleep(50);
// await tapOn('copyPubkey');
// expect('Cette clé publique a été copié dans votre presse-papier.',
// findsOneWidget);
// await goBack();
// // Add a third derivation
// await createDerivation('Derivation 3');
// // Add a fourth derivation
// await createDerivation('Derivation 4');
// await sleep(50);
// // Go to third derivation options
// await tester.tap(find.text('Derivation 3'));
// await sleep(100);
// await tapOn('displayBalance');
// // Delete third derivation
// await deleteWallet(true);
// });
// test('My wallets - Extra tests', (
// {timeout: const Duration(seconds: 2)}) async {
// // Add derivation 5,6 and 7
// expect('Derivation 4', findsOneWidget);
// await createDerivation('Derivation 5');
// await createDerivation('Derivation 6');
// await createDerivation('Derivation 7');
// // Go home and come back to my wallets view
// await goBack();
// await sleep(100);
// await tapOn('manageWallets');
// await sleep(200);
// //Enter secret code
// await tester.enterText(find.byKey(Key('formKey')), pinCode);
// await sleep(200);
// // Go to derivation 6 and delete it
// await tester.tap(find.text('Derivation 6'));
// await sleep(100);
// await deleteWallet(true);
// // Go to 2nd derivation and check if it's de default
// await tester.tap(find.text('Derivation 2'));
// expect('Ce portefeuille est celui par defaut', findsOneWidget);
// await tapOn('setDefaultWallet');
// await sleep(100);
// expect('Ce portefeuille est celui par defaut', findsOneWidget);
// await sleep(300);
// // Display history, copy pubkey, go back and rename wallet name
// await tapOn('displayHistory');
// await sleep(400);
// await tapOn('copyPubkey');
// expect('Cette clé publique a été copié dans votre presse-papier.',
// findsOneWidget);
// await sleep(800);
// await goBack();
// await sleep(300);
// await tapOn('renameWallet');
// await sleep(100);
// await tapOn('walletName');
// await sleep(100);
// await tester.enterText(
// find.byKey(Key('walletName')), 'Renommage wallet 2');
// await sleep(300);
// await tapOn('renameWallet');
// await sleep(400);
// await goBack();
// expect('Renommage wallet 2', findsOneWidget);
// await createDerivation('Derivation 8');
// await createDerivation('Derivation 9');
// await createDerivation('Derivation 10');
// await createDerivation('Derivation 11');
// await createDerivation('Derivation 12');
// await createDerivation('Derivation 13');
// await createDerivation('Derivation 14');
// await createDerivation('Derivation 15');
// await createDerivation('Derivation 16');
// await createDerivation('Derivation 17');
// await createDerivation('Derivation 18');
// await createDerivation('Derivation 19');
// await createDerivation('Derivation 20');
// await sleep(400);
// // Scroll the wallet screen until Derivation 20 and open it
// await tester.scrollUntilVisible(find.byKey(Key('listWallets')), -300.0);
// expect('Derivation 20', findsOneWidget);
// await sleep(400);
// await tester.tap(find.text('Derivation 20'));
// await tapOn('copyPubkey');
// });
// test('Search - Search Pi profile, navigate in history transactions', (
// {timeout: const Duration(seconds: 2)}) async {
// expect('Derivation 20', findsOneWidget);
// await goBack();
// await goBack();
// await sleep(200);
// await tapOn('searchIcon');
// await sleep(400);
// await tester.enterText(find.byKey(Key('searchInput')),
// 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU');
// await sleep(100);
// await tapOn('copyPubkey');
// await sleep(500);
// await tapOn('switchPayHistory');
// await sleep(1200);
// // await tester.scrollIntoView(find.byValueKey('listTransactions'));
// await tester.scrollUntilVisible(
// find.byKey(Key('listTransactions')),
// -600.0,
// );
// await sleep(100);
// await tapOn('transaction33');
// expect('Commentaire:', findsOneWidget);
// // Want to paste pubkey copied, but doesn't work actualy with flutter driver: https://github.com/flutter/flutter/issues/47448
// // final ClipboardData pubkeyCopied =
// // await Clipboard.getData(Clipboard.kTextPlain);
// // await tester.enterText(pubkeyCopied.text);
// await sleep(300);
// }, timeout: Timeout(Duration(minutes: globalTimeout)));
// test('Wallet generation - Fast wallets generations', (
// {timeout: const Duration(seconds: 2)}) async {
// expect('Commentaire:', findsOneWidget);
// await goBack();
// await goBack();
// await deleteAllWallets();
// await sleep(100);
// final String pincode = await createNewKeychain('Fast wallet');
// await sleep(100);
// await tapOn('manageWallets');
// await sleep(200);
// await tester.enterText(find.byKey(Key('formKey')), pinCode);
// await sleep(100);
// await createDerivation('Derivation 2');
// await sleep(100);
// await tester.tap(find.text('Fast wallet'));
// expect('Fast wallet', findsOneWidget);
// // Wait 3 seconds at the end
// await sleep(3000);
// });
},
);
}

View File

@ -1,79 +0,0 @@
{
"first_ud": 10000,
"first_ud_reeval": 50,
"genesis_parameters": {
"genesis_certs_expire_on": 10,
"genesis_certs_min_received": 3,
"genesis_memberships_expire_on": 1051200,
"genesis_smith_certs_expire_on": 2102400,
"genesis_smith_certs_min_received": 3,
"genesis_smith_memberships_expire_on": 1051200
},
"identities": {
"test1": {
"balance": 10000,
"certs": ["test2", "test3", "test4"],
"pubkey": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa"
},
"test2": {
"balance": 10000,
"certs": ["test1", "test3", "test4"],
"pubkey": "5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb"
},
"test3": {
"balance": 10000,
"certs": ["test1", "test2", "test4"],
"pubkey": "5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p"
},
"test4": {
"balance": 10000,
"certs": ["test1", "test2", "test3"],
"pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5"
},
"testCesium1": {
"balance": 10000,
"certs": ["test1", "test2", "test3"],
"pubkey": "5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1"
}
},
"parameters": {
"babe_epoch_duration": 30,
"cert_period": 15,
"cert_max_by_issuer": 10,
"cert_min_received_cert_to_issue_cert": 2,
"cert_validity_period": 1000,
"idty_confirm_period": 40,
"idty_creation_period": 50,
"membership_period": 1000,
"pending_membership_period": 500,
"ud_creation_period": 10,
"ud_reeval_period": 50,
"smith_cert_period": 15,
"smith_cert_max_by_issuer": 8,
"smith_cert_min_received_cert_to_issue_cert": 2,
"smith_cert_validity_period": 1000,
"smith_membership_period": 1000,
"smith_pending_membership_period": 500,
"smiths_wot_first_cert_issuable_on": 4,
"smiths_wot_min_cert_for_membership": 3,
"wot_first_cert_issuable_on": 0,
"wot_min_cert_for_create_idty_right": 3,
"wot_min_cert_for_membership": 3
},
"smiths": {
"test1": {
"certs": ["test2", "test3", "test4"]
},
"test2": {
"certs": ["test1", "test3", "test4"]
},
"test3": {
"certs": ["test1", "test2", "test4"]
},
"test4": {
"certs": ["test1", "test2", "test3"]
}
},
"sudo_key": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa",
"technical_committee": ["test1", "test2", "test3"]
}

View File

@ -1,18 +0,0 @@
version: "3.5"
services:
duniter-v2s-gecko-tests:
container_name: duniter-v2s-gecko-tests
image: duniter/duniter-v2s:debug-latest
command: --sealing=manual
ports:
- "127.0.0.1:9615:9615"
- "127.0.0.1:9933:9933"
- "0.0.0.0:9944:9944"
- "30333:30333"
environment:
DUNITER_INSTANCE_NAME: "gecko_tests"
DUNITER_CHAIN_NAME: "dev"
DUNITER_GENESIS_CONFIG: "/var/lib/duniter/gecko_tests.json"
volumes:
- ./data:/var/lib/duniter

View File

@ -1,6 +0,0 @@
#!/bin/bash
for test_file in $(ls integration_test/scenarios/); do
testName=$(echo $test_file | awk -F '.' '{print $1}')
./integration_test/launch_test.sh $testName || break
done

View File

@ -1,29 +0,0 @@
#!/bin/bash
testName=$1
option=$2
[[ ! $testName ]] && testName='gecko_complete'
# Get local IP and set .env
ip_address=$(hostname -I | awk '{print $1}')
echo "ip_address=$ip_address" > .env
[[ $option == 'human' ]] && echo "isHumanReading=true" >> .env
## Start local Duniter node
cd integration_test/duniter
docker compose down
rm -rf data/chains
docker compose up -d
cd ../..
# Start integration test
flutter test integration_test/scenarios/$testName.dart && echo '0' > /tmp/geckoTestResult || echo '1' > /tmp/geckoTestResult
# Reset .env
echo "ip_address=127.0.0.1" > .env
# Stop Duniter
cd integration_test/duniter
docker compose down

View File

@ -1,61 +0,0 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('Certifications state', (testerLoc) async {
tester = testerLoc;
// Connect local node and import test chest in background
await bkFastStart();
// Open chest
await firstOpenChest();
spawnBlock(until: 15);
await goBack();
// Go wallet 5 view
await tapKey(keyOpenSearch);
await enterText(keySearchField, test5.address);
await tapKey(keyConfirmSearch);
await waitFor(test5.shortAddress());
await tapKey(keySearchResult(test5.address));
await waitFor('Certifier');
await waitFor('Vous devez ', reverse: true);
await waitFor('Vous pourrez renouveler ', reverse: true);
// Background pay 25
await bkPay(
fromAddress: test1.address, destAddress: test5.address, amount: 25);
await waitFor('25.0', exactMatch: true);
await spawnBlock();
await waitFor('22.0', exactMatch: true);
await bkCertify(
fromAddress: test1.address,
destAddress: test5.address,
spawnBloc: false);
await bkConfirmIdentity(fromAddress: test5.address, name: test5.name);
await waitFor('1', exactMatch: true);
await bkCertify(
fromAddress: test2.address,
destAddress: test5.address,
spawnBloc: false);
// await waitFor('2', exactMatch: true);
await bkCertify(fromAddress: test3.address, destAddress: test5.address);
await waitFor('3', exactMatch: true);
await bkCertify(fromAddress: test4.address, destAddress: test5.address);
await waitFor('4', exactMatch: true);
// await bkPay(
// fromAddress: test2.address, destAddress: test5.address, amount: 40);
await waitFor('21.99', exactMatch: true);
await spawnBlock(until: 30);
await waitFor('121.99', exactMatch: true);
await spawnBlock(until: 40);
await waitFor('221.99', exactMatch: true);
}, timeout: testTimeout());
}

View File

@ -1,140 +0,0 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('Gecko complete', (testerLoc) async {
// Share WidgetTester to test provider
tester = testerLoc;
// Start app and wait finish starting
await startWait();
// Change Duniter endpoint to local
await changeNode();
// Delete all existing chests is exists
await deleteAllWallets();
// Restore the test chest
await restoreChest();
// Execute a transaction to test5
await payTest2();
// Certify test5 account with 3 accounts to become member
await certifyTest5();
}, timeout: testTimeout());
}
Future payTest2() async {
spawnBlock(until: 13);
await waitFor('Rechercher');
await tapKey(keyOpenSearch);
final addressToSearch = await clipPaste();
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
expect(addressToSearch, test5.address);
await enterText(keySearchField, addressToSearch);
await tapKey(keyConfirmSearch);
await waitFor(endAddress);
await tapKey(keySearchResult(addressToSearch));
await waitFor(endAddress);
await waitFor('0.0', exactMatch: true);
await tapKey(keyPay);
await enterText(keyAmountField, '12.14');
await tapKey(keyConfirmPayment);
spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen, duration: 0);
await waitFor('12.14');
spawnBlock(duration: 500);
await waitFor('9.14');
humanRead(2);
}
Future certifyTest5() async {
// Create identity with Test1 account
await tapKey(keyCertify);
await tapKey(keyConfirm);
spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen);
await waitFor('Identité créée');
// Confirm Identity Test5
await tapKey(keyAppBarChest, duration: 300);
await tapKey(keyOpenWallet(test5.address));
await tapKey(keyCopyAddress);
humanRead(3);
await tapKey(keyConfirmIdentity);
await enterText(keyEnterIdentityUsername, test5.name);
await tapKey(keyConfirm);
spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen);
await waitFor('Identité confirmée');
humanRead(2);
// Set wallet 2 as default wallet
await goBack();
await tapKey(keyOpenWallet(test2.address));
await tapKey(keySetDefaultWallet);
await waitFor('Ce portefeuille est celui par defaut');
// Search Wallet 5 again
await tapKey(keyAppBarSearch);
final addressToSearch = await clipPaste();
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
expect(addressToSearch, test5.address);
await enterText(keySearchField, addressToSearch);
await tapKey(keyConfirmSearch);
await waitFor(endAddress);
await tapKey(keySearchResult(addressToSearch));
await waitFor(endAddress);
await waitFor('1');
// Certify with test2 account
await tapKey(keyCertify);
await tapKey(keyConfirm);
spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen);
await waitFor('2');
// Change default wallet to test3
await tapKey(keyPay);
await tapKey(keyChangeChest);
await tapKey(keySelectThisWallet(test3.address));
await tapKey(keyConfirm);
await sleep();
// Certify with test3 account
await tapKey(keyCertify);
await tapKey(keyConfirm);
spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen);
await waitFor('Vous devez attendre');
// Check if test5 is member
await tapKey(keyAppBarChest, duration: 300);
await tapKey(keyOpenWallet(test5.address));
await waitFor('Membre validé !');
// spawn 20 blocs and check if ud is creating
await spawnBlock(until: 20);
await waitFor('109.13');
await spawnBlock(until: 30);
await waitFor('209.13');
// Check UD reval
await spawnBlock(until: 60);
await waitFor('509.57');
humanRead(5);
}

View File

@ -1,67 +0,0 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('Identity revocation', (testerLoc) async {
tester = testerLoc;
// Connect local node and import test chest in background
await bkFastStart();
// Open chest
await firstOpenChest();
await spawnBlock(until: 13);
await sleep();
// Create test5 identity
await bkPay(
fromAddress: test1.address, destAddress: test5.address, amount: 30);
sub.reload();
await bkCertify(fromAddress: test1.address, destAddress: test5.address);
sub.reload();
await sleep();
// Certify test5 to become member
await tapKey(keyOpenWallet(test5.address));
await bkConfirmIdentity(fromAddress: test5.address, name: test5.name);
await bkCertify(fromAddress: test2.address, destAddress: test5.address);
await bkCertify(fromAddress: test3.address, destAddress: test5.address);
await waitFor('Membre validé !', exactMatch: true);
// Revoke test5
await tapKey(keyManageMembership, duration: 1000);
await tapKey(keyRevokeIdty);
await tapKey(keyConfirm);
spawnBlock(duration: 2000);
await waitFor('validé !', timeout: const Duration(seconds: 4));
await tapKey(keyCloseTransactionScreen, duration: 0);
await waitFor('Aucune identité', exactMatch: true);
await sleep();
// Check test1 cannot be revoked
await goBack();
await tapKey(keyAddDerivation);
await tapKey(keyOpenWallet(test1.address), duration: 500);
await tapKey(keyManageMembership, duration: 1000);
await waitFor('Vous ne pouvez pas révoquer cette identité');
// // Try migrate test1 identity to test6 address
// await tapKey(keyMigrateIdentity);
// await tapKey(keySelectWallet);
// await tapKey(keySelectThisWallet(test6.address), selectLast: true);
// await spawnBlock(number: 100);
// await waitFor('Vous devez attendre', reverse: true);
// await waitForButtonEnabled(keyConfirm);
// await tapKey(keyConfirm, duration: 500);
// await spawnBlock(duration: 2000);
// await waitFor('validé !');
// await tapKey(keyCloseTransactionScreen, duration: 0);
// await sleep(5000);
}, timeout: testTimeout());
}

View File

@ -1,64 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('Migrate Cesium identity and balance', (testerLoc) async {
tester = testerLoc;
// Connect local node and import test chest in background
await bkFastStart();
// Open chest
await firstOpenChest();
// Go to test1 options and check if balance growup with UDs creations
await tapKey(keyAddDerivation);
await waitFor('Portefeuille 6');
await scrollUntil(keyImportG1v1);
await tapKey(keyImportG1v1);
await enterText(keyCesiumId, 'test');
await enterText(keyCesiumPassword, 'test');
await waitFor(cesiumTest1.shortAddress());
await waitFor('100.0');
await waitFor('3', exactMatch: true);
isObscureText();
await tapKey(keyCesiumIdVisible);
await tester.pumpAndSettle();
isObscureText(false);
await tapKey(keyCesiumIdVisible);
await tester.pumpAndSettle();
isObscureText();
await tapKey(keySelectWallet);
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
await waitForButtonEnabled(keyConfirm);
await tapKey(keyConfirm);
spawnBlock(duration: 2000);
await waitFor('validé !');
await tapKey(keyCloseTransactionScreen, duration: 0);
await tapKey(keyOpenWallet(test6.address), duration: 300);
await waitFor('3', exactMatch: true);
await waitFor('Membre validé !');
await waitFor('99.98', exactMatch: true);
}, timeout: testTimeout());
}
isObscureText([bool isObscure = true]) {
final passwordTextFormField = find.descendant(
of: find.byKey(keyCesiumId),
matching: find.byType(EditableText),
);
final input = tester.widget<EditableText>(passwordTextFormField);
expect(input.obscureText, isObscure ? isTrue : isFalse);
}

View File

@ -1,16 +0,0 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('Onboarding and multi chest', (testerLoc) async {
tester = testerLoc;
await bkFastStart(false);
await onboardingNewChest();
}, timeout: testTimeout());
}

View File

@ -1,28 +0,0 @@
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:integration_test/integration_test.dart';
import '../utility/general_actions.dart';
import '../utility/tests_utility.dart';
void main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
await dotenv.load();
testWidgets('UDs creation state', (testerLoc) async {
tester = testerLoc;
// Connect local node and import test chest in background
await bkFastStart();
// Open chest
await firstOpenChest();
// Go to test1 options and check if balance growup with UDs creations
await tapKey(keyOpenWallet(test1.address));
await waitFor('100.0', exactMatch: true);
await spawnBlock(until: 10);
await waitFor('200.0', exactMatch: true);
await spawnBlock(until: 20);
await waitFor('300.0', exactMatch: true);
}, timeout: testTimeout());
}

View File

@ -1,169 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:provider/provider.dart';
import 'tests_utility.dart';
// GENERAL ACTIONS
Future changeNode() async {
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
log.d('ip address: $ipAddress');
await tapKey(keyDrawerMenu);
await tapKey(keyParameters);
await tapKey(keySelectDuniterNodeDropDown, duration: 5);
await tapKey(keySelectDuniterNode('Personnalisé'), selectLast: true);
await enterText(keyCustomDuniterEndpoint, 'ws://$ipAddress:9944');
await tapKey(keyConnectToEndpoint);
await isIconPresent(Icons.add_card_sharp,
timeout: const Duration(seconds: 8));
await goBack();
}
Future deleteAllWallets() async {
if (await isPresent('Rechercher')) {
await tapKey(keyDrawerMenu);
await tapKey(keyParameters);
// Check if ud unit checkbox is checked
final isUdUnit = await isIconPresent(Icons.check_box);
// If yes, tap on to use currency value
if (isUdUnit) await tapKey(keyUdUnit, duration: 0);
await tapKey(keyDeleteAllWallets);
await tapKey(keyConfirm);
await tester.pumpAndSettle();
}
}
Future restoreChest() async {
// Copy test mnemonic in clipboard
await clipCopy(testMnemonic);
// Open screen import chest
await tapKey(keyRestoreChest, duration: 0);
// Tap on button to paste mnemonic
await tapKey(keyPastMnemonic);
// Tap on next button 4 times to skip 3 screen
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
// Check if cached password checkbox is checked
final isCached = await isIconPresent(Icons.check_box);
// If not, tap on to cache password
if (!isCached) await tapKey(keyCachePassword, duration: 0);
// Enter password
await enterText(keyPinForm, 'AAAAA', 0);
// Check if string "Accéder à mon coffre" is present in screen
await waitFor('Accéder à mon coffre');
// Go to wallets home
await tapKey(keyGoWalletsHome, duration: 0);
// Check if string "ĞD" is present in screen
await waitFor('ĞD');
// Tap on add a new derivation button
await addDerivation();
// Tap on Wallet 5
await tapKey(keyOpenWallet(test5.address));
// Copy address of Wallet 5
await tapKey(keyCopyAddress);
// Check if string "Cette adresse a été copié" is present in screen
await waitFor('Cette adresse a été copié');
// Pop screen 2 time to go back home
await goBack();
await goBack();
}
Future onboardingNewChest() async {
final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(homeContext, listen: false);
// Open screen create new wallet
await tapKey(keyOnboardingNewChest);
// Tap on next button 4 times to skip 3 screen
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await waitFor('7', exactMatch: true);
final word41 = getWidgetText(keyMnemonicWord('4'));
// Change 2 times mnemonic
await tapKey(keyGenerateMnemonic);
await tester.pumpAndSettle();
final word42 = getWidgetText(keyMnemonicWord('4'));
expect(word41, isNot(word42));
await tapKey(keyGenerateMnemonic, duration: 500);
await tester.pumpAndSettle();
final word43 = getWidgetText(keyMnemonicWord('4'));
expect(word42, isNot(word43));
// Go next screen
await tapKey(keyGoNext);
await tester.pumpAndSettle();
// Enter asked word
final askedWordNumber = int.parse(getWidgetText(keyAskedWord));
List mnemonic = generateWalletProvider.generatedMnemonic!.split(' ');
final askedWord = mnemonic[askedWordNumber - 1];
await enterText(keyInputWord, askedWord);
await waitFor('Continuer', exactMatch: true);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await tapKey(keyGoNext);
await waitFor('AAAAA', exactMatch: true);
await tapKey(keyGoNext);
// Check if cached password checkbox is checked
final isCached = await isIconPresent(Icons.check_box);
// If not, tap on to cache password
if (!isCached) await tapKey(keyCachePassword, duration: 0);
// Enter password
await enterText(keyPinForm, 'AAAAA', 0);
// Check if string "Accéder à mon coffre" is present in screen
await waitFor('Accéder à mon coffre');
// Go to wallets home
await tapKey(keyGoWalletsHome, duration: 0);
// Check if string "Mon portefeuille co" is present in screen
await waitFor('Mon portefeuille co');
await waitFor('0.0', exactMatch: true);
// await waitFor('Scanner un');
}
Future addDerivation() async {
await tapKey(keyAddDerivation);
await waitFor('Portefeuille 5');
}
Future firstOpenChest() async {
await tapKey(keyOpenWalletsHomme);
sleep(300);
final isCached = await isIconPresent(Icons.check_box);
if (!isCached) await tapKey(keyCachePassword, duration: 0);
await enterText(keyPinForm, 'AAAAA', 0);
await waitFor('100.0', exactMatch: true);
}

View File

@ -1,328 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
import 'dart:io' as io;
import 'package:gecko/main.dart' as app;
final bool isHumanReading =
dotenv.env['isHumanReading'] == 'true' ? true : false;
Timeout testTimeout([int seconds = 120]) =>
Timeout(Duration(seconds: isHumanReading ? 600 : seconds));
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
late WidgetTester tester;
// TEST WALLETS CONSTS
const testMnemonic =
'pipe paddle ketchup filter life ice feel embody glide quantum ride usage';
final test1 =
TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test1');
final test2 =
TestWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb', 'test2');
final test3 =
TestWallet('5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p', 'test3');
final test4 =
TestWallet('5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5', 'test4');
final test5 =
TestWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R', 'test5');
final test6 =
TestWallet('5GxEp3do81j97kNaH4JyZgDXuPoKWoTuxXXWGyyNXeKeVLHb', 'test6');
final test7 =
TestWallet('5FZ1sSvREbQLCtSSCvMUx7KCAnpJkB7q5mfz2oixiZq2ChET', 'test7');
final test8 =
TestWallet('5CoKV9EEgwb2NmWamTXUAa6ycfNb2k1iNfVGvJAkg7dLq9RH', 'test8');
final cesiumTest1 = TestWallet(
'5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1', 'cesiumTest1');
final cesiumTest2 = TestWallet(
'5DTnny1tTkUs1SXHZTx98RUAj76Z88FfFhsQjd48dXnk8gHR', 'cesiumTest2');
final cesiumTest3 = TestWallet(
'5EJct9jTDNKco4YiYfETAseq1gaduBtsJUcNnFicfvh3bTV6', 'cesiumTest3');
final cesiumTest4 = TestWallet(
'5HD1oSv6A7VNxPYos6F86JFZ3bhz5LnEaWC4hkwLMj84v4ww', 'cesiumTest4');
// CUSTOM FUNCTIONS
Future sleep([int time = 1000]) async {
await Future.delayed(Duration(milliseconds: time));
}
Future<String> clipPaste() async =>
(await Clipboard.getData('text/plain'))?.text ?? '';
clipCopy(String text) async =>
await Clipboard.setData(ClipboardData(text: text));
Future humanRead([int time = 1, bool force = false]) async {
if (isHumanReading || force) io.sleep(Duration(seconds: time));
}
Future tapKey(Key buttonKey,
{Finder? customFinder, int duration = 100, bool selectLast = false}) async {
if (duration != 0) {
await tester.pumpAndSettle(Duration(milliseconds: duration));
}
final Finder finder = customFinder ?? find.byKey(buttonKey);
log.d('INTEGRATION TEST: Tap on ${finder.description}}');
await tester.tap(selectLast ? finder.last : finder);
humanRead();
}
Finder findByKey(Key key) {
return find.byKey(key);
}
bool isButtonEnabled(Key key) {
return tester.widget<ElevatedButton>(findByKey(key)).enabled;
}
Future scrollUntil(Key element) async {
final findList = find.byType(Scrollable);
final findElement = findByKey(element);
await tester.scrollUntilVisible(
findElement,
500.0,
scrollable: findList,
);
}
Future<void> waitForButtonEnabled(Key key,
{Duration timeout = const Duration(seconds: 5),
bool reverse = false}) async {
final end = DateTime.now().add(timeout);
log.d('INTEGRATION TEST: Wait for $key to be enabled');
do {
if (DateTime.now().isAfter(end)) {
throw Exception('Timed out waiting for button enabled: $key');
}
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 100));
} while (reverse ? isButtonEnabled(key) : !isButtonEnabled(key));
humanRead();
}
Future goBack() async {
final NavigatorState navigator = tester.state(find.byType(Navigator));
log.d('INTEGRATION TEST: Go back');
navigator.pop();
await tester.pump();
humanRead();
}
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');
await tester.enterText(find.byKey(fieldKey), textIn);
humanRead();
}
Future<void> waitFor(String text,
{Duration timeout = const Duration(seconds: 5),
bool reverse = false,
bool exactMatch = false}) async {
final end = DateTime.now().add(timeout);
Finder finder = exactMatch ? find.text(text) : find.textContaining(text);
log.d('INTEGRATION TEST: Wait for: $text');
final String searchType = reverse ? 'reversed text' : 'text';
do {
if (DateTime.now().isAfter(end)) {
throw Exception('Timed out waiting for $searchType : "$text"');
}
await tester.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 100));
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
humanRead();
}
// Test if text is visible on screen, return a boolean
Future<bool> isPresent(String text,
{Duration timeout = const Duration(seconds: 1)}) async {
try {
await waitFor(text, timeout: timeout);
humanRead();
return true;
} catch (exception) {
humanRead();
return false;
}
}
// Test if widget exist on screen, return a boolean
Future<bool> isIconPresent(IconData icon,
{Duration timeout = const Duration(seconds: 1)}) async {
await tester.pumpAndSettle();
final finder = find.byIcon(icon);
log.d('tatatatatatata: ${finder.evaluate()}');
humanRead();
return finder.evaluate().isEmpty ? false : true;
}
Future spawnBlock({int number = 1, int duration = 200, int? until}) async {
if (duration != 0) {
await sleep(duration);
}
if (until != null) {
number = until - sub.blocNumber;
}
await sub.spawnBlock(number);
await sleep(200);
}
// Pay in background
Future bkPay(
{required String fromAddress,
required String destAddress,
required double amount}) async {
sub.pay(
fromAddress: fromAddress,
destAddress: destAddress,
amount: amount,
password: 'AAAAA');
await sleep(500);
await spawnBlock();
await sleep(500);
}
// Certify in background
Future bkCertify(
{required String fromAddress,
required String destAddress,
bool spawnBloc = true}) async {
sub.certify(fromAddress, destAddress, 'AAAAA');
if (spawnBloc) {
await sleep(500);
await spawnBlock();
}
await sleep(500);
}
// Confirm my identity in background
Future bkConfirmIdentity(
{required String fromAddress, required String name}) async {
sub.confirmIdentity(fromAddress, name, 'AAAAA');
await sleep(500);
await spawnBlock();
await sleep(500);
}
// Change node in background
Future bkSetNode([String? endpoint]) async {
if (endpoint == null) {
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
endpoint = 'ws://$ipAddress:9944';
}
configBox.put('customEndpoint', endpoint);
sub.connectNode(homeContext);
}
// Restore chest in background
Future bkRestoreChest([String mnemonic = testMnemonic]) async {
final myWalletProvider =
Provider.of<MyWalletsProvider>(homeContext, listen: false);
final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(homeContext, listen: false);
await generateWalletProvider.storeHDWChest(homeContext);
for (int number = 0; number <= 4; number++) {
await _addImportAccount(
mnemonic: mnemonic,
chest: 0,
number: number,
name: 'test${number + 1}',
derivation: (number + 1) * 2);
}
myWalletProvider.reload();
}
Future<WalletData> _addImportAccount(
{required String mnemonic,
required int chest,
required int number,
required String name,
required int derivation}) async {
final address = await sub.importAccount(
mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA');
final myWallet = WalletData(
version: dataVersion,
chest: chest,
address: address,
number: number,
name: name,
derivation: derivation,
imageDefaultPath: '${number % 4}.png');
await walletBox.add(myWallet);
return myWallet;
}
// Delete all wallets in background
Future bkDeleteAllWallets() async {
final myWalletProvider =
Provider.of<MyWalletsProvider>(homeContext, listen: false);
final isWalletsPresents =
await isPresent('Scanner un', timeout: const Duration(milliseconds: 300));
if (isWalletsPresents) {
await walletBox.clear();
await chestBox.clear();
await configBox.delete('defaultWallet');
await configBox.delete('isUdUnit');
await sub.deleteAllAccounts();
myWalletProvider.pinCode = '';
myWalletProvider.reload();
}
}
Future bkFastStart([bool restoreChest = true]) async {
// Start app and wait finish starting
await startWait();
// Connect to local endpoint
await bkSetNode();
await sleep();
// Delete all existing chests is exists
await bkDeleteAllWallets();
if (restoreChest) {
// Restore the test chest
await bkRestoreChest();
await waitFor("y'a pas de lézard");
}
}
Future startWait() async {
app.main();
await waitFor('Test starting...', reverse: true);
await tester.pumpAndSettle(const Duration(milliseconds: 300));
await sleep(3000);
}
String getWidgetText(Key key) {
final word4Finder = find.byKey(key);
return (word4Finder.evaluate().single.widget as Text).data!;
}
class TestWallet {
String address;
String name;
TestWallet(this.address, this.name);
endAddress() => address.substring(address.length - 6);
shortAddress() => getShortPubkey(address);
}

View File

@ -1,2 +1 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +1 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,41 +0,0 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

View File

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
@ -288,7 +288,6 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 72JY5XXU29;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -421,7 +420,6 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 72JY5XXU29;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -449,7 +447,6 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 72JY5XXU29;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",

View File

@ -2,10 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for barcode scanning.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Access to user's is required for profile image upload in wallet management</string>
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for barcode scanning.</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
@ -16,8 +14,6 @@
<string>6.0</string>
<key>CFBundleName</key>
<string>gecko</string>
<key>ITSAppUsesNonExemptEncryption</key>
<string>NO</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

View File

@ -3,13 +3,18 @@ import 'package:flutter/material.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:hive_flutter/hive_flutter.dart';
import 'package:hive/hive.dart';
import 'package:logger/logger.dart';
import 'package:shared_preferences/shared_preferences.dart';
// Version of box data
const int dataVersion = 4;
// Files paths
Directory? appPath;
late String appVersion;
late SharedPreferences prefs;
const int pinLength = 5;
const String appLang = 'english';
@ -18,6 +23,7 @@ late Box<ChestData> chestBox;
late Box configBox;
late Box<G1WalletsList> g1WalletsBox;
late Box<G1WalletsList> contactsBox;
// late Box keystoreBox;
late Directory imageDirectory;
@ -33,20 +39,19 @@ late double ratio;
late BuildContext homeContext;
// Logger
final log = Logger();
var log = Logger();
// Colors
const Color orangeC = Color(0xffd07316);
const Color yellowC = Color(0xffFFD68E);
const Color floattingYellow = Color(0xffEFEFBF);
const Color backgroundColor = Color(0xFFF5F5F5);
Color orangeC = const Color(0xffd07316);
Color yellowC = const Color(0xffFFD68E);
Color floattingYellow = const Color(0xffEFEFBF);
Color backgroundColor = const Color(0xFFF5F5F5);
// Substrate settings
const String currencyName = 'ĞD';
const int ss58 = 42;
String currencyName = 'ĞD';
// Debug
const debugPin = true;
String indexerEndpoint = '';
late double balanceRatio;
late int udValue;

View File

@ -13,10 +13,11 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// ignore_for_file: avoid_print
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/models/chest_data.dart';
@ -24,7 +25,6 @@ import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/models/g1_wallets_list.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/wallets_profiles.dart';
import 'package:gecko/providers/home.dart';
@ -41,7 +41,9 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:window_size/window_size.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
@ -50,20 +52,18 @@ const bool enableSentry = true;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
if (kDebugMode) {
await dotenv.load();
if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
setWindowTitle('Ğecko');
setWindowMinSize(const Size(400, 700));
setWindowMaxSize(const Size(800, 1000));
}
HomeProvider homeProvider = HomeProvider();
// DuniterIndexer _duniterIndexer = DuniterIndexer();
HomeProvider _homeProvider = HomeProvider();
DuniterIndexer _duniterIndexer = DuniterIndexer();
await initHiveForFlutter();
await homeProvider.initHive();
appVersion = await homeProvider.getAppVersion();
// Reset GraphQL cache
// final cache = HiveStore();
// cache.reset();
await _homeProvider.initHive();
appVersion = await _homeProvider.getAppVersion();
prefs = await SharedPreferences.getInstance();
// Configure Hive and open boxes
Hive.registerAdapter(WalletDataAdapter());
@ -78,13 +78,15 @@ Future<void> main() async {
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
contactsBox = await Hive.openBox<G1WalletsList>("contactsBox");
await homeProvider.getValidEndpoints();
await _homeProvider.getValidEndpoints();
// await configBox.delete('isCacheChecked');
if (configBox.get('isCacheChecked') == null) {
configBox.put('isCacheChecked', false);
}
// log.d(await configBox.get('endpoint'));
_duniterIndexer.getValidIndexerEndpoint();
HttpOverrides.global = MyHttpOverrides();
if (kReleaseMode && enableSentry) {
@ -108,26 +110,27 @@ Future<void> main() async {
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
path: 'assets/translations',
fallbackLocale: const Locale('en'),
child: const Gecko(),
child: Gecko(indexerEndpoint),
),
),
);
} else {
log.i('Debug mode enabled: No sentry alerte');
print('Debug mode enabled: No sentry alerte');
runApp(
EasyLocalization(
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
path: 'assets/translations',
fallbackLocale: const Locale('en'),
child: const Gecko(),
fallbackLocale: const Locale('fr'),
child: Gecko(indexerEndpoint),
),
);
}
}
class Gecko extends StatelessWidget {
const Gecko({Key? key}) : super(key: key);
const Gecko(this.indexerEndpoint, {Key? key}) : super(key: key);
final String? indexerEndpoint;
@override
Widget build(BuildContext context) {
@ -146,8 +149,7 @@ class Gecko extends StatelessWidget {
ChangeNotifierProvider(create: (_) => SearchProvider()),
ChangeNotifierProvider(create: (_) => CesiumPlusProvider()),
ChangeNotifierProvider(create: (_) => SubstrateSdk()),
ChangeNotifierProvider(create: (_) => DuniterIndexer()),
ChangeNotifierProvider(create: (_) => SettingsProvider())
ChangeNotifierProvider(create: (_) => DuniterIndexer())
],
child: MaterialApp(
localizationsDelegates: context.localizationDelegates,

View File

@ -6,7 +6,7 @@ part 'g1_wallets_list.g.dart';
@HiveType(typeId: 2)
class G1WalletsList {
@HiveField(0)
late String address;
String? pubkey;
@HiveField(1)
double? balance;
@ -27,7 +27,7 @@ class G1WalletsList {
bool? isMembre;
G1WalletsList({
required this.address,
this.pubkey,
this.balance,
this.id,
this.avatar,
@ -37,14 +37,14 @@ class G1WalletsList {
});
G1WalletsList.fromJson(Map<String, dynamic> json) {
address = json['pubkey'];
pubkey = json['pubkey'];
balance = json['balance'];
id = json['id'] != null ? Id.fromJson(json['id']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['pubkey'] = address;
data['pubkey'] = pubkey;
data['balance'] = balance;
if (id != null) {
data['id'] = id!.toJson();

View File

@ -17,7 +17,7 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return G1WalletsList(
address: fields[0] as String,
pubkey: fields[0] as String?,
balance: fields[1] as double?,
id: fields[2] as Id?,
avatar: fields[3] as Image?,
@ -32,7 +32,7 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
writer
..writeByte(7)
..writeByte(0)
..write(obj.address)
..write(obj.pubkey)
..writeByte(1)
..write(obj.balance)
..writeByte(2)

View File

@ -1,10 +1,9 @@
const String getNameByAddressQ = r'''
query ($address: String!) {
account_by_pk(pubkey: $address) {
account_by_pk(id: $address) {
identity {
name
}
pubkey
}
}
''';
@ -12,18 +11,52 @@ query ($address: String!) {
const String searchAddressByNameQ = r'''
query ($name: String!) {
search_identity(args: {name: $name}) {
pubkey
id
name
}
}
''';
const String getHistoryByAddressQ = r'''
query ($address: String!) {
account_by_pk(id: "5CQ8T4qpbYJq7uVsxGPQ5q2df7x3Wa4aRY6HUWMBYjfLZhnn") {
transactions_issued {
receiver_id
amount
created_at
created_on
}
transactions_received {
issuer_id
amount
created_at
created_on
}
}
}
''';
const String getHistoryByAddressQ2 = r'''
query ($address: String!) {
{
transaction(where: {_or: [{issuer_id: {_eq: $address}},
{receiver_id: {_eq: $address}}]}, order_by: {created_at: desc})
{
amount
created_at
issuer_id
receiver_id
}
}
}
''';
const String getHistoryByAddressQ3 = r'''
query ($address: String!, $number: Int!, $cursor: String) {
transaction_connection(where:
{_or: [
{issuer_pubkey: {_eq: $address}},
{receiver_pubkey: {_eq: $address}}
{issuer_id: {_eq: $address}},
{receiver_id: {_eq: $address}}
]},
order_by: {created_at: desc},
first: $number,
@ -32,8 +65,8 @@ query ($address: String!, $number: Int!, $cursor: String) {
node {
amount
created_at
issuer_pubkey
receiver_pubkey
issuer_id
receiver_id
issuer {
identity {
name

View File

@ -6,10 +6,10 @@ class StatefulWrapper extends StatefulWidget {
const StatefulWrapper({Key? key, required this.onInit, required this.child})
: super(key: key);
@override
StatefulWrapperState createState() => StatefulWrapperState();
_StatefulWrapperState createState() => _StatefulWrapperState();
}
class StatefulWrapperState extends State<StatefulWrapper> {
class _StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
widget.onInit();

View File

@ -1,103 +0,0 @@
import 'package:flutter/material.dart';
// General
const keyInfoPopup = Key('keyInfoPopup');
const keyGoNext = Key('keyGoNext');
const keyCancel = Key('keyCancel');
const keyConfirm = Key('keyConfirm');
const keyAppBarSearch = Key('keyAppBarSearch');
const keyAppBarQrcode = Key('keyAppBarQrcode');
const keyAppBarChest = Key('keyAppBarChest');
// Home
const keyParameters = Key('keyParameters');
const keyContacts = Key('keyContacts');
const keyDrawerMenu = Key('keyDrawerMenu');
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
const keyOpenSearch = Key('keyOpenSearch');
const keyRestoreChest = Key('keyRestoreChest');
const keyOnboardingNewChest = Key('keyOnboardingNewChest');
// Wallets home
const keyImportG1v1 = Key('keyImportG1v1');
const keyChangeChest = Key('keyChangeChest');
const keyListWallets = Key('keyListWallets');
const keyAddDerivation = Key('keyAddDerivation');
// Wallet options
const keyCopyAddress = Key('keyCopyAddress');
const keyOpenActivity = Key('keyOpenActivity');
const keyManageMembership = Key('keyManageMembership');
const keySetDefaultWallet = Key('keySetDefaultWallet');
const keyDeleteWallet = Key('keyDeleteWallet');
const keyWalletName = Key('keyWalletName');
const keyRenameWallet = Key('keyRenameWallet');
const keyConfirmIdentity = Key('keyConfirmIdentity');
const keyEnterIdentityUsername = Key('keyEnterIdentityUsername');
// Chest options
const keyShowSeed = Key('keyShowSeed');
const keyChangePin = Key('keyChangePin');
const keycreateRootDerivation = Key('keycreateRootDerivation');
const keyDeleteChest = Key('keyDeleteChest');
// Manage membership
const keyMigrateIdentity = Key('keyMigrateIdentity');
const keyRevokeIdty = Key('keyRevokeIdty');
// Choose chest
const keyCreateNewChest = Key('keyCreateNewChest');
const keyImportChest = Key('keyImportChest');
// Profile view
const keyViewActivity = Key('keyViewActivity');
const keyCertify = Key('keyCertify');
const keyPay = Key('keyPay');
const keyAmountField = Key('keyAmountField');
const keyConfirmPayment = Key('keyConfirmPayment');
const keyCloseTransactionScreen = Key('keyCloseTransactionScreen');
// Activity view
const keyListTransactions = Key('keyListTransactions');
const keyActivityScreen = Key('keyActivityScreen');
// Unlock wallet
const keyUnlockWallet = Key('keyUnlockWallet');
const keyPinForm = Key('keyPinForm');
const keyPopButton = Key('keyPopButton');
const keyCachePassword = Key('keyCachePassword');
// Settings
const keyDeleteAllWallets = Key('keyDeleteAllWallets');
const keySelectDuniterNodeDropDown = Key('keySelectDuniterNodeDropDown');
const keyCustomDuniterEndpoint = Key('keyCustomDuniterEndpoint');
const keyConnectToEndpoint = Key('keyConnectToEndpoint');
const keyUdUnit = Key('keyUdUnit');
// Onboarding
const keyPastMnemonic = Key('keyPastMnemonic');
const keyBubbleSpeak = Key('keyBubbleSpeak');
const keyGenerateMnemonic = Key('keyGenerateMnemonic');
const keyAskedWord = Key('keyAskedWord');
const keyInputWord = Key('keyInputWord');
const keyGeneratedPin = Key('keyGeneratedPin');
const keyGoWalletsHome = Key('keyGoWalletsHome');
// Search
const keySearchField = Key('keySearchField');
const keyConfirmSearch = Key('keyConfirmSearch');
// Import Cesium wallet
const keyCesiumId = Key('keyCesiumId');
const keyCesiumPassword = Key('keyCesiumPassword');
const keySelectWallet = Key('keySelectWallet');
const keyCesiumIdVisible = Key('keyCesiumIdVisible');
// Items keys
Key keyTransaction(int keyId) => Key('keyTransaction$keyId');
Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word');
Key keySearchResult(String address) => Key('keySearchResult$address');
Key keySelectDuniterNode(String endpoint) =>
Key('keySelectDuniterNode$endpoint');
Key keyOpenWallet(String address) => Key('keyOpenWallet$address');
Key keySelectThisWallet(String address) => Key('keySelectThisWallet$address');

View File

@ -8,23 +8,23 @@ import 'package:path_provider/path_provider.dart';
class CesiumPlusProvider with ChangeNotifier {
TextEditingController cesiumName = TextEditingController();
Image defaultAvatar(double size) =>
Image defaultAvatar(double? size) =>
Image.asset(('assets/icon_user.png'), height: size);
CancelToken avatarCancelToken = CancelToken();
Future<List> _buildQuery(pubkey) async {
Future<List> _buildQuery(_pubkey) async {
var queryGetAvatar = json.encode({
"query": {
"bool": {
"should": [
{
"match": {
'_id': {"query": pubkey, "boost": 2}
'_id': {"query": _pubkey, "boost": 2}
}
},
{
"prefix": {'_id': pubkey}
"prefix": {'_id': _pubkey}
}
]
}
@ -60,14 +60,14 @@ class CesiumPlusProvider with ChangeNotifier {
return [podRequest, queryGetAvatar, headers];
}
Future<String> getName(String? pubkey) async {
String? name;
Future<String> getName(String? _pubkey) async {
String? _name;
if (g1WalletsBox.get(pubkey)?.csName != null) {
return g1WalletsBox.get(pubkey)!.csName!;
if (g1WalletsBox.get(_pubkey)?.csName != null) {
return g1WalletsBox.get(_pubkey)!.csName!;
}
List queryOptions = await _buildQuery(pubkey);
List queryOptions = await _buildQuery(_pubkey);
var dio = Dio();
late Response response;
@ -90,28 +90,28 @@ class CesiumPlusProvider with ChangeNotifier {
if (response.data['hits']['hits'].toString() == '[]') {
return '';
}
final bool nameExist =
final bool _nameExist =
response.data['hits']['hits'][0]['_source'].containsKey("title");
if (!nameExist) {
if (!_nameExist) {
return '';
}
name = response.data['hits']['hits'][0]['_source']['title'];
_name = response.data['hits']['hits'][0]['_source']['title'];
name ??= '';
g1WalletsBox.get(pubkey)!.csName = name;
_name ??= '';
g1WalletsBox.get(_pubkey)!.csName = _name;
return name;
return _name;
}
Future<Image?> getAvatar(String? pubkey, double size) async {
if (g1WalletsBox.get(pubkey)?.avatar != null) {
return g1WalletsBox.get(pubkey)!.avatar;
Future<Image?> 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);
List queryOptions = await _buildQuery(_pubkey);
late Response response;
try {
@ -138,12 +138,12 @@ class CesiumPlusProvider with ChangeNotifier {
return defaultAvatar(size);
}
final avatar =
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));
File('${(await getTemporaryDirectory()).path}/avatar_$_pubkey.png');
await avatarFile.writeAsBytes(base64.decode(_avatar));
final finalAvatar = Image.file(
avatarFile,
@ -151,7 +151,7 @@ class CesiumPlusProvider with ChangeNotifier {
fit: BoxFit.fitWidth,
);
g1WalletsBox.get(pubkey)!.avatar = finalAvatar;
g1WalletsBox.get(_pubkey)!.avatar = finalAvatar;
return finalAvatar;
}

View File

@ -4,26 +4,25 @@ import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
class ChestProvider with ChangeNotifier {
void reload() {
void rebuildWidget() {
notifyListeners();
}
Future deleteChest(context, ChestData chest) async {
final bool? answer = await (_confirmDeletingChest(context, chest.name));
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
if (answer ?? false) {
await sub.deleteAccounts(getChestWallets(chest));
await chestBox.delete(chest.key);
MyWalletsProvider myWalletProvider =
Future deleteChest(context, ChestData _chest) async {
final bool? _answer = await (_confirmDeletingChest(context, _chest.name));
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
if (_answer ?? false) {
await _sub.deleteAccounts(getChestWallets(_chest));
await chestBox.delete(_chest.key);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
myWalletProvider.pinCode = '';
_myWalletProvider.pinCode = '';
if (chestBox.isEmpty) {
await configBox.put('currentChest', 0);
@ -40,33 +39,33 @@ class ChestProvider with ChangeNotifier {
}
}
List<String> getChestWallets(ChestData chest) {
List<String> getChestWallets(ChestData _chest) {
List<String> toDelete = [];
log.d(chest.key);
log.d(_chest.key);
walletBox.toMap().forEach((key, WalletData value) {
if (value.chest == chest.key) {
if (value.chest == _chest.key) {
toDelete.add(value.address!);
}
});
return toDelete;
}
Future<bool?> _confirmDeletingChest(context, String? walletName) async {
Future<bool?> _confirmDeletingChest(context, String? _walletName) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])),
title: Text('areYouSureToDeleteWallet'.tr(args: [_walletName!])),
actions: <Widget>[
TextButton(
child: Text("no".tr(), key: keyCancel),
child: Text("no".tr(), key: const Key('cancelDeleting')),
onPressed: () {
Navigator.pop(context, false);
},
),
TextButton(
child: Text("yes".tr(), key: keyConfirm),
child: Text("yes".tr(), key: const Key('confirmDeleting')),
onPressed: () {
Navigator.pop(context, true);
},

View File

@ -5,10 +5,8 @@ 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/g1_wallets_list.dart';
import 'package:gecko/models/queries_indexer.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/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
@ -16,7 +14,6 @@ import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:truncate/truncate.dart';
class DuniterIndexer with ChangeNotifier {
Map<String, String?> walletNameIndexer = {};
@ -25,133 +22,89 @@ class DuniterIndexer with ChangeNotifier {
int nPage = 1;
int nRepositories = 20;
List? transBC;
List listIndexerEndpoints = [];
bool isLoadingIndexer = false;
void reload() {
notifyListeners();
}
Future<bool> checkIndexerEndpoint(String endpoint) async {
isLoadingIndexer = true;
notifyListeners();
final client = HttpClient();
client.connectionTimeout = const Duration(milliseconds: 4000);
try {
final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql'));
final response = await request.close();
if (response.statusCode != 200) {
Future checkIndexerEndpoint() async {
final oldEndpoint = indexerEndpoint;
while (true) {
await Future.delayed(const Duration(seconds: 30));
final _client = HttpClient();
_client.connectionTimeout = const Duration(milliseconds: 4000);
try {
final request =
await _client.postUrl(Uri.parse('$oldEndpoint/v1/graphql'));
final response = await request.close();
if (response.statusCode != 200) {
log.d('INDEXER IS OFFILINE');
indexerEndpoint = '';
} else {
// log.d('Indexer is online');
indexerEndpoint = oldEndpoint;
}
} catch (e) {
log.d('INDEXER IS OFFILINE');
indexerEndpoint = '';
isLoadingIndexer = false;
notifyListeners();
return false;
} else {
indexerEndpoint = endpoint;
await configBox.put('indexerEndpoint', endpoint);
// await configBox.put('customEndpoint', endpoint);
isLoadingIndexer = false;
notifyListeners();
final cache = HiveStore();
cache.reset();
return true;
}
} catch (e) {
log.d('INDEXER IS OFFILINE');
indexerEndpoint = '';
isLoadingIndexer = false;
notifyListeners();
return false;
}
}
// 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<String> getValidIndexerEndpoint() async {
// await configBox.delete('indexerEndpoint');
listIndexerEndpoints = await rootBundle
List _listEndpoints = await rootBundle
.loadString('config/indexer_endpoints.json')
.then((jsonStr) => jsonDecode(jsonStr));
// _listEndpoints.shuffle();
log.d(listIndexerEndpoints);
listIndexerEndpoints.add('Personnalisé');
if (configBox.containsKey('customIndexer')) {
return configBox.get('customIndexer');
// listIndexerEndpoints.insert(0, configBox.get('customIndexer'));
}
if (configBox.containsKey('indexerEndpoint')) {
if (await checkIndexerEndpoint(configBox.get('indexerEndpoint'))) {
return configBox.get('indexerEndpoint');
}
}
int i = 0;
// String _endpoint = '';
int statusCode = 0;
int _statusCode = 0;
final client = HttpClient();
client.connectionTimeout = const Duration(milliseconds: 3000);
final _client = HttpClient();
_client.connectionTimeout = const Duration(milliseconds: 3000);
do {
int listLenght = listIndexerEndpoints.length - 1;
int listLenght = _listEndpoints.length;
if (i >= listLenght) {
log.e('NO VALID INDEXER ENDPOINT FOUND');
indexerEndpoint = '';
break;
}
log.d('${i + 1}n indexer endpoint try: ${listIndexerEndpoints[i]}');
log.d(
(i + 1).toString() + 'n indexer endpoint try: ${_listEndpoints[i]}');
if (i != 0) {
await Future.delayed(const Duration(milliseconds: 300));
}
try {
String endpointPath = '${listIndexerEndpoints[i]}/v1/graphql';
final request = await client.postUrl(Uri.parse(endpointPath));
final request =
await _client.postUrl(Uri.parse('${_listEndpoints[i]}/v1/graphql'));
final response = await request.close();
indexerEndpoint = listIndexerEndpoints[i];
await configBox.put('indexerEndpoint', listIndexerEndpoints[i]);
statusCode = response.statusCode;
indexerEndpoint = _listEndpoints[i];
_statusCode = response.statusCode;
i++;
} on TimeoutException catch (_) {
log.e('This endpoint is timeout, next');
statusCode = 50;
_statusCode = 50;
i++;
continue;
} on SocketException catch (_) {
log.e('This endpoint is a bad endpoint, next');
statusCode = 70;
_statusCode = 70;
i++;
continue;
} on Exception {
log.e('Unknown error');
statusCode = 60;
_statusCode = 60;
i++;
continue;
}
} while (statusCode != 200);
} while (_statusCode != 200);
log.i('INDEXER: $indexerEndpoint');
log.i('INDEXER: ' + indexerEndpoint);
return indexerEndpoint;
}
@ -159,34 +112,34 @@ class DuniterIndexer with ChangeNotifier {
[WalletData? wallet,
double size = 20,
bool canEdit = false,
Color color = Colors.black,
Color _color = Colors.black,
FontWeight fontWeight = FontWeight.w400,
FontStyle fontStyle = FontStyle.italic]) {
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
if (indexerEndpoint == '') {
if (wallet == null) {
return const SizedBox();
} else {
if (canEdit) {
return walletOptions.walletName(context, wallet, size, color);
return _walletOptions.walletName(context, wallet, size, _color);
} else {
return walletOptions.walletNameController(context, wallet, size);
return _walletOptions.walletNameController(context, wallet, size);
}
}
}
final httpLink = HttpLink(
final _httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: httpLink,
link: _httpLink,
),
);
return GraphQLProvider(
client: client,
client: _client,
child: Query(
options: QueryOptions(
document: gql(
@ -209,33 +162,27 @@ class DuniterIndexer with ChangeNotifier {
walletNameIndexer[address] =
result.data?['account_by_pk']?['identity']?['name'];
g1WalletsBox.put(
address,
G1WalletsList(
address: address, username: walletNameIndexer[address]));
// log.d(g1WalletsBox.toMap().values.first.username);
if (walletNameIndexer[address] == null) {
if (wallet == null) {
return const SizedBox();
} else {
if (canEdit) {
return walletOptions.walletName(context, wallet, size, color);
return _walletOptions.walletName(
context, wallet, size, _color);
} else {
return walletOptions.walletNameController(
return _walletOptions.walletNameController(
context, wallet, size);
}
}
}
return Text(
color == Colors.grey[700]!
_color == Colors.grey[700]!
? '(${walletNameIndexer[address]!})'
: truncate(walletNameIndexer[address]!, 20),
: walletNameIndexer[address]!,
style: TextStyle(
fontSize: size,
color: color,
color: _color,
fontWeight: fontWeight,
fontStyle: fontStyle,
),
@ -247,28 +194,26 @@ class DuniterIndexer with ChangeNotifier {
Widget searchIdentity(BuildContext context, String name) {
// WalletOptionsProvider _walletOptions =
// Provider.of<WalletOptionsProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfiles =
WalletsProfilesProvider _walletsProfiles =
Provider.of<WalletsProfilesProvider>(context, listen: false);
if (indexerEndpoint == '') {
return const Text('Aucun résultat');
}
log.d(indexerEndpoint);
final httpLink = HttpLink(
final _httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(
store: HiveStore()), // GraphQLCache(store: HiveStore())
link: httpLink,
cache: GraphQLCache(store: HiveStore()),
link: _httpLink,
),
);
return GraphQLProvider(
client: client,
client: _client,
child: Query(
options: QueryOptions(
document: gql(
@ -294,37 +239,29 @@ class DuniterIndexer with ChangeNotifier {
return Text('noResult'.tr());
}
double avatarSize = 55;
int keyID = 0;
double _avatarSize = 55;
return Expanded(
child: ListView(children: <Widget>[
for (Map profile in identities)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult(profile['pubkey']),
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider.defaultAvatar(avatarSize),
leading: _cesiumPlusProvider.defaultAvatar(_avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(profile['pubkey']),
Text(getShortPubkey(profile['id']),
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(context, profile['pubkey'], 16),
]),
]),
),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [balance(context, profile['id'], 16)]),
subtitle: Row(children: <Widget>[
Text(profile['name'] ?? '',
style: const TextStyle(
@ -337,15 +274,14 @@ class DuniterIndexer with ChangeNotifier {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfiles.address = profile['pubkey'];
_walletsProfiles.address = profile['id'];
return WalletViewScreen(
address: profile['pubkey'],
pubkey: profile['id'],
username: g1WalletsBox
.get(profile['pubkey'])
.get(profile['id'])
?.id
?.username,
avatar:
g1WalletsBox.get(profile['pubkey'])?.avatar,
avatar: g1WalletsBox.get(profile['id'])?.avatar,
);
}),
);
@ -357,29 +293,29 @@ class DuniterIndexer with ChangeNotifier {
);
}
List parseHistory(blockchainTX, pubkey) {
List parseHistory(blockchainTX, _pubkey) {
var transBC = [];
int i = 0;
for (final trans in blockchainTX) {
final transaction = trans['node'];
final direction =
transaction['issuer_pubkey'] != pubkey ? 'RECEIVED' : 'SENT';
transaction['issuer_id'] != _pubkey ? 'RECEIVED' : 'SENT';
transBC.add(i);
transBC[i] = [];
transBC[i].add(DateTime.parse(transaction['created_at']));
final int amountBrut = transaction['amount'];
final double amount = removeDecimalZero(amountBrut / 100);
final num amount = removeDecimalZero(amountBrut / 100);
if (direction == "RECEIVED") {
transBC[i].add(transaction['issuer_pubkey']);
transBC[i].add(transaction['issuer_id']);
transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
transBC[i].add(amount.toString());
} else if (direction == "SENT") {
transBC[i].add(transaction['receiver_pubkey']);
transBC[i].add(transaction['receiver_id']);
transBC[i].add(transaction['receiver']['identity']?['name'] ?? '');
transBC[i].add('- ' + amount.toString());
}
transBC[i].add(amount);
transBC[i].add(direction);
// transBC[i].add(''); //transaction comment
i++;
@ -387,7 +323,7 @@ class DuniterIndexer with ChangeNotifier {
return transBC;
}
FetchMoreOptions? checkQueryResult(result, opts, pubkey) {
FetchMoreOptions? checkQueryResult(result, opts, _pubkey) {
final List<dynamic>? blockchainTX =
(result.data['transaction_connection']['edges'] as List<dynamic>?);
// final List<dynamic> mempoolTX =
@ -418,9 +354,9 @@ class DuniterIndexer with ChangeNotifier {
as List<dynamic>
];
log.d('repos: $previousResultData');
log.d('repos: $fetchMoreResultData');
log.d('repos: $repos');
log.d('repos: ' + previousResultData.toString());
log.d('repos: ' + fetchMoreResultData.toString());
log.d('repos: ' + repos.toString());
fetchMoreResultData['transaction_connection']['edges'] = repos;
return fetchMoreResultData;
@ -431,7 +367,7 @@ class DuniterIndexer with ChangeNotifier {
log.d(
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
if (fetchMoreCursor != null) {
transBC = parseHistory(blockchainTX, pubkey);
transBC = parseHistory(blockchainTX, _pubkey);
} else {
log.i("###### DEBUG H - Début de l'historique");
}
@ -439,9 +375,9 @@ class DuniterIndexer with ChangeNotifier {
return opts;
}
double removeDecimalZero(double n) {
num removeDecimalZero(double n) {
String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
return double.parse(result);
return num.parse(result);
}
// checkHistoryResult(

View File

@ -1,4 +1,5 @@
import 'dart:math';
import 'dart:typed_data';
import 'package:durt/durt.dart' as durt;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -22,9 +23,7 @@ class GenerateWalletsProvider with ChangeNotifier {
FocusNode walletNameFocus = FocusNode();
Color? askedWordColor = Colors.black;
bool isAskedWordValid = false;
int scanedValidWalletNumber = -1;
int scanedWalletNumber = -1;
int numberScan = 20;
late int nbrWord;
String? nbrWordAlpha;
@ -66,7 +65,7 @@ class GenerateWalletsProvider with ChangeNotifier {
if (chestNumber == 0) {
chestName = 'geckoChest'.tr();
} else {
chestName = '${'geckoChest'.tr()}${chestNumber + 1}';
chestName = 'geckoChest'.tr() + '${chestNumber + 1}';
}
await configBox.put('currentChest', chestNumber);
@ -82,8 +81,8 @@ class GenerateWalletsProvider with ChangeNotifier {
notifyListeners();
}
void checkAskedWord(String inputWord, String mnemo) {
final expectedWord = mnemo.split(' ')[nbrWord];
void checkAskedWord(String inputWord, String _mnemo) {
final expectedWord = _mnemo.split(' ')[nbrWord];
final normInputWord = unorm.nfkd(inputWord);
log.i("Is $expectedWord equal to input $normInputWord ?");
@ -119,7 +118,7 @@ class GenerateWalletsProvider with ChangeNotifier {
return rng.nextInt(12);
}
String? intToString(int nbr) {
String? intToString(int _nbr) {
Map nbrToString = {};
nbrToString[1] = '1th'.tr();
nbrToString[2] = '2th'.tr();
@ -134,7 +133,7 @@ class GenerateWalletsProvider with ChangeNotifier {
nbrToString[11] = '11th'.tr();
nbrToString[12] = '12th'.tr();
nbrWordAlpha = nbrToString[nbr];
nbrWordAlpha = nbrToString[_nbr];
return nbrWordAlpha;
}
@ -223,12 +222,12 @@ class GenerateWalletsProvider with ChangeNotifier {
}
Future<void> generateCesiumWalletPubkey(
String cesiumID, String cesiumPWD) async {
cesiumWallet = durt.CesiumWallet(cesiumID, cesiumPWD);
String walletPubkey = cesiumWallet.pubkey;
String _cesiumID, String _cesiumPWD) async {
cesiumWallet = durt.CesiumWallet(_cesiumID, _cesiumPWD);
String _walletPubkey = cesiumWallet.pubkey;
cesiumPubkey.text = walletPubkey;
log.d(walletPubkey);
cesiumPubkey.text = _walletPubkey;
log.d(_walletPubkey);
}
void cesiumIDisVisible() {
@ -249,19 +248,19 @@ class GenerateWalletsProvider with ChangeNotifier {
}
Future<List<String>> generateWordList(BuildContext context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
generatedMnemonic = await sub.generateMnemonic(lang: appLang);
List<String> wordsList = [];
generatedMnemonic = await _sub.generateMnemonic(lang: appLang);
List<String> _wordsList = [];
String word;
int nbr = 1;
int _nbr = 1;
for (word in generatedMnemonic!.split(' ')) {
wordsList.add("$nbr:$word");
nbr++;
_wordsList.add("$_nbr:$word");
_nbr++;
}
return wordsList;
return _wordsList;
}
bool isBipWord(String word, [bool checkRedondance = true]) {
@ -353,7 +352,6 @@ class GenerateWalletsProvider with ChangeNotifier {
cellController10,
cellController11
];
if (sentence?.text == null) return;
for (var word in sentence!.text!.split(' ')) {
bool isValid = isBipWord(word, false);
@ -368,48 +366,45 @@ class GenerateWalletsProvider with ChangeNotifier {
notifyListeners();
}
Future<bool> scanDerivations(BuildContext context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
Future<bool> scanDerivations(BuildContext context,
{int numberScan = 20}) async {
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final currentChestNumber = configBox.get('currentChest');
bool isAlive = false;
scanedValidWalletNumber = 0;
scanedWalletNumber = 0;
notifyListeners();
if (!sub.nodeConnected) {
if (!_sub.nodeConnected) {
return false;
}
final hasRoot = await scanRootBalance(sub, currentChestNumber);
scanedWalletNumber = 1;
notifyListeners();
final hasRoot = await scanRootBalance(_sub, currentChestNumber);
if (hasRoot) {
scanedValidWalletNumber = 1;
scanedWalletNumber = 1;
isAlive = true;
}
for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
sub.currencyParameters['ss58']!,
final addressData = await _sub.sdk.api.keyring.addressFromMnemonic(ss58,
cryptoType: CryptoType.sr25519,
mnemonic: generatedMnemonic!,
derivePath: '//$derivationNbr');
final Map balance = await sub.getBalance(addressData.address!).timeout(
final balance = await _sub.getBalance(addressData.address!).timeout(
const Duration(seconds: 1),
onTimeout: () => {'transferableBalance': 0},
onTimeout: () => 0,
);
// const balance = 0;
log.d(
"${addressData.address!}: ${balance['transferableBalance']} $currencyName");
if (balance['transferableBalance'] != 0) {
log.d(balance);
if (balance != 0) {
isAlive = true;
String walletName = scanedValidWalletNumber == 0
String walletName = scanedWalletNumber == 0
? 'currentWallet'.tr()
: '${'wallet'.tr()} ${scanedValidWalletNumber + 1}';
await sub.importAccount(
mnemonic: generatedMnemonic!,
: 'wallet'.tr() + ' ${scanedWalletNumber + 1}';
await _sub.importAccount(
mnemonic: '',
fromMnemonic: true,
derivePath: '//$derivationNbr',
password: pin.text);
@ -417,39 +412,34 @@ class GenerateWalletsProvider with ChangeNotifier {
version: dataVersion,
chest: currentChestNumber,
address: addressData.address!,
number: scanedValidWalletNumber,
number: scanedWalletNumber,
name: walletName,
derivation: derivationNbr,
imageDefaultPath: '${scanedValidWalletNumber % 4}.png');
imageDefaultPath: '${scanedWalletNumber % 4}.png');
await walletBox.add(myWallet);
scanedValidWalletNumber = scanedValidWalletNumber + 1;
scanedWalletNumber = scanedWalletNumber + 1;
}
scanedWalletNumber = scanedWalletNumber + 1;
notifyListeners();
}
log.d(scanedWalletNumber);
scanedWalletNumber = -1;
scanedValidWalletNumber = -1;
notifyListeners();
return isAlive;
}
Future<bool> scanRootBalance(SubstrateSdk sub, int currentChestNumber) async {
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
sub.currencyParameters['ss58']!,
cryptoType: CryptoType.sr25519,
mnemonic: generatedMnemonic!);
Future<bool> scanRootBalance(
SubstrateSdk _sub, int currentChestNumber) async {
final addressData = await _sub.sdk.api.keyring.addressFromMnemonic(ss58,
cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!);
final balance = await sub.getBalance(addressData.address!).timeout(
final balance = await _sub.getBalance(addressData.address!).timeout(
const Duration(seconds: 1),
onTimeout: () => {},
onTimeout: () => 0,
);
log.d(
"${addressData.address!}: ${balance['transferableBalance']} $currencyName");
if (balance['transferableBalance'] != 0) {
log.d(balance);
if (balance != 0) {
String walletName = 'myRootWallet'.tr();
await sub.importAccount(mnemonic: generatedMnemonic!, password: pin.text);
await _sub.importAccount(
mnemonic: '', fromMnemonic: true, password: pin.text);
WalletData myWallet = WalletData(
version: dataVersion,

View File

@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:convert';
import 'dart:io';
import 'dart:math';
@ -11,10 +9,7 @@ import 'package:flutter/services.dart';
import 'dart:async';
import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
@ -65,15 +60,6 @@ class HomeProvider with ChangeNotifier {
}
}
Future changeCurrencyUnit(BuildContext context) async {
final sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
await configBox.put('isUdUnit', !isUdUnit);
balanceCache = {};
sub.getBalanceRatio();
notifyListeners();
}
Future<String> getAppVersion() async {
String version;
String buildNumber;
@ -84,7 +70,7 @@ class HomeProvider with ChangeNotifier {
: (int.parse(packageInfo.buildNumber) - 1000).toString();
notifyListeners();
return '$version+$buildNumber';
return version + '+' + buildNumber;
}
Future changeMessage(String newMessage, int seconds) async {
@ -97,23 +83,20 @@ class HomeProvider with ChangeNotifier {
Future<List?> getValidEndpoints() async {
await configBox.delete('endpoint');
if (!configBox.containsKey('autoEndpoint')) {
configBox.put('autoEndpoint', true);
}
List listEndpoints = [];
List _listEndpoints = [];
if (!configBox.containsKey('endpoint') ||
configBox.get('endpoint') == [] ||
configBox.get('endpoint') == '') {
listEndpoints = await rootBundle
_listEndpoints = await rootBundle
.loadString('config/gdev_endpoints.json')
.then((jsonStr) => jsonDecode(jsonStr));
listEndpoints.shuffle();
configBox.put('endpoint', listEndpoints);
_listEndpoints.shuffle();
configBox.put('endpoint', _listEndpoints);
}
log.i('ENDPOINT: $listEndpoints');
return listEndpoints;
log.i('ENDPOINT: ' + _listEndpoints.toString());
return _listEndpoints;
}
T getRandomElement<T>(List<T> list) {
@ -133,17 +116,17 @@ class HomeProvider with ChangeNotifier {
// }
Widget bottomAppBar(BuildContext context) {
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
WalletsProfilesProvider historyProvider =
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
final size = MediaQuery.of(context).size;
const bool showBottomBar = true;
const bool _showBottomBar = true;
return Visibility(
visible: showBottomBar,
visible: _showBottomBar,
child: Container(
color: yellowC,
width: size.width,
@ -160,7 +143,6 @@ class HomeProvider with ChangeNotifier {
const Spacer(),
const SizedBox(width: 11),
IconButton(
key: keyAppBarSearch,
iconSize: 40,
icon: const Image(image: AssetImage('assets/loupe-noire.png')),
onPressed: () {
@ -179,7 +161,6 @@ class HomeProvider with ChangeNotifier {
const SizedBox(width: 22),
const Spacer(),
IconButton(
key: keyAppBarQrcode,
iconSize: 70,
icon: const Image(image: AssetImage('assets/qrcode-scan.png')),
onPressed: () async {
@ -187,20 +168,19 @@ class HomeProvider with ChangeNotifier {
context,
ModalRoute.withName('/'),
);
historyProvider.scan(homeContext);
_historyProvider.scan(homeContext);
},
),
const Spacer(),
const SizedBox(width: 15),
IconButton(
key: keyAppBarChest,
iconSize: 60,
icon: const Image(image: AssetImage('assets/wallet.png')),
onPressed: () async {
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
WalletData? defaultWallet = _myWalletProvider.getDefaultWallet();
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -210,7 +190,7 @@ class HomeProvider with ChangeNotifier {
);
}
if (pin != null || myWalletProvider.pinCode != '') {
if (_pin != null || _myWalletProvider.pinCode != '') {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
@ -230,7 +210,28 @@ class HomeProvider with ChangeNotifier {
);
}
void reload() {
void rebuildWidget() {
notifyListeners();
}
}
class CustomRoundedButton extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = yellowC
..style = PaintingStyle.fill;
Path path = Path();
path.lineTo(size.width * 0.4, 0);
path.quadraticBezierTo(size.width * 0.5, -40, size.width * 0.6, 0);
path.lineTo(size.width, 0);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}

View File

@ -13,8 +13,6 @@ class MyWalletsProvider with ChangeNotifier {
late String mnemonic;
int? pinLenght;
bool isNewDerivationLoading = false;
String lastFlyBy = '';
String dragAddress = '';
int getCurrentChest() {
if (configBox.get('currentChest') == null) {
@ -33,11 +31,11 @@ class MyWalletsProvider with ChangeNotifier {
}
}
List<WalletData> readAllWallets([int? chest]) {
chest = chest ?? configBox.get('currentChest') ?? 0;
List<WalletData> readAllWallets([int? _chest]) {
_chest = _chest ?? configBox.get('currentChest') ?? 0;
listWallets.clear();
walletBox.toMap().forEach((key, value) {
if (value.chest == chest) {
if (value.chest == _chest) {
listWallets.add(value);
}
});
@ -45,33 +43,33 @@ class MyWalletsProvider with ChangeNotifier {
return listWallets;
}
WalletData? getWalletDataById(List<int?> id) {
if (id.isEmpty) return WalletData();
int? chest = id[0];
int? nbr = id[1];
WalletData? targetedWallet;
WalletData? getWalletDataById(List<int?> _id) {
if (_id.isEmpty) return WalletData();
int? _chest = _id[0];
int? _nbr = _id[1];
WalletData? _targetedWallet;
walletBox.toMap().forEach((key, value) {
if (value.chest == chest && value.number == nbr) {
targetedWallet = value;
if (value.chest == _chest && value.number == _nbr) {
_targetedWallet = value;
return;
}
});
return targetedWallet;
return _targetedWallet;
}
WalletData? getWalletDataByAddress(String address) {
WalletData? targetedWallet;
WalletData? _targetedWallet;
walletBox.toMap().forEach((key, value) {
if (value.address == address) {
targetedWallet = value;
_targetedWallet = value;
return;
}
});
return targetedWallet;
return _targetedWallet;
}
WalletData getDefaultWallet([int? chest]) {
@ -86,21 +84,21 @@ class MyWalletsProvider with ChangeNotifier {
}
Future<int> deleteAllWallet(context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider =
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
try {
log.w('DELETE ALL WALLETS ?');
final bool? answer =
final bool? _answer =
await (confirmPopup(context, 'areYouSureForgetAllChests'.tr()));
if (answer!) {
if (_answer!) {
await walletBox.clear();
await chestBox.clear();
await configBox.delete('defaultWallet');
await sub.deleteAllAccounts();
await _sub.deleteAllAccounts();
myWalletProvider.pinCode = '';
_myWalletProvider.pinCode = '';
await Navigator.of(context).pushNamedAndRemoveUntil(
'/',
@ -113,32 +111,32 @@ class MyWalletsProvider with ChangeNotifier {
}
}
Future<void> generateNewDerivation(context, String name,
Future<void> generateNewDerivation(context, String _name,
[int? number]) async {
isNewDerivationLoading = true;
notifyListeners();
final List idList = getNextWalletNumberAndDerivation();
int newWalletNbr = idList[0];
int newDerivationNbr = number ?? idList[1];
int _newWalletNbr = idList[0];
int _newDerivationNbr = number ?? idList[1];
int? chest = getCurrentChest();
int? _chest = getCurrentChest();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = getDefaultWallet();
final address = await sub.derive(
context, defaultWallet.address!, newDerivationNbr, pinCode);
final address = await _sub.derive(
context, defaultWallet.address!, _newDerivationNbr, pinCode);
WalletData newWallet = WalletData(
version: dataVersion,
chest: chest,
chest: _chest,
address: address,
number: newWalletNbr,
name: name,
derivation: newDerivationNbr,
imageDefaultPath: '${newWalletNbr % 4}.png');
number: _newWalletNbr,
name: _name,
derivation: _newDerivationNbr,
imageDefaultPath: '${_newWalletNbr % 4}.png');
await walletBox.add(newWallet);
@ -146,37 +144,37 @@ class MyWalletsProvider with ChangeNotifier {
notifyListeners();
}
Future<void> generateRootWallet(context, String name) async {
MyWalletsProvider myWalletProvider =
Future<void> generateRootWallet(context, String _name) async {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
isNewDerivationLoading = true;
notifyListeners();
int newWalletNbr;
int? chest = getCurrentChest();
int _newWalletNbr;
int? _chest = getCurrentChest();
List<WalletData> walletConfig = readAllWallets(chest);
List<WalletData> _walletConfig = readAllWallets(_chest);
if (walletConfig.isEmpty) {
newWalletNbr = 0;
if (_walletConfig.isEmpty) {
_newWalletNbr = 0;
} else {
newWalletNbr = walletConfig.last.number! + 1;
_newWalletNbr = _walletConfig.last.number! + 1;
}
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
WalletData defaultWallet = _myWalletProvider.getDefaultWallet();
final address =
await sub.generateRootKeypair(defaultWallet.address!, pinCode);
await _sub.generateRootKeypair(defaultWallet.address!, pinCode);
WalletData newWallet = WalletData(
version: dataVersion,
chest: chest,
chest: _chest,
address: address,
number: newWalletNbr,
name: name,
number: _newWalletNbr,
name: _name,
derivation: -1,
imageDefaultPath: '${newWalletNbr % 4}.png');
imageDefaultPath: '${_newWalletNbr % 4}.png');
await walletBox.add(newWallet);
@ -186,29 +184,29 @@ class MyWalletsProvider with ChangeNotifier {
List<int> getNextWalletNumberAndDerivation(
{int? chestNumber, bool isOneshoot = false}) {
int newDerivationNbr = 0;
int newWalletNbr = 0;
int _newDerivationNbr = 0;
int _newWalletNbr = 0;
chestNumber ??= getCurrentChest();
List<WalletData> walletConfig = readAllWallets(chestNumber);
List<WalletData> _walletConfig = readAllWallets(chestNumber);
if (walletConfig.isEmpty) {
newDerivationNbr = 2;
if (_walletConfig.isEmpty) {
_newDerivationNbr = 2;
} else {
WalletData lastWallet = walletConfig.reduce(
WalletData _lastWallet = _walletConfig.reduce(
(curr, next) => curr.derivation! > next.derivation! ? curr : next);
if (lastWallet.derivation == -1) {
newDerivationNbr = 2;
if (_lastWallet.derivation == -1) {
_newDerivationNbr = 2;
} else {
newDerivationNbr = lastWallet.derivation! + (isOneshoot ? 1 : 2);
_newDerivationNbr = _lastWallet.derivation! + (isOneshoot ? 1 : 2);
}
newWalletNbr = walletConfig.last.number! + 1;
_newWalletNbr = _walletConfig.last.number! + 1;
}
return [newWalletNbr, newDerivationNbr];
return [_newWalletNbr, _newDerivationNbr];
}
int lockPin = 0;
@ -221,7 +219,7 @@ class MyWalletsProvider with ChangeNotifier {
if (actualLock == lockPin) pinCode = '';
}
void reload() {
void rebuildWidget() {
notifyListeners();
}
}

View File

@ -8,7 +8,7 @@ class SearchProvider with ChangeNotifier {
final cacheDuring = 20 * 60 * 1000; //First number is minutes
int cacheTime = 0;
void reload() {
void rebuildWidget() {
notifyListeners();
}
@ -68,12 +68,12 @@ class SearchProvider with ChangeNotifier {
// }
Future<List<G1WalletsList>> searchAddress() async {
final WalletsProfilesProvider walletProfiles =
final WalletsProfilesProvider _walletProfiles =
WalletsProfilesProvider('pubkey');
if (walletProfiles.isAddress(searchController.text)) {
G1WalletsList wallet = G1WalletsList(address: searchController.text);
return [wallet];
if (_walletProfiles.isAddress(searchController.text)) {
G1WalletsList _wallet = G1WalletsList(pubkey: searchController.text);
return [_wallet];
} else {
return [];
}

View File

@ -1,7 +0,0 @@
import 'package:flutter/material.dart';
class SettingsProvider with ChangeNotifier {
void reload() {
notifyListeners();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,8 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
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/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';
@ -18,7 +14,6 @@ import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:truncate/truncate.dart';
class WalletOptionsProvider with ChangeNotifier {
TextEditingController address = TextEditingController();
@ -32,46 +27,46 @@ class WalletOptionsProvider with ChangeNotifier {
TextEditingController nameController = TextEditingController();
late bool isDefaultWallet;
bool canValidateNameBool = false;
Map<String, String> idtyStatusCache = {};
Future<NewWallet>? get badWallet => null;
int getPinLenght(walletNbr) {
int getPinLenght(_walletNbr) {
return pinLength;
}
void _renameWallet(List<int?> walletID, String newName,
void _renameWallet(List<int?> _walletID, String _newName,
{required bool isCesium}) async {
MyWalletsProvider myWalletClass = MyWalletsProvider();
WalletData walletTarget = myWalletClass.getWalletDataById(walletID)!;
walletTarget.name = newName;
await walletBox.put(walletTarget.key, walletTarget);
WalletData _walletTarget = myWalletClass.getWalletDataById(_walletID)!;
_walletTarget.name = _newName;
await walletBox.put(_walletTarget.key, _walletTarget);
_newWalletName.text = '';
}
Future<int> deleteWallet(context, WalletData wallet) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool? answer = await (confirmPopup(
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool? _answer = await (confirmPopup(
context, 'areYouSureToForgetWallet'.tr(args: [wallet.name!])));
if (answer ?? false) {
if (_answer ?? false) {
//Check if balance is null
final balance = await sub.getBalance(wallet.address!);
if (balance != {}) {
MyWalletsProvider myWalletProvider =
final _balance = await _sub.getBalance(wallet.address!);
if (_balance != 0) {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final defaultWallet = myWalletProvider.getDefaultWallet();
log.d(defaultWallet.address);
sub.pay(
final _defaultWallet = _myWalletProvider.getDefaultWallet();
log.d(_defaultWallet.address);
_sub.pay(
fromAddress: wallet.address!,
destAddress: defaultWallet.address!,
destAddress: _defaultWallet.address!,
amount: -1,
password: myWalletProvider.pinCode);
password: _myWalletProvider.pinCode);
}
await walletBox.delete(wallet.key);
await sub.deleteAccounts([wallet.address!]);
await _sub.deleteAccounts([wallet.address!]);
Navigator.pop(context);
}
@ -134,12 +129,12 @@ class WalletOptionsProvider with ChangeNotifier {
Widget idtyStatus(BuildContext context, String address,
{bool isOwner = false, Color color = Colors.black}) {
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
showText(String text,
[double size = 18, bool bold = false, bool smooth = true]) {
log.d('$address $text');
_showText(String text,
[double size = 18, bool _bold = false, bool smooth = true]) {
log.d(text);
return AnimatedFadeOutIn<String>(
data: text,
duration: Duration(milliseconds: smooth ? 200 : 0),
@ -148,32 +143,39 @@ class WalletOptionsProvider with ChangeNotifier {
textAlign: TextAlign.center,
style: TextStyle(
fontSize: size,
color: bold ? color : Colors.black,
fontWeight: bold ? FontWeight.w500 : FontWeight.w400),
color: _bold ? color : Colors.black,
fontWeight: _bold ? FontWeight.w500 : FontWeight.w400),
),
);
}
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
return Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return FutureBuilder(
future: sub.idtyStatus(address),
future: _sub.idtyStatus(address),
initialData: '',
builder: (context, snapshot) {
idtyStatusCache[address] = snapshot.data.toString();
switch (snapshot.data.toString()) {
case 'noid':
{
return showText('noIdentity'.tr());
return _showText('noIdentity'.tr());
}
case 'Created':
{
return showText('identityCreated'.tr());
return isOwner
? InkWell(
child: _showText(
'clickHereToConfirmIdentity'.tr(), 18, true),
onTap: () async {
await validateIdentity(context);
},
)
: _showText('identityCreated'.tr());
}
case 'ConfirmedByOwner':
{
return isOwner
? showText('identityConfirmed'.tr())
: duniterIndexer.getNameByAddress(
? _showText('identityConfirmed'.tr())
: _duniterIndexer.getNameByAddress(
context,
address,
null,
@ -187,8 +189,8 @@ class WalletOptionsProvider with ChangeNotifier {
case 'Validated':
{
return isOwner
? showText('memberValidated'.tr(), 18, true)
: duniterIndexer.getNameByAddress(
? _showText('memberValidated'.tr(), 18, true)
: _duniterIndexer.getNameByAddress(
context,
address,
null,
@ -201,27 +203,27 @@ class WalletOptionsProvider with ChangeNotifier {
case 'expired':
{
return showText('identityExpired'.tr());
return _showText('identityExpired'.tr());
}
}
return SizedBox(
child: showText('', 18, false, false),
child: _showText('', 18, false, false),
);
});
});
}
Future<bool> isMember(BuildContext context, String address) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
return await sub.idtyStatus(address) == 'Validated';
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
return await _sub.idtyStatus(address) == 'Validated';
}
Future<String?> confirmIdentityPopup(BuildContext context) async {
Future<String?> validateIdentity(BuildContext context) async {
TextEditingController idtyName = TextEditingController();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletOptionsProvider walletOptions =
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
return showDialog<String>(
@ -238,14 +240,12 @@ class WalletOptionsProvider with ChangeNotifier {
height: 100,
child: Column(children: [
const SizedBox(height: 20),
const Text(
'Nom:',
style: TextStyle(fontSize: 19),
),
TextField(
key: keyEnterIdentityUsername,
onChanged: (_) => notifyListeners(),
inputFormatters: <TextInputFormatter>[
// FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")),
FilteringTextInputFormatter.deny(RegExp(r'^ ')),
// FilteringTextInputFormatter.deny(RegExp(r' $')),
],
textAlign: TextAlign.center,
autofocus: true,
controller: idtyName,
@ -258,30 +258,26 @@ class WalletOptionsProvider with ChangeNotifier {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer<WalletOptionsProvider>(
builder: (context, wOptions, _) {
builder: (context, _wOptions, _) {
return TextButton(
key: keyConfirm,
key: const Key('infoPopup'),
child: Text(
"validate".tr(),
style: TextStyle(
fontSize: 21,
color: idtyName.text.length.clamp(3, 64) ==
idtyName.text.length
color: idtyName.text.length >= 2
? const Color(0xffD80000)
: Colors.grey,
),
),
onPressed: () async {
idtyName.text = idtyName.text.trim().replaceAll(' ', '');
if (idtyName.text.length.clamp(3, 64) ==
idtyName.text.length) {
if (idtyName.text.length >= 2) {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
_myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -290,22 +286,19 @@ class WalletOptionsProvider with ChangeNotifier {
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
final wallet = myWalletProvider
if (_pin != null || _myWalletProvider.pinCode != '') {
final _wallet = _myWalletProvider
.getWalletDataByAddress(address.text);
await sub.setCurrentWallet(wallet!);
sub.confirmIdentity(walletOptions.address.text,
idtyName.text, myWalletProvider.pinCode);
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 const TransactionInProgress(
transType: 'comfirmIdty');
}),
);
}
@ -322,7 +315,7 @@ class WalletOptionsProvider with ChangeNotifier {
);
}
Future<String?> editWalletName(BuildContext context, List<int?> wID) async {
Future<String?> editWalletName(BuildContext context, List<int?> _wID) async {
TextEditingController walletName = TextEditingController();
canValidateNameBool = false;
@ -354,9 +347,9 @@ class WalletOptionsProvider with ChangeNotifier {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer<WalletOptionsProvider>(
builder: (context, wOptions, _) {
builder: (context, _wOptions, _) {
return TextButton(
key: keyInfoPopup,
key: const Key('infoPopup'),
child: Text(
"validate".tr(),
style: TextStyle(
@ -370,7 +363,7 @@ class WalletOptionsProvider with ChangeNotifier {
onPressed: () async {
if (canValidateNameBool) {
nameController.text = walletName.text;
_renameWallet(wID, walletName.text, isCesium: false);
_renameWallet(_wID, walletName.text, isCesium: false);
// notifyListeners();
Navigator.pop(context);
}
@ -383,7 +376,7 @@ class WalletOptionsProvider with ChangeNotifier {
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
key: keyCancel,
key: const Key('cancel'),
child: Text(
"cancel".tr(),
style: TextStyle(
@ -405,7 +398,7 @@ class WalletOptionsProvider with ChangeNotifier {
}
bool canValidateName(BuildContext context, TextEditingController walletName) {
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
bool isNameValid = walletName.text.length >= 2 &&
@ -413,7 +406,7 @@ class WalletOptionsProvider with ChangeNotifier {
walletName.text.length <= 39;
if (isNameValid) {
for (var wallet in myWalletProvider.listWallets) {
for (var wallet in _myWalletProvider.listWallets) {
if (walletName.text == wallet.name!) {
canValidateNameBool = false;
break;
@ -427,7 +420,7 @@ class WalletOptionsProvider with ChangeNotifier {
return canValidateNameBool;
}
void reload() {
void reloadBuild() {
notifyListeners();
}
@ -438,28 +431,32 @@ class WalletOptionsProvider with ChangeNotifier {
}
String? getAddress(int chest, int derivation) {
String? addressGet;
String? _address;
walletBox.toMap().forEach((key, value) {
if (value.chest == chest && value.derivation == derivation) {
addressGet = value.address!;
_address = value.address!;
return;
}
});
address.text = addressGet ?? '';
address.text = _address ?? '';
return addressGet;
return _address;
}
Widget walletNameController(BuildContext context, WalletData wallet,
[double size = 20]) {
// WidgetsBinding.instance.addPostFrameCallback((_) {
log.d('aaaaaaaaaaaaaaaaaaaaa: ${wallet.name}');
nameController.text = wallet.name!;
// _walletOptions.reloadBuild();
// });
return SizedBox(
width: 260,
child: Stack(children: <Widget>[
TextField(
key: keyWalletName,
key: const Key('walletName'),
autofocus: false,
focusNode: walletNameFocus,
enabled: isEditing,
@ -483,7 +480,7 @@ class WalletOptionsProvider with ChangeNotifier {
Positioned(
right: 0,
child: InkWell(
key: keyRenameWallet,
key: const Key('renameWallet'),
onTap: () async {
// _isNewNameValid =
// walletProvider.editWalletName(wallet.id(), isCesium: false);
@ -507,71 +504,63 @@ class WalletOptionsProvider with ChangeNotifier {
Widget walletName(BuildContext context, WalletData wallet,
[double size = 20, Color color = Colors.black]) {
double newSize = wallet.name!.length <= 15 ? size : size - 2;
return Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
truncate(wallet.name!, 20),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isTall ? newSize : newSize * 0.9,
color: color,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.italic,
return SizedBox(
width: 260,
child:
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
wallet.name!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: color,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.italic,
),
),
softWrap: false,
overflow: TextOverflow.ellipsis,
),
]);
]),
);
}
}
Map<String, double> balanceCache = {};
Widget balance(BuildContext context, String address, double size,
[Color color = Colors.black,
Color loadingColor = const Color(0xffd07316)]) {
[Color _color = Colors.black,
Color _loadingColor = const Color(0xffd07316)]) {
return Column(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
Consumer<SubstrateSdk>(builder: (context, _sdk, _) {
return FutureBuilder(
future: sdk.getBalance(address),
builder: (BuildContext context,
AsyncSnapshot<Map<String, double>> globalBalance) {
if (globalBalance.connectionState != ConnectionState.done ||
globalBalance.hasError) {
future: _sdk.getBalance(address),
builder: (BuildContext context, AsyncSnapshot<double> _balance) {
if (_balance.connectionState != ConnectionState.done ||
_balance.hasError) {
if (balanceCache[address] != null &&
balanceCache[address] != -1) {
return Row(children: [
Text(balanceCache[address]!.toString(),
style: TextStyle(
fontSize: isTall ? size : size * 0.9, color: color)),
const SizedBox(width: 5),
udUnitDisplay(size, color),
]);
return Text(
"${balanceCache[address]!.toString()} $currencyName",
style: TextStyle(
fontSize: isTall ? size : size * 0.9, color: _color));
} else {
return SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
color: loadingColor,
color: _loadingColor,
strokeWidth: 2,
),
);
}
}
balanceCache[address] = globalBalance.data!['transferableBalance']!;
balanceCache[address] = _balance.data!;
if (balanceCache[address] != -1) {
return Row(children: [
Text(
balanceCache[address]!.toString(),
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: color,
),
return Text(
"${balanceCache[address]!.toString()} $currencyName",
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: _color,
),
const SizedBox(width: 5),
udUnitDisplay(size, color),
]);
);
} else {
return const Text('');
}
@ -581,24 +570,24 @@ Widget balance(BuildContext context, String address, double size,
}
Widget getCerts(BuildContext context, String address, double size,
[Color color = Colors.black]) {
[Color _color = Colors.black]) {
return Column(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
Consumer<SubstrateSdk>(builder: (context, _sdk, _) {
return FutureBuilder(
future: sdk.getCerts(address),
builder: (BuildContext context, AsyncSnapshot<List<int>> certs) {
future: _sdk.getCerts(address),
builder: (BuildContext context, AsyncSnapshot<List<int>> _certs) {
// log.d(_certs.data);
return certs.data?[0] != 0 && certs.data != null
return _certs.data?[0] != 0 && _certs.data != null
? Row(
children: [
Image.asset('assets/medal.png', height: 20),
const SizedBox(width: 1),
Text(certs.data?[0].toString() ?? '0',
Text(_certs.data?[0].toString() ?? '0',
style: const TextStyle(fontSize: 20)),
const SizedBox(width: 5),
Text(
"(${certs.data?[1].toString() ?? '0'})",
"(${_certs.data?[1].toString() ?? '0'})",
style: const TextStyle(fontSize: 14),
)
],
@ -608,32 +597,3 @@ Widget getCerts(BuildContext context, String address, double size,
}),
]);
}
Widget udUnitDisplay(double size, [Color color = Colors.black]) {
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
return isUdUnit
? Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
'ud'.tr(args: ['']),
style:
TextStyle(fontSize: isTall ? size : size * 0.9, color: color),
),
Column(
children: [
Text(
currencyName,
style: TextStyle(
fontSize: (isTall ? size : size * 0.9) * 0.7,
fontWeight: FontWeight.w500,
color: color),
),
const SizedBox(height: 15)
],
)
],
)
: Text(currencyName,
style: TextStyle(fontSize: isTall ? size : size * 0.9, color: color));
}

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
@ -19,7 +18,7 @@ import 'package:provider/provider.dart';
class WalletsProfilesProvider with ChangeNotifier {
WalletsProfilesProvider(this.address);
String address = '';
String? address = '';
String pubkeyShort = '';
bool isHistoryScreen = false;
@ -44,7 +43,7 @@ class WalletsProfilesProvider with ChangeNotifier {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(address: barcode!.rawContent);
return WalletViewScreen(pubkey: barcode!.rawContent);
}),
);
} else {
@ -102,8 +101,8 @@ class WalletsProfilesProvider with ChangeNotifier {
notifyListeners();
}
String generateIdenticon(String pubkey) {
return Jdenticon.toSvg(pubkey);
String generateIdenticon(String _pubkey) {
return Jdenticon.toSvg(_pubkey);
}
// Future<num> getBalance(String _pubkey) async {
@ -121,7 +120,7 @@ class WalletsProfilesProvider with ChangeNotifier {
// return balance;
// }
Future<num?> getBalance(String? pubkey) async {
Future<num?> getBalance(String? _pubkey) async {
while (_balance == null) {
await Future.delayed(const Duration(milliseconds: 50));
}
@ -130,18 +129,19 @@ class WalletsProfilesProvider with ChangeNotifier {
}
Widget headerProfileView(
BuildContext context, String address, String? username) {
const double avatarSize = 140;
BuildContext context, String _address, String? username) {
const double _avatarSize = 140;
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
bool isAccountExist = balanceCache[_address] != 0;
return Stack(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sub, _) {
bool isAccountExist = balanceCache[address] != 0;
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return Container(
height: 180,
decoration: BoxDecoration(
@ -167,13 +167,13 @@ class WalletsProfilesProvider with ChangeNotifier {
),
Row(children: [
GestureDetector(
key: keyCopyAddress,
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(text: address));
Clipboard.setData(ClipboardData(text: _address));
snackCopyKey(context);
},
child: Text(
getShortPubkey(address),
getShortPubkey(_address),
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w800,
@ -182,40 +182,17 @@ class WalletsProfilesProvider with ChangeNotifier {
),
]),
const SizedBox(height: 25),
balance(context, address, 22),
balance(context, _address, 22),
const SizedBox(height: 10),
walletOptions.idtyStatus(context, address,
_walletOptions.idtyStatus(context, _address,
isOwner: false, color: Colors.black),
getCerts(context, address, 14),
// if (username == null &&
// g1WalletsBox.get(address)?.username != null)
// SizedBox(
// width: 230,
// child: Text(
// g1WalletsBox.get(address)?.username ?? '',
// style: const TextStyle(
// fontSize: 27,
// color: Color(0xff814C00),
// ),
// ),
// ),
// if (username != null)
// SizedBox(
// width: 230,
// child: Text(
// username,
// style: const TextStyle(
// fontSize: 27,
// color: Color(0xff814C00),
// ),
// ),
// ),
const SizedBox(height: 55),
getCerts(context, _address, 14),
const SizedBox(height: 40),
]),
const Spacer(),
Column(children: <Widget>[
ClipOval(
child: cesiumPlusProvider.defaultAvatar(avatarSize),
child: _cesiumPlusProvider.defaultAvatar(_avatarSize),
),
const SizedBox(height: 25),
]),
@ -225,16 +202,16 @@ class WalletsProfilesProvider with ChangeNotifier {
]);
}
bool isContact(String address) {
return contactsBox.containsKey(address);
bool isContact(String _address) {
return contactsBox.containsKey(_address);
}
Future addContact(G1WalletsList profile) async {
// log.d(profile.username);
if (isContact(profile.address)) {
await contactsBox.delete(profile.address);
void addContact(G1WalletsList profile) {
log.d(profile.username);
if (isContact(profile.pubkey!)) {
contactsBox.delete(profile.pubkey);
} else {
await contactsBox.put(profile.address, profile);
contactsBox.put(profile.pubkey, profile);
}
notifyListeners();
}

View File

@ -1,10 +1,7 @@
// ignore_for_file: must_be_immutable
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/queries_indexer.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
@ -15,14 +12,15 @@ import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class ActivityScreen extends StatelessWidget with ChangeNotifier {
ActivityScreen({required this.address, required this.avatar, this.username})
: super(key: keyActivityScreen);
ActivityScreen({required this.address, this.avatar, this.username, Key? key})
: super(key: key);
final ScrollController scrollController = ScrollController();
final double avatarsSize = 80;
final String address;
final String? address;
final String? username;
final Image avatar;
final Image? avatar;
FetchMore? fetchMore;
FetchMoreOptions? opts;
@ -32,9 +30,9 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider walletProfile =
WalletsProfilesProvider _walletProfile =
Provider.of<WalletsProfilesProvider>(context, listen: false);
HomeProvider homeProvider =
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
return Scaffold(
@ -47,15 +45,15 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
child: Text('accountActivity'.tr()),
),
),
bottomNavigationBar: homeProvider.bottomAppBar(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: Column(children: <Widget>[
walletProfile.headerProfileView(context, address, username),
_walletProfile.headerProfileView(context, address!, username),
historyQuery(context),
]));
}
Widget historyQuery(context) {
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
if (indexerEndpoint == '') {
@ -69,19 +67,19 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
]);
}
final httpLink = HttpLink(
final _httpLink = HttpLink(
'$indexerEndpoint/v1beta1/relay',
);
final client = ValueNotifier(
final _client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
link: _httpLink,
),
);
return GraphQLProvider(
client: client,
client: _client,
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
@ -89,7 +87,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistoryByAddressQ),
document: gql(getHistoryByAddressQ3),
variables: <String, dynamic>{
'address': address,
'number': 20,
@ -104,7 +102,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
}
if (result.hasException) {
log.e('Error Indexer: ${result.exception}');
log.e('Error Indexer: ' + result.exception.toString());
return Column(children: <Widget>[
const SizedBox(height: 50),
Text(
@ -126,7 +124,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
if (result.isNotLoading) {
// log.d(result.data);
opts = duniterIndexer.checkQueryResult(result, opts, address);
opts = _duniterIndexer.checkQueryResult(result, opts, address!);
}
// Build history list
@ -134,7 +132,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: keyListTransactions,
key: const Key('listTransactions'),
controller: scrollController,
children: <Widget>[historyView(context, result)],
),
@ -144,7 +142,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7 &&
duniterIndexer.pageInfo!['hasNextPage'] &&
_duniterIndexer.pageInfo!['hasNextPage'] &&
result.isNotLoading) {
fetchMore!(opts!);
}
@ -158,10 +156,10 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
}
Widget historyView(context, result) {
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return duniterIndexer.transBC == null
return _duniterIndexer.transBC == null
? Column(children: <Widget>[
const SizedBox(height: 50),
Text(
@ -170,15 +168,16 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
)
])
: Column(children: <Widget>[
getTransactionTile(context, duniterIndexer),
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
getTransactionTile(context, _duniterIndexer),
if (result.isLoading &&
_duniterIndexer.pageInfo!['hasPreviousPage'])
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
],
),
if (!duniterIndexer.pageInfo!['hasNextPage'])
if (!_duniterIndexer.pageInfo!['hasNextPage'])
Column(
children: const <Widget>[
SizedBox(height: 15),
@ -192,14 +191,13 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
}
Widget getTransactionTile(
BuildContext context, DuniterIndexer duniterIndexer) {
CesiumPlusProvider cesiumPlusProvider =
BuildContext context, DuniterIndexer _duniterIndexer) {
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
int keyID = 0;
String? dateDelimiter;
String? lastDateDelimiter;
const double avatarSize = 200;
const double _avatarSize = 200;
bool isTody = false;
bool isYesterday = false;
@ -221,7 +219,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
};
return Column(
children: duniterIndexer.transBC!.map((repository) {
children: _duniterIndexer.transBC!.map((repository) {
// log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString());
DateTime now = DateTime.now();
@ -274,25 +272,13 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
dateDelimiter = null;
}
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
late double amount;
late String finalAmount;
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
if (isUdUnit) {
amount = round(amount / balanceRatio);
finalAmount = 'ud'.tr(args: ['$amount ']);
} else {
finalAmount = '$amount $currencyName';
}
return Column(children: <Widget>[
if (dateDelimiter != null)
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Text(
dateDelimiter!,
style: const TextStyle(
style: TextStyle(
fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
),
),
@ -301,11 +287,11 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
child:
// Row(children: [Column(children: [],)],)
ListTile(
key: keyTransaction(keyID++),
key: Key('transaction${keyID++}'),
contentPadding: const EdgeInsets.only(
left: 20, right: 30, top: 15, bottom: 15),
leading: ClipOval(
child: cesiumPlusProvider.defaultAvatar(avatarSize),
child: _cesiumPlusProvider.defaultAvatar(_avatarSize),
),
title: Padding(
padding: const EdgeInsets.only(bottom: 5),
@ -341,19 +327,19 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
],
),
),
trailing: Text(finalAmount,
trailing: Text("${repository[3]} $currencyName",
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.justify),
dense: false,
isThreeLine: false,
onTap: () {
duniterIndexer.nPage = 1;
_duniterIndexer.nPage = 1;
// _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(address: repository[1]);
return WalletViewScreen(pubkey: repository[1]);
}),
);
// Navigator.pop(context);

View File

@ -29,10 +29,10 @@ class AnimatedFadeOutIn<T> extends StatefulWidget {
}) : super(key: key);
@override
AnimatedFadeOutInState<T> createState() => AnimatedFadeOutInState<T>();
_AnimatedFadeOutInState<T> createState() => _AnimatedFadeOutInState<T>();
}
class AnimatedFadeOutInState<T> extends State<AnimatedFadeOutIn<T>>
class _AnimatedFadeOutInState<T> extends State<AnimatedFadeOutIn<T>>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<double> animation;

View File

@ -0,0 +1,54 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class AvatarFullscreen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
AvatarFullscreen(this.avatar, {this.title, this.color, Key? key})
: super(key: key);
final Image? avatar;
final String? title;
final Color? color;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: color ?? Colors.black,
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: orangeC),
onPressed: () {
Navigator.pop(context);
}),
title: SizedBox(
height: 22,
child: Text(
title ?? 'Photo de profil',
style: TextStyle(color: orangeC),
),
)),
body: SafeArea(
child: SizedBox.expand(
child: Container(
color: color ?? Colors.black,
// alignment: Alignment.center,
// height: MediaQuery.of(context).size.height,
// width: MediaQuery.of(context).size.width,
child: Image(
image: avatar!.image,
height: avatar!.height,
fit: BoxFit.fitWidth),
),
),
),
);
}
}

View File

@ -3,7 +3,6 @@ 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/widgets_keys.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
@ -63,10 +62,10 @@ class CommonElements {
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGoNext,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, backgroundColor: orangeC,
elevation: 4, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
@ -132,17 +131,6 @@ class CommonElements {
EdgeInsets padding,
) {
return Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
@ -156,14 +144,26 @@ class CommonElements {
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
);
}
Widget offlineInfo(BuildContext context) {
final double screenWidth = MediaQuery.of(homeContext).size.width;
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final double screenWidth = MediaQuery.of(context).size.width;
return Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return Visibility(
visible: !sub.nodeConnected,
visible: !_sub.nodeConnected,
child: Positioned(
top: 0,
child: Container(
@ -174,7 +174,7 @@ class CommonElements {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'youAreOffline'.tr(),
"Vous êtes hors ligne...",
style: TextStyle(color: Colors.grey[50]),
textAlign: TextAlign.center,
),
@ -187,8 +187,8 @@ class CommonElements {
}
class SmoothTransition extends PageRouteBuilder {
final Widget page;
SmoothTransition({required this.page})
final Widget? page;
SmoothTransition({this.page})
: super(
pageBuilder: (
BuildContext context,
@ -199,7 +199,7 @@ class SmoothTransition extends PageRouteBuilder {
duration: const Duration(seconds: 5),
tween: Tween(begin: 200, end: 200),
builder: (BuildContext context, dynamic value, Widget? child) {
return page;
return page!;
},
),
);
@ -248,7 +248,7 @@ Future<bool?> confirmPopup(BuildContext context, String title) async {
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
key: keyConfirm,
key: const Key('confirmPopop'),
child: Text(
"yes".tr(),
style: const TextStyle(
@ -296,7 +296,7 @@ Future<void> infoPopup(BuildContext context, String title) async {
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
key: keyInfoPopup,
key: const Key('infoPopup'),
child: const Text(
"D'accord",
style: TextStyle(

View File

@ -1,11 +1,8 @@
// ignore_for_file: use_build_context_synchronously
import 'package:bubble/bubble.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
@ -19,26 +16,27 @@ import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/screens/my_contacts.dart';
import 'package:gecko/screens/onBoarding/1.dart';
import 'package:gecko/screens/search.dart';
import 'package:gecko/screens/settings.dart';
import 'package:flutter/services.dart';
import 'package:gecko/screens/substrate_sandbox.dart';
import 'package:provider/provider.dart';
import 'package:gecko/screens/my_contacts.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
homeContext = context;
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
homeContext = context;
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
isTall = false;
ratio = 1;
@ -54,18 +52,18 @@ class HomeScreen extends StatelessWidget {
Expanded(
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
DrawerHeader(
decoration: const BoxDecoration(
color: orangeC,
),
child: Column(children: const <Widget>[
SizedBox(height: 0),
Image(
image: AssetImage('assets/icon/gecko_final.png'),
height: 130),
]),
decoration: BoxDecoration(
color: orangeC,
),
),
ListTile(
key: keyParameters,
key: const Key('parameters'),
title: Text('parameters'.tr()),
onTap: () {
Navigator.pop(context);
@ -78,7 +76,7 @@ class HomeScreen extends StatelessWidget {
},
),
ListTile(
key: keyContacts,
key: const Key('contacts'),
title: Text('contactsManagement'.tr()),
onTap: () {
Navigator.pop(context);
@ -90,6 +88,25 @@ class HomeScreen extends StatelessWidget {
);
},
),
ListTile(
key: const Key('substrateSandbox'),
title: const Text('Substrate debug'),
onTap: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const SubstrateSandBox();
}),
);
},
),
// ListTile(
// title: const Text('A propos'),
// onTap: () {
// },
// ),
])),
Align(
alignment: FractionalOffset.bottomCenter,
@ -104,12 +121,8 @@ class HomeScreen extends StatelessWidget {
builder: (ctx) => StatefulWrapper(
onInit: () {
WidgetsBinding.instance.addPostFrameCallback((_) async {
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(ctx, listen: false);
duniterIndexer.getValidIndexerEndpoint();
if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi();
if (sub.sdkReady && !sub.nodeConnected) {
if (!_sub.sdkReady && !_sub.sdkLoading) await _sub.initApi();
if (_sub.sdkReady && !_sub.nodeConnected) {
// Check if versionData non compatible, drop everything
if (walletBox.isNotEmpty &&
walletBox.getAt(0)!.version! < dataVersion) {
@ -118,40 +131,39 @@ class HomeScreen extends StatelessWidget {
await walletBox.clear();
await chestBox.clear();
await configBox.delete('defaultWallet');
await sub.deleteAllAccounts();
myWalletProvider.reload();
await _sub.deleteAllAccounts();
_myWalletProvider.rebuildWidget();
}
// var connectivityResult =
// await (Connectivity().checkConnectivity());
// if (connectivityResult != ConnectivityResult.mobile &&
// connectivityResult != ConnectivityResult.wifi) {
// homeProvider.changeMessage(
// "notConnectedToInternet".tr(), 0);
// sub.nodeConnected = false;
// }
// TODO: fix random bad network status on startup
HomeProvider homeProvider =
var connectivityResult =
await (Connectivity().checkConnectivity());
HomeProvider _homeProvider =
Provider.of<HomeProvider>(ctx, listen: false);
if (connectivityResult != ConnectivityResult.mobile &&
connectivityResult != ConnectivityResult.wifi) {
_homeProvider.changeMessage(
"notConnectedToInternet".tr(), 0);
_sub.nodeConnected = false;
}
Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
log.d('Network changed: $result');
if (result == ConnectivityResult.none) {
sub.nodeConnected = false;
await sub.sdk.api.setting.unsubscribeBestNumber();
homeProvider.changeMessage(
_sub.nodeConnected = false;
await _sub.sdk.api.setting.unsubscribeBestNumber();
_homeProvider.changeMessage(
"notConnectedToInternet".tr(), 0);
sub.reload();
_sub.reload();
} else {
await sub.connectNode(ctx);
await _sub.connectNode(ctx);
}
});
// await sub.connectNode(ctx);
}
// _duniterIndexer.checkIndexerEndpointBackground();
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(ctx, listen: false);
_duniterIndexer.checkIndexerEndpoint();
});
},
child: isWalletsExists ? geckHome(context) : welcomeHome(context)
@ -183,10 +195,10 @@ class HomeScreen extends StatelessWidget {
}
Widget geckHome(context) {
MyWalletsProvider myWalletProvider = Provider.of<MyWalletsProvider>(context);
MyWalletsProvider _myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
WalletsProfilesProvider historyProvider =
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context);
final double statusBarHeight = MediaQuery.of(context).padding.top;
return Container(
@ -204,7 +216,7 @@ Widget geckHome(context) {
left: 15,
child: Builder(
builder: (context) => IconButton(
key: keyDrawerMenu,
key: const Key('drawerMenu'),
icon: const Icon(
Icons.menu,
color: Colors.white,
@ -242,9 +254,9 @@ Widget geckHome(context) {
),
],
),
child: Consumer<HomeProvider>(builder: (context, homeP, _) {
child: Consumer<HomeProvider>(builder: (context, _homeP, _) {
return AnimatedFadeOutIn<String>(
data: homeP.homeMessage,
data: _homeP.homeMessage,
duration: const Duration(milliseconds: 100),
builder: (value) => Text(value),
);
@ -271,21 +283,10 @@ Widget geckHome(context) {
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Column(children: <Widget>[
Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
child: ClipOval(
child: Material(
color: orangeC, // button color
child: InkWell(
key: keyOpenSearch,
child: Padding(
padding: const EdgeInsets.all(18),
child: Image(
@ -303,6 +304,16 @@ Widget geckHome(context) {
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
Text(
@ -317,18 +328,8 @@ Widget geckHome(context) {
const SizedBox(width: 120),
Column(children: <Widget>[
Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
child: ClipOval(
key: keyOpenWalletsHomme,
key: const Key('manageWallets'),
child: Material(
color: orangeC, // button color
child: InkWell(
@ -340,10 +341,10 @@ Widget geckHome(context) {
height: 68 * ratio)),
onTap: () async {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
_myWalletProvider.getDefaultWallet();
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -353,7 +354,8 @@ Widget geckHome(context) {
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
if (_pin != null ||
_myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
@ -368,6 +370,16 @@ Widget geckHome(context) {
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
Text(
@ -387,16 +399,6 @@ Widget geckHome(context) {
children: <Widget>[
Column(children: <Widget>[
Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
child: ClipOval(
child: Material(
color: orangeC, // button color
@ -408,10 +410,20 @@ Widget geckHome(context) {
'assets/home/qrcode.png'),
height: 68 * ratio)),
onTap: () async {
await historyProvider.scan(context);
await _historyProvider.scan(context);
}),
),
),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
boxShadow: [
BoxShadow(
blurRadius: 2,
offset: Offset(1, 1.5),
spreadRadius: 0.5)
],
),
),
const SizedBox(height: 12),
Text(
@ -451,7 +463,7 @@ Widget welcomeHome(context) {
left: 15,
child: Builder(
builder: (context) => IconButton(
key: keyDrawerMenu,
key: const Key('drawerMenu'),
icon: const Icon(
Icons.menu,
color: Colors.white,
@ -539,10 +551,10 @@ Widget welcomeHome(context) {
width: 410,
height: 70,
child: ElevatedButton(
key: keyOnboardingNewChest,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(
@ -566,9 +578,8 @@ Widget welcomeHome(context) {
width: 410,
height: 70,
child: OutlinedButton(
key: keyRestoreChest,
style: OutlinedButton.styleFrom(
side: const BorderSide(width: 4, color: orangeC)),
side: BorderSide(width: 4, color: orangeC)),
onPressed: () {
Navigator.push(
context,
@ -581,7 +592,7 @@ Widget welcomeHome(context) {
},
child: Text(
"restoreWallet".tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 24,
color: orangeC,
fontWeight: FontWeight.w600),

View File

@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously, must_be_immutable
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:durt/durt.dart';
@ -10,9 +8,11 @@ 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 'dart:io';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class ChangePinScreen extends StatelessWidget with ChangeNotifier {
ChangePinScreen(
{Key? keyMyWallets,
@ -21,14 +21,15 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
: super(key: keyMyWallets);
final String? walletName;
final MyWalletsProvider walletProvider;
Directory? appPath;
final TextEditingController newPin = TextEditingController();
TextEditingController newPin = TextEditingController();
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider =
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
return WillPopScope(
@ -99,16 +100,17 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black, elevation: 12,
backgroundColor: Colors.green[400], // foreground
elevation: 12,
primary: Colors.green[400], //smoothYellow, // background
onPrimary: Colors.black, // foreground
),
onPressed: () async {
WalletData defaultWallet =
myWalletProvider.getDefaultWallet();
_myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -117,8 +119,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
await sub.changePassword(context, defaultWallet.address!,
if (_pin != null || _myWalletProvider.pinCode != '') {
await _sub.changePassword(context, defaultWallet.address!,
walletProvider.pinCode, newPin.text);
walletProvider.pinCode = newPin.text;
newPin.text = '';

View File

@ -1,12 +1,9 @@
// ignore_for_file: use_build_context_synchronously
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:flutter/services.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart';
@ -26,9 +23,9 @@ class ChestOptions extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
ChestProvider chestProvider =
ChestProvider _chestProvider =
Provider.of<ChestProvider>(context, listen: false);
HomeProvider homeProvider =
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
ChestData currentChest = chestBox.get(configBox.get('currentChest'))!;
@ -52,21 +49,21 @@ class ChestOptions extends StatelessWidget {
height: 22,
child: Text(currentChest.name!),
)),
bottomNavigationBar: homeProvider.bottomAppBar(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: Stack(children: [
Builder(
builder: (ctx) => SafeArea(
child: Column(children: <Widget>[
SizedBox(height: 30 * ratio),
InkWell(
key: keyShowSeed,
key: const Key('showSeed'),
onTap: () async {
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
pin = await Navigator.push(
_myWalletProvider.getDefaultWallet();
String? _pin;
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -75,7 +72,7 @@ class ChestOptions extends StatelessWidget {
),
);
if (pin != null) {
if (_pin != null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
@ -98,7 +95,7 @@ class ChestOptions extends StatelessWidget {
const SizedBox(width: 15),
Text(
'displayMnemonic'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 20,
color: orangeC,
),
@ -107,10 +104,10 @@ class ChestOptions extends StatelessWidget {
),
),
SizedBox(height: 10 * ratio),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return InkWell(
key: keyChangePin,
onTap: sub.nodeConnected
key: const Key('changePin'),
onTap: _sub.nodeConnected
? () async {
// await _chestProvider.changePin(context, cesiumWallet);
String? pinResult = await Navigator.push(
@ -143,7 +140,7 @@ class ChestOptions extends StatelessWidget {
'changePassword'.tr(),
style: TextStyle(
fontSize: 20,
color: sub.nodeConnected
color: _sub.nodeConnected
? Colors.black
: Colors.grey[500]),
),
@ -151,10 +148,10 @@ class ChestOptions extends StatelessWidget {
);
}),
SizedBox(height: 10 * ratio),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return InkWell(
key: keycreateRootDerivation,
onTap: sub.nodeConnected
key: const Key('createRootDerivation'),
onTap: _sub.nodeConnected
? () async {
await Navigator.push(
context,
@ -179,7 +176,7 @@ class ChestOptions extends StatelessWidget {
'createDerivation'.tr(),
style: TextStyle(
fontSize: 20,
color: sub.nodeConnected
color: _sub.nodeConnected
? Colors.black
: Colors.grey[500]),
),
@ -189,9 +186,9 @@ class ChestOptions extends StatelessWidget {
}),
SizedBox(height: 10 * ratio),
InkWell(
key: keyDeleteChest,
key: const Key('deleteChest'),
onTap: () async {
await chestProvider.deleteChest(context, currentChest);
await _chestProvider.deleteChest(context, currentChest);
},
child: SizedBox(
height: 50,

View File

@ -1,9 +1,6 @@
// 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:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:flutter/material.dart';
@ -23,6 +20,7 @@ class ChooseChest extends StatefulWidget {
}
}
// ignore: must_be_immutable
class _ChooseChestState extends State<ChooseChest> {
TextEditingController tplController = TextEditingController();
CarouselController buttonCarouselController = CarouselController();
@ -31,7 +29,7 @@ class _ChooseChestState extends State<ChooseChest> {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
return Scaffold(
@ -111,15 +109,15 @@ class _ChooseChestState extends State<ChooseChest> {
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
backgroundColor: orangeC, // foreground
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () async {
await configBox.put('currentChest', currentChest);
myWalletProvider.pinCode = '';
_myWalletProvider.pinCode = '';
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
myWalletProvider.reload();
_myWalletProvider.getDefaultWallet();
_myWalletProvider.rebuildWidget();
await Navigator.push(
context,
@ -133,7 +131,7 @@ class _ChooseChestState extends State<ChooseChest> {
context,
ModalRoute.withName('/'),
);
if (myWalletProvider.pinCode != '') {
if (_myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
@ -144,7 +142,7 @@ class _ChooseChestState extends State<ChooseChest> {
},
child: Text(
'openThisChest'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 22,
color: backgroundColor,
fontWeight: FontWeight.w600),
@ -156,7 +154,7 @@ class _ChooseChestState extends State<ChooseChest> {
child: Align(
alignment: Alignment.bottomCenter,
child: InkWell(
key: keyCreateNewChest,
key: const Key('createNewChest'),
onTap: () {
Navigator.push(
context,
@ -170,7 +168,7 @@ class _ChooseChestState extends State<ChooseChest> {
height: 50,
child: Center(
child: Text('createChest'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600))),
@ -179,7 +177,7 @@ class _ChooseChestState extends State<ChooseChest> {
),
),
InkWell(
key: keyImportChest,
key: const Key('importChest'),
onTap: () {
Navigator.push(
context,
@ -193,7 +191,7 @@ class _ChooseChestState extends State<ChooseChest> {
height: 50,
child: Center(
child: Text('importChest'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600))),

View File

@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously, must_be_immutable
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
@ -7,7 +5,6 @@ import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
@ -16,6 +13,7 @@ import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class ChooseWalletScreen extends StatelessWidget {
ChooseWalletScreen({Key? key, required this.pin}) : super(key: key);
final String pin;
@ -24,7 +22,7 @@ class ChooseWalletScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final int chest = configBox.get('currentChest');
return Scaffold(
@ -46,14 +44,16 @@ class ChooseWalletScreen extends StatelessWidget {
width: 470,
height: 70,
child: ElevatedButton(
key: keyConfirm,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () async {
await sub.setCurrentWallet(selectedWallet!);
sub.reload();
await _sub.setCurrentWallet(selectedWallet!);
// _walletViewProvider.reload();
_sub.reload();
// Navigator.pop(context);
Navigator.pop(context);
@ -72,22 +72,22 @@ class ChooseWalletScreen extends StatelessWidget {
));
}
Widget myWalletsTiles(BuildContext context, int currentChest) {
MyWalletsProvider myWalletProvider =
Widget myWalletsTiles(BuildContext context, int? currentChest) {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
WalletData? defaultWallet = _myWalletProvider.getDefaultWallet();
selectedWallet ??= defaultWallet;
myWalletProvider.readAllWallets(currentChest);
_myWalletProvider.readAllWallets(currentChest);
if (!isWalletsExists) {
return const Text('');
}
if (myWalletProvider.listWallets.isEmpty) {
if (_myWalletProvider.listWallets.isEmpty) {
return Column(children: const <Widget>[
Center(
child: Text(
@ -97,7 +97,7 @@ class ChooseWalletScreen extends StatelessWidget {
]);
}
List listWallets = myWalletProvider.listWallets;
List _listWallets = _myWalletProvider.listWallets;
final double screenWidth = MediaQuery.of(context).size.width;
int nTule = 2;
@ -110,20 +110,19 @@ class ChooseWalletScreen extends StatelessWidget {
return CustomScrollView(slivers: <Widget>[
const SliverToBoxAdapter(child: SizedBox(height: 20)),
SliverGrid.count(
key: keyListWallets,
key: const Key('listWallets'),
crossAxisCount: nTule,
childAspectRatio: 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
children: <Widget>[
for (WalletData repository in listWallets as Iterable<WalletData>)
for (WalletData _repository in _listWallets as Iterable<WalletData>)
Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
key: keySelectThisWallet(repository.address!),
onTap: () {
selectedWallet = repository;
myWalletProvider.reload();
selectedWallet = _repository;
_myWalletProvider.rebuildWidget();
},
child: ClipOvalShadow(
shadow: const Shadow(
@ -148,9 +147,9 @@ class ChooseWalletScreen extends StatelessWidget {
const Color(0xFFE7E7A6),
],
)),
child: repository.imageCustomPath == null
child: _repository.imageCustomPath == null
? Image.asset(
'assets/avatars/${repository.imageDefaultPath}',
'assets/avatars/${_repository.imageDefaultPath}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
@ -163,14 +162,14 @@ class ChooseWalletScreen extends StatelessWidget {
image: DecorationImage(
fit: BoxFit.contain,
image: FileImage(
File(repository.imageCustomPath!),
File(_repository.imageCustomPath!),
),
),
),
),
)),
balanceBuilder(context, repository.address!,
selectedWallet!.address == repository.address!),
balanceBuilder(context, _repository.address!,
selectedWallet!.address == _repository.address!),
ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
@ -178,7 +177,7 @@ class ChooseWalletScreen extends StatelessWidget {
),
),
tileColor:
repository.address == selectedWallet!.address
_repository.address == selectedWallet!.address
? orangeC
: const Color(0xffFFD58D),
title: Center(
@ -186,11 +185,11 @@ class ChooseWalletScreen extends StatelessWidget {
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: Text(
repository.name!,
_repository.name!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 17.0,
color: repository.address ==
color: _repository.address ==
selectedWallet!.address
? const Color(0xffF9F9F1)
: Colors.black,
@ -199,8 +198,8 @@ class ChooseWalletScreen extends StatelessWidget {
),
),
onTap: () async {
selectedWallet = repository;
myWalletProvider.reload();
selectedWallet = _repository;
_myWalletProvider.rebuildWidget();
},
)
]),
@ -211,12 +210,12 @@ class ChooseWalletScreen extends StatelessWidget {
]);
}
Widget balanceBuilder(context, String address, bool isDefault) {
Widget balanceBuilder(context, String _address, bool isDefault) {
return Container(
width: double.infinity,
color: isDefault ? orangeC : yellowC,
child: SizedBox(
height: 30,
height: 25,
child: Column(children: [
const Spacer(),
// Text(
@ -224,10 +223,8 @@ class ChooseWalletScreen extends StatelessWidget {
// textAlign: TextAlign.center,
// style: TextStyle(color: isDefault ? Colors.white : Colors.black),
// ),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
balance(
context, address, 16, isDefault ? Colors.white : Colors.black),
])
balance(
context, _address, 15, isDefault ? Colors.white : Colors.black)
]),
),
);

View File

@ -1,5 +1,3 @@
// ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
@ -28,7 +26,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final derivationList = <String>[
@ -36,11 +34,11 @@ class _CustomDerivationState extends State<CustomDerivation> {
for (var i = 0; i < 51; i += 1) i.toString()
];
final listWallets = myWalletProvider.readAllWallets();
final listWallets = _myWalletProvider.readAllWallets();
for (WalletData wallet in listWallets) {
derivationList.remove(wallet.derivation.toString());
if (wallet.derivation == -1) {
for (WalletData _wallet in listWallets) {
derivationList.remove(_wallet.derivation.toString());
if (_wallet.derivation == -1) {
derivationList.remove('root');
}
}
@ -72,7 +70,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
menuMaxHeight: 300,
icon: const Icon(Icons.arrow_downward),
elevation: 16,
style: const TextStyle(color: orangeC),
style: TextStyle(color: orangeC),
underline: Container(
height: 2,
color: orangeC,
@ -107,15 +105,16 @@ class _CustomDerivationState extends State<CustomDerivation> {
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () async {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
_myWalletProvider.getDefaultWallet();
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -125,16 +124,16 @@ class _CustomDerivationState extends State<CustomDerivation> {
);
}
if (pin != null || myWalletProvider.pinCode != '') {
String newDerivationName =
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
if (_pin != null || _myWalletProvider.pinCode != '') {
String _newDerivationName = 'wallet'.tr() +
' ${_myWalletProvider.listWallets.last.number! + 2}';
if (dropdownValue == 'root') {
await myWalletProvider.generateRootWallet(
await _myWalletProvider.generateRootWallet(
context, 'Portefeuille racine');
} else {
await myWalletProvider.generateNewDerivation(
await _myWalletProvider.generateNewDerivation(
context,
newDerivationName,
_newDerivationName,
int.parse(dropdownValue!),
);
}

View File

@ -1,317 +0,0 @@
// 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/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:provider/provider.dart';
class ImportG1v1 extends StatelessWidget {
const ImportG1v1({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
Timer? debounce;
const int debouneTime = 300;
WalletData selectedWallet = myWalletProvider.getDefaultWallet();
bool canValidate = false;
String validationStatus = '';
return WillPopScope(
onWillPop: () {
resetScreen(context);
return Future<bool>.value(true);
},
child: Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
resetScreen(context);
Navigator.of(context).pop();
}),
title: SizedBox(
height: 22,
child: Text('importOldAccount'.tr()),
)),
body: SafeArea(
child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.getBalanceAndIdtyStatus(
sub.g1V1NewAddress, selectedWallet.address!),
builder: (BuildContext context, AsyncSnapshot<List> status) {
// log.d(_certs.data);
if (status.data == null) {
return Column(children: [
const SizedBox(height: 80),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
SizedBox(
height: 35,
width: 35,
child: CircularProgressIndicator(
color: orangeC,
strokeWidth: 4,
),
),
]),
]);
}
final Map balance = status.data?[0] ?? {};
final String idtyStatus = status.data?[1];
final String myIdtyStatus = status.data?[2];
final bool hasConsumer = status.data?[3] ?? false;
// log.d('hasconsumer: $hasConsumer');
if (balance['transferableBalance'] != 0 && !hasConsumer) {
canValidate = true;
validationStatus = '';
} else {
canValidate = false;
validationStatus = hasConsumer
? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X'])
: 'thisAccountIsEmpty'.tr();
}
if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
canValidate = false;
validationStatus =
'youCannotMigrateIdentityToExistingIdentity'.tr();
}
if (sub.g1V1NewAddress == '') {
validationStatus = '';
}
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
return Column(children: <Widget>[
const SizedBox(height: 20),
TextFormField(
key: keyCesiumId,
autofocus: true,
onChanged: (text) {
if (debounce?.isActive ?? false) {
debounce!.cancel();
}
debounce = Timer(
const Duration(milliseconds: debouneTime), () {
sub.reload();
sub.csToV2Address(
sub.csSalt.text, sub.csPassword.text);
});
},
keyboardType: TextInputType.text,
controller: sub.csSalt,
obscureText: !sub
.isCesiumIDVisible, //This will obscure text dynamically
decoration: InputDecoration(
hintText: 'enterCesiumId'.tr(),
suffixIcon: IconButton(
key: keyCesiumIdVisible,
icon: Icon(
sub.isCesiumIDVisible
? Icons.visibility_off
: Icons.visibility,
color: Colors.black,
),
onPressed: () {
sub.cesiumIDisVisible();
},
),
),
),
const SizedBox(height: 20),
TextFormField(
key: keyCesiumPassword,
autofocus: true,
onChanged: (text) {
if (debounce?.isActive ?? false) {
debounce!.cancel();
}
debounce = Timer(
const Duration(milliseconds: debouneTime), () {
sub.g1V1NewAddress = '';
sub.reload();
sub.csToV2Address(
sub.csSalt.text, sub.csPassword.text);
});
},
keyboardType: TextInputType.text,
controller: sub.csPassword,
obscureText: !sub
.isCesiumIDVisible, //This will obscure text dynamically
decoration: InputDecoration(
hintText: 'enterCesiumPassword'.tr(),
suffixIcon: IconButton(
icon: Icon(
sub.isCesiumIDVisible
? Icons.visibility_off
: Icons.visibility,
color: Colors.black,
),
onPressed: () {
sub.cesiumIDisVisible();
},
),
),
),
const SizedBox(height: 20),
GestureDetector(
key: keyCopyAddress,
onTap: () {
Clipboard.setData(
ClipboardData(text: sub.g1V1NewAddress));
snackCopyKey(context);
},
child: Text(
getShortPubkey(sub.g1V1NewAddress),
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(height: 20),
Text(
'${balance['transferableBalance']} $unit',
style: const TextStyle(fontSize: 17),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
walletOptions.idtyStatus(context, sub.g1V1NewAddress,
isOwner: false, color: Colors.black),
const SizedBox(width: 10),
getCerts(context, sub.g1V1NewAddress, 14)
],
),
const SizedBox(height: 30),
Text('selectDestWallet'.tr()),
const SizedBox(height: 5),
DropdownButtonHideUnderline(
key: keySelectWallet,
child: DropdownButton(
// alignment: AlignmentDirectional.topStart,
value: selectedWallet,
icon: const Icon(Icons.keyboard_arrow_down),
items: myWalletProvider.listWallets.map((wallet) {
return DropdownMenuItem(
key: keySelectThisWallet(wallet.address!),
value: wallet,
child: Text(
wallet.name!,
style: const TextStyle(fontSize: 18),
),
);
}).toList(),
onChanged: (WalletData? newSelectedWallet) {
selectedWallet = newSelectedWallet!;
sub.reload();
},
),
),
const SizedBox(height: 30),
SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyConfirm,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
),
onPressed: canValidate
? () async {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(
wallet: defaultWallet);
},
),
);
}
sub.migrateCsToV2(
sub.csSalt.text,
sub.csPassword.text,
selectedWallet.address!,
destPassword:
pin ?? myWalletProvider.pinCode,
balance: balance,
idtyStatus: idtyStatus);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transType: 'identityMigration',
fromAddress:
getShortPubkey(sub.g1V1NewAddress),
toAddress: getShortPubkey(
selectedWallet.address!));
}),
);
resetScreen(context);
}
: null,
child: Text(
'migrateAccount'.tr(),
style: TextStyle(
fontSize: 23 * ratio,
fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 10),
Text(
validationStatus,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15, color: Colors.grey[600]),
)
]);
});
}),
),
),
);
}
void resetScreen(BuildContext context) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
sub.csSalt.text = '';
sub.csPassword.text = '';
sub.g1V1NewAddress = '';
}
}

View File

@ -1,18 +1,6 @@
// 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/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/screens/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:provider/provider.dart';
// import 'package:gecko/models/wallet_data.dart';
// import 'package:gecko/providers/my_wallets.dart';
// import 'package:gecko/providers/substrate_sdk.dart';
@ -28,140 +16,77 @@ class ManageMembership extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
final sub = Provider.of<SubstrateSdk>(context);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: SizedBox(
title: const SizedBox(
height: 22,
child: const Text('manageMembership').tr(),
child: Text('manageMembership'),
)),
body: SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 20),
migrateIdentity(context),
const SizedBox(height: 10),
FutureBuilder(
future: sub.isSmithGet(address),
builder: (BuildContext context, AsyncSnapshot<bool> isSmith) {
if (isSmith.data ?? false) {
return SizedBox(
height: 70,
child: Row(
children: <Widget>[
const SizedBox(width: 20),
Image.asset(
'assets/skull_Icon.png',
color: Colors.grey[500],
height: 30,
),
const SizedBox(width: 16),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('revokeMyIdentity'.tr(),
style: TextStyle(
fontSize: 20,
color: Colors.grey[500])),
const SizedBox(height: 5),
Text("youCannotRevokeThisIdentity".tr(),
style: TextStyle(
fontSize: 14,
color: Colors.grey[500])),
]),
],
));
} else {
return revokeMyIdentity(context);
}
})
revokeMyIdentity(context),
// const SizedBox(height: 20),
]),
));
}
Widget migrateIdentity(BuildContext context) {
return InkWell(
key: keyMigrateIdentity,
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const MigrateIdentityScreen();
}),
);
},
child: SizedBox(
height: 60,
child: Row(children: const <Widget>[
SizedBox(width: 16),
Icon(Icons.change_circle_outlined, size: 35),
SizedBox(width: 11.5),
Text('Migrer mon identité', style: TextStyle(fontSize: 20)),
]),
),
);
}
Widget revokeMyIdentity(BuildContext context) {
return InkWell(
key: keyRevokeIdty,
key: const Key('revokeIdty'),
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;
// final _answer = await confirmPopup(context,
// 'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
// false;
if (answer) {
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
// if (_answer) {
// MyWalletsProvider _myWalletProvider =
// Provider.of<MyWalletsProvider>(context, listen: false);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
// MyWalletsProvider mw = MyWalletsProvider();
// final wallet = mw.getWalletDataByAddress(address);
// await sub.setCurrentWallet(wallet!);
// 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);
// 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(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transType: 'revokeIdty',
fromAddress: getShortPubkey(address),
toAddress: getShortPubkey(address));
}),
);
}
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) {
// return const TransactionInProgress(transType: 'revokeIdty');
// }),
// );
// }
},
child: SizedBox(
height: 60,
child: Row(children: <Widget>[
const SizedBox(width: 20),
Image.asset(
'assets/skull_Icon.png',
height: 30,
),
const SizedBox(width: 16),
const Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)),
height: 40,
child: Row(children: const <Widget>[
SizedBox(width: 32),
// Image.asset(
// 'assets/medal.png',
// height: 45,
// ),
Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)),
]),
),
);

View File

@ -1,260 +0,0 @@
// ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/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:provider/provider.dart';
class MigrateIdentityScreen extends StatelessWidget {
const MigrateIdentityScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
final fromAddress = walletOptions.address.text;
final defaultWallet = myWalletProvider.getDefaultWallet();
final walletsList = myWalletProvider.listWallets.toList();
late WalletData selectedWallet;
if (fromAddress == defaultWallet.address) {
selectedWallet =
walletsList[fromAddress == walletsList[0].address ? 1 : 0];
} else {
selectedWallet = defaultWallet;
}
bool canValidate = false;
String validationStatus = '';
final mdStyle = MarkdownStyleSheet(
p: const TextStyle(fontSize: 18, color: Colors.black, letterSpacing: 0.3),
textAlign: WrapAlignment.center,
);
if (walletsList.length < 2) {
return Column(
children: [
const SizedBox(height: 80),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
style: TextStyle(fontSize: 20),
)
],
)
],
);
}
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: SizedBox(
height: 22,
child: Text('importOldAccount'.tr()),
)),
body: SafeArea(
child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.getBalanceAndIdtyStatus(
fromAddress, selectedWallet.address!),
builder: (BuildContext context, AsyncSnapshot<List> status) {
if (status.data == null) {
return Column(children: [
const SizedBox(height: 80),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
SizedBox(
height: 35,
width: 35,
child: CircularProgressIndicator(
color: orangeC,
strokeWidth: 4,
),
),
]),
]);
}
// log.d('statusData: ${status.data}');
final Map balance = status.data?[0] ?? {};
final String idtyStatus = status.data?[1];
final String myIdtyStatus = status.data?[2];
final bool hasConsumer = status.data?[3] ?? false;
// log.d('hasconsumer: $hasConsumer');
if (balance['transferableBalance'] != 0 && !hasConsumer) {
canValidate = true;
validationStatus = '';
} else {
canValidate = false;
validationStatus = hasConsumer
? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X'])
: 'thisAccountIsEmpty'.tr();
}
if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
canValidate = false;
validationStatus =
'youCannotMigrateIdentityToExistingIdentity'.tr();
}
log.d(
'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus');
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: <Widget>[
Row(children: const []),
const SizedBox(height: 20),
SizedBox(
width: 350,
child: MarkdownBody(
data: 'areYouSureMigrateIdentity'.tr(args: [
duniterIndexer.walletNameIndexer[fromAddress] ??
'???',
'${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),
DropdownButtonHideUnderline(
key: keySelectWallet,
child: DropdownButton(
// alignment: AlignmentDirectional.topStart,
value: selectedWallet,
icon: const Icon(Icons.keyboard_arrow_down),
items: walletsList.map((wallet) {
return DropdownMenuItem(
key: keySelectThisWallet(wallet.address!),
value: wallet,
child: Text(
wallet.name!,
style: const TextStyle(fontSize: 18),
),
);
}).toList(),
onChanged: (WalletData? newSelectedWallet) {
selectedWallet = newSelectedWallet!;
sub.reload();
},
),
),
const SizedBox(height: 30),
SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyConfirm,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
),
onPressed: canValidate
? () async {
log.d('GOOO');
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(
wallet: defaultWallet);
},
),
);
}
sub.migrateIdentity(
fromAddress: fromAddress,
destAddress: selectedWallet.address!,
fromPassword: pin ?? myWalletProvider.pinCode,
destPassword: pin ?? myWalletProvider.pinCode,
withBalance: true,
fromBalance: balance);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transType: 'identityMigration',
fromAddress: getShortPubkey(fromAddress),
toAddress: getShortPubkey(
selectedWallet.address!));
}),
);
}
: null,
child: Text(
'migrateIdentity'.tr(),
style: TextStyle(
fontSize: 23 * ratio, fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 10),
Text(
validationStatus,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15, color: Colors.grey[600]),
)
]);
});
}),
),
);
}
}

View File

@ -3,7 +3,6 @@ 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/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart';
@ -22,7 +21,7 @@ class RestoreChest extends StatelessWidget {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider genW =
Provider.of<GenerateWalletsProvider>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
genW.actualWallet = null;
if (genW.isSentenceComplete(context)) {
@ -50,114 +49,110 @@ class RestoreChest extends StatelessWidget {
child: Text('restoreAChest'.tr()),
)),
body: SafeArea(
child: Stack(children: [
child: Column(children: <Widget>[
SizedBox(height: isTall ? 30 : 15),
bubbleSpeak('toRestoreEnterMnemonic'.tr()),
SizedBox(height: isTall ? 30 : 15),
Column(children: <Widget>[
SizedBox(height: isTall ? 30 : 15),
bubbleSpeak('toRestoreEnterMnemonic'.tr()),
SizedBox(height: isTall ? 30 : 15),
Column(children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController0),
arrayCell(context, genW.cellController1),
arrayCell(context, genW.cellController2),
arrayCell(context, genW.cellController3),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController4),
arrayCell(context, genW.cellController5),
arrayCell(context, genW.cellController6),
arrayCell(context, genW.cellController7),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController8),
arrayCell(context, genW.cellController9),
arrayCell(context, genW.cellController10),
arrayCell(context, genW.cellController11),
]),
]),
// const Spacer(),
if (genW.isSentenceComplete(context))
Expanded(
child: Align(
alignment: Alignment.center,
child: SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
key: keyGoNext,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
),
onPressed: () async {
if (await sub
.isMnemonicValid(genW.generatedMnemonic!)) {
genW.resetImportView();
await Navigator.push(
context,
FaderTransition(
page: skipIntro
? const OnboardingStepNine(
scanDerivation: true)
: const OnboardingStepSeven(
scanDerivation: true),
isFast: true),
);
} else {
await badMnemonicPopup(context);
}
},
child: Text(
'restoreThisChest'.tr(),
style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.w600),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController0),
arrayCell(context, genW.cellController1),
arrayCell(context, genW.cellController2),
arrayCell(context, genW.cellController3),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController4),
arrayCell(context, genW.cellController5),
arrayCell(context, genW.cellController6),
arrayCell(context, genW.cellController7),
]),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
arrayCell(context, genW.cellController8),
arrayCell(context, genW.cellController9),
arrayCell(context, genW.cellController10),
arrayCell(context, genW.cellController11),
]),
]),
// const Spacer(),
if (genW.isSentenceComplete(context))
Expanded(
child: Align(
alignment: Alignment.center,
child: SizedBox(
width: 410,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () async {
if (await _sub.isMnemonicValid(genW.generatedMnemonic!)) {
genW.resetImportView();
await Navigator.push(
context,
FaderTransition(
page: skipIntro
? const OnboardingStepNine(
scanDerivation: true)
: const OnboardingStepSeven(
scanDerivation: true),
isFast: true),
);
} else {
await badMnemonicPopup(context);
}
},
child: Text(
'restoreThisChest'.tr(),
style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.w600),
),
),
// SizedBox(height: isTall ? 80 : 80),
))
else
Column(children: [
const SizedBox(height: 20),
SizedBox(
width: 190,
height: 60,
child: ElevatedButton(
key: keyPastMnemonic,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black, elevation: 4,
backgroundColor: yellowC, // foreground
),
onPressed: () {
genW.pasteMnemonic(context);
},
child: Row(
children: [
const Icon(
Icons.content_paste_go,
size: 25,
),
const SizedBox(width: 10),
Text(
'pasteFromClipboard'.tr(),
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 17, fontWeight: FontWeight.w400),
),
],
)),
)
])
]),
CommonElements().offlineInfo(context),
),
// SizedBox(height: isTall ? 80 : 80),
))
else
Column(children: [
const SizedBox(height: 20),
SizedBox(
width: 190,
height: 60,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 4,
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
genW.pasteMnemonic(context);
},
child: Row(
children: [
const Icon(
Icons.content_paste_go,
size: 25,
),
const SizedBox(width: 10),
Text(
'pasteFromClipboard'.tr(),
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 17, fontWeight: FontWeight.w400),
),
],
)),
)
])
]),
),
),
@ -174,7 +169,7 @@ class RestoreChest extends StatelessWidget {
color: Colors.white,
child: Text(
text,
key: keyBubbleSpeak,
key: const Key('importText'),
textAlign: TextAlign.justify,
style: const TextStyle(
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400),
@ -189,12 +184,6 @@ class RestoreChest extends StatelessWidget {
return Container(
width: 102,
height: 40 * ratio,
// ),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Colors.white,
borderRadius: BorderRadius.circular(3),
),
// child: RawKeyboardListener(
// focusNode: FocusNode(), // or FocusNode()
// onKey: (event) {
@ -221,6 +210,12 @@ class RestoreChest extends StatelessWidget {
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20),
),
// ),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Colors.white,
borderRadius: BorderRadius.circular(3),
),
);
}

View File

@ -1,9 +1,9 @@
import 'dart:typed_data';
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/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/screens/common_elements.dart';
@ -24,13 +24,13 @@ class ShowSeed extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
CommonElements common = CommonElements();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
WalletData defaultWallet = _myWalletProvider.getDefaultWallet();
return Scaffold(
backgroundColor: backgroundColor,
@ -44,12 +44,12 @@ class ShowSeed extends StatelessWidget {
child: Column(children: <Widget>[
const Spacer(flex: 1),
FutureBuilder(
future:
sub.getSeed(defaultWallet.address!, walletProvider.pinCode),
builder: (BuildContext context, AsyncSnapshot<String?> seed) {
if (seed.connectionState != ConnectionState.done ||
seed.hasError) {
return const SizedBox(
future: _sub.getSeed(
defaultWallet.address!, walletProvider.pinCode),
builder: (BuildContext context, AsyncSnapshot<String?> _seed) {
if (_seed.connectionState != ConnectionState.done ||
_seed.hasError) {
return SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
@ -57,7 +57,7 @@ class ShowSeed extends StatelessWidget {
strokeWidth: 2,
),
);
} else if (!seed.hasData) {
} else if (!_seed.hasData) {
return const Text('');
}
@ -67,22 +67,22 @@ class ShowSeed extends StatelessWidget {
Column(children: [
common.buildText('keepYourMnemonicSecret'.tr()),
SizedBox(height: 35 * ratio),
sentanceArray(context, seed.data!.split(' ')),
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),
),
backgroundColor: orangeC,
elevation: 1, // foreground
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(
ClipboardData(text: seed.data));
ClipboardData(text: _seed.data));
snackCopyKey(context);
},
child: Row(children: <Widget>[
@ -105,7 +105,7 @@ class ShowSeed extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return PrintWallet(seed.data);
return PrintWallet(_seed.data);
}),
);
},
@ -123,8 +123,9 @@ class ShowSeed extends StatelessWidget {
height: 60 * ratio,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.pop(context);
@ -151,7 +152,7 @@ class ShowSeed extends StatelessWidget {
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
Widget sentanceArray(BuildContext context, List mnemonic) {
Widget sentanceArray(BuildContext context, List _mnemonic) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: Container(
@ -169,24 +170,24 @@ class ShowSeed extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(mnemonic[0], 1),
arrayCell(mnemonic[1], 2),
arrayCell(mnemonic[2], 3),
arrayCell(mnemonic[3], 4),
arrayCell(_mnemonic[0], 1),
arrayCell(_mnemonic[1], 2),
arrayCell(_mnemonic[2], 3),
arrayCell(_mnemonic[3], 4),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(mnemonic[4], 5),
arrayCell(mnemonic[5], 6),
arrayCell(mnemonic[6], 7),
arrayCell(mnemonic[7], 8),
arrayCell(_mnemonic[4], 5),
arrayCell(_mnemonic[5], 6),
arrayCell(_mnemonic[6], 7),
arrayCell(_mnemonic[7], 8),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(mnemonic[8], 9),
arrayCell(mnemonic[9], 10),
arrayCell(mnemonic[10], 11),
arrayCell(mnemonic[11], 12),
arrayCell(_mnemonic[8], 9),
arrayCell(_mnemonic[9], 10),
arrayCell(_mnemonic[10], 11),
arrayCell(_mnemonic[11], 12),
]),
])),
);
@ -205,7 +206,7 @@ class ShowSeed extends StatelessWidget {
),
Text(
dataWord,
key: keyMnemonicWord(dataWord),
key: Key('word$dataWord'),
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
),
]),
@ -248,26 +249,26 @@ class PrintWallet extends StatelessWidget {
);
}
Future<Uint8List> printWallet(String seed) async {
Future<Uint8List> printWallet(String _seed) async {
final ByteData fontData =
await rootBundle.load("assets/OpenSans-Regular.ttf");
final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData());
final pdf = pw.Document();
int nbr = 1;
final seedList = seed.split(' ');
final _seedList = _seed.split(' ');
// const imageProvider = AssetImage('assets/icon/gecko_final.png');
// final geckoLogo = await flutterImageProvider(imageProvider);
pw.Widget arrayCell(String dataWord, int nbr) {
pw.Widget arrayCell(String dataWord, int _nbr) {
nbr++;
return pw.SizedBox(
width: 120,
child: pw.Column(children: <pw.Widget>[
pw.Text(
nbr.toString(),
_nbr.toString(),
style: pw.TextStyle(
fontSize: 15, color: const PdfColor(0.5, 0, 0), font: ttf),
),
@ -291,22 +292,22 @@ class PrintWallet extends StatelessWidget {
// crossAxisAlignment: pw.CrossAxisAlignment.center,
children: <pw.Widget>[
pw.Row(children: <pw.Widget>[
arrayCell(seedList[0], nbr),
arrayCell(seedList[1], nbr),
arrayCell(seedList[2], nbr),
arrayCell(seedList[3], nbr),
arrayCell(_seedList[0], nbr),
arrayCell(_seedList[1], nbr),
arrayCell(_seedList[2], nbr),
arrayCell(_seedList[3], nbr),
]),
pw.Row(children: <pw.Widget>[
arrayCell(seedList[4], nbr),
arrayCell(seedList[5], nbr),
arrayCell(seedList[6], nbr),
arrayCell(seedList[7], nbr),
arrayCell(_seedList[4], nbr),
arrayCell(_seedList[5], nbr),
arrayCell(_seedList[6], nbr),
arrayCell(_seedList[7], nbr),
]),
pw.Row(children: <pw.Widget>[
arrayCell(seedList[8], nbr),
arrayCell(seedList[9], nbr),
arrayCell(seedList[10], nbr),
arrayCell(seedList[11], nbr)
arrayCell(_seedList[8], nbr),
arrayCell(_seedList[9], nbr),
arrayCell(_seedList[10], nbr),
arrayCell(_seedList[11], nbr)
]),
pw.Expanded(
child: pw.Align(

View File

@ -0,0 +1,45 @@
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/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class TransactionCommentScreen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
TransactionCommentScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: SizedBox(
height: 22,
child: Text('confirmPayment'.tr()),
),
),
body: SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 20),
TextField(
enabled: true,
controller: tplController,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(15.0),
),
style: const TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.w400)),
const SizedBox(height: 20),
]),
));
}
}

View File

@ -1,11 +1,9 @@
// ignore_for_file: must_be_immutable
// ignore_for_file: avoid_print
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart';
@ -16,29 +14,32 @@ import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
import 'package:gecko/globals.dart';
// ignore: must_be_immutable
class UnlockingWallet extends StatelessWidget {
UnlockingWallet({required this.wallet}) : super(key: keyUnlockWallet);
WalletData wallet;
UnlockingWallet({Key? keyUnlockWallet, required this.wallet})
: super(key: keyUnlockWallet);
WalletData? wallet;
late int currentChestNumber;
late ChestData currentChest;
bool canUnlock = true;
// ignore: close_sinks
StreamController<ErrorAnimationType>? errorController;
final formKey = GlobalKey<FormState>();
Color? pinColor = const Color(0xffF9F9F1);
var walletPin = '';
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
// final double statusBarHeight = MediaQuery.of(context).padding.top;
currentChestNumber = configBox.get('currentChest');
currentChest = chestBox.get(currentChestNumber)!;
int pinLenght = walletOptions.getPinLenght(wallet.number);
int _pinLenght = _walletOptions.getPinLenght(wallet!.number);
errorController = StreamController<ErrorAnimationType>();
return Scaffold(
@ -53,7 +54,7 @@ class UnlockingWallet extends StatelessWidget {
left: 15,
child: Builder(
builder: (context) => IconButton(
key: keyPopButton,
key: const Key('popButton'),
icon: const Icon(
Icons.arrow_back,
color: Colors.black,
@ -100,13 +101,12 @@ class UnlockingWallet extends StatelessWidget {
fontWeight: FontWeight.w400),
)),
SizedBox(height: 40 * ratio),
pinForm(context, pinLenght),
pinForm(context, _pinLenght),
SizedBox(height: 3 * ratio),
if (canUnlock)
InkWell(
key: keyCachePassword,
onTap: () {
walletOptions.changePinCacheChoice();
_walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
@ -129,7 +129,7 @@ class UnlockingWallet extends StatelessWidget {
const SizedBox(height: 10),
// if (canUnlock)
InkWell(
key: keyChangeChest,
key: const Key('chooseChest'),
onTap: () {
Navigator.push(
context,
@ -144,7 +144,7 @@ class UnlockingWallet extends StatelessWidget {
child: Center(
child: Text(
'changeChest'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w600),
@ -157,20 +157,20 @@ class UnlockingWallet extends StatelessWidget {
));
}
Widget pinForm(context, pinLenght) {
Widget pinForm(context, _pinLenght) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController enterPin = TextEditingController();
WalletOptionsProvider walletOptions =
TextEditingController _enterPin = TextEditingController();
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
FocusNode pinFocus = FocusNode();
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
WalletData defaultWallet = _myWalletProvider.getDefaultWallet();
// defaultWallet.address = null;
if (defaultWallet.address == null) {
@ -184,11 +184,10 @@ class UnlockingWallet extends StatelessWidget {
}
return Form(
// key: keyPinForm,
key: formKey,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30),
child: PinCodeTextField(
key: keyPinForm,
focusNode: pinFocus,
autoFocus: true,
appContext: context,
@ -196,13 +195,14 @@ class UnlockingWallet extends StatelessWidget {
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: pinLenght,
length: _pinLenght,
obscureText: true,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v!.length < pinLenght) {
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
if (v!.length < _pinLenght) {
return "yourPasswordLengthIsX"
.tr(args: [_pinLenght.toString()]);
} else {
return null;
}
@ -216,14 +216,13 @@ class UnlockingWallet extends StatelessWidget {
fieldWidth: 50,
activeFillColor: Colors.black,
),
showCursor: kDebugMode ? false : true,
cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: enterPin,
controller: _enterPin,
keyboardType: TextInputType.visiblePassword,
boxShadows: const [
BoxShadow(
@ -232,23 +231,23 @@ class UnlockingWallet extends StatelessWidget {
blurRadius: 10,
)
],
onCompleted: (pin) async {
myWalletProvider.pinCode = pin.toUpperCase();
final isValid = await sub.checkPassword(
defaultWallet.address!, pin.toUpperCase());
onCompleted: (_pin) async {
_myWalletProvider.pinCode = _pin.toUpperCase();
final isValid = await _sub.checkPassword(
defaultWallet.address!, _pin.toUpperCase());
if (!isValid) {
await Future.delayed(const Duration(milliseconds: 50));
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
pinColor = Colors.red[600];
myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
walletOptions.reload();
_myWalletProvider.pinCode = _myWalletProvider.mnemonic = '';
_walletOptions.reloadBuild();
pinFocus.requestFocus();
} else {
pinColor = Colors.green[400];
myWalletProvider.resetPinCode();
Navigator.pop(context, pin.toUpperCase());
_myWalletProvider.resetPinCode();
Navigator.pop(context, _pin.toUpperCase());
}
},
onChanged: (value) {

View File

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart';
@ -27,34 +26,30 @@ class WalletOptions extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
WalletsProfilesProvider historyProvider =
WalletsProfilesProvider _historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
HomeProvider homeProvider =
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
// SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
// sub.spawnBlock();
// sub.spawnBlock(0, 20);
log.d(_walletOptions.address.text);
log.d(walletOptions.address.text);
final int currentChest = myWalletProvider.getCurrentChest();
final int _currentChest = _myWalletProvider.getCurrentChest();
// final currentWallet = _myWalletProvider.getDefaultWallet();
// log.d(_walletOptions.getAddress(_currentChest, 3));
log.d("Wallet options: $currentChest:${wallet.derivation}");
log.d("Wallet options: $_currentChest:${wallet.derivation}");
return WillPopScope(
onWillPop: () {
walletOptions.isEditing = false;
walletOptions.isBalanceBlur = false;
myWalletProvider.reload();
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = false;
_myWalletProvider.rebuildWidget();
Navigator.pop(context);
return Future<bool>.value(true);
},
@ -67,9 +62,9 @@ class WalletOptions extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
walletOptions.isEditing = false;
walletOptions.isBalanceBlur = false;
myWalletProvider.reload();
_walletOptions.isEditing = false;
_walletOptions.isBalanceBlur = false;
_myWalletProvider.rebuildWidget();
Navigator.pop(context);
}),
title: SizedBox(
@ -79,27 +74,8 @@ class WalletOptions extends StatelessWidget {
return Text(wallet.name!);
}),
),
actions: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return QrCodeFullscreen(
walletOptions.address.text,
);
}),
);
},
child: QrImageWidget(
data: walletOptions.address.text,
version: QrVersions.auto,
size: 80,
),
),
],
),
bottomNavigationBar: homeProvider.bottomAppBar(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: Stack(children: [
Builder(
builder: (ctx) => SafeArea(
@ -111,7 +87,7 @@ class WalletOptions extends StatelessWidget {
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Container(
decoration: const BoxDecoration(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
@ -129,7 +105,7 @@ class WalletOptions extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
duniterIndexer.getNameByAddress(
_duniterIndexer.getNameByAddress(
context,
walletProvider.address.text,
wallet,
@ -148,8 +124,8 @@ class WalletOptions extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
walletOptions.idtyStatus(
context, walletOptions.address.text,
_walletOptions.idtyStatus(
context, _walletOptions.address.text,
isOwner: true, color: orangeC),
getCerts(context,
walletProvider.address.text, 15),
@ -165,60 +141,59 @@ class WalletOptions extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 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),
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: 15 * ratio),
Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) {
return Column(children: [
confirmIdentityButton(walletProvider),
pubkeyWidget(walletProvider, ctx),
SizedBox(height: 10 * ratio),
activityWidget(
context, historyProvider, walletProvider),
context, _historyProvider, walletProvider),
SizedBox(height: 12 * ratio),
setDefaultWalletWidget(
context,
walletProvider,
myWalletProvider,
walletOptions,
currentChest),
_myWalletProvider,
_walletOptions,
_currentChest),
SizedBox(height: 17 * ratio),
// walletProvider.isMember(context, _walletOptions.address.text)
FutureBuilder(
future: walletProvider.isMember(
context, walletOptions.address.text),
context, _walletOptions.address.text),
builder: (BuildContext context,
AsyncSnapshot<bool> isMember) {
if (isMember.connectionState !=
AsyncSnapshot<bool> _isMember) {
if (_isMember.connectionState !=
ConnectionState.done ||
isMember.hasError) {
_isMember.hasError) {
return const Text('');
}
return Column(children: [
if (!walletProvider.isDefaultWallet &&
!isMember.data!)
!_isMember.data!)
deleteWallet(context, walletProvider,
currentChest)
_currentChest)
else
const SizedBox(),
if (isMember.data!)
manageMembership(context)
if (_isMember.data!)
manageMemberStatus(context)
]);
}),
]);
@ -240,12 +215,12 @@ class WalletOptions extends StatelessWidget {
children: <Widget>[
InkWell(
onTap: () async {
final newPath = await (walletProvider.changeAvatar());
if (newPath != '') {
wallet.imageCustomPath = newPath;
final _newPath = await (walletProvider.changeAvatar());
if (_newPath != '') {
wallet.imageCustomPath = _newPath;
walletBox.put(wallet.key, wallet);
}
walletProvider.reload();
walletProvider.reloadBuild();
},
child: wallet.imageCustomPath == null || wallet.imageCustomPath == ''
? Image.asset(
@ -273,7 +248,7 @@ class WalletOptions extends StatelessWidget {
child: InkWell(
onTap: () async {
wallet.imageCustomPath = await (walletProvider.changeAvatar());
walletProvider.reload();
walletProvider.reloadBuild();
},
child: Image.asset(
'assets/walletOptions/camera.png',
@ -285,61 +260,10 @@ class WalletOptions extends StatelessWidget {
);
}
Widget confirmIdentityButton(WalletOptionsProvider walletProvider) {
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.idtyStatus(walletProvider.address.text),
initialData: '',
builder: (context, snapshot) {
if (snapshot.data == 'Created') {
return Column(children: [
SizedBox(
width: 320,
height: 60,
child: ElevatedButton(
key: keyConfirmIdentity,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
),
onPressed: () {
walletProvider.confirmIdentityPopup(context);
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) {
// return const SearchResultScreen();
// }),
// );
},
child: Text(
'confirmMyIdentity'.tr(),
style: const TextStyle(
fontSize: 21, fontWeight: FontWeight.w600),
),
),
),
const SizedBox(height: 7),
Text(
"someoneCreatedYourIdentity".tr(args: [currencyName]),
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
fontStyle: FontStyle.italic,
),
),
const SizedBox(height: 40),
]);
} else {
return const SizedBox();
}
});
});
}
Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) {
final String shortPubkey = getShortPubkey(walletProvider.address.text);
return GestureDetector(
key: keyCopyAddress,
key: const Key('copyPubkey'),
onTap: () {
Clipboard.setData(ClipboardData(text: walletProvider.address.text));
snackCopyKey(ctx);
@ -364,12 +288,12 @@ class WalletOptions extends StatelessWidget {
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
backgroundColor: orangeC,
elevation: 1, // foreground
elevation: 1,
primary: orangeC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () {
Clipboard.setData(
@ -396,10 +320,10 @@ class WalletOptions extends StatelessWidget {
Widget activityWidget(
BuildContext context,
WalletsProfilesProvider historyProvider,
WalletsProfilesProvider _historyProvider,
WalletOptionsProvider walletProvider) {
return InkWell(
key: keyOpenActivity,
key: const Key('displayActivity'),
onTap: () {
// _historyProvider.nPage = 1;
Navigator.push(
@ -436,17 +360,17 @@ class WalletOptions extends StatelessWidget {
);
}
Widget manageMembership(BuildContext context) {
WalletOptionsProvider walletOptions =
Widget manageMemberStatus(BuildContext context) {
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
return InkWell(
key: keyManageMembership,
key: const Key('manageStatus'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ManageMembership(
address: walletOptions.address.text,
address: _walletOptions.address.text,
);
}),
);
@ -469,17 +393,18 @@ class WalletOptions extends StatelessWidget {
Widget setDefaultWalletWidget(
BuildContext context,
WalletOptionsProvider walletProvider,
MyWalletsProvider myWalletProvider,
WalletOptionsProvider walletOptions,
int currentChest) {
return Consumer<MyWalletsProvider>(builder: (context, myWalletProvider, _) {
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
MyWalletsProvider _myWalletProvider,
WalletOptionsProvider _walletOptions,
int _currentChest) {
return Consumer<MyWalletsProvider>(
builder: (context, _myWalletProvider, _) {
WalletData defaultWallet = _myWalletProvider.getDefaultWallet();
_walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
return InkWell(
key: keySetDefaultWallet,
key: const Key('setDefaultWallet'),
onTap: !walletProvider.isDefaultWallet
? () async {
await setDefaultWallet(context, currentChest);
await setDefaultWallet(context, _currentChest);
}
: null,
child: SizedBox(
@ -510,53 +435,50 @@ class WalletOptions extends StatelessWidget {
});
}
Future setDefaultWallet(BuildContext context, int currentChest) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider =
Future setDefaultWallet(BuildContext context, int _currentChest) async {
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
// WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
// defaultWallet = wallet;
await sub.setCurrentWallet(wallet);
myWalletProvider.readAllWallets(currentChest);
myWalletProvider.reload();
walletOptions.reload();
await _sub.setCurrentWallet(wallet);
_myWalletProvider.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
}
Widget deleteWallet(BuildContext context,
WalletOptionsProvider walletProvider, int currentChest) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider =
WalletOptionsProvider walletProvider, int _currentChest) {
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final defaultWallet = myWalletProvider.getDefaultWallet();
final _defaultWallet = _myWalletProvider.getDefaultWallet();
final bool isDefaultWallet =
walletProvider.address.text == defaultWallet.address;
walletProvider.address.text == _defaultWallet.address;
// return Consumer<MyWalletsProvider>(
// builder: (context, _myWalletProvider, _) {
return FutureBuilder(
future: sub.hasAccountConsumers(wallet.address!),
builder: (BuildContext context, AsyncSnapshot<bool> hasConsumers) {
if (hasConsumers.connectionState != ConnectionState.done ||
hasConsumers.hasError) {
future: _sub.hasAccountConsumers(wallet.address!),
builder: (BuildContext context, AsyncSnapshot<bool> _hasConsumers) {
if (_hasConsumers.connectionState != ConnectionState.done ||
_hasConsumers.hasError) {
return const Text('');
}
final double balance =
final double _balance =
balanceCache[walletProvider.address.text] ?? -1;
final bool canDelete = !isDefaultWallet &&
!hasConsumers.data! &&
(balance > 2 || balance == 0);
!_hasConsumers.data! &&
(_balance > 2 || _balance == 0);
return InkWell(
key: keyDeleteWallet,
key: const Key('deleteWallet'),
onTap: canDelete
? () async {
await walletProvider.deleteWallet(context, wallet);
WidgetsBinding.instance.addPostFrameCallback((_) {
myWalletProvider.listWallets =
myWalletProvider.readAllWallets(currentChest);
myWalletProvider.reload();
_myWalletProvider.listWallets =
_myWalletProvider.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
});
}
: null,

View File

@ -1,13 +1,9 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart';
@ -18,10 +14,8 @@ import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/chest_options.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:provider/provider.dart';
class WalletsHome extends StatelessWidget {
@ -32,16 +26,17 @@ class WalletsHome extends StatelessWidget {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
HomeProvider homeProvider =
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
final int currentChestNumber = myWalletProvider.getCurrentChest();
final ChestData currentChest = chestBox.get(currentChestNumber)!;
final int? _currentChestNumber = myWalletProvider.getCurrentChest();
final ChestData _currentChest = chestBox.get(_currentChestNumber)!;
myWalletProvider.listWallets =
myWalletProvider.readAllWallets(currentChestNumber);
myWalletProvider.readAllWallets(_currentChestNumber);
return WillPopScope(
onWillPop: () {
// myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil(
context,
ModalRoute.withName('/'),
@ -56,65 +51,36 @@ class WalletsHome extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
// myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
}),
title: Text(currentChest.name!,
title: Text(_currentChest.name!,
key: const Key('myWallets'),
style: TextStyle(color: Colors.grey[850])),
backgroundColor: const Color(0xffFFD58D),
),
bottomNavigationBar: myWalletProvider.lastFlyBy == ''
? homeProvider.bottomAppBar(context)
: dragInfo(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: SafeArea(
child: Stack(children: [
myWalletsTiles(context, currentChestNumber),
CommonElements().offlineInfo(context),
]),
child: Stack(
children: [
myWalletsTiles(context, _currentChestNumber!),
CommonElements().offlineInfo(context),
],
),
),
),
);
}
Widget dragInfo(BuildContext context) {
final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final walletDataFrom =
myWalletProvider.getWalletDataByAddress(myWalletProvider.dragAddress);
final walletDataTo =
myWalletProvider.getWalletDataByAddress(myWalletProvider.lastFlyBy);
final bool isSameAddress =
myWalletProvider.dragAddress == myWalletProvider.lastFlyBy;
final double screenWidth = MediaQuery.of(homeContext).size.width;
return Container(
color: yellowC,
width: screenWidth,
height: 80,
child: Center(
child: Column(
children: [
const SizedBox(height: 5),
Text('${'executeATransfer'.tr()}:'),
MarkdownBody(data: '${'from'.tr()} **${walletDataFrom!.name}**'),
if (isSameAddress) Text('chooseATargetWallet'.tr()),
if (!isSameAddress)
MarkdownBody(data: 'Vers: **${walletDataTo!.name}**'),
],
)),
);
}
Widget chestOptions(
BuildContext context, MyWalletsProvider myWalletProvider) {
BuildContext context, MyWalletsProvider _myWalletProvider) {
return Column(children: [
const SizedBox(height: 50),
SizedBox(
height: 80,
height: 90,
width: 420,
child: ElevatedButton.icon(
icon: Image.asset(
@ -122,17 +88,18 @@ class WalletsHome extends StatelessWidget {
height: 60,
),
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black, elevation: 2,
backgroundColor: floattingYellow, // foreground
elevation: 2,
primary: floattingYellow, // background
onPrimary: Colors.black, // foreground
),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ChestOptions(walletProvider: myWalletProvider);
return ChestOptions(walletProvider: _myWalletProvider);
}),
),
label: Text(
" ${"manageChest".tr()}",
" " + "manageChest".tr(),
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
@ -142,29 +109,7 @@ class WalletsHome extends StatelessWidget {
)),
const SizedBox(height: 30),
InkWell(
key: keyImportG1v1,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const ImportG1v1();
}),
);
},
child: SizedBox(
width: 400,
height: 60,
child: Center(
child: Text('importG1v1'.tr(),
style: TextStyle(
fontSize: 22,
color: Colors.blue[900],
fontWeight: FontWeight.w500))),
),
),
const SizedBox(height: 5),
InkWell(
key: keyChangeChest,
key: const Key('changeChest'),
onTap: () {
Navigator.push(
context,
@ -175,10 +120,10 @@ class WalletsHome extends StatelessWidget {
},
child: SizedBox(
width: 400,
height: 60,
height: 50,
child: Center(
child: Text('changeChest'.tr(),
style: const TextStyle(
style: TextStyle(
fontSize: 22,
color: orangeC,
fontWeight: FontWeight.w500))),
@ -188,19 +133,20 @@ class WalletsHome extends StatelessWidget {
]);
}
Widget myWalletsTiles(BuildContext context, int currentChestNumber) {
MyWalletsProvider myWalletProvider =
Widget myWalletsTiles(BuildContext context, int _currentChestNumber) {
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
final bool isWalletsExists = _myWalletProvider.checkIfWalletExist();
if (!isWalletsExists) {
return const Text('');
}
if (myWalletProvider.listWallets.isEmpty) {
if (_myWalletProvider.listWallets.isEmpty) {
return Expanded(
child: Column(children: const <Widget>[
Center(
@ -211,8 +157,8 @@ class WalletsHome extends StatelessWidget {
]));
}
List listWallets = myWalletProvider.listWallets;
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
List _listWallets = _myWalletProvider.listWallets;
WalletData? defaultWallet = _myWalletProvider.getDefaultWallet();
final double screenWidth = MediaQuery.of(context).size.width;
int nTule = 2;
@ -221,226 +167,201 @@ class WalletsHome extends StatelessWidget {
} else if (screenWidth >= 650) {
nTule = 3;
}
// Offset followDragAnchorStrategy(
// Draggable<Object> d, BuildContext context, Offset point) {
// return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0);
// }
return CustomScrollView(slivers: <Widget>[
const SliverToBoxAdapter(child: SizedBox(height: 20)),
SliverGrid.count(
key: keyListWallets,
key: const Key('listWallets'),
crossAxisCount: nTule,
childAspectRatio: 1,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
children: <Widget>[
for (WalletData repository in listWallets as Iterable<WalletData>)
LongPressDraggable<String>(
delay: const Duration(milliseconds: 200),
data: repository.address!,
dragAnchorStrategy:
(Draggable<Object> _, BuildContext __, Offset ___) =>
const Offset(0, 0),
// feedbackOffset: const Offset(-500, -500),
// dragAnchorStrategy: childDragAnchorStrategy,
onDragStarted: () =>
myWalletProvider.dragAddress = repository.address!,
onDragEnd: (_) {
myWalletProvider.lastFlyBy = '';
myWalletProvider.dragAddress = '';
myWalletProvider.reload();
},
feedback: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: orangeC,
shape: const CircleBorder(),
padding: const EdgeInsets.all(15),
),
child: const SizedBox(
height: 35,
child: Image(image: AssetImage('assets/vector_white.png')),
),
),
child: DragTarget<String>(
onAccept: (senderAddress) async {
log.d(
'INTERPAY: sender: $senderAddress --- receiver: ${repository.address!}');
final walletData = myWalletProvider
.getWalletDataByAddress(senderAddress);
await sub.setCurrentWallet(walletData!);
sub.reload();
paymentPopup(context, repository.address!);
},
onMove: (details) {
if (repository.address! != myWalletProvider.lastFlyBy) {
myWalletProvider.lastFlyBy = repository.address!;
myWalletProvider.reload();
}
},
onWillAccept: (senderAddress) =>
senderAddress != repository.address!,
builder: (
BuildContext context,
List<dynamic> accepted,
List<dynamic> rejected,
) {
return Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
key: keyOpenWallet(repository.address!),
onTap: () {
walletOptions.getAddress(
currentChestNumber, repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: repository,
),
),
);
},
child: ClipOvalShadow(
shadow: const Shadow(
color: Colors.transparent,
offset: Offset(0, 0),
blurRadius: 5,
),
clipper: CustomClipperOval(),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(12)),
child: Column(children: <Widget>[
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: RadialGradient(
radius: 0.6,
colors: [
Colors.green[400]!,
const Color(0xFFE7E7A6),
],
)),
child:
// SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48),
repository.imageCustomPath == null ||
repository.imageCustomPath == ''
? Image.asset(
'assets/avatars/${repository.imageDefaultPath}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.fitHeight,
image: FileImage(
File(repository
.imageCustomPath!),
),
),
),
),
)),
Stack(children: <Widget>[
balanceBuilder(
context,
repository.address!,
repository.address ==
defaultWallet.address),
nameBuilder(context, repository,
defaultWallet, currentChestNumber),
]),
]),
),
for (WalletData _repository in _listWallets as Iterable<WalletData>)
Padding(
padding: const EdgeInsets.all(16),
child: GestureDetector(
onTap: () {
// _walletOptions.readLocalWallet(context, _repository,
// _myWalletProvider.pinCode, pinLength);
_walletOptions.getAddress(
_currentChestNumber, _repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: _repository,
),
),
);
}),
),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return sub.nodeConnected
// Navigator.push(context,
// MaterialPageRoute(builder: (context) {
// return UnlockingWallet(wallet: _repository);
// }));
},
child: ClipOvalShadow(
shadow: const Shadow(
color: Colors.transparent,
offset: Offset(0, 0),
blurRadius: 5,
),
clipper: CustomClipperOval(),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(12)),
child: Column(children: <Widget>[
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
gradient: RadialGradient(
radius: 0.6,
colors: [
Colors.green[400]!,
const Color(0xFFE7E7A6),
],
)),
child:
// SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48),
_repository.imageCustomPath == null ||
_repository.imageCustomPath == ''
? Image.asset(
'assets/avatars/${_repository.imageDefaultPath}',
alignment: Alignment.bottomCenter,
scale: 0.5,
)
: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
image: DecorationImage(
fit: BoxFit.fitHeight,
image: FileImage(
File(
_repository.imageCustomPath!),
),
),
),
),
)),
balanceBuilder(context, _repository.address!,
_repository.address == defaultWallet.address),
ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(12))),
// contentPadding: const EdgeInsets.only(left: 7.0),
tileColor:
_repository.address == defaultWallet.address
? orangeC
: const Color(0xffFFD58D),
// leading: Text('IMAGE'),
// subtitle: Text(_repository.split(':')[3],
// style: TextStyle(fontSize: 12.0, fontFamily: 'Monospace')),
title: Center(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: _duniterIndexer.getNameByAddress(
context,
_repository.address!,
_repository,
17,
true,
_repository.id()[1] == defaultWallet.id()[1]
? const Color(0xffF9F9F1)
: Colors.black),
// Text(
// _repository.name!,
// textAlign: TextAlign.center,
// style: TextStyle(
// fontSize: 17.0,
// color: _repository.id()[1] ==
// defaultWallet.id()[1]
// ? const Color(0xffF9F9F1)
// : Colors.black,
// fontStyle: FontStyle.italic),
// ),
),
),
// dense: true,
onTap: () {
// _walletOptions.readLocalWallet(
// context,
// _repository,
// _myWalletProvider.pinCode,
// pinLength);
_walletOptions.getAddress(
_currentChestNumber, _repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: _repository,
),
),
);
},
)
]),
),
),
)),
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return _sub.nodeConnected
? addNewDerivation(context)
: const Text('');
}),
// SizedBox(height: 1),
// Padding(
// padding: EdgeInsets.symmetric(horizontal: 35),
// child: Text(
// 'Ajouter un portefeuille',
// textAlign: TextAlign.center,
// style: TextStyle(fontSize: 18),
// ))
]),
SliverToBoxAdapter(child: chestOptions(context, myWalletProvider)),
// SliverToBoxAdapter(child: Spacer()),
SliverToBoxAdapter(child: chestOptions(context, _myWalletProvider)),
]);
}
Widget balanceBuilder(context, String address, bool isDefault) {
Widget balanceBuilder(context, String _address, bool isDefault) {
return Container(
width: double.infinity,
color: isDefault ? orangeC : yellowC,
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 38),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
balance(
context,
address,
15,
isDefault ? Colors.white : Colors.black,
isDefault ? yellowC : orangeC)
],
)),
);
}
Widget nameBuilder(BuildContext context, WalletData repository,
WalletData defaultWallet, int currentChestNumber) {
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))),
tileColor: repository.address == defaultWallet.address
? orangeC
: const Color(0xffFFD58D),
title: Center(
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, bottom: 35, top: 5),
child: duniterIndexer.getNameByAddress(
child: SizedBox(
height: 25,
child: Column(children: [
const Spacer(),
// Text(
// '0.0 gd',
// textAlign: TextAlign.center,
// style: TextStyle(color: isDefault ? Colors.white : Colors.black),
// ),
balance(
context,
repository.address!,
repository,
20,
true,
repository.id()[1] == defaultWallet.id()[1]
? const Color(0xffF9F9F1)
: Colors.black),
),
_address,
15,
isDefault ? Colors.white : Colors.black,
isDefault ? yellowC : orangeC)
]),
),
onTap: () {
walletOptions.getAddress(currentChestNumber, repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: repository,
),
),
);
},
);
}
Widget addNewDerivation(context) {
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
String newDerivationName =
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
String _newDerivationName =
'wallet'.tr() + ' ${_myWalletProvider.listWallets.last.number! + 2}';
return Padding(
padding: const EdgeInsets.all(16),
child: ClipRRect(
@ -448,14 +369,14 @@ class WalletsHome extends StatelessWidget {
child: Column(children: <Widget>[
Expanded(
child: InkWell(
key: keyAddDerivation,
key: const Key('addDerivation'),
onTap: () async {
if (!myWalletProvider.isNewDerivationLoading) {
if (!_myWalletProvider.isNewDerivationLoading) {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
_myWalletProvider.getDefaultWallet();
String? _pin;
if (_myWalletProvider.pinCode == '') {
_pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
@ -464,19 +385,19 @@ class WalletsHome extends StatelessWidget {
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
await myWalletProvider.generateNewDerivation(
context, newDerivationName);
if (_pin != null || _myWalletProvider.pinCode != '') {
await _myWalletProvider.generateNewDerivation(
context, _newDerivationName);
}
}
},
child: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(color: floattingYellow),
decoration: BoxDecoration(color: floattingYellow),
child: Center(
child: myWalletProvider.isNewDerivationLoading
? const SizedBox(
child: _myWalletProvider.isNewDerivationLoading
? SizedBox(
height: 60,
width: 60,
child: CircularProgressIndicator(
@ -497,6 +418,12 @@ class WalletsHome extends StatelessWidget {
}
}
// extension Range on num {
// bool isBetween(num from, num to) {
// return from < this && this < to;
// }
// }
class CustomClipperOval extends CustomClipper<Rect> {
@override
Rect getClip(Size size) {
@ -530,7 +457,7 @@ class ClipOvalShadow extends StatelessWidget {
clipper: clipper,
shadow: shadow,
),
child: ClipRect(clipper: clipper, child: child),
child: ClipRect(child: child, clipper: clipper),
);
}
}

View File

@ -2,7 +2,6 @@ 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/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/providers/duniter_indexer.dart';
@ -20,27 +19,24 @@ class ContactsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CesiumPlusProvider cesiumPlusProvider =
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: true);
HomeProvider homeProvider =
WalletsProfilesProvider _walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: false);
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
double avatarSize = 55;
int keyID = 0;
double _avatarSize = 55;
final myContacts = contactsBox.toMap().values.toList();
// for (var element in myContacts) {
// log.d('yooo: ${element.pubkey} ${element.username}');
// }
myContacts.sort((p1, p2) {
return Comparable.compare(p1.username?.toLowerCase() ?? 'zz',
p2.username?.toLowerCase() ?? 'zz');
});
// myContacts.sort((a, b) {
// final aa = a.username?.toLowerCase() ?? '';
// final bb = b.username?.toLowerCase() ?? '';
// return aa.compareTo(bb);
// });
return Scaffold(
backgroundColor: backgroundColor,
@ -49,11 +45,10 @@ class ContactsScreen extends StatelessWidget {
toolbarHeight: 60 * ratio,
title: SizedBox(
height: 22,
child: Text(
'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])),
child: Text('contactsManagement'.tr()),
),
),
bottomNavigationBar: homeProvider.bottomAppBar(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: SafeArea(
child: Stack(children: [
Padding(
@ -61,7 +56,7 @@ class ContactsScreen extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 20),
const SizedBox(height: 40),
if (myContacts.isEmpty)
Text('noContacts'.tr())
else
@ -71,13 +66,13 @@ class ContactsScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult('keyID++'),
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider
.defaultAvatar(avatarSize),
leading: _cesiumPlusProvider
.defaultAvatar(_avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(g1Wallet.address),
Text(getShortPubkey(g1Wallet.pubkey!),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
@ -87,25 +82,11 @@ class ContactsScreen extends StatelessWidget {
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 110,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
balance(context,
g1Wallet.address, 16),
]),
]),
),
balance(context, g1Wallet.pubkey!, 16)
]),
subtitle: Row(children: <Widget>[
duniterIndexer.getNameByAddress(
context, g1Wallet.address)
_duniterIndexer.getNameByAddress(
context, g1Wallet.pubkey!)
]),
dense: false,
isThreeLine: false,
@ -113,16 +94,16 @@ class ContactsScreen extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfilesClass.address =
g1Wallet.address;
_walletsProfilesClass.address =
g1Wallet.pubkey;
return WalletViewScreen(
address: g1Wallet.address,
pubkey: g1Wallet.pubkey,
username: g1WalletsBox
.get(g1Wallet.address)
.get(g1Wallet.pubkey)
?.id
?.username,
avatar: g1WalletsBox
.get(g1Wallet.address)
.get(g1Wallet.pubkey)
?.avatar,
);
}),

View File

@ -27,18 +27,15 @@ class OnboardingStepOne extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(
context,
'geckoGenerateYourWalletFromMnemonic'.tr(),
'fabrication-de-portefeuille.png',
'>',
const OnboardingStepTwo(),
0,
isMd: true,
),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(
context,
'geckoGenerateYourWalletFromMnemonic'.tr(),
'fabrication-de-portefeuille.png',
'>',
const OnboardingStepTwo(),
0,
isMd: true,
),
),
);
}

View File

@ -1,14 +1,11 @@
// ignore_for_file: file_names
// ignore_for_file: must_be_immutable
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
@ -18,6 +15,7 @@ import 'package:gecko/screens/onBoarding/11_congratulations.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepTen extends StatelessWidget {
OnboardingStepTen({Key? validationKey, this.scanDerivation = false})
: super(key: validationKey);
@ -30,12 +28,12 @@ class OnboardingStepTen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
WalletOptionsProvider walletOptions =
WalletOptionsProvider _walletOptions =
Provider.of<WalletOptionsProvider>(context);
CommonElements common = CommonElements();
final int pinLenght = generateWalletProvider.pin.text.length;
final int _pinLenght = _generateWalletProvider.pin.text.length;
return Scaffold(
backgroundColor: backgroundColor,
@ -51,121 +49,108 @@ class OnboardingStepTen extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(9),
SizedBox(height: isTall ? 40 : 20),
common.buildText("geckoWillCheckPassword".tr()),
SizedBox(height: isTall ? 80 : 20),
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,
),
),
],
child: Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(9),
SizedBox(height: isTall ? 40 : 20),
common.buildText("geckoWillCheckPassword".tr()),
SizedBox(height: isTall ? 80 : 20),
Visibility(
visible: _generateWalletProvider.scanedWalletNumber != -1,
child: Padding(
padding: const EdgeInsets.only(bottom: 15),
child: SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
color: orangeC,
strokeWidth: 3,
),
),
),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return sub.nodeConnected
? pinForm(context, walletOptions, pinLenght, 1, 2)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Vous devez vous connecter à internet\npour valider votre coffre',
style: TextStyle(
fontSize: 20,
color: Colors.redAccent,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
]);
}),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return sub.nodeConnected
? InkWell(
key: keyCachePassword,
onTap: () {
walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
const Spacer(),
Icon(
configBox.get('isCacheChecked') ?? false
? Icons.check_box
: Icons.check_box_outline_blank,
color: orangeC,
),
const SizedBox(width: 8),
),
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return _sub.nodeConnected
? pinForm(context, _walletOptions, _pinLenght, 1, 2)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'rememberPassword'.tr(),
'Vous devez vous connecter à internet\npour valider votre coffre',
style: TextStyle(
fontSize: 16, color: Colors.grey[700]),
fontSize: 20,
color: Colors.redAccent,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
),
const Spacer()
]))
: const Text('');
}),
const SizedBox(height: 10),
]),
CommonElements().offlineInfo(context),
]);
}),
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return _sub.nodeConnected
? InkWell(
onTap: () {
_walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
const Spacer(),
Icon(
configBox.get('isCacheChecked') ?? false
? Icons.check_box
: Icons.check_box_outline_blank,
color: orangeC,
),
const SizedBox(width: 8),
Text(
'rememberPassword'.tr(),
style:
TextStyle(fontSize: 16, color: Colors.grey[700]),
),
const Spacer()
]))
: const Text('');
}),
const SizedBox(height: 10),
]),
));
}
Widget pinForm(context, WalletOptionsProvider walletOptions, pinLenght,
int walletNbr, int derivation) {
Widget pinForm(context, WalletOptionsProvider _walletOptions, _pinLenght,
int _walletNbr, int _derivation) {
// var _walletPin = '';
// ignore: close_sinks
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController enterPin = TextEditingController();
MyWalletsProvider myWalletProvider =
TextEditingController _enterPin = TextEditingController();
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context);
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final int currentChest = myWalletProvider.getCurrentChest();
final int? _currentChest = _myWalletProvider.getCurrentChest();
return Form(
key: formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField(
key: keyPinForm,
key: const Key('formKey2'),
autoFocus: true,
appContext: context,
pastedTextStyle: TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
),
length: pinLenght,
length: _pinLenght,
obscureText: true,
obscuringCharacter: '*',
animationType: AnimationType.fade,
validator: (v) {
if (v!.length < pinLenght) {
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
if (v!.length < _pinLenght) {
return "yourPasswordLengthIsX"
.tr(args: [_pinLenght.toString()]);
} else {
return null;
}
@ -179,14 +164,13 @@ class OnboardingStepTen extends StatelessWidget {
fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
),
showCursor: kDebugMode ? false : true,
cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false,
errorAnimationController: errorController,
controller: enterPin,
controller: _enterPin,
keyboardType: TextInputType.visiblePassword,
boxShadows: const [
BoxShadow(
@ -195,24 +179,25 @@ class OnboardingStepTen extends StatelessWidget {
blurRadius: 10,
)
],
onCompleted: (pin) async {
myWalletProvider.pinCode = pin.toUpperCase();
myWalletProvider.pinLenght = pinLenght;
log.d('$pin || ${generateWalletProvider.pin.text}');
if (pin.toUpperCase() == generateWalletProvider.pin.text) {
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];
await generateWalletProvider.storeHDWChest(context);
await _generateWalletProvider.storeHDWChest(context);
bool isAlive = false;
if (scanDerivation) {
isAlive =
await generateWalletProvider.scanDerivations(context);
isAlive = await _generateWalletProvider
.scanDerivations(context, numberScan: 20);
}
if (!isAlive) {
final address = await sub.importAccount(
mnemonic: generateWalletProvider.generatedMnemonic!,
final address = await _sub.importAccount(
fromMnemonic: true,
mnemonic: _generateWalletProvider.generatedMnemonic!,
derivePath: '//2',
password: generateWalletProvider.pin.text);
password: _generateWalletProvider.pin.text);
WalletData myWallet = WalletData(
version: dataVersion,
chest: configBox.get('currentChest'),
@ -223,12 +208,11 @@ class OnboardingStepTen extends StatelessWidget {
imageDefaultPath: '0.png');
await walletBox.add(myWallet);
}
myWalletProvider.readAllWallets(currentChest);
myWalletProvider.reload();
_myWalletProvider.readAllWallets(_currentChest);
_myWalletProvider.rebuildWidget();
generateWalletProvider.generatedMnemonic = '';
myWalletProvider.resetPinCode();
// sleep(const Duration(milliseconds: 500));
_generateWalletProvider.generatedMnemonic = '';
_myWalletProvider.resetPinCode();
Navigator.push(
context,
FaderTransition(
@ -239,7 +223,7 @@ class OnboardingStepTen extends StatelessWidget {
.shake); // Triggering error shake animation
hasError = true;
pinColor = Colors.red[600];
walletOptions.reload();
_walletOptions.reloadBuild();
}
},
onChanged: (value) {

View File

@ -4,9 +4,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
// ignore: must_be_immutable
class OnboardingStepEleven extends StatelessWidget {
const OnboardingStepEleven({Key? key}) : super(key: key);
@ -53,28 +54,20 @@ Widget finishButton(BuildContext context) {
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGoWalletsHome,
key: const Key('goWalletHome'),
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC,
onPrimary: Colors.white, // foreground
),
onPressed: () {
//TODO: fix bad widget ancestor when pupUntil (multi_chest test failed)
// Navigator.popUntil(homeContext, ModalRoute.withName('/'));
// Navigator.of(homeContext, rootNavigator: true)
// .popUntil(ModalRoute.withName('/'));
// while (Navigator.of(homeContext).canPop()) {
// Navigator.of(homeContext).pop();
// }
// Navigator.pushNamed(homeContext, '/mywallets');
Navigator.pushNamedAndRemoveUntil(
context, '/mywallets', (route) => route.isFirst);
// Navigator.pushNamedAndRemoveUntil(
// homeContext, '/mywallets', ModalRoute.withName('/'));
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
ModalRoute.withName('/'),
);
},
child: Text("accessMyChest".tr(),
style:

View File

@ -29,16 +29,13 @@ class OnboardingStepTwo extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(
context,
'keepThisMnemonicSecure'.tr(),
'fabrication-de-portefeuille-impossible-sans-phrase.png',
'>',
const OnboardingStepThree(),
1),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(
context,
'keepThisMnemonicSecure'.tr(),
'fabrication-de-portefeuille-impossible-sans-phrase.png',
'>',
const OnboardingStepThree(),
1),
),
);
}

View File

@ -29,11 +29,8 @@ class OnboardingStepThree extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(context, 'warningForgotPassword'.tr(),
'forgot_password.png'.tr(), '>', const OnboardingStepFor(), 2),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(context, 'warningForgotPassword'.tr(),
'forgot_password.png'.tr(), '>', const OnboardingStepFor(), 2),
),
);
}

View File

@ -29,17 +29,14 @@ class OnboardingStepFor extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(
context,
'itsTimeToUseAPenAndPaper'.tr(),
'gecko_also_can_forget.png'.tr(),
'>',
const OnboardingStepFive(),
3,
isMd: true),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(
context,
'itsTimeToUseAPenAndPaper'.tr(),
'gecko_also_can_forget.png'.tr(),
'>',
const OnboardingStepFive(),
3,
isMd: true),
),
);
}

View File

@ -4,7 +4,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/common_elements.dart';
@ -30,7 +29,7 @@ class _ChooseChestState extends State<OnboardingStepFive> {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
final CommonElements common = CommonElements();
@ -49,62 +48,57 @@ class _ChooseChestState extends State<OnboardingStepFive> {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
Column(children: [
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(4),
SizedBox(height: isTall ? 40 : 20),
common.buildText('geckoGeneratedYourMnemonicKeepItSecret'.tr()),
SizedBox(height: 35 * ratio),
sentanceArray(context),
SizedBox(height: 17 * ratio),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return PrintWallet(
generateWalletProvider.generatedMnemonic);
}),
);
},
child: Image.asset(
'assets/printer.png',
height: 42 * ratio,
child: Column(children: [
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(4),
SizedBox(height: isTall ? 40 : 20),
common.buildText('geckoGeneratedYourMnemonicKeepItSecret'.tr()),
SizedBox(height: 35 * ratio),
sentanceArray(context),
SizedBox(height: 17 * ratio),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return PrintWallet(_generateWalletProvider.generatedMnemonic);
}),
);
},
child: Image.asset(
'assets/printer.png',
height: 42 * ratio,
),
),
const SizedBox(height: 40),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: const Key('generateMnemonic'),
style: ElevatedButton.styleFrom(
elevation: 4,
primary: const Color(0xffFFD58D),
onPrimary: Colors.black, // foreground
),
onPressed: () {
// _generateWalletProvider.reloadBuild();
setState(() {});
},
child: Text("chooseAnotherMnemonic".tr(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22 * ratio,
fontWeight: FontWeight.w600))),
),
),
const SizedBox(height: 40),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGenerateMnemonic,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black, elevation: 4,
backgroundColor: const Color(0xffFFD58D), // foreground
),
onPressed: () {
// _generateWalletProvider.reloadBuild();
setState(() {});
},
child: Text("chooseAnotherMnemonic".tr(),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22 * ratio,
fontWeight: FontWeight.w600))),
),
),
),
SizedBox(height: 22 * ratio),
nextButton(
context, "iNotedMyMnemonic".tr(), false, widget.skipIntro),
const Spacer(),
// SizedBox(height: 35 * ratio),
]),
CommonElements().offlineInfo(context),
),
SizedBox(height: 22 * ratio),
nextButton(context, "iNotedMyMnemonic".tr(), false, widget.skipIntro),
SizedBox(height: 35 * ratio),
]),
),
);
@ -112,7 +106,7 @@ class _ChooseChestState extends State<OnboardingStepFive> {
}
Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
return Padding(
@ -127,36 +121,36 @@ Widget sentanceArray(BuildContext context) {
)),
padding: const EdgeInsets.all(20),
child: FutureBuilder(
future: generateWalletProvider.generateWordList(context),
builder: (BuildContext context, AsyncSnapshot<List> data) {
if (!data.hasData) {
future: _generateWalletProvider.generateWordList(context),
builder: (BuildContext context, AsyncSnapshot<List> _data) {
if (!_data.hasData) {
return const Text('');
} else {
mnemoList = data;
mnemoList = _data;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(data.data![0]),
arrayCell(data.data![1]),
arrayCell(data.data![2]),
arrayCell(data.data![3]),
arrayCell(_data.data![0]),
arrayCell(_data.data![1]),
arrayCell(_data.data![2]),
arrayCell(_data.data![3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(data.data![4]),
arrayCell(data.data![5]),
arrayCell(data.data![6]),
arrayCell(data.data![7]),
arrayCell(_data.data![4]),
arrayCell(_data.data![5]),
arrayCell(_data.data![6]),
arrayCell(_data.data![7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(data.data![8]),
arrayCell(data.data![9]),
arrayCell(data.data![10]),
arrayCell(data.data![11]),
arrayCell(_data.data![8]),
arrayCell(_data.data![9]),
arrayCell(_data.data![10]),
arrayCell(_data.data![11]),
]),
]);
}
@ -175,13 +169,14 @@ Widget arrayCell(dataWord) {
),
Text(
dataWord.split(':')[1],
key: keyMnemonicWord(dataWord.split(':')[0]),
key: Key('word${dataWord.split(':')[0]}'),
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
),
]),
);
}
// ignore: must_be_immutable
class PrintWallet extends StatelessWidget {
const PrintWallet(this.sentence, {Key? key}) : super(key: key);
@ -189,7 +184,7 @@ class PrintWallet extends StatelessWidget {
@override
Widget build(BuildContext context) {
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
return MaterialApp(
home: Scaffold(
@ -213,7 +208,7 @@ class PrintWallet extends StatelessWidget {
body: PdfPreview(
canDebug: false,
canChangeOrientation: false,
build: (format) => generateWalletProvider.printWallet(mnemoList),
build: (format) => _generateWalletProvider.printWallet(mnemoList),
),
),
);
@ -222,30 +217,31 @@ class PrintWallet extends StatelessWidget {
Widget nextButton(
BuildContext context, String text, bool isFast, bool skipIntro) {
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
return SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGoNext,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt();
generateWalletProvider.nbrWordAlpha = generateWalletProvider
.intToString(generateWalletProvider.nbrWord + 1);
myWalletProvider.mnemonic = generateWalletProvider.generatedMnemonic!;
_generateWalletProvider.nbrWord =
_generateWalletProvider.getRandomInt();
_generateWalletProvider.nbrWordAlpha = _generateWalletProvider
.intToString(_generateWalletProvider.nbrWord + 1);
_myWalletProvider.mnemonic = _generateWalletProvider.generatedMnemonic!;
Navigator.push(
context,
FaderTransition(
page: OnboardingStepSix(
generatedMnemonic: generateWalletProvider.generatedMnemonic,
generatedMnemonic: _generateWalletProvider.generatedMnemonic,
skipIntro: skipIntro),
isFast: true),
);

View File

@ -1,17 +1,16 @@
// ignore_for_file: file_names
// ignore_for_file: must_be_immutable
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/7.dart';
import 'package:gecko/screens/onBoarding/9.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepSix extends StatelessWidget {
OnboardingStepSix(
{Key? key, required this.skipIntro, required this.generatedMnemonic})
@ -25,7 +24,7 @@ class OnboardingStepSix extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: true);
CommonElements common = CommonElements();
@ -33,8 +32,8 @@ class OnboardingStepSix extends StatelessWidget {
return WillPopScope(
onWillPop: () {
generateWalletProvider.isAskedWordValid = false;
generateWalletProvider.askedWordColor = Colors.black;
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
return Future<bool>.value(true);
},
child: Scaffold(
@ -52,113 +51,180 @@ class OnboardingStepSix extends StatelessWidget {
),
),
body: SafeArea(
child: Stack(children: [
Align(
alignment: Alignment.topCenter,
child: Column(children: [
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(5),
SizedBox(height: isTall ? 40 : 20),
common.buildText(
"didYouNoteMnemonicToBeSureTypeWord".tr(args: [
(generateWalletProvider.nbrWord + 1).toString()
]),
20,
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),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(
color: Colors.grey[600]!,
width: 3,
)),
width: 430,
child: TextFormField(
key: keyInputWord,
autofocus: true,
enabled: !generateWalletProvider.isAskedWordValid,
controller: wordController,
textInputAction: TextInputAction.next,
onChanged: (value) {
generateWalletProvider.checkAskedWord(
value, _mnemonicController.text);
},
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 22.0,
color: Colors.grey[500],
fontWeight: FontWeight.w500),
labelText: generateWalletProvider.isAskedWordValid
? "itsTheGoodWord".tr()
: "${generateWalletProvider.nbrWordAlpha} ${"nthMnemonicWord".tr()}",
fillColor: const Color(0xffeeeedd),
filled: true,
contentPadding: const EdgeInsets.all(12),
),
style: TextStyle(
fontSize: 40.0,
color: generateWalletProvider.askedWordColor,
fontWeight: FontWeight.w500))),
Visibility(
visible: generateWalletProvider.isAskedWordValid,
child: Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: nextButton(
context,
'continue'.tr(),
skipIntro
? const OnboardingStepNine()
: const OnboardingStepSeven(),
false),
),
child: Align(
alignment: Alignment.topCenter,
child: Column(children: [
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(5),
SizedBox(height: isTall ? 40 : 20),
common.buildText(
"didYouNoteMnemonicToBeSureTypeWord".tr(
args: [(_generateWalletProvider.nbrWord + 1).toString()]),
20,
true),
SizedBox(height: isTall ? 70 : 20),
Text('${_generateWalletProvider.nbrWord + 1}',
key: const Key('askedWord'),
style: TextStyle(
fontSize: isTall ? 17 : 15,
color: orangeC,
fontWeight: FontWeight.w400)),
const SizedBox(height: 10),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(
color: Colors.grey[600]!,
width: 3,
)),
width: 430,
child: TextFormField(
key: const Key('inputWord'),
autofocus: true,
enabled: !_generateWalletProvider.isAskedWordValid,
controller: wordController,
textInputAction: TextInputAction.next,
onChanged: (value) {
_generateWalletProvider.checkAskedWord(
value, _mnemonicController.text);
},
maxLines: 1,
textAlign: TextAlign.center,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 22.0,
color: Colors.grey[500],
fontWeight: FontWeight.w500),
labelText: _generateWalletProvider.isAskedWordValid
? "itsTheGoodWord".tr()
: "${_generateWalletProvider.nbrWordAlpha} " +
"nthMnemonicWord".tr(),
fillColor: const Color(0xffeeeedd),
filled: true,
contentPadding: const EdgeInsets.all(12),
),
style: TextStyle(
fontSize: 40.0,
color: _generateWalletProvider.askedWordColor,
fontWeight: FontWeight.w500))),
Visibility(
visible: _generateWalletProvider.isAskedWordValid,
child: Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: nextButton(
context,
'continue'.tr(),
skipIntro
? const OnboardingStepNine()
: const OnboardingStepSeven(),
false),
),
),
// Visibility(
// visible: !_generateWalletProvider.isAskedWordValid,
// child: const Expanded(
// child: Align(
// alignment: Alignment.bottomCenter,
// child: Text(''),
// ),
// ),
// ),
SizedBox(height: 35 * ratio),
]),
),
CommonElements().offlineInfo(context),
]),
),
// Visibility(
// visible: !_generateWalletProvider.isAskedWordValid,
// child: const Expanded(
// child: Align(
// alignment: Alignment.bottomCenter,
// child: Text(''),
// ),
// ),
// ),
SizedBox(height: 35 * ratio),
]),
),
),
),
);
}
}
Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
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<List> _data) {
if (!_data.hasData) {
return const Text('');
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(children: <Widget>[
arrayCell(_data.data![0]),
arrayCell(_data.data![1]),
arrayCell(_data.data![2]),
arrayCell(_data.data![3]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(_data.data![4]),
arrayCell(_data.data![5]),
arrayCell(_data.data![6]),
arrayCell(_data.data![7]),
]),
const SizedBox(height: 15),
Row(children: <Widget>[
arrayCell(_data.data![8]),
arrayCell(_data.data![9]),
arrayCell(_data.data![10]),
arrayCell(_data.data![11]),
]),
]);
}
}),
),
);
}
Widget arrayCell(dataWord) {
return SizedBox(
width: 100,
child: Column(children: <Widget>[
Text(
dataWord.split(':')[0],
style: const TextStyle(fontSize: 15, color: Color(0xff6b6b52)),
),
Text(
dataWord.split(':')[1],
key: Key('word${dataWord.split(':')[0]}'),
style: const TextStyle(fontSize: 20, color: Colors.black),
),
]),
);
}
Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false);
generateWalletProvider.isAskedWordValid = false;
generateWalletProvider.askedWordColor = Colors.black;
_generateWalletProvider.isAskedWordValid = false;
_generateWalletProvider.askedWordColor = Colors.black;
return SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGoNext,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.push(

View File

@ -29,17 +29,14 @@ class OnboardingStepSeven extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(
context,
'geckoWillGenerateAPassword'.tr(),
'coffre-fort-code-secret-dans-telephone.png',
'>',
OnboardingStepEight(scanDerivation: scanDerivation),
6,
boxHeight: 400),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(
context,
'geckoWillGenerateAPassword'.tr(),
'coffre-fort-code-secret-dans-telephone.png',
'>',
OnboardingStepEight(scanDerivation: scanDerivation),
6,
boxHeight: 400),
),
);
}

View File

@ -29,17 +29,14 @@ class OnboardingStepEight extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
common.infoIntro(
context,
'thisPasswordProtectsYourWalletsInASecureChest'.tr(),
'coffre-fort-protege-les-portefeuilles.png',
'>',
OnboardingStepNine(scanDerivation: scanDerivation),
7,
isMd: true),
CommonElements().offlineInfo(context),
]),
child: common.infoIntro(
context,
'thisPasswordProtectsYourWalletsInASecureChest'.tr(),
'coffre-fort-protege-les-portefeuilles.png',
'>',
OnboardingStepNine(scanDerivation: scanDerivation),
7,
isMd: true),
),
);
}

View File

@ -3,12 +3,12 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/10.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class OnboardingStepNine extends StatelessWidget {
const OnboardingStepNine({Key? key, this.scanDerivation = false})
: super(key: key);
@ -17,15 +17,15 @@ class OnboardingStepNine extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GenerateWalletsProvider generateWalletProvider =
GenerateWalletsProvider _generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context);
// MyWalletsProvider myWalletProvider =
// Provider.of<MyWalletsProvider>(context);
CommonElements common = CommonElements();
generateWalletProvider.pin.text = debugPin // kDebugMode &&
_generateWalletProvider.pin.text = debugPin // kDebugMode &&
? 'AAAAA'
: generateWalletProvider.changePinCode(reload: false).toUpperCase();
: _generateWalletProvider.changePinCode(reload: false).toUpperCase();
return Scaffold(
backgroundColor: backgroundColor,
@ -41,66 +41,61 @@ class OnboardingStepNine extends StatelessWidget {
),
extendBodyBehindAppBar: true,
body: SafeArea(
child: Stack(children: [
Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(8),
SizedBox(height: isTall ? 40 : 20),
common.buildText("hereIsThePasswordKeepIt".tr(), 20, true),
const SizedBox(height: 100),
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
key: keyGeneratedPin,
enabled: false,
controller: generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
letterSpacing: 5,
fontSize: 35.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.replay),
color: orangeC,
onPressed: () {
generateWalletProvider.changePinCode(reload: true);
},
),
],
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyChangePin,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
elevation: 4,
backgroundColor:
const Color(0xffFFD58D), // foreground
),
onPressed: () {
generateWalletProvider.changePinCode(
reload: true);
},
child: Text("chooseAnotherPassword".tr(),
style: TextStyle(
fontSize: 22 * ratio,
fontWeight: FontWeight.w600))),
))),
SizedBox(height: 22 * ratio),
common.nextButton(context, "iNotedMyPassword".tr(),
OnboardingStepTen(scanDerivation: scanDerivation), false),
SizedBox(height: 35 * ratio),
]),
CommonElements().offlineInfo(context),
child: Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(8),
SizedBox(height: isTall ? 40 : 20),
common.buildText("hereIsThePasswordKeepIt".tr(), 20, true),
const SizedBox(height: 100),
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
key: const Key('generatedPin'),
enabled: false,
controller: _generateWalletProvider.pin,
maxLines: 1,
textAlign: TextAlign.center,
decoration: const InputDecoration(),
style: const TextStyle(
letterSpacing: 5,
fontSize: 35.0,
color: Colors.black,
fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.replay),
color: orangeC,
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
),
],
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: const Key('changeSecretCode'),
style: ElevatedButton.styleFrom(
elevation: 4,
primary: const Color(0xffFFD58D),
onPrimary: Colors.black, // foreground
),
onPressed: () {
_generateWalletProvider.changePinCode(reload: true);
},
child: Text("chooseAnotherPassword".tr(),
style: TextStyle(
fontSize: 22 * ratio,
fontWeight: FontWeight.w600))),
))),
SizedBox(height: 22 * ratio),
common.nextButton(context, "iNotedMyPassword".tr(),
OnboardingStepTen(scanDerivation: scanDerivation), false),
SizedBox(height: 35 * ratio),
]),
));
}

View File

@ -1,5 +1,3 @@
// ignore_for_file: must_be_immutable
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
@ -8,6 +6,7 @@ import 'package:qr_flutter/qr_flutter.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class QrCodeFullscreen extends StatelessWidget {
TextEditingController tplController = TextEditingController();
@ -24,7 +23,7 @@ class QrCodeFullscreen extends StatelessWidget {
backgroundColor: color ?? Colors.black,
toolbarHeight: 60 * ratio,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: orangeC),
icon: Icon(Icons.arrow_back, color: orangeC),
onPressed: () {
Navigator.pop(context);
}),
@ -32,7 +31,7 @@ class QrCodeFullscreen extends StatelessWidget {
height: 22,
child: Text(
'QR Code de ${getShortPubkey(address)}',
style: const TextStyle(color: orangeC),
style: TextStyle(color: orangeC),
),
)),
body: SafeArea(

View File

@ -2,7 +2,6 @@ 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/widgets_keys.dart';
// import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/search.dart';
import 'package:gecko/screens/common_elements.dart';
@ -17,14 +16,14 @@ class SearchScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SearchProvider searchProvider = Provider.of<SearchProvider>(context);
SearchProvider _searchProvider = Provider.of<SearchProvider>(context);
final double screenHeight = MediaQuery.of(context).size.height;
// HomeProvider _homeProvider =
// Provider.of<HomeProvider>(context, listen: false);
return WillPopScope(
onWillPop: () {
searchProvider.searchController.text = '';
_searchProvider.searchController.text = '';
return Future<bool>.value(true);
},
child: Scaffold(
@ -40,7 +39,7 @@ class SearchScreen extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
searchProvider.searchController.text = '';
_searchProvider.searchController.text = '';
Navigator.of(context).pop();
}),
),
@ -52,12 +51,11 @@ class SearchScreen extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 17),
child: TextField(
key: keySearchField,
controller: searchProvider.searchController,
controller: _searchProvider.searchController,
autofocus: true,
maxLines: 1,
textAlign: TextAlign.left,
onChanged: (v) => searchProvider.reload(),
onChanged: (v) => _searchProvider.rebuildWidget(),
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
@ -93,12 +91,12 @@ class SearchScreen extends StatelessWidget {
width: 410,
height: 70,
child: ElevatedButton(
key: keyConfirmSearch,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: searchProvider.searchController.text.length >= 2
onPressed: _searchProvider.searchController.text.length >= 2
? () {
Navigator.push(
context,

View File

@ -2,7 +2,6 @@ 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/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/providers/duniter_indexer.dart';
@ -21,18 +20,19 @@ class SearchResultScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SearchProvider searchProvider =
SearchProvider _searchProvider =
Provider.of<SearchProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
CesiumPlusProvider _cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfilesClass =
WalletsProfilesProvider _walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: false);
HomeProvider homeProvider =
HomeProvider _homeProvider =
Provider.of<HomeProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
DuniterIndexer _duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
double avatarSize = 55;
int keyID = 0;
double _avatarSize = 55;
return Scaffold(
backgroundColor: backgroundColor,
@ -44,11 +44,11 @@ class SearchResultScreen extends StatelessWidget {
child: Text('researchResults'.tr()),
),
),
bottomNavigationBar: homeProvider.bottomAppBar(context),
bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: SafeArea(
child: Stack(children: [
Padding(
padding: const EdgeInsets.only(left: 15, right: 10),
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
@ -64,7 +64,7 @@ class SearchResultScreen extends StatelessWidget {
text: "resultsFor".tr(),
),
TextSpan(
text: '"${searchProvider.searchController.text}"',
text: '"${_searchProvider.searchController.text}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],
@ -77,12 +77,13 @@ class SearchResultScreen extends StatelessWidget {
),
const SizedBox(height: 20),
FutureBuilder(
future: searchProvider.searchAddress(),
future: _searchProvider.searchAddress(),
builder: (context, AsyncSnapshot<List?> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
log.d(snapshot.data);
if (snapshot.data?.isEmpty ?? true) {
return duniterIndexer.searchIdentity(
context, searchProvider.searchController.text);
return _duniterIndexer.searchIdentity(
context, _searchProvider.searchController.text);
// const Text('Aucun résultat');
} else {
@ -94,13 +95,13 @@ class SearchResultScreen extends StatelessWidget {
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult(g1Wallet.address),
key: Key('searchResult${keyID++}'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider
.defaultAvatar(avatarSize),
leading: _cesiumPlusProvider
.defaultAvatar(_avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(g1Wallet.address),
Text(getShortPubkey(g1Wallet.pubkey!),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
@ -111,28 +112,12 @@ class SearchResultScreen extends StatelessWidget {
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SizedBox(
width: 110,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
balance(
context,
g1Wallet.address,
16),
]),
]),
),
balance(
context, g1Wallet.pubkey!, 16)
]),
subtitle: Row(children: <Widget>[
duniterIndexer.getNameByAddress(
context, g1Wallet.address)
_duniterIndexer.getNameByAddress(
context, g1Wallet.pubkey!)
]),
dense: false,
isThreeLine: false,
@ -140,16 +125,16 @@ class SearchResultScreen extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfilesClass.address =
g1Wallet.address;
_walletsProfilesClass.address =
g1Wallet.pubkey;
return WalletViewScreen(
address: g1Wallet.address,
pubkey: g1Wallet.pubkey,
username: g1WalletsBox
.get(g1Wallet.address)
.get(g1Wallet.pubkey)
?.id
?.username,
avatar: g1WalletsBox
.get(g1Wallet.address)
.get(g1Wallet.pubkey)
?.avatar,
);
}),
@ -160,7 +145,7 @@ class SearchResultScreen extends StatelessWidget {
);
}
}
return const Center(
return Center(
heightFactor: 5,
child: CircularProgressIndicator(
strokeWidth: 3,

View File

@ -1,17 +1,26 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/settings_provider.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'dart:io';
import 'package:gecko/globals.dart';
import 'package:polkawallet_sdk/api/types/networkParams.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class SettingsScreen extends StatelessWidget {
String? generatedMnemonic;
bool walletIsGenerated = false;
NewWallet? actualWallet;
String? newWalletName;
bool hasError = false;
String validPin = 'NO PIN';
String currentText = "";
var pinColor = Colors.grey[300];
Directory? appPath;
final MyWalletsProvider _myWallets = MyWalletsProvider();
SettingsScreen({Key? key}) : super(key: key);
@ -23,7 +32,10 @@ class SettingsScreen extends StatelessWidget {
const double buttonHigh = 50;
const double buttonWidth = 240;
const double fontSize = 16;
TextEditingController _endpointController =
TextEditingController(text: configBox.get('endpoint').first);
// getAppDirectory();
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
@ -32,372 +44,75 @@ class SettingsScreen extends StatelessWidget {
height: 22,
child: Text('parameters'.tr()),
)),
body: Column(children: <Widget>[
const SizedBox(height: 30),
Text(
'Connectivité réseau',
style: TextStyle(color: Colors.grey[500], fontSize: 22),
),
const SizedBox(height: 20),
duniterEndpointSelection(context),
const SizedBox(height: 30),
indexerEndpointSelection(context),
const SizedBox(height: 40),
Text(
'Affichage',
style: TextStyle(color: Colors.grey[500], fontSize: 22),
),
const SizedBox(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,
),
),
),
),
),
// const Spacer(),
SizedBox(height: isTall ? 90 : 60),
]),
);
}
Widget chooseCurrencyUnit(BuildContext context) {
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
return InkWell(
key: keyUdUnit,
onTap: () async {
await homeProvider.changeCurrencyUnit(context);
},
child: SizedBox(
height: 50,
child: Row(
children: [
const SizedBox(width: 12),
Text('showUdAmounts'.tr()),
const Spacer(),
Consumer<HomeProvider>(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,
);
}),
const SizedBox(width: 30),
],
),
),
);
}
Widget duniterEndpointSelection(BuildContext context) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
String? selectedDuniterEndpoint;
// List of items in our dropdown menu
var duniterBootstrapNodes = sub.getDuniterBootstrap();
selectedDuniterEndpoint =
sub.getConnectedEndpoint() ?? duniterBootstrapNodes.first.endpoint;
final customEndpoint = NetworkParams();
customEndpoint.endpoint = 'Personnalisé';
final localEndpoint = NetworkParams();
localEndpoint.endpoint = 'ws://127.0.0.1:9944';
final automaticEndpoint = NetworkParams();
automaticEndpoint.endpoint = 'Auto';
// duniterBootstrapNodes.add(_sub.getDuniterCustomEndpoint());
duniterBootstrapNodes.insert(0, automaticEndpoint);
duniterBootstrapNodes.add(localEndpoint);
duniterBootstrapNodes.add(customEndpoint);
if (configBox.get('autoEndpoint') == true) {
selectedDuniterEndpoint = automaticEndpoint.endpoint;
} else if (configBox.containsKey('customEndpoint')) {
selectedDuniterEndpoint = customEndpoint.endpoint;
}
TextEditingController endpointController = TextEditingController(
text: configBox.containsKey('customEndpoint')
? configBox.get('customEndpoint')
: 'wss://');
return Column(children: <Widget>[
Row(children: [
Consumer<SubstrateSdk>(builder: (context, sub, _) {
log.d(sub.sdk.api.connectedNode?.endpoint);
return Expanded(
child: Row(children: [
const SizedBox(width: 10),
SizedBox(
width: 100,
child: Text(
'currencyNode'.tr(args: [currencyName]),
),
),
const Spacer(),
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: 265,
child: Consumer<SettingsProvider>(builder: (context, set, _) {
return DropdownButtonHideUnderline(
key: keySelectDuniterNodeDropDown,
child: DropdownButton(
// alignment: AlignmentDirectional.topStart,
value: selectedDuniterEndpoint,
icon: const Icon(Icons.keyboard_arrow_down),
items: duniterBootstrapNodes
.map((NetworkParams endpointParams) {
return DropdownMenuItem(
key: keySelectDuniterNode(endpointParams.endpoint!),
value: endpointParams.endpoint,
child: Text(endpointParams.endpoint!),
);
}).toList(),
onChanged: (String? newEndpoint) {
log.d(newEndpoint!);
selectedDuniterEndpoint = newEndpoint;
set.reload();
},
body: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 60),
Row(children: [
Consumer<SubstrateSdk>(builder: (context, _sub, _) {
log.d(_sub.sdk.api.connectedNode?.endpoint);
return Expanded(
child: Row(children: [
const SizedBox(width: 10),
Text('currencyNode'.tr(args: [currencyName])),
const Spacer(),
Icon(_sub.nodeConnected && !_sub.isLoadingEndpoint
? Icons.check
: Icons.close),
const Spacer(),
SizedBox(
width: 200,
height: 50,
child: TextField(
controller: _endpointController,
autocorrect: false,
),
),
);
}),
),
const Spacer(flex: 5),
sub.isLoadingEndpoint
? const CircularProgressIndicator(color: orangeC)
: Consumer<SettingsProvider>(builder: (context, set, _) {
return IconButton(
key: keyConnectToEndpoint,
icon: Icon(
Icons.send,
color: selectedDuniterEndpoint !=
sub.getConnectedEndpoint()
? orangeC
: Colors.grey[500],
size: 40,
),
onPressed: selectedDuniterEndpoint !=
sub.getConnectedEndpoint()
? () async {
if (selectedDuniterEndpoint == 'Auto') {
configBox.delete('customEndpoint');
configBox.put('autoEndpoint', true);
} else {
configBox.put('autoEndpoint', false);
final finalEndpoint =
selectedDuniterEndpoint ==
'Personnalisé'
? endpointController.text
: selectedDuniterEndpoint;
configBox.put(
'customEndpoint', finalEndpoint);
}
await sub.connectNode(context);
}
: null);
}),
const Spacer(flex: 8),
const Spacer(flex: 5),
_sub.isLoadingEndpoint
? CircularProgressIndicator(color: orangeC)
: IconButton(
icon: Icon(
Icons.send,
color: orangeC,
size: 40,
),
onPressed: () async {
configBox
.put('endpoint', [_endpointController.text]);
await _sub.connectNode(context);
}),
const Spacer(flex: 8),
]),
);
}),
]),
);
}),
]),
Consumer<SettingsProvider>(builder: (context, set, _) {
return Visibility(
visible: selectedDuniterEndpoint == 'Personnalisé',
child: SizedBox(
width: 200,
height: 50,
child: TextField(
key: keyCustomDuniterEndpoint,
controller: endpointController,
autocorrect: false,
),
),
);
}),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Consumer<SettingsProvider>(builder: (context, set, _) {
return Visibility(
visible: selectedDuniterEndpoint == 'Auto',
child: SizedBox(
width: 250,
height: sub.getConnectedEndpoint() == null ? 60 : 20,
// SizedBox(height: isTall ? 80 : 120),
const Spacer(),
SizedBox(
height: buttonHigh,
width: buttonWidth,
child: Center(
child: InkWell(
key: const Key('deleteChest'),
onTap: () async {
log.i('Oublier tous mes coffres');
await _myWallets.deleteAllWallet(context);
},
child: Text(
sub.getConnectedEndpoint() ??
"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.",
style: TextStyle(
fontSize: 15,
fontStyle: FontStyle.italic,
color: Colors.grey[700]),
'forgetAllMyChests'.tr(),
style: const TextStyle(
fontSize: fontSize + 4,
color: Color(0xffD80000),
fontWeight: FontWeight.w600,
),
),
),
);
}),
Text(
'bloc N°${sub.blocNumber}',
style: TextStyle(fontSize: 14, color: Colors.grey[700]),
)
],
);
}),
]);
}
Widget indexerEndpointSelection(BuildContext context) {
DuniterIndexer indexer =
Provider.of<DuniterIndexer>(context, listen: false);
String? selectedIndexerEndpoint;
if (configBox.containsKey('customIndexer')) {
selectedIndexerEndpoint = 'Personnalisé';
} else {
selectedIndexerEndpoint = indexerEndpoint;
}
if (selectedIndexerEndpoint == '') {
selectedIndexerEndpoint = indexer.listIndexerEndpoints[0];
}
TextEditingController indexerEndpointController = TextEditingController(
text: configBox.containsKey('customIndexer')
? configBox.get('customIndexer')
: 'https://');
return Column(children: <Widget>[
Row(children: [
Consumer<DuniterIndexer>(builder: (context, indexer, _) {
log.d(selectedIndexerEndpoint);
log.d(indexer.listIndexerEndpoints);
return Expanded(
child: Row(children: [
const SizedBox(width: 10),
const SizedBox(
width: 100,
child: Text('Indexer : '),
),
const Spacer(),
Icon(indexerEndpoint != '' ? Icons.check : Icons.close),
const Spacer(),
SizedBox(
width: 265,
child: Consumer<SettingsProvider>(builder: (context, set, _) {
return DropdownButtonHideUnderline(
child: DropdownButton(
// alignment: AlignmentDirectional.topStart,
value: selectedIndexerEndpoint,
icon: const Icon(Icons.keyboard_arrow_down),
items:
indexer.listIndexerEndpoints.map((indexerEndpoint) {
return DropdownMenuItem(
value: indexerEndpoint,
child: Text(indexerEndpoint),
);
}).toList(),
onChanged: (newEndpoint) {
log.d(newEndpoint!);
selectedIndexerEndpoint = newEndpoint.toString();
set.reload();
},
),
);
}),
),
const Spacer(flex: 5),
indexer.isLoadingIndexer
? const CircularProgressIndicator(color: orangeC)
: Consumer<SettingsProvider>(builder: (context, set, _) {
return IconButton(
icon: Icon(
Icons.send,
color: selectedIndexerEndpoint != indexerEndpoint
? orangeC
: Colors.grey[500],
size: 40,
),
onPressed: selectedIndexerEndpoint != indexerEndpoint
? () async {
final finalEndpoint =
selectedIndexerEndpoint == 'Personnalisé'
? indexerEndpointController.text
: selectedIndexerEndpoint!;
if (selectedIndexerEndpoint ==
'Personnalisé') {
configBox.put('customIndexer',
indexerEndpointController.text);
} else {
configBox.delete('customIndexer');
}
log.d('connection to indexer $finalEndpoint');
await indexer
.checkIndexerEndpoint(finalEndpoint);
}
: null);
}),
const Spacer(flex: 8),
]),
);
}),
]),
Consumer<SettingsProvider>(builder: (context, set, _) {
return Visibility(
visible: selectedIndexerEndpoint == 'Personnalisé',
child: SizedBox(
width: 200,
height: 50,
child: TextField(
controller: indexerEndpointController,
autocorrect: false,
),
),
);
}),
Consumer<SubstrateSdk>(builder: (context, sub, _) {
return Consumer<SettingsProvider>(builder: (context, set, _) {
return Visibility(
visible: selectedIndexerEndpoint == 'Auto',
child: SizedBox(
width: 250,
height: 60,
child: Text(
sub.getConnectedEndpoint() ??
"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.",
style: TextStyle(
fontSize: 15,
fontStyle: FontStyle.italic,
color: Colors.grey[700]),
),
),
);
});
}),
]);
// const Spacer(),
SizedBox(height: isTall ? 90 : 60),
]),
);
}
}

View File

@ -0,0 +1,176 @@
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:provider/provider.dart';
class SubstrateSandBox extends StatelessWidget {
const SubstrateSandBox({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
return StatefulWrapper(
onInit: () async {
// if (!_sub.sdkReady && !_sub.sdkLoading) await _sub.initApi();
// if (_sub.sdkReady && !_sub.nodeConnected) await _sub.connectNode();
},
child: Scaffold(
appBar: AppBar(
toolbarHeight: 60 * ratio,
title: const SizedBox(
height: 22,
child: Text('⏳ Substrate Sandbox'),
),
),
body: SafeArea(
child: Consumer<SubstrateSdk>(builder: (context, _sub, _) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('js-api chargé ?: ${_sub.sdkReady}'),
InkWell(
onTap: () async {
await _sub.connectNode(context);
},
child: Text(
'🌐 Noeud connecté ?: ${_sub.nodeConnected} (${_sub.sdk.api.connectedNode?.endpoint})')),
if (_sub.nodeConnected)
Text(
'🏆 Noeud "$currencyName", bloc N°${_sub.blocNumber}'),
const SizedBox(height: 20),
Row(children: [
const Text('💳 Liste des coffres:'),
const Spacer(),
InkWell(
child: Image.asset(
'assets/walletOptions/trash.png',
height: 35,
),
onTap: () async {
await _sub.deleteAllAccounts();
_sub.reload();
},
),
const SizedBox(width: 10),
]),
FutureBuilder(
future: _sub.getKeyStoreAddress(),
builder: (BuildContext context,
AsyncSnapshot<List<AddressInfo>> _data) {
return Column(children: [
if (_data.data != null)
for (final AddressInfo addressInfo in _data.data!)
Row(children: [
InkWell(
onTap: () => _sub.keyring.setCurrent(_sub
.keyring.keyPairs
.firstWhere((element) =>
element.address ==
addressInfo.address!)),
child: Text(
getShortPubkey(addressInfo.address!),
style: const TextStyle(
fontFamily: 'Monospace'),
),
),
const SizedBox(width: 20),
// InkWell(
// onTap: () async => await _sub.pay(
// context,
// addressInfo.address!,
// 10,
// _sub.keystorePassword.text),
// child:
Text(
"${addressInfo.balance.toString()} $currencyName"),
// ),
const SizedBox(width: 20),
InkWell(
onTap: () async => await _sub.derive(
context,
addressInfo.address!,
2,
_sub.keystorePassword.text),
child: const Text("🏂 Dériver"),
)
])
]);
}),
const SizedBox(height: 20),
const Text('🔒 Mot de passe du coffre:'),
TextField(
controller: _sub.keystorePassword,
obscureText: true,
obscuringCharacter: '',
enableSuggestions: false,
autocorrect: false,
onChanged: (_) => _sub.reload(),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 20, width: double.infinity),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: _sub.keystorePassword.text.isNotEmpty
? () async {
final res = await _sub.importAccount();
_sub.importIsLoading = false;
_sub.reload();
snack(
context,
res != ''
? 'Portefeuille importé'
: 'Le format de coffre est invalide');
}
: null,
child: const Text(
'📎 Importer depuis le presse-papier',
style: TextStyle(fontSize: 20),
),
),
if (_sub.importIsLoading)
const CircularProgressIndicator(),
const SizedBox(height: 20),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: yellowC, // background
onPrimary: Colors.black, // foreground
),
onPressed: () async {
await _sub.generateMnemonic();
_sub.importIsLoading = false;
_sub.reload();
snack(context, 'Le mnemonic a été copié');
},
child: const Text(
"🏦 Générer un mnemonic et le copier",
style: TextStyle(fontSize: 20),
),
),
const SizedBox(height: 10),
SizedBox(
width: 400,
child: Text(
_sub.generatedMnemonic,
textAlign: TextAlign.center,
),
),
const Text('-〰️---〰️---〰️-'),
const SizedBox(height: 10),
Text(_sub.debugConnection)
])
]),
);
}),
),
),
);
}
}

View File

@ -2,7 +2,6 @@ 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/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart';
@ -10,144 +9,132 @@ import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
// ignore: must_be_immutable
class TransactionInProgress extends StatelessWidget {
const TransactionInProgress(
{Key? key, this.transType = 'pay', this.fromAddress, this.toAddress})
const TransactionInProgress({Key? key, this.transType = 'pay'})
: super(key: key);
final String transType;
final String? fromAddress;
final String? toAddress;
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: true);
WalletsProfilesProvider walletViewProvider =
SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: true);
WalletsProfilesProvider _walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
MyWalletsProvider _myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
bool isValid = false;
String resultText;
String _resultText;
bool isLoading = true;
// Map jsonResult;
final result = sub.transactionStatus;
final _result = _sub.transactionStatus;
// sub.spawnBlock();
log.d(_walletViewProvider.address!);
log.d(walletViewProvider.address);
final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!;
final to = toAddress ?? getShortPubkey(walletViewProvider.address);
final amount = walletViewProvider.payAmount.text;
String actionName = '';
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
final from = _myWalletProvider.getDefaultWallet().name!;
final to = getShortPubkey(_walletViewProvider.address!);
final amount = _walletViewProvider.payAmount.text;
String _actionName = '';
switch (transType) {
case 'pay':
{
actionName = 'transaction'.tr();
_actionName = 'transaction'.tr();
}
break;
case 'cert':
{
actionName = 'certification'.tr();
_actionName = 'certification'.tr();
}
break;
case 'comfirmIdty':
{
actionName = "identityConfirm".tr();
_actionName = "identityConfirm".tr();
}
break;
case 'revokeIdty':
{
actionName = "revokeAdhesion".tr();
}
break;
case 'identityMigration':
{
actionName = "identityMigration".tr();
_actionName = "revokeAdhesion".tr();
}
break;
default:
{
actionName = 'strangeTransaction'.tr();
_actionName = 'strangeTransaction'.tr();
}
}
switch (result) {
switch (_result) {
case '':
{
resultText = 'sending'.tr();
_resultText = 'sending'.tr();
}
break;
case 'Ready':
{
resultText = 'propagating'.tr();
_resultText = 'propagating'.tr();
}
break;
case 'Broadcast':
{
resultText = 'validating'.tr();
_resultText = 'validating'.tr();
}
break;
default:
{
isLoading = false;
// jsonResult = json.decode(_result);
log.d(result);
if (result.contains('blockHash: ')) {
log.d(_result);
if (_result.contains('blockHash: ')) {
isValid = true;
resultText = 'extrinsicValidated'.tr(args: [actionName]);
log.i(
'g1migration Bloc of last transaction: ${sub.blocNumber} --- $result');
_resultText = 'extrinsicValidated'.tr(args: [_actionName]);
} else {
isValid = false;
resultText = "${"anErrorOccurred".tr()}:\n";
final List exceptionSplit = result.split('Exception: ');
String exception;
if (exceptionSplit.length > 1) {
exception = exceptionSplit[1];
_resultText = "anErrorOccured".tr() + ":\n";
final List _exceptionSplit = _result.split('Exception: ');
String _exception;
if (_exceptionSplit.length > 1) {
_exception = _exceptionSplit[1];
} else {
exception = exceptionSplit[0];
_exception = _exceptionSplit[0];
}
// log.d('expection: $_exception');
switch (exception) {
switch (_exception) {
case 'cert.NotRespectCertPeriod':
case 'identity.CreatorNotAllowedToCreateIdty':
{
resultText = "24hbetweenCerts".tr();
_resultText = "24hbetweenCerts".tr();
}
break;
case 'cert.CannotCertifySelf':
{
resultText = "canNotCertifySelf".tr();
_resultText = "canNotCertifySelf".tr();
}
break;
case 'identity.IdtyNameAlreadyExist':
{
resultText = "nameAlreadyExist".tr();
_resultText = "nameAlreadyExist".tr();
}
break;
case 'balances.KeepAlive':
{
resultText = "2GDtoKeepAlive".tr();
_resultText = "2GDtoKeepAlive".tr();
}
break;
case '1010: Invalid Transaction: Inability to pay some fees , e.g. account balance too low':
{
resultText = "youHaveToFeedThisAccountBeforeUsing".tr();
_resultText = "youHaveToFeedThisAccountBeforeUsing".tr();
}
break;
case 'timeout':
{
resultText += "execTimeoutOver".tr();
_resultText += "execTimeoutOver".tr();
}
break;
default:
{
resultText += "\n$exception";
_resultText += "\n$_exception";
}
break;
}
@ -157,11 +144,9 @@ class TransactionInProgress extends StatelessWidget {
return WillPopScope(
onWillPop: () {
sub.transactionStatus = '';
_sub.transactionStatus = '';
Navigator.pop(context);
if (transType == 'pay' || transType == 'identityMigration') {
Navigator.pop(context);
}
if (transType == 'pay') Navigator.pop(context);
return Future<bool>.value(true);
},
child: Scaffold(
@ -175,7 +160,7 @@ class TransactionInProgress extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('extrinsicInProgress'.tr(args: [actionName]))
Text('extrinsicInProgress'.tr(args: [_actionName]))
]),
)),
body: SafeArea(
@ -184,7 +169,7 @@ class TransactionInProgress extends StatelessWidget {
child: Column(children: <Widget>[
Container(
width: double.infinity,
decoration: const BoxDecoration(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
@ -197,9 +182,7 @@ class TransactionInProgress extends StatelessWidget {
const SizedBox(height: 10),
if (transType == 'pay')
Text(
isUdUnit
? 'ud'.tr(args: ['$amount '])
: '$amount $currencyName',
'$amount $currencyName',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w600),
@ -236,7 +219,7 @@ class TransactionInProgress extends StatelessWidget {
Column(children: [
Visibility(
visible: isLoading,
child: const SizedBox(
child: SizedBox(
height: 18,
width: 18,
child: CircularProgressIndicator(
@ -255,7 +238,7 @@ class TransactionInProgress extends StatelessWidget {
),
const SizedBox(height: 10),
Text(
resultText,
_resultText,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 19 * ratio),
),
@ -268,18 +251,15 @@ class TransactionInProgress extends StatelessWidget {
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyCloseTransactionScreen,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground
elevation: 4,
primary: orangeC, // background
onPrimary: Colors.white, // foreground
),
onPressed: () {
Navigator.pop(context);
sub.transactionStatus = '';
if (transType == 'pay' ||
transType == 'identityMigration') {
Navigator.pop(context);
}
_sub.transactionStatus = '';
if (transType == 'pay') Navigator.pop(context);
},
child: Text(
'close'.tr(),

File diff suppressed because it is too large Load Diff

7
macos/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
# Flutter-related
**/Flutter/ephemeral/
**/Pods/
# Xcode-related
**/dgph
**/xcuserdata/

View File

@ -0,0 +1 @@
#include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -0,0 +1 @@
#include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -0,0 +1,26 @@
//
// Generated file. Do not edit.
//
import FlutterMacOS
import Foundation
import connectivity_plus_macos
import desktop_window
import package_info_plus_macos
import path_provider_macos
import printing
import sentry_flutter
import shared_preferences_macos
import window_size
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
DesktopWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWindowPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
WindowSizePlugin.register(with: registry.registrar(forPlugin: "WindowSizePlugin"))
}

View File

@ -0,0 +1,572 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXAggregateTarget section */
33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
buildPhases = (
33CC111E2044C6BF0003C045 /* ShellScript */,
);
dependencies = (
);
name = "Flutter Assemble";
productName = FLX;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 33CC111A2044C6BA0003C045;
remoteInfo = FLX;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
33CC110E2044A8840003C045 /* Bundle Framework */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* gecko.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "gecko.app"; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
33CC10EA2044A3C60003C045 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
33BA886A226E78AF003329D5 /* Configs */ = {
isa = PBXGroup;
children = (
33E5194F232828860026EE4D /* AppInfo.xcconfig */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
);
path = Configs;
sourceTree = "<group>";
};
33CC10E42044A3C60003C045 = {
isa = PBXGroup;
children = (
33FAB671232836740065AC1E /* Runner */,
33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
);
sourceTree = "<group>";
};
33CC10EE2044A3C60003C045 /* Products */ = {
isa = PBXGroup;
children = (
33CC10ED2044A3C60003C045 /* gecko.app */,
);
name = Products;
sourceTree = "<group>";
};
33CC11242044D66E0003C045 /* Resources */ = {
isa = PBXGroup;
children = (
33CC10F22044A3C60003C045 /* Assets.xcassets */,
33CC10F42044A3C60003C045 /* MainMenu.xib */,
33CC10F72044A3C60003C045 /* Info.plist */,
);
name = Resources;
path = ..;
sourceTree = "<group>";
};
33CEB47122A05771004F2AC0 /* Flutter */ = {
isa = PBXGroup;
children = (
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
);
path = Flutter;
sourceTree = "<group>";
};
33FAB671232836740065AC1E /* Runner */ = {
isa = PBXGroup;
children = (
33CC10F02044A3C60003C045 /* AppDelegate.swift */,
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
33E51913231747F40026EE4D /* DebugProfile.entitlements */,
33E51914231749380026EE4D /* Release.entitlements */,
33CC11242044D66E0003C045 /* Resources */,
33BA886A226E78AF003329D5 /* Configs */,
);
path = Runner;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
33CC10EC2044A3C60003C045 /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
);
buildRules = (
);
dependencies = (
33CC11202044C79F0003C045 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
productReference = 33CC10ED2044A3C60003C045 /* gecko.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
33CC10E52044A3C60003C045 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
33CC111A2044C6BA0003C045 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 33CC10E42044A3C60003C045;
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
33CC10EC2044A3C60003C045 /* Runner */,
33CC111A2044C6BA0003C045 /* Flutter Assemble */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
33CC10EB2044A3C60003C045 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
};
33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
Flutter/ephemeral/FlutterInputs.xcfilelist,
);
inputPaths = (
Flutter/ephemeral/tripwire,
);
outputFileListPaths = (
Flutter/ephemeral/FlutterOutputs.xcfilelist,
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
33CC10E92044A3C60003C045 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
33CC10F52044A3C60003C045 /* Base */,
);
name = MainMenu.xib;
path = Runner;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
338D0CE9231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Profile;
};
338D0CEA231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Profile;
};
338D0CEB231458BD00FA5F75 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Profile;
};
33CC10F92044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
33CC10FA2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
33CC10FC2044A3C60003C045 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
33CC10FD2044A3C60003C045 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
};
name = Release;
};
33CC111C2044C6BA0003C045 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
33CC111D2044C6BA0003C045 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10F92044A3C60003C045 /* Debug */,
33CC10FA2044A3C60003C045 /* Release */,
338D0CE9231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC10FC2044A3C60003C045 /* Debug */,
33CC10FD2044A3C60003C045 /* Release */,
338D0CEA231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
isa = XCConfigurationList;
buildConfigurations = (
33CC111C2044C6BA0003C045 /* Debug */,
33CC111D2044C6BA0003C045 /* Release */,
338D0CEB231458BD00FA5F75 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 33CC10E52044A3C60003C045 /* Project object */;
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "gecko.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "gecko.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "gecko.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "gecko.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More