Compare commits
98 Commits
Author | SHA1 | Date |
---|---|---|
poka | 68c8a61939 | |
poka | 1878ea5f63 | |
poka | 41b9db0dfb | |
poka | 61d28e79d6 | |
pokapow | 4f07c390bd | |
Eloi Torrents | 58c82069d4 | |
pokapow | e0d1d3a085 | |
Eloi Torrents | 66dca555ab | |
pokapow | 54b721627b | |
Eloi Torrents | 985c888a47 | |
guenoel | cbeaacfca8 | |
guenoel | 32beb33be4 | |
guenoel | 459a76452b | |
guenoel | 57d68e012d | |
guenoel | ae30355b9b | |
pokapow | ebc69445ed | |
poka | be52158959 | |
poka | 228e556198 | |
poka | 2c7dcd0ee6 | |
poka | aa917b1c25 | |
poka | a0b0423856 | |
poka | 6443e04191 | |
poka | bf58e8e3d1 | |
poka | a0d6bfaf22 | |
poka | 0728bc6aba | |
poka | d927ccea39 | |
poka | 2b0a0428a0 | |
poka | eb9275fa84 | |
pokapow | 09e1592f55 | |
poka | a432db334d | |
poka | ad0019522f | |
poka | d76ad9b7e3 | |
poka | 8b32bb8e26 | |
poka | edbe1d8b5c | |
pokapow | 7f5dbf04ee | |
poka | 57cdc23436 | |
poka | 0233816f68 | |
poka | 776a0f8c75 | |
pokapow | 164fc16ed8 | |
poka | 83189990c6 | |
poka | 0d54030c1a | |
poka | 147557f545 | |
poka | fd281ad822 | |
poka | f7e3066352 | |
poka | e2ed9c5c98 | |
poka | 3825bf0488 | |
poka | e752de474d | |
poka | 23b6858a60 | |
poka | 8663186a4a | |
poka | f46acb23e4 | |
pokapow | 549996578b | |
poka | 34c69b64ee | |
poka | 0fe0c4d3c5 | |
poka | 03a9f1ea19 | |
poka | d9222fe6ba | |
poka | 58572a5e0e | |
Hugo Trentesaux | 7491b9b489 | |
poka | ad9ee382d3 | |
pokapow | e01dea9329 | |
poka | 425677827c | |
poka | a8dbf79eaa | |
poka | 37dee7f866 | |
poka | 9301eaf1a7 | |
poka | 939c6b3108 | |
poka | 03ab85a282 | |
poka | 525c375c71 | |
poka | 18743c871b | |
poka | 3761494606 | |
poka | aa7bc74645 | |
poka | 05f41e16a9 | |
poka | c060c85df8 | |
poka | 27e4de7254 | |
poka | a03f711539 | |
poka | fbc8cbd0d9 | |
poka | 5744155400 | |
poka | afae4130a6 | |
poka | fc80f5693c | |
poka | cbbd4eee34 | |
poka | dcb64c74b6 | |
poka | 9239901608 | |
poka | 3abf2666ba | |
poka | ebc33e4f6c | |
poka | 2facd8cd7f | |
poka | dd49e76fa1 | |
pokapow | 5369599b20 | |
poka | ae5fe3b128 | |
poka | 3100dc5126 | |
poka | 92992c2f69 | |
poka | ad601be19c | |
poka | c840753f4a | |
poka | 99f939d5a2 | |
poka | 506110cfc8 | |
poka | d42e715482 | |
poka | 237e581d0f | |
poka | 1b896960ea | |
poka | dbfd033fba | |
poka | 5ce381b174 | |
poka | 0983c1d01e |
|
@ -55,4 +55,9 @@ scripts/private/
|
|||
AppDir/
|
||||
appimage-builder-cache/
|
||||
AppImageBuilder.yml
|
||||
android/app/build.gradle
|
||||
android/app/build.gradle
|
||||
integration_test/duniter/data/chains/
|
||||
|
||||
# Ignore PC deps
|
||||
macos/
|
||||
windows/
|
|
@ -5,7 +5,7 @@ stages:
|
|||
- package
|
||||
|
||||
.env:
|
||||
image: axiomteam/gecko-ci:v0.0.9
|
||||
image: axiomteam/gecko-ci:v0.0.11
|
||||
tags:
|
||||
- redshift
|
||||
|
||||
|
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -51,7 +51,6 @@
|
|||
"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.",
|
||||
|
@ -126,7 +125,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 note connected to internet",
|
||||
"notConnectedToInternet": "You are not connected to internet",
|
||||
"researchResults": "Results of your research",
|
||||
"resultsFor": "Results for ",
|
||||
"forgetAllMyChests": "Forget all my chests",
|
||||
|
@ -138,7 +137,7 @@
|
|||
"sending": "Sending...",
|
||||
"propagating": "Propagating...",
|
||||
"validating": "Validating...",
|
||||
"anErrorOccured": "An error occured",
|
||||
"anErrorOccurred": "An error occurred",
|
||||
"24hbetweenCerts": "You have to wait 24h between certs",
|
||||
"canNotCertifySelf": "You can not certify yourself",
|
||||
"nameAlreadyExist": "This name is already taken",
|
||||
|
@ -147,6 +146,7 @@
|
|||
"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,6 +158,7 @@
|
|||
"months": "{} months",
|
||||
"certify": "Certify",
|
||||
"from": "From:",
|
||||
"to": "To:",
|
||||
"amount": "Amount:",
|
||||
"choiceOfSourceWallet": "Choose a source wallet",
|
||||
"extrinsicInProgress": "{} in progress",
|
||||
|
@ -174,5 +175,25 @@
|
|||
"noContacts": "You don't have any contact",
|
||||
"addContact": "Add\nto contacts",
|
||||
"removeContact": "Remove\nthis contact",
|
||||
"derivationsScanProgress": "Scan address {}/{}"
|
||||
"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"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"searchWallet": "Search\nwallet",
|
||||
"manageWallets": "Manage\nwallets",
|
||||
"searchWallet": "Buscar\nbilletera",
|
||||
"manageWallets": "Gestionar\nbilleteras",
|
||||
"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": "Parameters",
|
||||
"parameters": "Parámetros",
|
||||
"chooseAnotherMnemonic": "Choose an other\nmnemonic sentence",
|
||||
"iNotedMyMnemonic": "I wrote down my sentence",
|
||||
"iNotedMyMnemonic": "He escrito mi frase",
|
||||
"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": "My root wallet",
|
||||
"myRootWallet": "Mi billetera principal",
|
||||
"currentWallet": "My current chest",
|
||||
"wallet": "Wallet",
|
||||
"wallet": "Billetera",
|
||||
"displayMnemonic": "Display my mnemonic sentence",
|
||||
"changePassword": "Change my password",
|
||||
"changePassword": "Cambiar mi contraseña",
|
||||
"createDerivation": "Create a new derivation",
|
||||
"createCustomDerivation": "Create a new custom derivation",
|
||||
"deleteChest": "Delete this chest",
|
||||
|
@ -36,22 +36,21 @@
|
|||
"selectMyChest": "Select my chest",
|
||||
"accessMyChest": "Access my chest",
|
||||
"manageMembership": "Manage my membership",
|
||||
"chooseThisWallet": "Choose this wallet",
|
||||
"chooseThisWallet": "Elegir esta billetera",
|
||||
"thisWalletIsDefault": "This wallet is the default one",
|
||||
"defineWalletAsDefault": "Define this as the default one",
|
||||
"displayActivity": "Display activity",
|
||||
"displayNActivity": "Display\nactivity",
|
||||
"memberValidated": "Validated member!",
|
||||
"copyAddress": "Copy\naddress",
|
||||
"copy": "Copy",
|
||||
"thisAddressHasBeenCopiedToClipboard": "This address has been copied to clipboard",
|
||||
"memberValidated": "Miembro validado!",
|
||||
"copyAddress": "Copiar\ndirección",
|
||||
"copy": "Copiar",
|
||||
"thisAddressHasBeenCopiedToClipboard": "Esta dirección se ha copiado al cortapapeles",
|
||||
"chooseWalletName": "Choose a new name\nfor your wallet:",
|
||||
"choosePassword": "Choose a random password:",
|
||||
"chooseDerivation": "Choose a derivation:",
|
||||
"validate": "Validate",
|
||||
"confirm": "Confirm",
|
||||
"confirmPayment": "Confirm payment",
|
||||
"clickHereToConfirmIdentity": "Click here to confirm\nyour new identity",
|
||||
"validate": "Validar",
|
||||
"confirm": "Confirmar",
|
||||
"confirmPayment": "Confirmar pago",
|
||||
"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.",
|
||||
|
@ -64,7 +63,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": "Choose an other password",
|
||||
"chooseAnotherPassword": "Elige otra contraseña",
|
||||
"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!",
|
||||
|
@ -73,7 +72,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": "Yes",
|
||||
"yes": "Si",
|
||||
"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.",
|
||||
|
@ -83,96 +82,118 @@
|
|||
"pasteFromClipboard": "Paste from\nclipboard",
|
||||
"restoreAChest": "Restore a chest",
|
||||
"restoreThisChest": "Restore this chest",
|
||||
"continue": "Continue",
|
||||
"continue": "Continuar",
|
||||
"itsTheGoodWord": "It's the good word!",
|
||||
"nthMnemonicWord": "word of your mnemonic",
|
||||
"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 {}",
|
||||
"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 {}",
|
||||
"noIdentity": "No identity",
|
||||
"identityCreated": "Identity created",
|
||||
"identityConfirmed": "Identity confirmed",
|
||||
"identityExpired": "Identity expired",
|
||||
"confirmYourIdentity": "Confirm your identity",
|
||||
"identityCreated": "Identidad creada",
|
||||
"identityConfirmed": "Identidad confirmada",
|
||||
"identityExpired": "Identitdad caducada",
|
||||
"confirmYourIdentity": "Confirma tu identidad",
|
||||
"noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later",
|
||||
"youAreConnectedToNode": "You are connected to node",
|
||||
"accountActivity": "Account activity",
|
||||
"accountActivity": "Actividad de la cuenta",
|
||||
"noNetworkNoHistory": "Network state does not allow\nto display account history",
|
||||
"noDataToDisplay": "No data to be displayed.",
|
||||
"noTransactionToDisplay": "No transaction to display",
|
||||
"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",
|
||||
"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",
|
||||
"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 note connected to internet",
|
||||
"notConnectedToInternet": "No estas conectado a internet",
|
||||
"researchResults": "Results of your research",
|
||||
"resultsFor": "Results for ",
|
||||
"forgetAllMyChests": "Forget all my chests",
|
||||
"transaction": "Transaction",
|
||||
"certification": "Certification",
|
||||
"transaction": "Transaccion",
|
||||
"certification": "Certificacion",
|
||||
"identityConfirm": "Identity confirmation",
|
||||
"revokeAdhesion": "Adhesion revocation",
|
||||
"strangeTransaction": "Strange transaction",
|
||||
"sending": "Sending...",
|
||||
"propagating": "Propagating...",
|
||||
"validating": "Validating...",
|
||||
"anErrorOccured": "An error occured",
|
||||
"sending": "Enviando...",
|
||||
"propagating": "Propagando...",
|
||||
"validating": "Validando...",
|
||||
"anErrorOccurred": "Ocurrió un error",
|
||||
"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": "See a wallet",
|
||||
"mustWaitXBeforeCertify": "You have to wait\n{} before\ncertifying again",
|
||||
"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",
|
||||
"canRenewCertInX": "You can renew\nthis certification\nin {}",
|
||||
"executeATransfer": "Execute a transfer",
|
||||
"executeTheTransfer": "Execute the transfer",
|
||||
"doATransfer" : "Execute a\ntransfer",
|
||||
"seconds": "{} seconds",
|
||||
"minutes": "{} minutes",
|
||||
"hours": "{} hours {}",
|
||||
"days": "{} days",
|
||||
"months": "{} months",
|
||||
"seconds": "{} segundos",
|
||||
"minutes": "{} minutos",
|
||||
"hours": "{} horas {}",
|
||||
"days": "{} dias",
|
||||
"months": "{} meses",
|
||||
"certify": "Certify",
|
||||
"from": "From:",
|
||||
"amount": "Amount:",
|
||||
"from": "De:",
|
||||
"to": "A:",
|
||||
"amount": "Importe:",
|
||||
"choiceOfSourceWallet": "Choose a source wallet",
|
||||
"extrinsicInProgress": "{} in progress",
|
||||
"extrinsicValidated": "{} validated !",
|
||||
"fromMinus": "from",
|
||||
"toMinus": "to",
|
||||
"extrinsicInProgress": "{} en progreso",
|
||||
"extrinsicValidated": "{} validado !",
|
||||
"fromMinus": "de",
|
||||
"toMinus": "a",
|
||||
"deleteThisWallet": "Delete this wallet",
|
||||
"cancel": "Cancel",
|
||||
"cancel": "Cancelar",
|
||||
"inBlockchainResult": "In {} blockchain",
|
||||
"search": "Search",
|
||||
"currencyNode": "{} node :",
|
||||
"contactsManagementWithNbr": "My contacts ({})",
|
||||
"contactsManagement": "My contacts",
|
||||
"search": "Buscar",
|
||||
"currencyNode": "{} nodo :",
|
||||
"contactsManagementWithNbr": "Mis contactos ({})",
|
||||
"contactsManagement": "Mis contactos",
|
||||
"noContacts": "You don't have any contact",
|
||||
"addContact": "Add\nto contacts",
|
||||
"removeContact": "Remove\nthis contact",
|
||||
"derivationsScanProgress": "Scan address {}/{}"
|
||||
}
|
||||
"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"
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
"validate": "Valider",
|
||||
"confirm": "Confirmer",
|
||||
"confirmPayment": "Confirmer le paiement",
|
||||
"clickHereToConfirmIdentity": "Cliquez ici pour confirmer\nvotre nouvelle identité",
|
||||
"geckoGenerateYourWalletFromMnemonic": "Ğecko fabrique votre portefeuille à partir d’une **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 d’accéder à tous vos portefeuilles.",
|
||||
|
@ -139,7 +138,7 @@
|
|||
"sending": "Envoi en cours...",
|
||||
"propagating": "En cours de propagation...",
|
||||
"validating": "En cours de validation...",
|
||||
"anErrorOccured": "Une erreur s'est produite",
|
||||
"anErrorOccurred": "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",
|
||||
|
@ -148,7 +147,8 @@
|
|||
"execTimeoutOver": "Le délais d'éxecution est dépassé",
|
||||
"seeAWallet": "Voir un portefeuille",
|
||||
"mustWaitXBeforeCertify": "Vous devez attendre\n{} avant\nde pouvoir certifier",
|
||||
"canRenewCertInX": "Vous pourrez renouveller\ncette certification\ndans {}",
|
||||
"mustConfirmHisIdentity": "Cette personne doit confirmer\nson identité avant de pouvoir\nêtre certifié",
|
||||
"canRenewCertInX": "Vous pourrez renouveler\ncette certification\ndans {}",
|
||||
"executeATransfer": "Effectuer un virement",
|
||||
"executeTheTransfer": "Effectuer le virement",
|
||||
"doATransfer": "Faire un\nvirement",
|
||||
|
@ -159,6 +159,7 @@
|
|||
"months": "{} mois",
|
||||
"certify": "Certifier",
|
||||
"from": "Depuis:",
|
||||
"to": "Vers:",
|
||||
"amount": "Montant:",
|
||||
"choiceOfSourceWallet": "Choix du portefeuille source",
|
||||
"extrinsicInProgress": "{} en cours",
|
||||
|
@ -175,5 +176,25 @@
|
|||
"noContacts": "Vous n'avez aucun contact",
|
||||
"addContact": "Ajouter\naux contacts",
|
||||
"removeContact": "Supprimer\nce contact",
|
||||
"derivationsScanProgress": "Scan de l'adresse {}/{}"
|
||||
"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"
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
[
|
||||
"wss://gdev.p2p.legal/ws",
|
||||
"wss://gdev.librelois.fr/ws"
|
||||
]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[
|
||||
"https://gdev-indexer.p2p.legal",
|
||||
"https://idx.gdev.cgeek.fr",
|
||||
"https://duniter-indexer.coinduf.eu",
|
||||
"http://192.168.1.72:8080"
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
# 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 d’interagir 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 l’appellerons `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.
|
|
@ -1,447 +0,0 @@
|
|||
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 l’instant 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 l’instant 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(
|
||||
// "J’ai généré votre phrase de restauration !\nTâchez de la garder bien secrète, car elle permet à quiconque la connaît d’accé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 d’autres, 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);
|
||||
// });
|
||||
},
|
||||
);
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"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"]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
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
|
|
@ -0,0 +1,6 @@
|
|||
#!/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
|
|
@ -0,0 +1,29 @@
|
|||
#!/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
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
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());
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
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);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
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());
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
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);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
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());
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
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());
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
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);
|
||||
}
|
|
@ -0,0 +1,328 @@
|
|||
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);
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# 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
|
|
@ -3,18 +3,13 @@ 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/hive.dart';
|
||||
import 'package:hive_flutter/hive_flutter.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';
|
||||
|
||||
|
@ -38,18 +33,20 @@ late double ratio;
|
|||
late BuildContext homeContext;
|
||||
|
||||
// Logger
|
||||
var log = Logger();
|
||||
final log = Logger();
|
||||
|
||||
// Colors
|
||||
Color orangeC = const Color(0xffd07316);
|
||||
Color yellowC = const Color(0xffFFD68E);
|
||||
Color floattingYellow = const Color(0xffEFEFBF);
|
||||
Color backgroundColor = const Color(0xFFF5F5F5);
|
||||
const Color orangeC = Color(0xffd07316);
|
||||
const Color yellowC = Color(0xffFFD68E);
|
||||
const Color floattingYellow = Color(0xffEFEFBF);
|
||||
const Color backgroundColor = Color(0xFFF5F5F5);
|
||||
|
||||
// Substrate settings
|
||||
String currencyName = 'ĞD';
|
||||
const String currencyName = 'ĞD';
|
||||
|
||||
// Debug
|
||||
const debugPin = true;
|
||||
|
||||
String indexerEndpoint = '';
|
||||
late double balanceRatio;
|
||||
late int udValue;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
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';
|
||||
|
@ -40,7 +41,6 @@ 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:graphql_flutter/graphql_flutter.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
@ -51,12 +51,15 @@ Future<void> main() async {
|
|||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await EasyLocalization.ensureInitialized();
|
||||
|
||||
if (kDebugMode) {
|
||||
await dotenv.load();
|
||||
}
|
||||
|
||||
HomeProvider homeProvider = HomeProvider();
|
||||
// DuniterIndexer _duniterIndexer = DuniterIndexer();
|
||||
await initHiveForFlutter();
|
||||
await homeProvider.initHive();
|
||||
appVersion = await homeProvider.getAppVersion();
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// Reset GraphQL cache
|
||||
// final cache = HiveStore();
|
||||
|
@ -105,7 +108,7 @@ Future<void> main() async {
|
|||
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
|
||||
path: 'assets/translations',
|
||||
fallbackLocale: const Locale('en'),
|
||||
child: Gecko(indexerEndpoint),
|
||||
child: const Gecko(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -117,15 +120,14 @@ Future<void> main() async {
|
|||
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
|
||||
path: 'assets/translations',
|
||||
fallbackLocale: const Locale('en'),
|
||||
child: Gecko(indexerEndpoint),
|
||||
child: const Gecko(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Gecko extends StatelessWidget {
|
||||
const Gecko(this.indexerEndpoint, {Key? key}) : super(key: key);
|
||||
final String? indexerEndpoint;
|
||||
const Gecko({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -6,7 +6,7 @@ part 'g1_wallets_list.g.dart';
|
|||
@HiveType(typeId: 2)
|
||||
class G1WalletsList {
|
||||
@HiveField(0)
|
||||
String? pubkey;
|
||||
late String address;
|
||||
|
||||
@HiveField(1)
|
||||
double? balance;
|
||||
|
@ -27,7 +27,7 @@ class G1WalletsList {
|
|||
bool? isMembre;
|
||||
|
||||
G1WalletsList({
|
||||
this.pubkey,
|
||||
required this.address,
|
||||
this.balance,
|
||||
this.id,
|
||||
this.avatar,
|
||||
|
@ -37,14 +37,14 @@ class G1WalletsList {
|
|||
});
|
||||
|
||||
G1WalletsList.fromJson(Map<String, dynamic> json) {
|
||||
pubkey = json['pubkey'];
|
||||
address = 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'] = pubkey;
|
||||
data['pubkey'] = address;
|
||||
data['balance'] = balance;
|
||||
if (id != null) {
|
||||
data['id'] = id!.toJson();
|
||||
|
|
|
@ -17,7 +17,7 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
|
|||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return G1WalletsList(
|
||||
pubkey: fields[0] as String?,
|
||||
address: 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.pubkey)
|
||||
..write(obj.address)
|
||||
..writeByte(1)
|
||||
..write(obj.balance)
|
||||
..writeByte(2)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
const String getNameByAddressQ = r'''
|
||||
query ($address: String!) {
|
||||
account_by_pk(id: $address) {
|
||||
account_by_pk(pubkey: $address) {
|
||||
identity {
|
||||
name
|
||||
}
|
||||
pubkey
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
@ -11,52 +12,18 @@ query ($address: String!) {
|
|||
const String searchAddressByNameQ = r'''
|
||||
query ($name: String!) {
|
||||
search_identity(args: {name: $name}) {
|
||||
id
|
||||
pubkey
|
||||
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_id: {_eq: $address}},
|
||||
{receiver_id: {_eq: $address}}
|
||||
{issuer_pubkey: {_eq: $address}},
|
||||
{receiver_pubkey: {_eq: $address}}
|
||||
]},
|
||||
order_by: {created_at: desc},
|
||||
first: $number,
|
||||
|
@ -65,8 +32,8 @@ query ($address: String!, $number: Int!, $cursor: String) {
|
|||
node {
|
||||
amount
|
||||
created_at
|
||||
issuer_id
|
||||
receiver_id
|
||||
issuer_pubkey
|
||||
receiver_pubkey
|
||||
issuer {
|
||||
identity {
|
||||
name
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
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');
|
|
@ -8,7 +8,7 @@ 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();
|
||||
|
|
|
@ -4,12 +4,13 @@ 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 rebuildWidget() {
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -59,13 +60,13 @@ class ChestProvider with ChangeNotifier {
|
|||
title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text("no".tr(), key: const Key('cancelDeleting')),
|
||||
child: Text("no".tr(), key: keyCancel),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, false);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text("yes".tr(), key: const Key('confirmDeleting')),
|
||||
child: Text("yes".tr(), key: keyConfirm),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, true);
|
||||
},
|
||||
|
|
|
@ -8,6 +8,7 @@ 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';
|
||||
|
@ -211,7 +212,7 @@ class DuniterIndexer with ChangeNotifier {
|
|||
g1WalletsBox.put(
|
||||
address,
|
||||
G1WalletsList(
|
||||
pubkey: address, username: walletNameIndexer[address]));
|
||||
address: address, username: walletNameIndexer[address]));
|
||||
|
||||
// log.d(g1WalletsBox.toMap().values.first.username);
|
||||
|
||||
|
@ -293,7 +294,6 @@ class DuniterIndexer with ChangeNotifier {
|
|||
return Text('noResult'.tr());
|
||||
}
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
return Expanded(
|
||||
child: ListView(children: <Widget>[
|
||||
|
@ -301,21 +301,30 @@ class DuniterIndexer with ChangeNotifier {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult(profile['pubkey']),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider.defaultAvatar(avatarSize),
|
||||
title: Row(children: <Widget>[
|
||||
Text(getShortPubkey(profile['id']),
|
||||
Text(getShortPubkey(profile['pubkey']),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Monospace',
|
||||
fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center),
|
||||
]),
|
||||
trailing: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [balance(context, profile['id'], 16)]),
|
||||
trailing: SizedBox(
|
||||
width: 110,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
balance(context, profile['pubkey'], 16),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
subtitle: Row(children: <Widget>[
|
||||
Text(profile['name'] ?? '',
|
||||
style: const TextStyle(
|
||||
|
@ -328,14 +337,15 @@ class DuniterIndexer with ChangeNotifier {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
walletsProfiles.address = profile['id'];
|
||||
walletsProfiles.address = profile['pubkey'];
|
||||
return WalletViewScreen(
|
||||
pubkey: profile['id'],
|
||||
address: profile['pubkey'],
|
||||
username: g1WalletsBox
|
||||
.get(profile['id'])
|
||||
.get(profile['pubkey'])
|
||||
?.id
|
||||
?.username,
|
||||
avatar: g1WalletsBox.get(profile['id'])?.avatar,
|
||||
avatar:
|
||||
g1WalletsBox.get(profile['pubkey'])?.avatar,
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
@ -354,22 +364,22 @@ class DuniterIndexer with ChangeNotifier {
|
|||
for (final trans in blockchainTX) {
|
||||
final transaction = trans['node'];
|
||||
final direction =
|
||||
transaction['issuer_id'] != pubkey ? 'RECEIVED' : 'SENT';
|
||||
transaction['issuer_pubkey'] != pubkey ? 'RECEIVED' : 'SENT';
|
||||
|
||||
transBC.add(i);
|
||||
transBC[i] = [];
|
||||
transBC[i].add(DateTime.parse(transaction['created_at']));
|
||||
final int amountBrut = transaction['amount'];
|
||||
final num amount = removeDecimalZero(amountBrut / 100);
|
||||
final double amount = removeDecimalZero(amountBrut / 100);
|
||||
if (direction == "RECEIVED") {
|
||||
transBC[i].add(transaction['issuer_id']);
|
||||
transBC[i].add(transaction['issuer_pubkey']);
|
||||
transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
|
||||
transBC[i].add(amount.toString());
|
||||
} else if (direction == "SENT") {
|
||||
transBC[i].add(transaction['receiver_id']);
|
||||
transBC[i].add(transaction['receiver_pubkey']);
|
||||
transBC[i].add(transaction['receiver']['identity']?['name'] ?? '');
|
||||
transBC[i].add('- $amount');
|
||||
}
|
||||
transBC[i].add(amount);
|
||||
transBC[i].add(direction);
|
||||
// transBC[i].add(''); //transaction comment
|
||||
|
||||
i++;
|
||||
|
@ -429,9 +439,9 @@ class DuniterIndexer with ChangeNotifier {
|
|||
return opts;
|
||||
}
|
||||
|
||||
num removeDecimalZero(double n) {
|
||||
double removeDecimalZero(double n) {
|
||||
String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
|
||||
return num.parse(result);
|
||||
return double.parse(result);
|
||||
}
|
||||
|
||||
// checkHistoryResult(
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
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';
|
||||
|
@ -354,6 +353,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
cellController10,
|
||||
cellController11
|
||||
];
|
||||
if (sentence?.text == null) return;
|
||||
for (var word in sentence!.text!.split(' ')) {
|
||||
bool isValid = isBipWord(word, false);
|
||||
|
||||
|
@ -435,8 +435,10 @@ class GenerateWalletsProvider with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<bool> scanRootBalance(SubstrateSdk sub, int currentChestNumber) async {
|
||||
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(sub.currencyParameters['ss58']!,
|
||||
cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!);
|
||||
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
||||
sub.currencyParameters['ss58']!,
|
||||
cryptoType: CryptoType.sr25519,
|
||||
mnemonic: generatedMnemonic!);
|
||||
|
||||
final balance = await sub.getBalance(addressData.address!).timeout(
|
||||
const Duration(seconds: 1),
|
||||
|
|
|
@ -11,7 +11,10 @@ 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';
|
||||
|
@ -62,6 +65,15 @@ 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;
|
||||
|
@ -148,6 +160,7 @@ 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: () {
|
||||
|
@ -166,6 +179,7 @@ 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 {
|
||||
|
@ -179,6 +193,7 @@ class HomeProvider with ChangeNotifier {
|
|||
const Spacer(),
|
||||
const SizedBox(width: 15),
|
||||
IconButton(
|
||||
key: keyAppBarChest,
|
||||
iconSize: 60,
|
||||
icon: const Image(image: AssetImage('assets/wallet.png')),
|
||||
onPressed: () async {
|
||||
|
@ -215,28 +230,7 @@ class HomeProvider with ChangeNotifier {
|
|||
);
|
||||
}
|
||||
|
||||
void rebuildWidget() {
|
||||
void reload() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ class MyWalletsProvider with ChangeNotifier {
|
|||
late String mnemonic;
|
||||
int? pinLenght;
|
||||
bool isNewDerivationLoading = false;
|
||||
String lastFlyBy = '';
|
||||
String dragAddress = '';
|
||||
|
||||
int getCurrentChest() {
|
||||
if (configBox.get('currentChest') == null) {
|
||||
|
@ -219,7 +221,7 @@ class MyWalletsProvider with ChangeNotifier {
|
|||
if (actualLock == lockPin) pinCode = '';
|
||||
}
|
||||
|
||||
void rebuildWidget() {
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ class SearchProvider with ChangeNotifier {
|
|||
final cacheDuring = 20 * 60 * 1000; //First number is minutes
|
||||
int cacheTime = 0;
|
||||
|
||||
void rebuildWidget() {
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ class SearchProvider with ChangeNotifier {
|
|||
WalletsProfilesProvider('pubkey');
|
||||
|
||||
if (walletProfiles.isAddress(searchController.text)) {
|
||||
G1WalletsList wallet = G1WalletsList(pubkey: searchController.text);
|
||||
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
||||
return [wallet];
|
||||
} else {
|
||||
return [];
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
import 'dart:typed_data';
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/chest_data.dart';
|
||||
import 'package:gecko/models/wallet_data.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/my_wallets.dart';
|
||||
import 'package:gecko/providers/wallet_options.dart';
|
||||
import 'package:gecko/providers/wallets_profiles.dart';
|
||||
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||
import 'package:polkawallet_sdk/api/types/networkParams.dart';
|
||||
import 'package:polkawallet_sdk/api/types/txInfoData.dart';
|
||||
import 'package:polkawallet_sdk/polkawallet_sdk.dart';
|
||||
import 'package:polkawallet_sdk/storage/keyring.dart';
|
||||
import 'package:polkawallet_sdk/storage/types/keyPairData.dart';
|
||||
import 'package:polkawallet_sdk/webviewWithExtension/types/signExtrinsicParam.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:truncate/truncate.dart';
|
||||
import 'package:pointycastle/pointycastle.dart' as pc;
|
||||
|
@ -31,20 +36,32 @@ class SubstrateSdk with ChangeNotifier {
|
|||
String transactionStatus = '';
|
||||
final int initSs58 = 42;
|
||||
Map<String, int> currencyParameters = {};
|
||||
TextEditingController csSalt = TextEditingController();
|
||||
TextEditingController csPassword = TextEditingController();
|
||||
String g1V1NewAddress = '';
|
||||
bool isCesiumIDVisible = false;
|
||||
bool isCesiumAddresLoading = false;
|
||||
late int udValue;
|
||||
|
||||
/////////////////////////////////////
|
||||
////////// 1: API METHODS ///////////
|
||||
/////////////////////////////////////
|
||||
|
||||
Future<String> executeCall(TxInfoData txInfo, txOptions, String password,
|
||||
Future<String> _executeCall(TxInfoData txInfo, txOptions, String password,
|
||||
[String? rawParams]) async {
|
||||
final walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||
final walletProfiles =
|
||||
Provider.of<WalletsProfilesProvider>(homeContext, listen: false);
|
||||
try {
|
||||
final hash = await sdk.api.tx
|
||||
.signAndSend(txInfo, txOptions, password, rawParam: rawParams)
|
||||
.timeout(
|
||||
const Duration(seconds: 12),
|
||||
onTimeout: () => {},
|
||||
);
|
||||
final hash = await sdk.api.tx.signAndSend(txInfo, txOptions, password,
|
||||
rawParam: rawParams, onStatusChange: (p0) {
|
||||
transactionStatus = p0;
|
||||
notifyListeners();
|
||||
}).timeout(
|
||||
const Duration(seconds: 18),
|
||||
onTimeout: () => {},
|
||||
);
|
||||
log.d(hash);
|
||||
if (hash.isEmpty) {
|
||||
transactionStatus = 'timeout';
|
||||
|
@ -52,8 +69,11 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
return 'timeout';
|
||||
} else {
|
||||
// Success !
|
||||
transactionStatus = hash.toString();
|
||||
notifyListeners();
|
||||
walletOptions.reload();
|
||||
walletProfiles.reload();
|
||||
return hash.toString();
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -63,46 +83,61 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
Future getStorage(String call) async {
|
||||
Future _getStorage(String call) async {
|
||||
return await sdk.webView!.evalJavascript('api.query.$call');
|
||||
}
|
||||
|
||||
Future getStorageConst(String call) async {
|
||||
Future _getStorageConst(String call) async {
|
||||
return (await sdk.webView!
|
||||
.evalJavascript('api.consts.$call', wrapPromise: false))[0];
|
||||
.evalJavascript('api.consts.$call', wrapPromise: false) ??
|
||||
[null])[0];
|
||||
}
|
||||
|
||||
TxSenderData _setSender() {
|
||||
Future<TxSenderData> _setSender(String address) async {
|
||||
final fromPubkey = await sdk.api.account.decodeAddress([address]);
|
||||
return TxSenderData(
|
||||
keyring.current.address,
|
||||
keyring.current.pubKey,
|
||||
address,
|
||||
fromPubkey!.keys.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _signMessage(
|
||||
Uint8List message, String address, String password) async {
|
||||
final params = SignAsExtensionParam();
|
||||
params.msgType = "pub(bytes.sign)";
|
||||
params.request = {
|
||||
"address": address,
|
||||
"data": message,
|
||||
};
|
||||
|
||||
final res = await sdk.api.keyring.signAsExtension(password, params);
|
||||
return res?.signature ?? '';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
////////// 2: GET ONCHAIN STORAGE //////////
|
||||
////////////////////////////////////////////
|
||||
|
||||
Future<int> getIdentityIndexOf(String address) async {
|
||||
return await getStorage('identity.identityIndexOf("$address")') ?? 0;
|
||||
Future<int> _getIdentityIndexOf(String address) async {
|
||||
return await _getStorage('identity.identityIndexOf("$address")') ?? 0;
|
||||
}
|
||||
|
||||
Future<List<int>> getCerts(String address) async {
|
||||
final idtyIndex = await getIdentityIndexOf(address);
|
||||
final idtyIndex = await _getIdentityIndexOf(address);
|
||||
final certsReceiver =
|
||||
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
|
||||
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
|
||||
|
||||
return [certsReceiver['receivedCount'], certsReceiver['issuedCount']];
|
||||
}
|
||||
|
||||
Future<int> getCertValidityPeriod(String from, String to) async {
|
||||
final idtyIndexFrom = await getIdentityIndexOf(from);
|
||||
final idtyIndexTo = await getIdentityIndexOf(to);
|
||||
final idtyIndexFrom = await _getIdentityIndexOf(from);
|
||||
final idtyIndexTo = await _getIdentityIndexOf(to);
|
||||
|
||||
if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0;
|
||||
|
||||
final List certData =
|
||||
await getStorage('cert.certsByReceiver($idtyIndexTo)') ?? [];
|
||||
await _getStorage('cert.certsByReceiver($idtyIndexTo)') ?? [];
|
||||
|
||||
if (certData.isEmpty) return 0;
|
||||
for (List certInfo in certData) {
|
||||
|
@ -115,25 +150,22 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<bool> hasAccountConsumers(String address) async {
|
||||
final accountInfo = await getStorage('system.account("$address")');
|
||||
final accountInfo = await _getStorage('system.account("$address")');
|
||||
final consumers = accountInfo['consumers'];
|
||||
return consumers == 0 ? false : true;
|
||||
}
|
||||
|
||||
// Future<double> getBalance(String address) async {
|
||||
// double balance = 0.0;
|
||||
Future<int> getUdValue() async {
|
||||
udValue = int.parse(await _getStorage('universalDividend.currentUd()'));
|
||||
return udValue;
|
||||
}
|
||||
|
||||
// if (nodeConnected) {
|
||||
// final brutBalance = await sdk.api.account.queryBalance(address);
|
||||
// // log.d(brutBalance?.toJson());
|
||||
// balance = int.parse(brutBalance!.freeBalance) / 100;
|
||||
// } else {
|
||||
// balance = -1;
|
||||
// }
|
||||
|
||||
// await getUnclaimedUd(address);
|
||||
// return balance;
|
||||
// }
|
||||
Future<double> getBalanceRatio() async {
|
||||
udValue = await getUdValue();
|
||||
balanceRatio =
|
||||
(configBox.get('isUdUnit') ?? false) ? round(udValue / 100, 6) : 1;
|
||||
return balanceRatio;
|
||||
}
|
||||
|
||||
Future<Map<String, double>> getBalance(String address) async {
|
||||
// log.d('currencyParameters: $currencyParameters');
|
||||
|
@ -148,16 +180,16 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
|
||||
// Get onchain storage values
|
||||
final Map balanceGlobal = await getStorage('system.account("$address")');
|
||||
final Map balanceGlobal = await _getStorage('system.account("$address")');
|
||||
final int? idtyIndex =
|
||||
await getStorage('identity.identityIndexOf("$address")');
|
||||
await _getStorage('identity.identityIndexOf("$address")');
|
||||
final Map? idtyData = idtyIndex == null
|
||||
? null
|
||||
: await getStorage('identity.identities($idtyIndex)');
|
||||
: await _getStorage('identity.identities($idtyIndex)');
|
||||
final int currentUdIndex =
|
||||
int.parse(await getStorage('universalDividend.currentUdIndex()'));
|
||||
int.parse(await _getStorage('universalDividend.currentUdIndex()'));
|
||||
final List pastReevals =
|
||||
await getStorage('universalDividend.pastReevals()');
|
||||
await _getStorage('universalDividend.pastReevals()');
|
||||
|
||||
// Compute amount of claimable UDs
|
||||
final int unclaimedUds = _computeUnclaimUds(currentUdIndex,
|
||||
|
@ -167,11 +199,14 @@ class SubstrateSdk with ChangeNotifier {
|
|||
final int transferableBalance =
|
||||
(balanceGlobal['data']['free'] + unclaimedUds);
|
||||
|
||||
// log.d('udValue: $udValue');
|
||||
|
||||
Map<String, double> finalBalances = {
|
||||
'transferableBalance': transferableBalance / 100,
|
||||
'free': balanceGlobal['data']['free'] / 100,
|
||||
'unclaimedUds': unclaimedUds / 100,
|
||||
'reserved': balanceGlobal['data']['reserved'] / 100,
|
||||
'transferableBalance': round((transferableBalance / balanceRatio) / 100),
|
||||
'free': round((balanceGlobal['data']['free'] / balanceRatio) / 100),
|
||||
'unclaimedUds': round((unclaimedUds / balanceRatio) / 100),
|
||||
'reserved':
|
||||
round((balanceGlobal['data']['reserved'] / balanceRatio) / 100),
|
||||
};
|
||||
|
||||
// log.i(finalBalances);
|
||||
|
@ -208,8 +243,23 @@ class SubstrateSdk with ChangeNotifier {
|
|||
return await idtyStatus(address) == 'Validated';
|
||||
}
|
||||
|
||||
Future<bool> isSmithGet(String address) async {
|
||||
var idtyIndex = await _getIdentityIndexOf(address);
|
||||
|
||||
final Map smithExpireOn =
|
||||
(await _getStorage('smithsMembership.membership($idtyIndex)')) ?? {};
|
||||
|
||||
if (smithExpireOn.isEmpty) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, int>> certState(String from, String to) async {
|
||||
Map<String, int> result = {};
|
||||
final toStatus = await idtyStatus(to);
|
||||
|
||||
if (from != to && await isMemberGet(from)) {
|
||||
final removableOn = await getCertValidityPeriod(from, to);
|
||||
final certMeta = await getCertMeta(from);
|
||||
|
@ -223,45 +273,71 @@ class SubstrateSdk with ChangeNotifier {
|
|||
} else if (nextIssuableOn > blocNumber) {
|
||||
final certDelayDuration = (nextIssuableOn - blocNumber) * 6;
|
||||
result.putIfAbsent('certDelay', () => certDelayDuration);
|
||||
} else if (toStatus == 'Created') {
|
||||
result.putIfAbsent('toStatus', () => 1);
|
||||
} else {
|
||||
result.putIfAbsent('canCert', () => 0);
|
||||
}
|
||||
// log.d('tatatatata: ${nextIssuableOn - blocNumber}');
|
||||
}
|
||||
|
||||
// if (toStatus == 'Created') result.putIfAbsent('toStatus', () => 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<Map> getCertMeta(String address) async {
|
||||
var idtyIndex = await getIdentityIndexOf(address);
|
||||
var idtyIndex = await _getIdentityIndexOf(address);
|
||||
|
||||
final certMeta =
|
||||
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
|
||||
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
|
||||
|
||||
return certMeta;
|
||||
}
|
||||
|
||||
Future<String> idtyStatus(String address, [bool smooth = true]) async {
|
||||
var idtyIndex = await getIdentityIndexOf(address);
|
||||
Future<String> idtyStatus(String address) async {
|
||||
// WalletOptionsProvider walletOptions =
|
||||
// Provider.of<WalletOptionsProvider>(homeContext, listen: false);
|
||||
|
||||
var idtyIndex = await _getIdentityIndexOf(address);
|
||||
|
||||
if (idtyIndex == 0) {
|
||||
return 'noid';
|
||||
}
|
||||
|
||||
final idtyStatus = await getStorage('identity.identities($idtyIndex)');
|
||||
final idtyStatus = await _getStorage('identity.identities($idtyIndex)');
|
||||
|
||||
if (idtyStatus != null) {
|
||||
final String status = idtyStatus['status'];
|
||||
|
||||
// if (address == walletOptions.address.text && status == 'Validated') {
|
||||
// walletOptions.reloadBuild();
|
||||
// }
|
||||
|
||||
return (status);
|
||||
} else {
|
||||
return 'expired';
|
||||
}
|
||||
}
|
||||
|
||||
// Future addressToPubkey(String address) async {
|
||||
// await sdk.api.account.decodeAddress([address]);
|
||||
// }
|
||||
Future<String> getGenesisHash() async {
|
||||
final String genesisHash = await sdk.webView!.evalJavascript(
|
||||
'api.genesisHash.toHex()',
|
||||
wrapPromise: false,
|
||||
) ??
|
||||
[];
|
||||
// log.d('genesisHash: $genesisHash');
|
||||
// log.d('genesisHash: ${HEX.decode(genesisHash.substring(2))}');
|
||||
return genesisHash;
|
||||
}
|
||||
|
||||
Future<Uint8List> addressToPubkey(String address) async {
|
||||
final pubkey = await sdk.api.account.decodeAddress([address]);
|
||||
final String pubkeyHex = pubkey!.keys.first;
|
||||
final pubkeyByte = HEX.decode(pubkeyHex.substring(2)) as Uint8List;
|
||||
// final pubkey58 = Base58Encode(pubkeyByte);
|
||||
|
||||
return pubkeyByte;
|
||||
}
|
||||
|
||||
// Future pubkeyToAddress(String pubkey) async {
|
||||
// await sdk.api.account.encodeAddress([pubkey]);
|
||||
|
@ -269,23 +345,41 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
Future initCurrencyParameters() async {
|
||||
currencyParameters['ss58'] =
|
||||
await getStorageConst('system.ss58Prefix.words');
|
||||
await _getStorageConst('system.ss58Prefix.words');
|
||||
currencyParameters['minCertForMembership'] =
|
||||
await getStorageConst('wot.minCertForMembership.words');
|
||||
await _getStorageConst('wot.minCertForMembership.words');
|
||||
currencyParameters['newAccountPrice'] =
|
||||
await getStorageConst('account.newAccountPrice.words');
|
||||
await _getStorageConst('account.newAccountPrice.words');
|
||||
currencyParameters['existentialDeposit'] =
|
||||
await getStorageConst('balances.existentialDeposit.words');
|
||||
await _getStorageConst('balances.existentialDeposit.words');
|
||||
currencyParameters['certPeriod'] =
|
||||
await getStorageConst('cert.certPeriod.words');
|
||||
await _getStorageConst('cert.certPeriod.words');
|
||||
currencyParameters['certMaxByIssuer'] =
|
||||
await getStorageConst('cert.maxByIssuer.words');
|
||||
await _getStorageConst('cert.maxByIssuer.words');
|
||||
currencyParameters['certValidityPeriod'] =
|
||||
await getStorageConst('cert.validityPeriod.words');
|
||||
await _getStorageConst('cert.validityPeriod.words');
|
||||
|
||||
log.i('currencyParameters: $currencyParameters');
|
||||
}
|
||||
|
||||
void cesiumIDisVisible() {
|
||||
isCesiumIDVisible = !isCesiumIDVisible;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<double> txFees(
|
||||
String fromAddress, String destAddress, double amount) async {
|
||||
if (amount == 0) return 0;
|
||||
final sender = await _setSender(fromAddress);
|
||||
final txInfo = TxInfoData('balances', 'transferKeepAlive', sender);
|
||||
final amountUnit = (amount * 100).toInt();
|
||||
|
||||
final estimateFees =
|
||||
await sdk.api.tx.estimateFees(txInfo, [destAddress, amountUnit]);
|
||||
|
||||
return estimateFees.partialFee / 100;
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
////// 3: SUBSTRATE CONNECTION //////
|
||||
/////////////////////////////////////
|
||||
|
@ -307,6 +401,8 @@ class SubstrateSdk with ChangeNotifier {
|
|||
|
||||
Future<void> connectNode(BuildContext ctx) async {
|
||||
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(ctx, listen: false);
|
||||
|
||||
homeProvider.changeMessage("connectionPending".tr(), 0);
|
||||
|
||||
|
@ -347,7 +443,9 @@ class SubstrateSdk with ChangeNotifier {
|
|||
notifyListeners();
|
||||
});
|
||||
|
||||
// currencyName = await getCurencyName();
|
||||
await initCurrencyParameters();
|
||||
await getBalanceRatio();
|
||||
|
||||
notifyListeners();
|
||||
homeProvider.changeMessage(
|
||||
"wellConnectedToNode"
|
||||
|
@ -359,7 +457,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
debugConnection = res.toString();
|
||||
notifyListeners();
|
||||
homeProvider.changeMessage("noDuniterEndointAvailable".tr(), 0);
|
||||
// snackNode(ctx, false);
|
||||
if (!myWalletProvider.checkIfWalletExist()) snackNode(homeContext, false);
|
||||
}
|
||||
|
||||
log.d(sdk.api.connectedNode?.endpoint);
|
||||
|
@ -468,7 +566,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<KeyPairData?> changePassword(BuildContext context, String address,
|
||||
String passOld, String? passNew) async {
|
||||
String passOld, String passNew) async {
|
||||
final account = getKeypair(address);
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
@ -527,8 +625,6 @@ class SubstrateSdk with ChangeNotifier {
|
|||
BuildContext context, String address, int number, String password) async {
|
||||
final keypair = getKeypair(address);
|
||||
|
||||
log.d('tatatata $address $number $password ${keypair.encoded}');
|
||||
|
||||
final seedMap =
|
||||
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
|
||||
|
||||
|
@ -563,7 +659,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
|
||||
}
|
||||
|
||||
Future csToV2(String salt, String password) async {
|
||||
Future<String> csToV2Address(String salt, String password) async {
|
||||
final scrypt = pc.KeyDerivator('scrypt');
|
||||
|
||||
scrypt.init(
|
||||
|
@ -579,29 +675,28 @@ class SubstrateSdk with ChangeNotifier {
|
|||
final rawSeedHex = '0x${HEX.encode(rawSeed)}';
|
||||
|
||||
// Just get the address without keystore
|
||||
// final newAddress1 = await sdk.api.keyring.addressFromRawSeed(ss58,
|
||||
// cryptoType: CryptoType.ed25519, rawSeed: '0x$rawSeedString');
|
||||
// log.d('csconvert address: ${newAddress1.address}');
|
||||
final newAddress = await sdk.api.keyring.addressFromRawSeed(
|
||||
currencyParameters['ss58']!,
|
||||
cryptoType: CryptoType.ed25519,
|
||||
rawSeed: rawSeedHex);
|
||||
|
||||
final json = await sdk.api.keyring.importAccount(keyring,
|
||||
keyType: KeyType.rawSeed,
|
||||
key: rawSeedHex,
|
||||
name: 'test',
|
||||
password: 'password',
|
||||
derivePath: '',
|
||||
cryptoType: CryptoType.ed25519);
|
||||
g1V1NewAddress = newAddress.address!;
|
||||
notifyListeners();
|
||||
return g1V1NewAddress;
|
||||
}
|
||||
|
||||
final keypair = await sdk.api.keyring.addAccount(
|
||||
keyring,
|
||||
keyType: KeyType.rawSeed,
|
||||
acc: json!,
|
||||
password: password,
|
||||
);
|
||||
await sdk.api.keyring.deleteAccount(keyring, keypair);
|
||||
Future<List> getBalanceAndIdtyStatus(
|
||||
String fromAddress, String toAddress) async {
|
||||
final fromBalance = fromAddress == ''
|
||||
? {'transferableBalance': 0}
|
||||
: await getBalance(fromAddress);
|
||||
final fromIdtyStatus =
|
||||
fromAddress == '' ? 'noid' : await idtyStatus(fromAddress);
|
||||
final fromHasConsumer =
|
||||
fromAddress == '' ? false : await hasAccountConsumers(fromAddress);
|
||||
final toIdtyStatus = await idtyStatus(toAddress);
|
||||
|
||||
// final keypair2 = KeyPairData.fromJson(json as Map<String, dynamic>);
|
||||
|
||||
log.d(keypair.address);
|
||||
return [fromBalance, fromIdtyStatus, toIdtyStatus, fromHasConsumer];
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
@ -614,23 +709,42 @@ class SubstrateSdk with ChangeNotifier {
|
|||
required double amount,
|
||||
required String password}) async {
|
||||
transactionStatus = '';
|
||||
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
|
||||
final int amountUnit = (amount * 100).toInt();
|
||||
|
||||
final sender = TxSenderData(
|
||||
fromAddress,
|
||||
fromPubkey!.keys.first,
|
||||
);
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
final globalBalance = await getBalance(fromAddress);
|
||||
TxInfoData txInfo;
|
||||
List txOptions = [];
|
||||
String? rawParams;
|
||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
late String palette;
|
||||
late String call;
|
||||
late String tx2;
|
||||
|
||||
if (amount == -1) {
|
||||
palette = 'balances';
|
||||
call = 'transferAll';
|
||||
txOptions = [destAddress, false];
|
||||
tx2 = 'api.tx.balances.transferAll("$destAddress", false)';
|
||||
} else {
|
||||
late int amountUnit;
|
||||
if (isUdUnit) {
|
||||
palette = 'universalDividend';
|
||||
call = 'transferUd';
|
||||
// amount is milliUds
|
||||
amountUnit = (amount * 1000).toInt();
|
||||
} else {
|
||||
palette = 'balances';
|
||||
call = 'transferKeepAlive';
|
||||
// amount is double at 2 decimals
|
||||
amountUnit = (amount * 100).toInt();
|
||||
}
|
||||
txOptions = [destAddress, amountUnit];
|
||||
tx2 = 'api.tx.$palette.$call("$destAddress", $amountUnit)';
|
||||
}
|
||||
|
||||
if (globalBalance['unclaimedUds'] == 0) {
|
||||
txInfo = TxInfoData('balances',
|
||||
amount == -1 ? 'transferAll' : 'transferKeepAlive', sender);
|
||||
txOptions = [destAddress, amount == -1 ? false : amountUnit];
|
||||
txInfo = TxInfoData(palette, call, sender);
|
||||
} else {
|
||||
txInfo = TxInfoData(
|
||||
'utility',
|
||||
|
@ -638,26 +752,21 @@ class SubstrateSdk with ChangeNotifier {
|
|||
sender,
|
||||
);
|
||||
const tx1 = 'api.tx.universalDividend.claimUds()';
|
||||
final tx2 = amount == -1
|
||||
? 'api.tx.balances.transferAll(false)'
|
||||
: 'api.tx.balances.transferKeepAlive("$destAddress", $amountUnit)';
|
||||
|
||||
rawParams = '[[$tx1, $tx2]]';
|
||||
}
|
||||
|
||||
// log.d('pay args: ${txInfo.module}, ${txInfo.call}, $txOptions, $rawParams');
|
||||
return await executeCall(txInfo, txOptions, password, rawParams);
|
||||
return await _executeCall(txInfo, txOptions, password, rawParams);
|
||||
}
|
||||
|
||||
Future<String> certify(
|
||||
String fromAddress, String password, String toAddress) async {
|
||||
String fromAddress, String destAddress, String password) async {
|
||||
transactionStatus = '';
|
||||
|
||||
final myIdtyStatus = await idtyStatus(fromAddress);
|
||||
final toIdtyStatus = await idtyStatus(toAddress);
|
||||
final toIdtyStatus = await idtyStatus(destAddress);
|
||||
|
||||
final fromIndex = await getIdentityIndexOf(fromAddress);
|
||||
final toIndex = await getIdentityIndexOf(toAddress);
|
||||
final fromIndex = await _getIdentityIndexOf(fromAddress);
|
||||
final toIndex = await _getIdentityIndexOf(destAddress);
|
||||
|
||||
if (myIdtyStatus != 'Validated') {
|
||||
transactionStatus = 'notMember';
|
||||
|
@ -665,12 +774,12 @@ class SubstrateSdk with ChangeNotifier {
|
|||
return 'notMember';
|
||||
}
|
||||
|
||||
final sender = _setSender();
|
||||
final sender = await _setSender(fromAddress);
|
||||
TxInfoData txInfo;
|
||||
List txOptions = [];
|
||||
String? rawParams;
|
||||
|
||||
final toCerts = await getCerts(toAddress);
|
||||
final toCerts = await getCerts(destAddress);
|
||||
|
||||
// log.d('debug: ${currencyParameters['minCertForMembership']}');
|
||||
|
||||
|
@ -680,7 +789,7 @@ class SubstrateSdk with ChangeNotifier {
|
|||
'createIdentity',
|
||||
sender,
|
||||
);
|
||||
txOptions = [toAddress];
|
||||
txOptions = [destAddress];
|
||||
} else if (toIdtyStatus == 'Validated' ||
|
||||
toIdtyStatus == 'ConfirmedByOwner') {
|
||||
if (toCerts[0] >= currencyParameters['minCertForMembership']! - 1 &&
|
||||
|
@ -710,32 +819,12 @@ class SubstrateSdk with ChangeNotifier {
|
|||
}
|
||||
|
||||
log.d('Cert action: ${txInfo.call!}');
|
||||
return await executeCall(txInfo, txOptions, password, rawParams);
|
||||
return await _executeCall(txInfo, txOptions, password, rawParams);
|
||||
}
|
||||
|
||||
// Future claimUDs(String password) async {
|
||||
// final sender = TxSenderData(
|
||||
// keyring.current.address,
|
||||
// keyring.current.pubKey,
|
||||
// );
|
||||
|
||||
// final txInfo = TxInfoData(
|
||||
// 'universalDividend',
|
||||
// 'claimUds',
|
||||
// sender,
|
||||
// );
|
||||
|
||||
// return await executeCall(txInfo, [], password);
|
||||
// }
|
||||
|
||||
Future<String> confirmIdentity(
|
||||
String fromAddress, String name, String password) async {
|
||||
log.d('me: ${keyring.current.address!}');
|
||||
|
||||
final sender = TxSenderData(
|
||||
keyring.current.address,
|
||||
keyring.current.pubKey,
|
||||
);
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
final txInfo = TxInfoData(
|
||||
'identity',
|
||||
|
@ -744,29 +833,164 @@ class SubstrateSdk with ChangeNotifier {
|
|||
);
|
||||
final txOptions = [name];
|
||||
|
||||
return await executeCall(txInfo, txOptions, password);
|
||||
return await _executeCall(txInfo, txOptions, password);
|
||||
}
|
||||
|
||||
Future<String> migrateIdentity(
|
||||
{required String fromAddress,
|
||||
required String destAddress,
|
||||
required String fromPassword,
|
||||
required String destPassword,
|
||||
required Map fromBalance,
|
||||
bool withBalance = false}) async {
|
||||
transactionStatus = '';
|
||||
final sender = await _setSender(fromAddress);
|
||||
|
||||
TxInfoData txInfo;
|
||||
List txOptions = [];
|
||||
String? rawParams;
|
||||
|
||||
final prefix = 'icok'.codeUnits;
|
||||
final genesisHashString = await getGenesisHash();
|
||||
final genesisHash = HEX.decode(genesisHashString.substring(2)) as Uint8List;
|
||||
final idtyIndex = _int32bytes(await _getIdentityIndexOf(fromAddress));
|
||||
final oldPubkey = await addressToPubkey(fromAddress);
|
||||
final messageToSign =
|
||||
Uint8List.fromList(prefix + genesisHash + idtyIndex + oldPubkey);
|
||||
final messageToSignHex = HEX.encode(messageToSign);
|
||||
final newKeySig =
|
||||
await _signMessage(messageToSign, destAddress, destPassword);
|
||||
|
||||
// messageToSign: [105, 99, 111, 107, 7, 193, 18, 255, 106, 185, 215, 208, 213, 49, 235, 229, 159, 152, 179, 83, 24, 178, 129, 59, 22, 85, 87, 115, 128, 129, 157, 56, 214, 24, 45, 153, 21, 0, 0, 0, 181, 82, 178, 99, 198, 4, 156, 190, 78, 35, 102, 137, 255, 7, 162, 31, 16, 79, 255, 132, 130, 237, 230, 222, 176, 88, 245, 217, 237, 78, 196, 239]
|
||||
|
||||
log.d("""
|
||||
fromAddress: $fromAddress
|
||||
destAddress: $destAddress
|
||||
genesisHashString: $genesisHashString
|
||||
|
||||
prefix: $prefix
|
||||
genesisHash: $genesisHash
|
||||
idtyIndex: $idtyIndex
|
||||
oldPubkey: $oldPubkey
|
||||
|
||||
messageToSign: $messageToSign
|
||||
messageToSignHex: $messageToSignHex
|
||||
newKeySig: $newKeySig""");
|
||||
|
||||
if (withBalance) {
|
||||
txInfo = TxInfoData(
|
||||
'utility',
|
||||
'batchAll',
|
||||
sender,
|
||||
);
|
||||
|
||||
const tx1 = 'api.tx.universalDividend.claimUds()';
|
||||
final tx2 =
|
||||
'api.tx.identity.changeOwnerKey("$destAddress", "$newKeySig")';
|
||||
final tx3 = 'api.tx.balances.transferAll("$destAddress", false)';
|
||||
|
||||
rawParams = fromBalance['unclaimedUds'] == 0
|
||||
? '[[$tx2, $tx3]]'
|
||||
: '[[$tx1, $tx2, $tx3]]';
|
||||
} else {
|
||||
txInfo = TxInfoData(
|
||||
'identity',
|
||||
'changeOwnerKey',
|
||||
sender,
|
||||
);
|
||||
|
||||
txOptions = [destAddress, newKeySig];
|
||||
}
|
||||
|
||||
return await _executeCall(txInfo, txOptions, fromPassword, rawParams);
|
||||
}
|
||||
|
||||
Future revokeIdentity(String address, String password) async {
|
||||
final idtyIndex = await getIdentityIndexOf(address);
|
||||
final idtyIndex = await _getIdentityIndexOf(address);
|
||||
final sender = await _setSender(address);
|
||||
|
||||
final sender = TxSenderData(
|
||||
keyring.current.address,
|
||||
keyring.current.pubKey,
|
||||
);
|
||||
final prefix = 'revo'.codeUnits;
|
||||
final genesisHashString = await getGenesisHash();
|
||||
final genesisHash = HEX.decode(genesisHashString.substring(2)) as Uint8List;
|
||||
final idtyIndexBytes = _int32bytes(idtyIndex);
|
||||
final messageToSign =
|
||||
Uint8List.fromList(prefix + genesisHash + idtyIndexBytes);
|
||||
final revocationSig =
|
||||
(await _signMessage(messageToSign, address, password)).substring(2);
|
||||
final revocationSigTyped = '0x01$revocationSig';
|
||||
|
||||
log.d(sender.address);
|
||||
TxInfoData txInfo;
|
||||
|
||||
txInfo = TxInfoData(
|
||||
'membership',
|
||||
'revokeMembership',
|
||||
final txInfo = TxInfoData(
|
||||
'identity',
|
||||
'revokeIdentity',
|
||||
sender,
|
||||
);
|
||||
|
||||
final txOptions = [idtyIndex];
|
||||
final txOptions = [idtyIndex, address, revocationSigTyped];
|
||||
return await _executeCall(txInfo, txOptions, password);
|
||||
}
|
||||
|
||||
return await executeCall(txInfo, txOptions, password);
|
||||
Future migrateCsToV2(String salt, String password, String destAddress,
|
||||
{required destPassword,
|
||||
required Map balance,
|
||||
String idtyStatus = 'noid'}) async {
|
||||
final scrypt = pc.KeyDerivator('scrypt');
|
||||
|
||||
scrypt.init(
|
||||
pc.ScryptParameters(
|
||||
4096,
|
||||
16,
|
||||
1,
|
||||
32,
|
||||
Uint8List.fromList(salt.codeUnits),
|
||||
),
|
||||
);
|
||||
final rawSeed = scrypt.process(Uint8List.fromList(password.codeUnits));
|
||||
final rawSeedHex = '0x${HEX.encode(rawSeed)}';
|
||||
|
||||
final json = await sdk.api.keyring.importAccount(keyring,
|
||||
keyType: KeyType.rawSeed,
|
||||
key: rawSeedHex,
|
||||
name: 'test',
|
||||
password: 'password',
|
||||
derivePath: '',
|
||||
cryptoType: CryptoType.ed25519);
|
||||
|
||||
final keypair = await sdk.api.keyring.addAccount(
|
||||
keyring,
|
||||
keyType: KeyType.rawSeed,
|
||||
acc: json!,
|
||||
password: password,
|
||||
);
|
||||
|
||||
log.d('g1migration idtyStatus: $idtyStatus');
|
||||
if (idtyStatus != 'noid') {
|
||||
await migrateIdentity(
|
||||
fromAddress: keypair.address!,
|
||||
destAddress: destAddress,
|
||||
fromPassword: 'password',
|
||||
destPassword: destPassword,
|
||||
withBalance: true,
|
||||
fromBalance: balance);
|
||||
} else if (balance['transferableBalance'] != 0) {
|
||||
await pay(
|
||||
fromAddress: keypair.address!,
|
||||
destAddress: destAddress,
|
||||
amount: -1,
|
||||
password: 'password');
|
||||
}
|
||||
|
||||
await sdk.api.keyring.deleteAccount(keyring, keypair);
|
||||
}
|
||||
|
||||
Future spawnBlock([int number = 1, int until = 0]) async {
|
||||
if (!kDebugMode) return;
|
||||
if (blocNumber < until) {
|
||||
number = until - blocNumber;
|
||||
}
|
||||
for (var i = 1; i <= number; i++) {
|
||||
await sdk.webView!
|
||||
.evalJavascript('api.rpc.engine.createBlock(true, true)');
|
||||
}
|
||||
}
|
||||
|
||||
void reload() {
|
||||
|
@ -778,24 +1002,10 @@ class SubstrateSdk with ChangeNotifier {
|
|||
/////// 6: UI ELEMENTS (off class) /////////
|
||||
////////////////////////////////////////////
|
||||
|
||||
void snack(BuildContext context, String message, {int duration = 2}) {
|
||||
final snackBar =
|
||||
SnackBar(content: Text(message), duration: Duration(seconds: duration));
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||
}
|
||||
|
||||
class AddressInfo {
|
||||
final String? address;
|
||||
double balance;
|
||||
|
||||
AddressInfo({@required this.address, this.balance = 0});
|
||||
}
|
||||
|
||||
void snackNode(BuildContext context, bool isConnected) {
|
||||
String message;
|
||||
if (!isConnected) {
|
||||
message =
|
||||
"${"noDuniterNodeAvailableTryLater".tr()}:\n${configBox.get('endpoint').first}";
|
||||
message = "noDuniterNodeAvailableTryLater".tr();
|
||||
} else {
|
||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
||||
|
@ -817,7 +1027,9 @@ String getShortPubkey(String pubkey) {
|
|||
return pubkeyShort;
|
||||
}
|
||||
|
||||
class PasswordException implements Exception {
|
||||
String cause;
|
||||
PasswordException(this.cause);
|
||||
Uint8List _int32bytes(int value) =>
|
||||
Uint8List(4)..buffer.asInt32List()[0] = value;
|
||||
|
||||
double round(double number, [int decimal = 2]) {
|
||||
return double.parse((number.toStringAsFixed(decimal)));
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
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';
|
||||
|
@ -30,7 +32,7 @@ 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) {
|
||||
|
@ -135,7 +137,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
_showText(String text,
|
||||
showText(String text,
|
||||
[double size = 18, bool bold = false, bool smooth = true]) {
|
||||
log.d('$address $text');
|
||||
return AnimatedFadeOutIn<String>(
|
||||
|
@ -157,27 +159,20 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
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 isOwner
|
||||
? InkWell(
|
||||
child: _showText(
|
||||
'clickHereToConfirmIdentity'.tr(), 18, true),
|
||||
onTap: () async {
|
||||
await validateIdentity(context);
|
||||
},
|
||||
)
|
||||
: _showText('identityCreated'.tr());
|
||||
return showText('identityCreated'.tr());
|
||||
}
|
||||
case 'ConfirmedByOwner':
|
||||
{
|
||||
return isOwner
|
||||
? _showText('identityConfirmed'.tr())
|
||||
? showText('identityConfirmed'.tr())
|
||||
: duniterIndexer.getNameByAddress(
|
||||
context,
|
||||
address,
|
||||
|
@ -192,7 +187,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
case 'Validated':
|
||||
{
|
||||
return isOwner
|
||||
? _showText('memberValidated'.tr(), 18, true)
|
||||
? showText('memberValidated'.tr(), 18, true)
|
||||
: duniterIndexer.getNameByAddress(
|
||||
context,
|
||||
address,
|
||||
|
@ -206,11 +201,11 @@ 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),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -221,7 +216,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
return await sub.idtyStatus(address) == 'Validated';
|
||||
}
|
||||
|
||||
Future<String?> validateIdentity(BuildContext context) async {
|
||||
Future<String?> confirmIdentityPopup(BuildContext context) async {
|
||||
TextEditingController idtyName = TextEditingController();
|
||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
WalletOptionsProvider walletOptions =
|
||||
|
@ -243,12 +238,14 @@ 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,
|
||||
|
@ -263,18 +260,22 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, wOptions, _) {
|
||||
return TextButton(
|
||||
key: const Key('infoPopup'),
|
||||
key: keyConfirm,
|
||||
child: Text(
|
||||
"validate".tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 21,
|
||||
color: idtyName.text.length >= 2
|
||||
color: idtyName.text.length.clamp(3, 64) ==
|
||||
idtyName.text.length
|
||||
? const Color(0xffD80000)
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
if (idtyName.text.length >= 2) {
|
||||
idtyName.text = idtyName.text.trim().replaceAll(' ', '');
|
||||
|
||||
if (idtyName.text.length.clamp(3, 64) ==
|
||||
idtyName.text.length) {
|
||||
WalletData? defaultWallet =
|
||||
myWalletProvider.getDefaultWallet();
|
||||
|
||||
|
@ -300,8 +301,11 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const TransactionInProgress(
|
||||
transType: 'comfirmIdty');
|
||||
return TransactionInProgress(
|
||||
transType: 'comfirmIdty',
|
||||
fromAddress: getShortPubkey(wallet.address!),
|
||||
toAddress: getShortPubkey(wallet.address!),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -352,7 +356,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, wOptions, _) {
|
||||
return TextButton(
|
||||
key: const Key('infoPopup'),
|
||||
key: keyInfoPopup,
|
||||
child: Text(
|
||||
"validate".tr(),
|
||||
style: TextStyle(
|
||||
|
@ -379,7 +383,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
key: const Key('cancel'),
|
||||
key: keyCancel,
|
||||
child: Text(
|
||||
"cancel".tr(),
|
||||
style: TextStyle(
|
||||
|
@ -423,7 +427,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
return canValidateNameBool;
|
||||
}
|
||||
|
||||
void reloadBuild() {
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
@ -455,7 +459,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
width: 260,
|
||||
child: Stack(children: <Widget>[
|
||||
TextField(
|
||||
key: const Key('walletName'),
|
||||
key: keyWalletName,
|
||||
autofocus: false,
|
||||
focusNode: walletNameFocus,
|
||||
enabled: isEditing,
|
||||
|
@ -479,7 +483,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
|||
Positioned(
|
||||
right: 0,
|
||||
child: InkWell(
|
||||
key: const Key('renameWallet'),
|
||||
key: keyRenameWallet,
|
||||
onTap: () async {
|
||||
// _isNewNameValid =
|
||||
// walletProvider.editWalletName(wallet.id(), isCesium: false);
|
||||
|
@ -537,10 +541,13 @@ Widget balance(BuildContext context, String address, double size,
|
|||
globalBalance.hasError) {
|
||||
if (balanceCache[address] != null &&
|
||||
balanceCache[address] != -1) {
|
||||
return Text(
|
||||
"${balanceCache[address]!.toString()} $currencyName",
|
||||
style: TextStyle(
|
||||
fontSize: isTall ? size : size * 0.9, color: color));
|
||||
return Row(children: [
|
||||
Text(balanceCache[address]!.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: isTall ? size : size * 0.9, color: color)),
|
||||
const SizedBox(width: 5),
|
||||
udUnitDisplay(size, color),
|
||||
]);
|
||||
} else {
|
||||
return SizedBox(
|
||||
height: 15,
|
||||
|
@ -554,13 +561,17 @@ Widget balance(BuildContext context, String address, double size,
|
|||
}
|
||||
balanceCache[address] = globalBalance.data!['transferableBalance']!;
|
||||
if (balanceCache[address] != -1) {
|
||||
return Text(
|
||||
"${balanceCache[address]!.toString()} $currencyName",
|
||||
style: TextStyle(
|
||||
fontSize: isTall ? size : size * 0.9,
|
||||
color: color,
|
||||
return Row(children: [
|
||||
Text(
|
||||
balanceCache[address]!.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: isTall ? size : size * 0.9,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
);
|
||||
const SizedBox(width: 5),
|
||||
udUnitDisplay(size, color),
|
||||
]);
|
||||
} else {
|
||||
return const Text('');
|
||||
}
|
||||
|
@ -597,3 +608,32 @@ 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));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ 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';
|
||||
|
@ -18,7 +19,7 @@ import 'package:provider/provider.dart';
|
|||
class WalletsProfilesProvider with ChangeNotifier {
|
||||
WalletsProfilesProvider(this.address);
|
||||
|
||||
String? address = '';
|
||||
String address = '';
|
||||
String pubkeyShort = '';
|
||||
|
||||
bool isHistoryScreen = false;
|
||||
|
@ -43,7 +44,7 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return WalletViewScreen(pubkey: barcode!.rawContent);
|
||||
return WalletViewScreen(address: barcode!.rawContent);
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
|
@ -138,10 +139,9 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
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;
|
||||
return Container(
|
||||
height: 180,
|
||||
decoration: BoxDecoration(
|
||||
|
@ -167,7 +167,7 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
),
|
||||
Row(children: [
|
||||
GestureDetector(
|
||||
key: const Key('copyPubkey'),
|
||||
key: keyCopyAddress,
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: address));
|
||||
snackCopyKey(context);
|
||||
|
@ -231,10 +231,10 @@ class WalletsProfilesProvider with ChangeNotifier {
|
|||
|
||||
Future addContact(G1WalletsList profile) async {
|
||||
// log.d(profile.username);
|
||||
if (isContact(profile.pubkey!)) {
|
||||
await contactsBox.delete(profile.pubkey);
|
||||
if (isContact(profile.address)) {
|
||||
await contactsBox.delete(profile.address);
|
||||
} else {
|
||||
await contactsBox.put(profile.pubkey, profile);
|
||||
await contactsBox.put(profile.address, profile);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// 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';
|
||||
|
@ -12,15 +15,14 @@ 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, this.avatar, this.username, Key? key})
|
||||
: super(key: key);
|
||||
ActivityScreen({required this.address, required this.avatar, this.username})
|
||||
: super(key: keyActivityScreen);
|
||||
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;
|
||||
|
@ -47,7 +49,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
),
|
||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
||||
body: Column(children: <Widget>[
|
||||
walletProfile.headerProfileView(context, address!, username),
|
||||
walletProfile.headerProfileView(context, address, username),
|
||||
historyQuery(context),
|
||||
]));
|
||||
}
|
||||
|
@ -87,7 +89,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
children: <Widget>[
|
||||
Query(
|
||||
options: QueryOptions(
|
||||
document: gql(getHistoryByAddressQ3),
|
||||
document: gql(getHistoryByAddressQ),
|
||||
variables: <String, dynamic>{
|
||||
'address': address,
|
||||
'number': 20,
|
||||
|
@ -124,7 +126,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
|
||||
|
@ -132,7 +134,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
child: Builder(
|
||||
builder: (context) => Expanded(
|
||||
child: ListView(
|
||||
key: const Key('listTransactions'),
|
||||
key: keyListTransactions,
|
||||
controller: scrollController,
|
||||
children: <Widget>[historyView(context, result)],
|
||||
),
|
||||
|
@ -193,6 +195,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
BuildContext context, DuniterIndexer duniterIndexer) {
|
||||
CesiumPlusProvider cesiumPlusProvider =
|
||||
Provider.of<CesiumPlusProvider>(context, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
String? dateDelimiter;
|
||||
String? lastDateDelimiter;
|
||||
|
@ -271,13 +274,25 @@ 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: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
|
||||
),
|
||||
),
|
||||
|
@ -286,7 +301,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
child:
|
||||
// Row(children: [Column(children: [],)],)
|
||||
ListTile(
|
||||
key: Key('transaction${keyID++}'),
|
||||
key: keyTransaction(keyID++),
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 20, right: 30, top: 15, bottom: 15),
|
||||
leading: ClipOval(
|
||||
|
@ -326,7 +341,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
],
|
||||
),
|
||||
),
|
||||
trailing: Text("${repository[3]} $currencyName",
|
||||
trailing: Text(finalAmount,
|
||||
style: const TextStyle(
|
||||
fontSize: 18, fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.justify),
|
||||
|
@ -338,7 +353,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return WalletViewScreen(pubkey: repository[1]);
|
||||
return WalletViewScreen(address: repository[1]);
|
||||
}),
|
||||
);
|
||||
// Navigator.pop(context);
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
@ -62,10 +63,10 @@ class CommonElements {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, backgroundColor: orangeC,
|
||||
elevation: 4, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
@ -159,8 +160,7 @@ class CommonElements {
|
|||
}
|
||||
|
||||
Widget offlineInfo(BuildContext context) {
|
||||
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
final double screenWidth = MediaQuery.of(context).size.width;
|
||||
final double screenWidth = MediaQuery.of(homeContext).size.width;
|
||||
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return Visibility(
|
||||
visible: !sub.nodeConnected,
|
||||
|
@ -174,7 +174,7 @@ class CommonElements {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Vous êtes hors ligne...",
|
||||
'youAreOffline'.tr(),
|
||||
style: TextStyle(color: Colors.grey[50]),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
@ -187,8 +187,8 @@ class CommonElements {
|
|||
}
|
||||
|
||||
class SmoothTransition extends PageRouteBuilder {
|
||||
final Widget? page;
|
||||
SmoothTransition({this.page})
|
||||
final Widget page;
|
||||
SmoothTransition({required 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: const Key('confirmPopop'),
|
||||
key: keyConfirm,
|
||||
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: const Key('infoPopup'),
|
||||
key: keyInfoPopup,
|
||||
child: const Text(
|
||||
"D'accord",
|
||||
style: TextStyle(
|
||||
|
|
|
@ -5,6 +5,7 @@ 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';
|
||||
|
@ -30,8 +31,8 @@ class HomeScreen extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
homeContext = context;
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context);
|
||||
Provider.of<ChestProvider>(context);
|
||||
|
@ -39,9 +40,6 @@ class HomeScreen extends StatelessWidget {
|
|||
|
||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
||||
|
||||
// sub.csToV2('test', 'test');
|
||||
// sub.getSs58Prefix();
|
||||
|
||||
isTall = false;
|
||||
ratio = 1;
|
||||
if (MediaQuery.of(context).size.height >= 930) {
|
||||
|
@ -56,7 +54,7 @@ class HomeScreen extends StatelessWidget {
|
|||
Expanded(
|
||||
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
|
||||
DrawerHeader(
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
color: orangeC,
|
||||
),
|
||||
child: Column(children: const <Widget>[
|
||||
|
@ -67,7 +65,7 @@ class HomeScreen extends StatelessWidget {
|
|||
]),
|
||||
),
|
||||
ListTile(
|
||||
key: const Key('parameters'),
|
||||
key: keyParameters,
|
||||
title: Text('parameters'.tr()),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -80,7 +78,7 @@ class HomeScreen extends StatelessWidget {
|
|||
},
|
||||
),
|
||||
ListTile(
|
||||
key: const Key('contacts'),
|
||||
key: keyContacts,
|
||||
title: Text('contactsManagement'.tr()),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -92,26 +90,6 @@ 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,
|
||||
|
@ -141,20 +119,22 @@ class HomeScreen extends StatelessWidget {
|
|||
await chestBox.clear();
|
||||
await configBox.delete('defaultWallet');
|
||||
await sub.deleteAllAccounts();
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
}
|
||||
|
||||
var connectivityResult =
|
||||
await (Connectivity().checkConnectivity());
|
||||
// var connectivityResult =
|
||||
// await (Connectivity().checkConnectivity());
|
||||
|
||||
// if (connectivityResult != ConnectivityResult.mobile &&
|
||||
// connectivityResult != ConnectivityResult.wifi) {
|
||||
// homeProvider.changeMessage(
|
||||
// "notConnectedToInternet".tr(), 0);
|
||||
// sub.nodeConnected = false;
|
||||
// }
|
||||
|
||||
// TODO: fix random bad network status on startup
|
||||
HomeProvider homeProvider =
|
||||
Provider.of<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 {
|
||||
|
@ -167,9 +147,9 @@ class HomeScreen extends StatelessWidget {
|
|||
sub.reload();
|
||||
} else {
|
||||
await sub.connectNode(ctx);
|
||||
await sub.initCurrencyParameters();
|
||||
}
|
||||
});
|
||||
// await sub.connectNode(ctx);
|
||||
}
|
||||
// _duniterIndexer.checkIndexerEndpointBackground();
|
||||
});
|
||||
|
@ -224,7 +204,7 @@ Widget geckHome(context) {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('drawerMenu'),
|
||||
key: keyDrawerMenu,
|
||||
icon: const Icon(
|
||||
Icons.menu,
|
||||
color: Colors.white,
|
||||
|
@ -305,6 +285,7 @@ Widget geckHome(context) {
|
|||
child: Material(
|
||||
color: orangeC, // button color
|
||||
child: InkWell(
|
||||
key: keyOpenSearch,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(18),
|
||||
child: Image(
|
||||
|
@ -347,7 +328,7 @@ Widget geckHome(context) {
|
|||
],
|
||||
),
|
||||
child: ClipOval(
|
||||
key: const Key('manageWallets'),
|
||||
key: keyOpenWalletsHomme,
|
||||
child: Material(
|
||||
color: orangeC, // button color
|
||||
child: InkWell(
|
||||
|
@ -470,7 +451,7 @@ Widget welcomeHome(context) {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('drawerMenu'),
|
||||
key: keyDrawerMenu,
|
||||
icon: const Icon(
|
||||
Icons.menu,
|
||||
color: Colors.white,
|
||||
|
@ -558,10 +539,10 @@ Widget welcomeHome(context) {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyOnboardingNewChest,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
@ -585,8 +566,9 @@ Widget welcomeHome(context) {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: OutlinedButton(
|
||||
key: keyRestoreChest,
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(width: 4, color: orangeC)),
|
||||
side: const BorderSide(width: 4, color: orangeC)),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -599,7 +581,7 @@ Widget welcomeHome(context) {
|
|||
},
|
||||
child: Text(
|
||||
"restoreWallet".tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
color: orangeC,
|
||||
fontWeight: FontWeight.w600),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
// ignore_for_file: use_build_context_synchronously, must_be_immutable
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -10,11 +10,9 @@ 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,
|
||||
|
@ -23,9 +21,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
|||
: super(key: keyMyWallets);
|
||||
final String? walletName;
|
||||
final MyWalletsProvider walletProvider;
|
||||
Directory? appPath;
|
||||
|
||||
TextEditingController newPin = TextEditingController();
|
||||
final TextEditingController newPin = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -102,9 +99,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
|||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 12,
|
||||
primary: Colors.green[400], //smoothYellow, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 12,
|
||||
backgroundColor: Colors.green[400], // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData defaultWallet =
|
||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||
|
@ -58,7 +59,7 @@ class ChestOptions extends StatelessWidget {
|
|||
child: Column(children: <Widget>[
|
||||
SizedBox(height: 30 * ratio),
|
||||
InkWell(
|
||||
key: const Key('showSeed'),
|
||||
key: keyShowSeed,
|
||||
onTap: () async {
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
@ -97,7 +98,7 @@ class ChestOptions extends StatelessWidget {
|
|||
const SizedBox(width: 15),
|
||||
Text(
|
||||
'displayMnemonic'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
color: orangeC,
|
||||
),
|
||||
|
@ -108,7 +109,7 @@ class ChestOptions extends StatelessWidget {
|
|||
SizedBox(height: 10 * ratio),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: const Key('changePin'),
|
||||
key: keyChangePin,
|
||||
onTap: sub.nodeConnected
|
||||
? () async {
|
||||
// await _chestProvider.changePin(context, cesiumWallet);
|
||||
|
@ -152,7 +153,7 @@ class ChestOptions extends StatelessWidget {
|
|||
SizedBox(height: 10 * ratio),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: const Key('createRootDerivation'),
|
||||
key: keycreateRootDerivation,
|
||||
onTap: sub.nodeConnected
|
||||
? () async {
|
||||
await Navigator.push(
|
||||
|
@ -188,7 +189,7 @@ class ChestOptions extends StatelessWidget {
|
|||
}),
|
||||
SizedBox(height: 10 * ratio),
|
||||
InkWell(
|
||||
key: const Key('deleteChest'),
|
||||
key: keyDeleteChest,
|
||||
onTap: () async {
|
||||
await chestProvider.deleteChest(context, currentChest);
|
||||
},
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
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';
|
||||
|
@ -22,7 +23,6 @@ class ChooseChest extends StatefulWidget {
|
|||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class _ChooseChestState extends State<ChooseChest> {
|
||||
TextEditingController tplController = TextEditingController();
|
||||
CarouselController buttonCarouselController = CarouselController();
|
||||
|
@ -111,15 +111,15 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
await configBox.put('currentChest', currentChest);
|
||||
myWalletProvider.pinCode = '';
|
||||
WalletData? defaultWallet =
|
||||
myWalletProvider.getDefaultWallet();
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
|
||||
await Navigator.push(
|
||||
context,
|
||||
|
@ -144,7 +144,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
},
|
||||
child: Text(
|
||||
'openThisChest'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
color: backgroundColor,
|
||||
fontWeight: FontWeight.w600),
|
||||
|
@ -156,7 +156,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: InkWell(
|
||||
key: const Key('createNewChest'),
|
||||
key: keyCreateNewChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -170,7 +170,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
height: 50,
|
||||
child: Center(
|
||||
child: Text('createChest'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
color: orangeC,
|
||||
fontWeight: FontWeight.w600))),
|
||||
|
@ -179,7 +179,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
),
|
||||
),
|
||||
InkWell(
|
||||
key: const Key('importChest'),
|
||||
key: keyImportChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -193,7 +193,7 @@ class _ChooseChestState extends State<ChooseChest> {
|
|||
height: 50,
|
||||
child: Center(
|
||||
child: Text('importChest'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
color: orangeC,
|
||||
fontWeight: FontWeight.w600))),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
// ignore_for_file: use_build_context_synchronously, must_be_immutable
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
|
@ -7,6 +7,7 @@ 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';
|
||||
|
@ -15,7 +16,6 @@ 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;
|
||||
|
@ -46,15 +46,13 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
width: 470,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirm,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
await sub.setCurrentWallet(selectedWallet!);
|
||||
|
||||
// _walletViewProvider.reload();
|
||||
sub.reload();
|
||||
|
||||
// Navigator.pop(context);
|
||||
|
@ -74,7 +72,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
));
|
||||
}
|
||||
|
||||
Widget myWalletsTiles(BuildContext context, int? currentChest) {
|
||||
Widget myWalletsTiles(BuildContext context, int currentChest) {
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context);
|
||||
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
@ -112,7 +110,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
return CustomScrollView(slivers: <Widget>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
||||
SliverGrid.count(
|
||||
key: const Key('listWallets'),
|
||||
key: keyListWallets,
|
||||
crossAxisCount: nTule,
|
||||
childAspectRatio: 1,
|
||||
crossAxisSpacing: 0,
|
||||
|
@ -122,9 +120,10 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
key: keySelectThisWallet(repository.address!),
|
||||
onTap: () {
|
||||
selectedWallet = repository;
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
},
|
||||
child: ClipOvalShadow(
|
||||
shadow: const Shadow(
|
||||
|
@ -201,7 +200,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
),
|
||||
onTap: () async {
|
||||
selectedWallet = repository;
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
},
|
||||
)
|
||||
]),
|
||||
|
@ -217,7 +216,7 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
width: double.infinity,
|
||||
color: isDefault ? orangeC : yellowC,
|
||||
child: SizedBox(
|
||||
height: 25,
|
||||
height: 30,
|
||||
child: Column(children: [
|
||||
const Spacer(),
|
||||
// Text(
|
||||
|
@ -225,7 +224,10 @@ class ChooseWalletScreen extends StatelessWidget {
|
|||
// textAlign: TextAlign.center,
|
||||
// style: TextStyle(color: isDefault ? Colors.white : Colors.black),
|
||||
// ),
|
||||
balance(context, address, 15, isDefault ? Colors.white : Colors.black)
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
balance(
|
||||
context, address, 16, isDefault ? Colors.white : Colors.black),
|
||||
])
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -72,7 +72,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
|||
menuMaxHeight: 300,
|
||||
icon: const Icon(Icons.arrow_downward),
|
||||
elevation: 16,
|
||||
style: TextStyle(color: orangeC),
|
||||
style: const TextStyle(color: orangeC),
|
||||
underline: Container(
|
||||
height: 2,
|
||||
color: orangeC,
|
||||
|
@ -107,9 +107,8 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
|||
height: 70,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () async {
|
||||
WalletData? defaultWallet =
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
// 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 = '';
|
||||
}
|
||||
}
|
|
@ -1,6 +1,18 @@
|
|||
// 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';
|
||||
|
@ -16,77 +28,140 @@ class ManageMembership extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
|
||||
final sub = Provider.of<SubstrateSdk>(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 60 * ratio,
|
||||
title: const SizedBox(
|
||||
title: SizedBox(
|
||||
height: 22,
|
||||
child: Text('manageMembership'),
|
||||
child: const Text('manageMembership').tr(),
|
||||
)),
|
||||
body: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
const SizedBox(height: 20),
|
||||
revokeMyIdentity(context),
|
||||
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);
|
||||
}
|
||||
})
|
||||
// const SizedBox(height: 20),
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
||||
Widget revokeMyIdentity(BuildContext context) {
|
||||
Widget migrateIdentity(BuildContext context) {
|
||||
return InkWell(
|
||||
key: const Key('revokeIdty'),
|
||||
key: keyMigrateIdentity,
|
||||
onTap: () async {
|
||||
// TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options
|
||||
// final _answer = await confirmPopup(context,
|
||||
// 'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
|
||||
// false;
|
||||
|
||||
// if (_answer) {
|
||||
// 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!);
|
||||
|
||||
// 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 const TransactionInProgress(transType: 'revokeIdty');
|
||||
// }),
|
||||
// );
|
||||
// }
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const MigrateIdentityScreen();
|
||||
}),
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 60,
|
||||
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)),
|
||||
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,
|
||||
onTap: () async {
|
||||
// TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options
|
||||
final answer = await confirmPopup(context,
|
||||
'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
|
||||
false;
|
||||
|
||||
if (answer) {
|
||||
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!);
|
||||
|
||||
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));
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
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)),
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
// 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]),
|
||||
)
|
||||
]);
|
||||
});
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ 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';
|
||||
|
@ -49,110 +50,114 @@ class RestoreChest extends StatelessWidget {
|
|||
child: Text('restoreAChest'.tr()),
|
||||
)),
|
||||
body: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
SizedBox(height: isTall ? 30 : 15),
|
||||
bubbleSpeak('toRestoreEnterMnemonic'.tr()),
|
||||
SizedBox(height: isTall ? 30 : 15),
|
||||
child: Stack(children: [
|
||||
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(
|
||||
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 ? 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),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// 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),
|
||||
),
|
||||
],
|
||||
)),
|
||||
)
|
||||
])
|
||||
// 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),
|
||||
]),
|
||||
),
|
||||
),
|
||||
|
@ -169,7 +174,7 @@ class RestoreChest extends StatelessWidget {
|
|||
color: Colors.white,
|
||||
child: Text(
|
||||
text,
|
||||
key: const Key('importText'),
|
||||
key: keyBubbleSpeak,
|
||||
textAlign: TextAlign.justify,
|
||||
style: const TextStyle(
|
||||
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400),
|
||||
|
|
|
@ -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';
|
||||
|
@ -49,7 +49,7 @@ class ShowSeed extends StatelessWidget {
|
|||
builder: (BuildContext context, AsyncSnapshot<String?> seed) {
|
||||
if (seed.connectionState != ConnectionState.done ||
|
||||
seed.hasError) {
|
||||
return SizedBox(
|
||||
return const SizedBox(
|
||||
height: 15,
|
||||
width: 15,
|
||||
child: CircularProgressIndicator(
|
||||
|
@ -73,12 +73,12 @@ class ShowSeed extends StatelessWidget {
|
|||
height: 40,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
elevation: 1,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
backgroundColor: orangeC,
|
||||
elevation: 1, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
|
@ -123,9 +123,8 @@ class ShowSeed extends StatelessWidget {
|
|||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
|
@ -206,7 +205,7 @@ class ShowSeed extends StatelessWidget {
|
|||
),
|
||||
Text(
|
||||
dataWord,
|
||||
key: Key('word$dataWord'),
|
||||
key: keyMnemonicWord(dataWord),
|
||||
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
|
||||
),
|
||||
]),
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
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),
|
||||
]),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
// 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: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';
|
||||
|
@ -12,18 +16,15 @@ 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({Key? keyUnlockWallet, required this.wallet})
|
||||
: super(key: keyUnlockWallet);
|
||||
WalletData? wallet;
|
||||
UnlockingWallet({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 = '';
|
||||
|
||||
|
@ -37,7 +38,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
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(
|
||||
|
@ -52,7 +53,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
left: 15,
|
||||
child: Builder(
|
||||
builder: (context) => IconButton(
|
||||
key: const Key('popButton'),
|
||||
key: keyPopButton,
|
||||
icon: const Icon(
|
||||
Icons.arrow_back,
|
||||
color: Colors.black,
|
||||
|
@ -103,6 +104,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
SizedBox(height: 3 * ratio),
|
||||
if (canUnlock)
|
||||
InkWell(
|
||||
key: keyCachePassword,
|
||||
onTap: () {
|
||||
walletOptions.changePinCacheChoice();
|
||||
},
|
||||
|
@ -127,7 +129,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
const SizedBox(height: 10),
|
||||
// if (canUnlock)
|
||||
InkWell(
|
||||
key: const Key('chooseChest'),
|
||||
key: keyChangeChest,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -142,7 +144,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
child: Center(
|
||||
child: Text(
|
||||
'changeChest'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
color: orangeC,
|
||||
fontWeight: FontWeight.w600),
|
||||
|
@ -182,10 +184,11 @@ class UnlockingWallet extends StatelessWidget {
|
|||
}
|
||||
|
||||
return Form(
|
||||
key: formKey,
|
||||
// key: keyPinForm,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30),
|
||||
child: PinCodeTextField(
|
||||
key: keyPinForm,
|
||||
focusNode: pinFocus,
|
||||
autoFocus: true,
|
||||
appContext: context,
|
||||
|
@ -213,6 +216,7 @@ 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),
|
||||
|
@ -239,7 +243,7 @@ class UnlockingWallet extends StatelessWidget {
|
|||
.shake); // Triggering error shake animation
|
||||
pinColor = Colors.red[600];
|
||||
myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
|
||||
walletOptions.reloadBuild();
|
||||
walletOptions.reload();
|
||||
pinFocus.requestFocus();
|
||||
} else {
|
||||
pinColor = Colors.green[400];
|
||||
|
|
|
@ -3,6 +3,7 @@ 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';
|
||||
|
@ -37,6 +38,10 @@ class WalletOptions extends StatelessWidget {
|
|||
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);
|
||||
|
||||
final int currentChest = myWalletProvider.getCurrentChest();
|
||||
|
@ -49,7 +54,7 @@ class WalletOptions extends StatelessWidget {
|
|||
onWillPop: () {
|
||||
walletOptions.isEditing = false;
|
||||
walletOptions.isBalanceBlur = false;
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
Navigator.pop(context);
|
||||
return Future<bool>.value(true);
|
||||
},
|
||||
|
@ -64,7 +69,7 @@ class WalletOptions extends StatelessWidget {
|
|||
onPressed: () {
|
||||
walletOptions.isEditing = false;
|
||||
walletOptions.isBalanceBlur = false;
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
title: SizedBox(
|
||||
|
@ -106,7 +111,7 @@ class WalletOptions extends StatelessWidget {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, walletProvider, _) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
|
@ -181,6 +186,7 @@ class WalletOptions extends StatelessWidget {
|
|||
Consumer<WalletOptionsProvider>(
|
||||
builder: (context, walletProvider, _) {
|
||||
return Column(children: [
|
||||
confirmIdentityButton(walletProvider),
|
||||
pubkeyWidget(walletProvider, ctx),
|
||||
SizedBox(height: 10 * ratio),
|
||||
activityWidget(
|
||||
|
@ -212,7 +218,7 @@ class WalletOptions extends StatelessWidget {
|
|||
else
|
||||
const SizedBox(),
|
||||
if (isMember.data!)
|
||||
manageMemberStatus(context)
|
||||
manageMembership(context)
|
||||
]);
|
||||
}),
|
||||
]);
|
||||
|
@ -239,7 +245,7 @@ class WalletOptions extends StatelessWidget {
|
|||
wallet.imageCustomPath = newPath;
|
||||
walletBox.put(wallet.key, wallet);
|
||||
}
|
||||
walletProvider.reloadBuild();
|
||||
walletProvider.reload();
|
||||
},
|
||||
child: wallet.imageCustomPath == null || wallet.imageCustomPath == ''
|
||||
? Image.asset(
|
||||
|
@ -267,7 +273,7 @@ class WalletOptions extends StatelessWidget {
|
|||
child: InkWell(
|
||||
onTap: () async {
|
||||
wallet.imageCustomPath = await (walletProvider.changeAvatar());
|
||||
walletProvider.reloadBuild();
|
||||
walletProvider.reload();
|
||||
},
|
||||
child: Image.asset(
|
||||
'assets/walletOptions/camera.png',
|
||||
|
@ -279,10 +285,61 @@ 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: const Key('copyPubkey'),
|
||||
key: keyCopyAddress,
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: walletProvider.address.text));
|
||||
snackCopyKey(ctx);
|
||||
|
@ -307,12 +364,12 @@ class WalletOptions extends StatelessWidget {
|
|||
height: 40,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.black,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
elevation: 1,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
backgroundColor: orangeC,
|
||||
elevation: 1, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
|
@ -342,7 +399,7 @@ class WalletOptions extends StatelessWidget {
|
|||
WalletsProfilesProvider historyProvider,
|
||||
WalletOptionsProvider walletProvider) {
|
||||
return InkWell(
|
||||
key: const Key('displayActivity'),
|
||||
key: keyOpenActivity,
|
||||
onTap: () {
|
||||
// _historyProvider.nPage = 1;
|
||||
Navigator.push(
|
||||
|
@ -379,11 +436,11 @@ class WalletOptions extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget manageMemberStatus(BuildContext context) {
|
||||
Widget manageMembership(BuildContext context) {
|
||||
WalletOptionsProvider walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||
return InkWell(
|
||||
key: const Key('manageStatus'),
|
||||
key: keyManageMembership,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -419,7 +476,7 @@ class WalletOptions extends StatelessWidget {
|
|||
WalletData defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]);
|
||||
return InkWell(
|
||||
key: const Key('setDefaultWallet'),
|
||||
key: keySetDefaultWallet,
|
||||
onTap: !walletProvider.isDefaultWallet
|
||||
? () async {
|
||||
await setDefaultWallet(context, currentChest);
|
||||
|
@ -464,8 +521,8 @@ class WalletOptions extends StatelessWidget {
|
|||
// defaultWallet = wallet;
|
||||
await sub.setCurrentWallet(wallet);
|
||||
myWalletProvider.readAllWallets(currentChest);
|
||||
myWalletProvider.rebuildWidget();
|
||||
walletOptions.reloadBuild();
|
||||
myWalletProvider.reload();
|
||||
walletOptions.reload();
|
||||
}
|
||||
|
||||
Widget deleteWallet(BuildContext context,
|
||||
|
@ -492,14 +549,14 @@ class WalletOptions extends StatelessWidget {
|
|||
!hasConsumers.data! &&
|
||||
(balance > 2 || balance == 0);
|
||||
return InkWell(
|
||||
key: const Key('deleteWallet'),
|
||||
key: keyDeleteWallet,
|
||||
onTap: canDelete
|
||||
? () async {
|
||||
await walletProvider.deleteWallet(context, wallet);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
myWalletProvider.listWallets =
|
||||
myWalletProvider.readAllWallets(currentChest);
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
});
|
||||
}
|
||||
: null,
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
// 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';
|
||||
|
@ -14,8 +18,10 @@ 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 {
|
||||
|
@ -36,7 +42,6 @@ class WalletsHome extends StatelessWidget {
|
|||
|
||||
return WillPopScope(
|
||||
onWillPop: () {
|
||||
// myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
|
||||
Navigator.popUntil(
|
||||
context,
|
||||
ModalRoute.withName('/'),
|
||||
|
@ -51,36 +56,65 @@ 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!,
|
||||
key: const Key('myWallets'),
|
||||
style: TextStyle(color: Colors.grey[850])),
|
||||
backgroundColor: const Color(0xffFFD58D),
|
||||
),
|
||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
||||
bottomNavigationBar: myWalletProvider.lastFlyBy == ''
|
||||
? homeProvider.bottomAppBar(context)
|
||||
: dragInfo(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) {
|
||||
return Column(children: [
|
||||
const SizedBox(height: 50),
|
||||
SizedBox(
|
||||
height: 90,
|
||||
height: 80,
|
||||
width: 420,
|
||||
child: ElevatedButton.icon(
|
||||
icon: Image.asset(
|
||||
|
@ -88,9 +122,8 @@ class WalletsHome extends StatelessWidget {
|
|||
height: 60,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 2,
|
||||
primary: floattingYellow, // background
|
||||
onPrimary: Colors.black, // foreground
|
||||
foregroundColor: Colors.black, elevation: 2,
|
||||
backgroundColor: floattingYellow, // foreground
|
||||
),
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
|
@ -109,7 +142,29 @@ class WalletsHome extends StatelessWidget {
|
|||
)),
|
||||
const SizedBox(height: 30),
|
||||
InkWell(
|
||||
key: const Key('changeChest'),
|
||||
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,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -120,10 +175,10 @@ class WalletsHome extends StatelessWidget {
|
|||
},
|
||||
child: SizedBox(
|
||||
width: 400,
|
||||
height: 50,
|
||||
height: 60,
|
||||
child: Center(
|
||||
child: Text('changeChest'.tr(),
|
||||
style: TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
color: orangeC,
|
||||
fontWeight: FontWeight.w500))),
|
||||
|
@ -139,6 +194,7 @@ class WalletsHome extends StatelessWidget {
|
|||
WalletOptionsProvider walletOptions =
|
||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
||||
if (!isWalletsExists) {
|
||||
return const Text('');
|
||||
|
@ -165,104 +221,156 @@ 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: const Key('listWallets'),
|
||||
key: keyListWallets,
|
||||
crossAxisCount: nTule,
|
||||
childAspectRatio: 1,
|
||||
crossAxisSpacing: 0,
|
||||
mainAxisSpacing: 0,
|
||||
children: <Widget>[
|
||||
for (WalletData repository in listWallets as Iterable<WalletData>)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
walletOptions.getAddress(
|
||||
currentChestNumber, repository.derivation!);
|
||||
Navigator.push(
|
||||
context,
|
||||
SmoothTransition(
|
||||
page: WalletOptions(
|
||||
wallet: repository,
|
||||
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),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
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),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
),
|
||||
)),
|
||||
}),
|
||||
),
|
||||
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: Spacer()),
|
||||
SliverToBoxAdapter(child: chestOptions(context, myWalletProvider)),
|
||||
]);
|
||||
}
|
||||
|
@ -273,12 +381,17 @@ class WalletsHome extends StatelessWidget {
|
|||
color: isDefault ? orangeC : yellowC,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 5, right: 5, top: 38),
|
||||
child: balance(
|
||||
context,
|
||||
address,
|
||||
15,
|
||||
isDefault ? Colors.white : Colors.black,
|
||||
isDefault ? yellowC : orangeC)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
balance(
|
||||
context,
|
||||
address,
|
||||
15,
|
||||
isDefault ? Colors.white : Colors.black,
|
||||
isDefault ? yellowC : orangeC)
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -291,14 +404,9 @@ class WalletsHome extends StatelessWidget {
|
|||
return 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.only(left: 5, right: 5, bottom: 35, top: 5),
|
||||
|
@ -313,13 +421,7 @@ class WalletsHome extends StatelessWidget {
|
|||
: Colors.black),
|
||||
),
|
||||
),
|
||||
// dense: true,
|
||||
onTap: () {
|
||||
// _walletOptions.readLocalWallet(
|
||||
// context,
|
||||
// _repository,
|
||||
// _myWalletProvider.pinCode,
|
||||
// pinLength);
|
||||
walletOptions.getAddress(currentChestNumber, repository.derivation!);
|
||||
Navigator.push(
|
||||
context,
|
||||
|
@ -346,7 +448,7 @@ class WalletsHome extends StatelessWidget {
|
|||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
key: const Key('addDerivation'),
|
||||
key: keyAddDerivation,
|
||||
onTap: () async {
|
||||
if (!myWalletProvider.isNewDerivationLoading) {
|
||||
WalletData? defaultWallet =
|
||||
|
@ -371,10 +473,10 @@ class WalletsHome extends StatelessWidget {
|
|||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
decoration: BoxDecoration(color: floattingYellow),
|
||||
decoration: const BoxDecoration(color: floattingYellow),
|
||||
child: Center(
|
||||
child: myWalletProvider.isNewDerivationLoading
|
||||
? SizedBox(
|
||||
? const SizedBox(
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: CircularProgressIndicator(
|
||||
|
@ -395,12 +497,6 @@ 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) {
|
||||
|
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
@ -28,7 +29,6 @@ class ContactsScreen extends StatelessWidget {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
|
||||
final myContacts = contactsBox.toMap().values.toList();
|
||||
|
@ -71,13 +71,13 @@ class ContactsScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult('keyID++'),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider
|
||||
.defaultAvatar(avatarSize),
|
||||
title: Row(children: <Widget>[
|
||||
Text(getShortPubkey(g1Wallet.pubkey!),
|
||||
Text(getShortPubkey(g1Wallet.address),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Monospace',
|
||||
|
@ -87,11 +87,25 @@ class ContactsScreen extends StatelessWidget {
|
|||
trailing: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
balance(context, g1Wallet.pubkey!, 16)
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
balance(context,
|
||||
g1Wallet.address, 16),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
subtitle: Row(children: <Widget>[
|
||||
duniterIndexer.getNameByAddress(
|
||||
context, g1Wallet.pubkey!)
|
||||
context, g1Wallet.address)
|
||||
]),
|
||||
dense: false,
|
||||
isThreeLine: false,
|
||||
|
@ -100,15 +114,15 @@ class ContactsScreen extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
walletsProfilesClass.address =
|
||||
g1Wallet.pubkey;
|
||||
g1Wallet.address;
|
||||
return WalletViewScreen(
|
||||
pubkey: g1Wallet.pubkey,
|
||||
address: g1Wallet.address,
|
||||
username: g1WalletsBox
|
||||
.get(g1Wallet.pubkey)
|
||||
.get(g1Wallet.address)
|
||||
?.id
|
||||
?.username,
|
||||
avatar: g1WalletsBox
|
||||
.get(g1Wallet.pubkey)
|
||||
.get(g1Wallet.address)
|
||||
?.avatar,
|
||||
);
|
||||
}),
|
||||
|
|
|
@ -27,15 +27,18 @@ class OnboardingStepOne extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(
|
||||
context,
|
||||
'geckoGenerateYourWalletFromMnemonic'.tr(),
|
||||
'fabrication-de-portefeuille.png',
|
||||
'>',
|
||||
const OnboardingStepTwo(),
|
||||
0,
|
||||
isMd: true,
|
||||
),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(
|
||||
context,
|
||||
'geckoGenerateYourWalletFromMnemonic'.tr(),
|
||||
'fabrication-de-portefeuille.png',
|
||||
'>',
|
||||
const OnboardingStepTwo(),
|
||||
0,
|
||||
isMd: true,
|
||||
),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// 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';
|
||||
|
@ -15,7 +18,6 @@ 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);
|
||||
|
@ -49,79 +51,83 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
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.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),
|
||||
SizedBox(
|
||||
height: 22,
|
||||
width: 22,
|
||||
child: CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 3,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
]);
|
||||
}),
|
||||
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),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'rememberPassword'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: Colors.grey[700]),
|
||||
),
|
||||
const Spacer()
|
||||
]))
|
||||
: const Text('');
|
||||
}),
|
||||
const SizedBox(height: 10),
|
||||
]),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
@ -146,7 +152,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
|
||||
child: PinCodeTextField(
|
||||
key: const Key('formKey2'),
|
||||
key: keyPinForm,
|
||||
autoFocus: true,
|
||||
appContext: context,
|
||||
pastedTextStyle: TextStyle(
|
||||
|
@ -173,6 +179,7 @@ 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),
|
||||
|
@ -217,10 +224,11 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
await walletBox.add(myWallet);
|
||||
}
|
||||
myWalletProvider.readAllWallets(currentChest);
|
||||
myWalletProvider.rebuildWidget();
|
||||
myWalletProvider.reload();
|
||||
|
||||
generateWalletProvider.generatedMnemonic = '';
|
||||
myWalletProvider.resetPinCode();
|
||||
// sleep(const Duration(milliseconds: 500));
|
||||
Navigator.push(
|
||||
context,
|
||||
FaderTransition(
|
||||
|
@ -231,7 +239,7 @@ class OnboardingStepTen extends StatelessWidget {
|
|||
.shake); // Triggering error shake animation
|
||||
hasError = true;
|
||||
pinColor = Colors.red[600];
|
||||
walletOptions.reloadBuild();
|
||||
walletOptions.reload();
|
||||
}
|
||||
},
|
||||
onChanged: (value) {
|
||||
|
|
|
@ -4,10 +4,9 @@ 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);
|
||||
|
||||
|
@ -54,20 +53,28 @@ Widget finishButton(BuildContext context) {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: const Key('goWalletHome'),
|
||||
key: keyGoWalletsHome,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC,
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const WalletsHome();
|
||||
}),
|
||||
ModalRoute.withName('/'),
|
||||
);
|
||||
//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('/'));
|
||||
},
|
||||
child: Text("accessMyChest".tr(),
|
||||
style:
|
||||
|
|
|
@ -29,13 +29,16 @@ class OnboardingStepTwo extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(
|
||||
context,
|
||||
'keepThisMnemonicSecure'.tr(),
|
||||
'fabrication-de-portefeuille-impossible-sans-phrase.png',
|
||||
'>',
|
||||
const OnboardingStepThree(),
|
||||
1),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(
|
||||
context,
|
||||
'keepThisMnemonicSecure'.tr(),
|
||||
'fabrication-de-portefeuille-impossible-sans-phrase.png',
|
||||
'>',
|
||||
const OnboardingStepThree(),
|
||||
1),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,8 +29,11 @@ class OnboardingStepThree extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(context, 'warningForgotPassword'.tr(),
|
||||
'forgot_password.png'.tr(), '>', const OnboardingStepFor(), 2),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(context, 'warningForgotPassword'.tr(),
|
||||
'forgot_password.png'.tr(), '>', const OnboardingStepFor(), 2),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,14 +29,17 @@ class OnboardingStepFor extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(
|
||||
context,
|
||||
'itsTimeToUseAPenAndPaper'.tr(),
|
||||
'gecko_also_can_forget.png'.tr(),
|
||||
'>',
|
||||
const OnboardingStepFive(),
|
||||
3,
|
||||
isMd: true),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(
|
||||
context,
|
||||
'itsTimeToUseAPenAndPaper'.tr(),
|
||||
'gecko_also_can_forget.png'.tr(),
|
||||
'>',
|
||||
const OnboardingStepFive(),
|
||||
3,
|
||||
isMd: true),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ 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';
|
||||
|
@ -48,57 +49,62 @@ class _ChooseChestState extends State<OnboardingStepFive> {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
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))),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 22 * ratio),
|
||||
nextButton(context, "iNotedMyMnemonic".tr(), false, widget.skipIntro),
|
||||
SizedBox(height: 35 * ratio),
|
||||
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),
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
@ -169,14 +175,13 @@ Widget arrayCell(dataWord) {
|
|||
),
|
||||
Text(
|
||||
dataWord.split(':')[1],
|
||||
key: Key('word${dataWord.split(':')[0]}'),
|
||||
key: keyMnemonicWord(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);
|
||||
|
||||
|
@ -225,10 +230,10 @@ Widget nextButton(
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt();
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
// 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})
|
||||
|
@ -51,164 +52,98 @@ class OnboardingStepSix extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
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),
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Visibility(
|
||||
// visible: !_generateWalletProvider.isAskedWordValid,
|
||||
// child: const Expanded(
|
||||
// child: Align(
|
||||
// alignment: Alignment.bottomCenter,
|
||||
// child: Text(''),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
SizedBox(height: 35 * ratio),
|
||||
]),
|
||||
),
|
||||
// Visibility(
|
||||
// visible: !_generateWalletProvider.isAskedWordValid,
|
||||
// child: const Expanded(
|
||||
// child: Align(
|
||||
// alignment: Alignment.bottomCenter,
|
||||
// child: Text(''),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
SizedBox(height: 35 * ratio),
|
||||
]),
|
||||
),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 =
|
||||
Provider.of<GenerateWalletsProvider>(context, listen: false);
|
||||
|
@ -220,10 +155,10 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyGoNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
|
|
|
@ -29,14 +29,17 @@ class OnboardingStepSeven extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(
|
||||
context,
|
||||
'geckoWillGenerateAPassword'.tr(),
|
||||
'coffre-fort-code-secret-dans-telephone.png',
|
||||
'>',
|
||||
OnboardingStepEight(scanDerivation: scanDerivation),
|
||||
6,
|
||||
boxHeight: 400),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(
|
||||
context,
|
||||
'geckoWillGenerateAPassword'.tr(),
|
||||
'coffre-fort-code-secret-dans-telephone.png',
|
||||
'>',
|
||||
OnboardingStepEight(scanDerivation: scanDerivation),
|
||||
6,
|
||||
boxHeight: 400),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,14 +29,17 @@ class OnboardingStepEight extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
child: common.infoIntro(
|
||||
context,
|
||||
'thisPasswordProtectsYourWalletsInASecureChest'.tr(),
|
||||
'coffre-fort-protege-les-portefeuilles.png',
|
||||
'>',
|
||||
OnboardingStepNine(scanDerivation: scanDerivation),
|
||||
7,
|
||||
isMd: true),
|
||||
child: Stack(children: [
|
||||
common.infoIntro(
|
||||
context,
|
||||
'thisPasswordProtectsYourWalletsInASecureChest'.tr(),
|
||||
'coffre-fort-protege-les-portefeuilles.png',
|
||||
'>',
|
||||
OnboardingStepNine(scanDerivation: scanDerivation),
|
||||
7,
|
||||
isMd: true),
|
||||
CommonElements().offlineInfo(context),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -41,61 +41,66 @@ class OnboardingStepNine extends StatelessWidget {
|
|||
),
|
||||
extendBodyBehindAppBar: true,
|
||||
body: SafeArea(
|
||||
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),
|
||||
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),
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -6,7 +8,6 @@ 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();
|
||||
|
||||
|
@ -23,7 +24,7 @@ class QrCodeFullscreen extends StatelessWidget {
|
|||
backgroundColor: color ?? Colors.black,
|
||||
toolbarHeight: 60 * ratio,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back, color: orangeC),
|
||||
icon: const Icon(Icons.arrow_back, color: orangeC),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
|
@ -31,7 +32,7 @@ class QrCodeFullscreen extends StatelessWidget {
|
|||
height: 22,
|
||||
child: Text(
|
||||
'QR Code de ${getShortPubkey(address)}',
|
||||
style: TextStyle(color: orangeC),
|
||||
style: const TextStyle(color: orangeC),
|
||||
),
|
||||
)),
|
||||
body: SafeArea(
|
||||
|
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
@ -51,11 +52,12 @@ class SearchScreen extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
child: TextField(
|
||||
key: keySearchField,
|
||||
controller: searchProvider.searchController,
|
||||
autofocus: true,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.left,
|
||||
onChanged: (v) => searchProvider.rebuildWidget(),
|
||||
onChanged: (v) => searchProvider.reload(),
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
|
@ -91,10 +93,10 @@ class SearchScreen extends StatelessWidget {
|
|||
width: 410,
|
||||
height: 70,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirmSearch,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: searchProvider.searchController.text.length >= 2
|
||||
? () {
|
||||
|
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
@ -31,7 +32,6 @@ class SearchResultScreen extends StatelessWidget {
|
|||
DuniterIndexer duniterIndexer =
|
||||
Provider.of<DuniterIndexer>(context, listen: false);
|
||||
|
||||
int keyID = 0;
|
||||
double avatarSize = 55;
|
||||
|
||||
return Scaffold(
|
||||
|
@ -48,7 +48,7 @@ class SearchResultScreen extends StatelessWidget {
|
|||
body: SafeArea(
|
||||
child: Stack(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
padding: const EdgeInsets.only(left: 15, right: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
|
@ -94,13 +94,13 @@ class SearchResultScreen extends StatelessWidget {
|
|||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ListTile(
|
||||
key: Key('searchResult${keyID++}'),
|
||||
key: keySearchResult(g1Wallet.address),
|
||||
horizontalTitleGap: 40,
|
||||
contentPadding: const EdgeInsets.all(5),
|
||||
leading: cesiumPlusProvider
|
||||
.defaultAvatar(avatarSize),
|
||||
title: Row(children: <Widget>[
|
||||
Text(getShortPubkey(g1Wallet.pubkey!),
|
||||
Text(getShortPubkey(g1Wallet.address),
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontFamily: 'Monospace',
|
||||
|
@ -111,12 +111,28 @@ class SearchResultScreen extends StatelessWidget {
|
|||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
balance(
|
||||
context, g1Wallet.pubkey!, 16)
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.center,
|
||||
children: [
|
||||
balance(
|
||||
context,
|
||||
g1Wallet.address,
|
||||
16),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
]),
|
||||
subtitle: Row(children: <Widget>[
|
||||
duniterIndexer.getNameByAddress(
|
||||
context, g1Wallet.pubkey!)
|
||||
context, g1Wallet.address)
|
||||
]),
|
||||
dense: false,
|
||||
isThreeLine: false,
|
||||
|
@ -125,15 +141,15 @@ class SearchResultScreen extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
walletsProfilesClass.address =
|
||||
g1Wallet.pubkey;
|
||||
g1Wallet.address;
|
||||
return WalletViewScreen(
|
||||
pubkey: g1Wallet.pubkey,
|
||||
address: g1Wallet.address,
|
||||
username: g1WalletsBox
|
||||
.get(g1Wallet.pubkey)
|
||||
.get(g1Wallet.address)
|
||||
?.id
|
||||
?.username,
|
||||
avatar: g1WalletsBox
|
||||
.get(g1Wallet.pubkey)
|
||||
.get(g1Wallet.address)
|
||||
?.avatar,
|
||||
);
|
||||
}),
|
||||
|
@ -144,7 +160,7 @@ class SearchResultScreen extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
return Center(
|
||||
return const Center(
|
||||
heightFactor: 5,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 3,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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 'package:gecko/globals.dart';
|
||||
import 'package:polkawallet_sdk/api/types/networkParams.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
// import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SettingsScreen extends StatelessWidget {
|
||||
final MyWalletsProvider _myWallets = MyWalletsProvider();
|
||||
|
||||
|
@ -34,9 +34,21 @@ class SettingsScreen extends StatelessWidget {
|
|||
)),
|
||||
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: 50),
|
||||
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(),
|
||||
|
@ -45,7 +57,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
width: buttonWidth,
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
key: const Key('deleteChest'),
|
||||
key: keyDeleteAllWallets,
|
||||
onTap: () async {
|
||||
log.i('Oublier tous mes coffres');
|
||||
await _myWallets.deleteAllWallet(context);
|
||||
|
@ -67,6 +79,36 @@ class SettingsScreen extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -115,11 +157,14 @@ class SettingsScreen extends StatelessWidget {
|
|||
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,
|
||||
|
@ -127,6 +172,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
items: duniterBootstrapNodes
|
||||
.map((NetworkParams endpointParams) {
|
||||
return DropdownMenuItem(
|
||||
key: keySelectDuniterNode(endpointParams.endpoint!),
|
||||
value: endpointParams.endpoint,
|
||||
child: Text(endpointParams.endpoint!),
|
||||
);
|
||||
|
@ -142,9 +188,10 @@ class SettingsScreen extends StatelessWidget {
|
|||
),
|
||||
const Spacer(flex: 5),
|
||||
sub.isLoadingEndpoint
|
||||
? CircularProgressIndicator(color: orangeC)
|
||||
? const CircularProgressIndicator(color: orangeC)
|
||||
: Consumer<SettingsProvider>(builder: (context, set, _) {
|
||||
return IconButton(
|
||||
key: keyConnectToEndpoint,
|
||||
icon: Icon(
|
||||
Icons.send,
|
||||
color: selectedDuniterEndpoint !=
|
||||
|
@ -185,6 +232,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
width: 200,
|
||||
height: 50,
|
||||
child: TextField(
|
||||
key: keyCustomDuniterEndpoint,
|
||||
controller: endpointController,
|
||||
autocorrect: false,
|
||||
),
|
||||
|
@ -283,7 +331,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
),
|
||||
const Spacer(flex: 5),
|
||||
indexer.isLoadingIndexer
|
||||
? CircularProgressIndicator(color: orangeC)
|
||||
? const CircularProgressIndicator(color: orangeC)
|
||||
: Consumer<SettingsProvider>(builder: (context, set, _) {
|
||||
return IconButton(
|
||||
icon: Icon(
|
||||
|
|
|
@ -2,6 +2,7 @@ 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';
|
||||
|
@ -9,11 +10,13 @@ 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'})
|
||||
const TransactionInProgress(
|
||||
{Key? key, this.transType = 'pay', this.fromAddress, this.toAddress})
|
||||
: super(key: key);
|
||||
final String transType;
|
||||
final String? fromAddress;
|
||||
final String? toAddress;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -30,12 +33,15 @@ class TransactionInProgress extends StatelessWidget {
|
|||
// Map jsonResult;
|
||||
final result = sub.transactionStatus;
|
||||
|
||||
log.d(walletViewProvider.address!);
|
||||
// sub.spawnBlock();
|
||||
|
||||
final from = myWalletProvider.getDefaultWallet().name!;
|
||||
final to = getShortPubkey(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;
|
||||
|
||||
switch (transType) {
|
||||
case 'pay':
|
||||
|
@ -58,6 +64,11 @@ class TransactionInProgress extends StatelessWidget {
|
|||
actionName = "revokeAdhesion".tr();
|
||||
}
|
||||
break;
|
||||
case 'identityMigration':
|
||||
{
|
||||
actionName = "identityMigration".tr();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
actionName = 'strangeTransaction'.tr();
|
||||
|
@ -88,9 +99,11 @@ class TransactionInProgress extends StatelessWidget {
|
|||
if (result.contains('blockHash: ')) {
|
||||
isValid = true;
|
||||
resultText = 'extrinsicValidated'.tr(args: [actionName]);
|
||||
log.i(
|
||||
'g1migration Bloc of last transaction: ${sub.blocNumber} --- $result');
|
||||
} else {
|
||||
isValid = false;
|
||||
resultText = "${"anErrorOccured".tr()}:\n";
|
||||
resultText = "${"anErrorOccurred".tr()}:\n";
|
||||
final List exceptionSplit = result.split('Exception: ');
|
||||
String exception;
|
||||
if (exceptionSplit.length > 1) {
|
||||
|
@ -146,7 +159,9 @@ class TransactionInProgress extends StatelessWidget {
|
|||
onWillPop: () {
|
||||
sub.transactionStatus = '';
|
||||
Navigator.pop(context);
|
||||
if (transType == 'pay') Navigator.pop(context);
|
||||
if (transType == 'pay' || transType == 'identityMigration') {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
return Future<bool>.value(true);
|
||||
},
|
||||
child: Scaffold(
|
||||
|
@ -169,7 +184,7 @@ class TransactionInProgress extends StatelessWidget {
|
|||
child: Column(children: <Widget>[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
|
@ -182,7 +197,9 @@ class TransactionInProgress extends StatelessWidget {
|
|||
const SizedBox(height: 10),
|
||||
if (transType == 'pay')
|
||||
Text(
|
||||
'$amount $currencyName',
|
||||
isUdUnit
|
||||
? 'ud'.tr(args: ['$amount '])
|
||||
: '$amount $currencyName',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 18, fontWeight: FontWeight.w600),
|
||||
|
@ -219,7 +236,7 @@ class TransactionInProgress extends StatelessWidget {
|
|||
Column(children: [
|
||||
Visibility(
|
||||
visible: isLoading,
|
||||
child: SizedBox(
|
||||
child: const SizedBox(
|
||||
height: 18,
|
||||
width: 18,
|
||||
child: CircularProgressIndicator(
|
||||
|
@ -251,15 +268,18 @@ class TransactionInProgress extends StatelessWidget {
|
|||
width: 380 * ratio,
|
||||
height: 60 * ratio,
|
||||
child: ElevatedButton(
|
||||
key: keyCloseTransactionScreen,
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
sub.transactionStatus = '';
|
||||
if (transType == 'pay') Navigator.pop(context);
|
||||
if (transType == 'pay' ||
|
||||
transType == 'identityMigration') {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'close'.tr(),
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:gecko/globals.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gecko/models/g1_wallets_list.dart';
|
||||
import 'package:gecko/models/widgets_keys.dart';
|
||||
import 'package:gecko/providers/cesium_plus.dart';
|
||||
import 'package:gecko/providers/home.dart';
|
||||
import 'package:gecko/providers/substrate_sdk.dart';
|
||||
|
@ -23,9 +24,9 @@ import 'package:qr_flutter/qr_flutter.dart';
|
|||
|
||||
class WalletViewScreen extends StatelessWidget {
|
||||
const WalletViewScreen(
|
||||
{required this.pubkey, this.username, this.avatar, Key? key})
|
||||
{required this.address, this.username, this.avatar, Key? key})
|
||||
: super(key: key);
|
||||
final String? pubkey;
|
||||
final String address;
|
||||
final String? username;
|
||||
final Image? avatar;
|
||||
final double buttonSize = 100;
|
||||
|
@ -38,14 +39,14 @@ class WalletViewScreen extends StatelessWidget {
|
|||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
CesiumPlusProvider cesiumPlusProvider =
|
||||
Provider.of<CesiumPlusProvider>(context, listen: false);
|
||||
walletProfile.address = pubkey!;
|
||||
walletProfile.address = address;
|
||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
HomeProvider homeProvider =
|
||||
Provider.of<HomeProvider>(context, listen: false);
|
||||
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
|
||||
sub.setCurrentWallet(defaultWallet);
|
||||
|
||||
return Scaffold(
|
||||
|
@ -63,14 +64,14 @@ class WalletViewScreen extends StatelessWidget {
|
|||
onPressed: () async {
|
||||
G1WalletsList? newContact;
|
||||
g1WalletsBox.toMap().forEach((key, value) {
|
||||
if (key == pubkey) newContact = value;
|
||||
if (key == address) newContact = value;
|
||||
});
|
||||
// G1WalletsList(pubkey: pubkey!, username: username);
|
||||
await walletProfile.addContact(
|
||||
newContact ?? G1WalletsList(pubkey: pubkey!));
|
||||
newContact ?? G1WalletsList(address: address));
|
||||
},
|
||||
icon: Icon(
|
||||
walletProfile.isContact(pubkey!)
|
||||
walletProfile.isContact(address)
|
||||
? Icons.add_reaction_rounded
|
||||
: Icons.add_reaction_outlined,
|
||||
size: 35,
|
||||
|
@ -84,13 +85,13 @@ class WalletViewScreen extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return QrCodeFullscreen(
|
||||
walletProfile.address!,
|
||||
walletProfile.address,
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
child: QrImageWidget(
|
||||
data: walletProfile.address!,
|
||||
data: walletProfile.address,
|
||||
version: QrVersions.auto,
|
||||
size: 80,
|
||||
),
|
||||
|
@ -106,7 +107,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
||||
body: SafeArea(
|
||||
child: Column(children: <Widget>[
|
||||
walletProfile.headerProfileView(context, pubkey!, username),
|
||||
walletProfile.headerProfileView(context, address, username),
|
||||
SizedBox(height: isTall ? 10 : 0),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
|
||||
Column(children: <Widget>[
|
||||
|
@ -114,9 +115,9 @@ class WalletViewScreen extends StatelessWidget {
|
|||
height: buttonSize,
|
||||
child: ClipOval(
|
||||
child: Material(
|
||||
color: yellowC, //const Color(0xffFFD58D), // button color
|
||||
color: yellowC,
|
||||
child: InkWell(
|
||||
key: const Key('viewHistory'),
|
||||
key: keyViewActivity,
|
||||
splashColor: orangeC, // inkwell color
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(13),
|
||||
|
@ -125,12 +126,11 @@ class WalletViewScreen extends StatelessWidget {
|
|||
'assets/walletOptions/clock.png'),
|
||||
height: 90)),
|
||||
onTap: () {
|
||||
// _historyProvider.nPage = 1;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return ActivityScreen(
|
||||
address: pubkey,
|
||||
address: address,
|
||||
avatar:
|
||||
cesiumPlusProvider.defaultAvatar(50));
|
||||
}),
|
||||
|
@ -150,8 +150,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
return FutureBuilder(
|
||||
future: sub.certState(defaultWallet.address!,
|
||||
pubkey!), // .canCertify(_defaultWallet.address!, pubkey!),
|
||||
future: sub.certState(defaultWallet.address!, address),
|
||||
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
||||
if (snapshot.data == null) return const SizedBox();
|
||||
String duration = '';
|
||||
|
@ -191,6 +190,8 @@ class WalletViewScreen extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
final toStatus = snapshot.data!['toStatus'] ?? 0;
|
||||
|
||||
return Visibility(
|
||||
visible: (snapshot.data != {}),
|
||||
child: Column(children: <Widget>[
|
||||
|
@ -201,11 +202,10 @@ class WalletViewScreen extends StatelessWidget {
|
|||
height: buttonSize,
|
||||
child: ClipOval(
|
||||
child: Material(
|
||||
color:
|
||||
const Color(0xffFFD58D), // button color
|
||||
color: const Color(0xffFFD58D),
|
||||
child: InkWell(
|
||||
key: const Key('certify'),
|
||||
splashColor: orangeC, // inkwell color
|
||||
key: keyCertify,
|
||||
splashColor: orangeC,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(bottom: 0),
|
||||
child: Image(
|
||||
|
@ -217,7 +217,7 @@ class WalletViewScreen extends StatelessWidget {
|
|||
context,
|
||||
"areYouSureYouWantToCertify".tr(
|
||||
args: [
|
||||
getShortPubkey(pubkey!)
|
||||
getShortPubkey(address)
|
||||
]));
|
||||
|
||||
if (result ?? false) {
|
||||
|
@ -243,9 +243,9 @@ class WalletViewScreen extends StatelessWidget {
|
|||
final acc = sub.getCurrentWallet();
|
||||
sub.certify(
|
||||
acc.address!,
|
||||
pin ?? myWalletProvider.pinCode,
|
||||
walletViewProvider.address!);
|
||||
|
||||
walletViewProvider.address,
|
||||
pin ??
|
||||
myWalletProvider.pinCode);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
|
@ -268,67 +268,14 @@ class WalletViewScreen extends StatelessWidget {
|
|||
fontSize: buttonFontSize,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
]),
|
||||
if (snapshot.data!['certDelay'] != null)
|
||||
Column(children: <Widget>[
|
||||
SizedBox(
|
||||
height: buttonSize,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 0),
|
||||
child: Container(
|
||||
foregroundDecoration: const BoxDecoration(
|
||||
color: Colors.grey,
|
||||
backgroundBlendMode: BlendMode.saturation,
|
||||
),
|
||||
child: const Opacity(
|
||||
opacity: 0.5,
|
||||
child: Image(
|
||||
image: AssetImage(
|
||||
'assets/gecko_certify.png')),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"mustWaitXBeforeCertify"
|
||||
.tr(args: [duration.toString()]),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: buttonFontSize - 4,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
]),
|
||||
if (snapshot.data!['certRenewable'] != null &&
|
||||
])
|
||||
else if (toStatus == 1)
|
||||
waitToCert('mustConfirmHisIdentity', duration)
|
||||
else if (snapshot.data!['certRenewable'] != null &&
|
||||
duration != 'seconds'.tr(args: ['0']))
|
||||
Column(children: <Widget>[
|
||||
SizedBox(
|
||||
height: buttonSize,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 0),
|
||||
child: Container(
|
||||
foregroundDecoration: const BoxDecoration(
|
||||
color: Colors.grey,
|
||||
backgroundBlendMode: BlendMode.saturation,
|
||||
),
|
||||
child: const Opacity(
|
||||
opacity: 0.5,
|
||||
child: Image(
|
||||
image: AssetImage(
|
||||
'assets/gecko_certify.png')),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"canRenewCertInX".tr(args: [duration.toString()]),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: buttonFontSize - 4,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
]),
|
||||
waitToCert('canRenewCertInX', duration)
|
||||
else if (snapshot.data!['certDelay'] != null)
|
||||
waitToCert('mustWaitXBeforeCertify', duration)
|
||||
]),
|
||||
);
|
||||
},
|
||||
|
@ -339,17 +286,17 @@ class WalletViewScreen extends StatelessWidget {
|
|||
height: buttonSize,
|
||||
child: ClipOval(
|
||||
child: Material(
|
||||
color: const Color(0xffFFD58D), // button color
|
||||
color: const Color(0xffFFD58D),
|
||||
child: InkWell(
|
||||
key: const Key('copyKey'),
|
||||
splashColor: orangeC, // inkwell color
|
||||
key: keyCopyAddress,
|
||||
splashColor: orangeC,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Image(
|
||||
image: AssetImage('assets/copy_key.png'),
|
||||
height: 90)),
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: pubkey));
|
||||
Clipboard.setData(ClipboardData(text: address));
|
||||
snackCopyKey(context);
|
||||
}),
|
||||
),
|
||||
|
@ -380,20 +327,20 @@ class WalletViewScreen extends StatelessWidget {
|
|||
),
|
||||
child: ClipOval(
|
||||
child: Material(
|
||||
color: orangeC, // button color
|
||||
color: orangeC,
|
||||
child: InkWell(
|
||||
key: const Key('pay'),
|
||||
key: keyPay,
|
||||
splashColor: yellowC,
|
||||
onTap: sub.nodeConnected
|
||||
? () {
|
||||
paymentPopup(context, walletProfile);
|
||||
paymentPopup(context, address);
|
||||
}
|
||||
: null, // inkwell color
|
||||
: null,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(14),
|
||||
child: Image(
|
||||
image: AssetImage('assets/vector_white.png'),
|
||||
))),
|
||||
padding: EdgeInsets.all(14),
|
||||
child: Image(
|
||||
image: AssetImage('assets/vector_white.png')),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -415,295 +362,328 @@ class WalletViewScreen extends StatelessWidget {
|
|||
));
|
||||
}
|
||||
|
||||
void paymentPopup(
|
||||
BuildContext context, WalletsProfilesProvider walletViewProvider) {
|
||||
// WalletsProfilesProvider _walletViewProvider =
|
||||
// Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
|
||||
MyWalletsProvider myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
|
||||
const double shapeSize = 20;
|
||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
log.d(defaultWallet.address);
|
||||
|
||||
bool canValidate = false;
|
||||
|
||||
showModalBottomSheet<void>(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(shapeSize),
|
||||
topLeft: Radius.circular(shapeSize),
|
||||
Widget waitToCert(String status, String duration) {
|
||||
return Column(children: <Widget>[
|
||||
SizedBox(
|
||||
height: buttonSize,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 0),
|
||||
child: Container(
|
||||
foregroundDecoration: const BoxDecoration(
|
||||
color: Colors.grey,
|
||||
backgroundBlendMode: BlendMode.saturation,
|
||||
),
|
||||
child: const Opacity(
|
||||
opacity: 0.5,
|
||||
child: Image(image: AssetImage('assets/gecko_certify.png')),
|
||||
),
|
||||
),
|
||||
),
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
if (walletViewProvider.payAmount.text != '' &&
|
||||
(double.parse(walletViewProvider.payAmount.text) + 2) <=
|
||||
(balanceCache[defaultWallet.address] ?? 0) &&
|
||||
walletViewProvider.address != defaultWallet.address) {
|
||||
if ((balanceCache[pubkey] == 0 || balanceCache[pubkey] == null) &&
|
||||
double.parse(walletViewProvider.payAmount.text) < 5) {
|
||||
canValidate = false;
|
||||
} else {
|
||||
canValidate = true;
|
||||
}
|
||||
} else {
|
||||
canValidate = false;
|
||||
}
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
child: Container(
|
||||
height: 400,
|
||||
decoration: const ShapeDecoration(
|
||||
color: Color(0xffffeed1),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(shapeSize),
|
||||
topLeft: Radius.circular(shapeSize),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24, bottom: 0, left: 24, right: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'executeATransfer'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 26, fontWeight: FontWeight.w700),
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 40,
|
||||
icon: const Icon(Icons.cancel_outlined),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
]),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'from'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
return UnlockingWallet(
|
||||
wallet: defaultWallet);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pin != null ||
|
||||
myWalletProvider.pinCode != '') {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return ChooseWalletScreen(
|
||||
pin: pin ?? myWalletProvider.pinCode);
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.blueAccent.shade200,
|
||||
width: 2),
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(10.0)),
|
||||
),
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(children: [
|
||||
Text(defaultWallet.name!),
|
||||
const Spacer(),
|
||||
FutureBuilder(
|
||||
future:
|
||||
sub.getBalance(defaultWallet.address!),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<Map<String, double>>
|
||||
globalBalance) {
|
||||
if (globalBalance.connectionState !=
|
||||
ConnectionState.done ||
|
||||
globalBalance.hasError) {
|
||||
if (balanceCache[
|
||||
defaultWallet.address!] !=
|
||||
null) {
|
||||
return Text(
|
||||
"${balanceCache[defaultWallet.address!]} $currencyName",
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
));
|
||||
} else {
|
||||
return SizedBox(
|
||||
height: 15,
|
||||
width: 15,
|
||||
child: CircularProgressIndicator(
|
||||
color: orangeC,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
balanceCache[defaultWallet.address!] =
|
||||
globalBalance
|
||||
.data!['transferableBalance']!;
|
||||
return Text(
|
||||
"${balanceCache[defaultWallet.address!]} $currencyName",
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
),
|
||||
);
|
||||
}),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}),
|
||||
const Spacer(),
|
||||
|
||||
// const SizedBox(height: 10),
|
||||
Text(
|
||||
'amount'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextField(
|
||||
controller: walletViewProvider.payAmount,
|
||||
autofocus: true,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (_) => setState(() {
|
||||
// _walletViewProvider.reload();
|
||||
}),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
// FilteringTextInputFormatter.digitsOnly,
|
||||
FilteringTextInputFormatter.deny(',',
|
||||
replacementString: '.'),
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'(^\d+\.?\d{0,2})')),
|
||||
],
|
||||
// onChanged: (v) => _searchProvider.rebuildWidget(),
|
||||
decoration: InputDecoration(
|
||||
hintText: '0.00',
|
||||
suffix: Text(currencyName),
|
||||
filled: true,
|
||||
fillColor: Colors.transparent,
|
||||
// border: OutlineInputBorder(
|
||||
// borderSide:
|
||||
// BorderSide(color: Colors.grey[500], width: 2),
|
||||
// borderRadius: BorderRadius.circular(8)),
|
||||
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey[500]!, width: 2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(20),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 40,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 40),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 4,
|
||||
primary: orangeC, // background
|
||||
onPrimary: Colors.white, // foreground
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
return UnlockingWallet(
|
||||
wallet: defaultWallet);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
log.d(pin);
|
||||
if (pin != null ||
|
||||
myWalletProvider.pinCode != '') {
|
||||
// Payment workflow !
|
||||
WalletsProfilesProvider
|
||||
walletViewProvider =
|
||||
Provider.of<WalletsProfilesProvider>(
|
||||
context,
|
||||
listen: false);
|
||||
SubstrateSdk sub =
|
||||
Provider.of<SubstrateSdk>(context,
|
||||
listen: false);
|
||||
final acc = sub.getCurrentWallet();
|
||||
log.d(
|
||||
"fromAddress: ${acc.address!},destAddress: ${walletViewProvider.address!}, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin");
|
||||
sub.pay(
|
||||
fromAddress: acc.address!,
|
||||
destAddress:
|
||||
walletViewProvider.address!,
|
||||
amount: double.parse(
|
||||
walletViewProvider
|
||||
.payAmount.text),
|
||||
password:
|
||||
pin ?? myWalletProvider.pinCode);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const TransactionInProgress();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: Text(
|
||||
'executeTheTransfer'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}).then((value) => walletViewProvider.payAmount.text = '');
|
||||
),
|
||||
Text(
|
||||
status.tr(args: [duration]),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: buttonFontSize - 4,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
void paymentPopup(BuildContext context, String toAddress) {
|
||||
final walletViewProvider =
|
||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
|
||||
final myWalletProvider =
|
||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||
|
||||
const double shapeSize = 20;
|
||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
||||
log.d(defaultWallet.address);
|
||||
|
||||
bool canValidate = false;
|
||||
|
||||
final toWalletData = myWalletProvider.getWalletDataByAddress(toAddress);
|
||||
|
||||
Future executeTransfert() async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
return UnlockingWallet(wallet: defaultWallet);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
log.d(pin);
|
||||
if (pin != null || myWalletProvider.pinCode != '') {
|
||||
// Payment workflow !
|
||||
WalletsProfilesProvider walletViewProvider =
|
||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||
final acc = sub.getCurrentWallet();
|
||||
log.d(
|
||||
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin");
|
||||
sub.pay(
|
||||
fromAddress: acc.address!,
|
||||
destAddress: toAddress,
|
||||
amount: double.parse(walletViewProvider.payAmount.text),
|
||||
password: pin ?? myWalletProvider.pinCode);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return const TransactionInProgress();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
showModalBottomSheet<void>(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(shapeSize),
|
||||
topLeft: Radius.circular(shapeSize),
|
||||
),
|
||||
),
|
||||
isScrollControlled: true,
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||
double fees = 0;
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
if (walletViewProvider.payAmount.text != '' &&
|
||||
(double.parse(walletViewProvider.payAmount.text) +
|
||||
2 / balanceRatio) <=
|
||||
(balanceCache[defaultWallet.address] ?? 0) &&
|
||||
toAddress != defaultWallet.address) {
|
||||
if ((balanceCache[toAddress] == 0 ||
|
||||
balanceCache[toAddress] == null) &&
|
||||
double.parse(walletViewProvider.payAmount.text) <
|
||||
5 / balanceRatio) {
|
||||
canValidate = false;
|
||||
} else {
|
||||
canValidate = true;
|
||||
}
|
||||
} else {
|
||||
canValidate = false;
|
||||
}
|
||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
child: Container(
|
||||
height: 420,
|
||||
decoration: const ShapeDecoration(
|
||||
color: Color(0xffffeed1),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(shapeSize),
|
||||
topLeft: Radius.circular(shapeSize),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24, bottom: 0, left: 24, right: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'executeATransfer'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 26, fontWeight: FontWeight.w700),
|
||||
),
|
||||
IconButton(
|
||||
iconSize: 40,
|
||||
icon: const Icon(Icons.cancel_outlined),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
]),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
'from'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||
return InkWell(
|
||||
key: keyChangeChest,
|
||||
onTap: () async {
|
||||
String? pin;
|
||||
if (myWalletProvider.pinCode == '') {
|
||||
pin = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (homeContext) {
|
||||
return UnlockingWallet(
|
||||
wallet: defaultWallet);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
if (pin != null || myWalletProvider.pinCode != '') {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) {
|
||||
return ChooseWalletScreen(
|
||||
pin: pin ?? myWalletProvider.pinCode);
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.blueAccent.shade200, width: 2),
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(children: [
|
||||
Text(defaultWallet.name!),
|
||||
const Spacer(),
|
||||
balance(context, defaultWallet.address!, 20)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'to'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
toWalletData == null
|
||||
? getShortPubkey(toAddress)
|
||||
: toWalletData.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 21,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'amount'.tr(),
|
||||
style: TextStyle(
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'frais: $fees $currencyName',
|
||||
style: const TextStyle(
|
||||
color: orangeC,
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextField(
|
||||
textInputAction: TextInputAction.done,
|
||||
onEditingComplete: () async =>
|
||||
canValidate ? await executeTransfert() : null,
|
||||
key: keyAmountField,
|
||||
controller: walletViewProvider.payAmount,
|
||||
autofocus: true,
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center,
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (_) async {
|
||||
fees = await sub.txFees(
|
||||
defaultWallet.address!,
|
||||
toAddress,
|
||||
double.parse(
|
||||
walletViewProvider.payAmount.text == ''
|
||||
? '0'
|
||||
: walletViewProvider.payAmount.text));
|
||||
log.d(fees);
|
||||
setState(() {});
|
||||
},
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.deny(',',
|
||||
replacementString: '.'),
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'(^\d+\.?\d{0,2})')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
hintText: '0.00',
|
||||
suffix: Text(isUdUnit
|
||||
? 'ud'.tr(args: [''])
|
||||
: currencyName), // udUnitDisplay(40),
|
||||
filled: true,
|
||||
fillColor: Colors.transparent,
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(color: Colors.grey[500]!, width: 2),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(20),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 35,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
key: keyConfirmPayment,
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white, elevation: 4,
|
||||
backgroundColor: orangeC, // foreground
|
||||
),
|
||||
onPressed: canValidate
|
||||
? () async => await executeTransfert()
|
||||
: null,
|
||||
child: Text(
|
||||
'executeTheTransfer'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 20, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}).then((value) => walletViewProvider.payAmount.text = '');
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
# Flutter-related
|
||||
**/Flutter/ephemeral/
|
||||
**/Pods/
|
||||
|
||||
# Xcode-related
|
||||
**/dgph
|
||||
**/xcuserdata/
|
|
@ -1 +0,0 @@
|
|||
#include "ephemeral/Flutter-Generated.xcconfig"
|
|
@ -1 +0,0 @@
|
|||
#include "ephemeral/Flutter-Generated.xcconfig"
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// 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"))
|
||||
}
|
|
@ -1,572 +0,0 @@
|
|||
// !$*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 */;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?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>
|
|
@ -1,89 +0,0 @@
|
|||
<?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>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -1,8 +0,0 @@
|
|||
<?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>
|
|
@ -1,9 +0,0 @@
|
|||
import Cocoa
|
||||
import FlutterMacOS
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: FlutterAppDelegate {
|
||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_64.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_256.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_512.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "app_icon_1024.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,339 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
|
||||
<outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="APP_NAME" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About APP_NAME" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<point key="canvasLocation" x="142" y="-258"/>
|
||||
</menu>
|
||||
<window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="800" height="600"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
|
@ -1,14 +0,0 @@
|
|||
// Application-level settings for the Runner target.
|
||||
//
|
||||
// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
|
||||
// future. If not, the values below would default to using the project name when this becomes a
|
||||
// 'flutter create' template.
|
||||
|
||||
// The application's name. By default this is also the title of the Flutter window.
|
||||
PRODUCT_NAME = gecko
|
||||
|
||||
// The application's bundle identifier
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gecko.axiomteam.fr
|
||||
|
||||
// The copyright displayed in application information
|
||||
PRODUCT_COPYRIGHT = Copyright © 2021 gecko.axiomteam.fr. All rights reserved.
|
|
@ -1,2 +0,0 @@
|
|||
#include "../../Flutter/Flutter-Debug.xcconfig"
|
||||
#include "Warnings.xcconfig"
|
|
@ -1,2 +0,0 @@
|
|||
#include "../../Flutter/Flutter-Release.xcconfig"
|
||||
#include "Warnings.xcconfig"
|