Compare commits

...

132 Commits

Author SHA1 Message Date
Hugo Trentesaux c304999e61 update endpoint list
duniter-rpc
duniter-indexer
2023-03-09 18:06:48 +01:00
pokapow 2571baa958 Merge branch 'fix/build-ios' into 'master'
Fix/build ios

See merge request clients/gecko!56
2023-02-28 19:19:34 +01:00
cgeek b31fbc9375 fix: build iOS 2023-02-28 19:00:34 +01:00
poka 472a4c1e5d set ios platform minimum version to 10 2023-02-27 19:43:16 +01:00
guenoel c8933fd5be fix: parse double to int in initCurrencyParameters for iPhone 2023-02-27 19:08:28 +01:00
poka 532a004fd9 remove old todo 2023-02-27 19:08:28 +01:00
poka 22c59613ee fix: double delimters in activity view 2023-02-27 19:08:28 +01:00
poka 60427463b5 feat: can copy app version number 2023-02-27 19:08:28 +01:00
poka 83764194e7 fix: french typo 2023-02-27 19:08:28 +01:00
pokapow 721e26ce05 Merge branch 'master' into 'master'
Master

See merge request clients/gecko!55
2023-02-27 18:44:00 +01:00
atlasan f5904e4f88 format 2023-02-26 02:26:12 +01:00
atlasan a0a3910adc translation updates, styles try? 2023-02-26 02:23:28 +01:00
atlasan d4740ab647 translations, debug test 2023-02-26 01:41:33 +01:00
pokapow 975614d873 Merge branch 'master' into 'master'
Translations and fixes

See merge request clients/gecko!54
2023-02-21 22:16:14 +01:00
atlasan 8e128963ad disable unused import 2023-02-19 19:59:19 +01:00
atlasan 515a058377 format: after disabling changeChest 2023-02-19 19:44:57 +01:00
atlasan 2d9e8025c0 disabling ChooseChest 2023-02-19 19:35:11 +01:00
atlasan 2cb7f234e5 flutter format 2023-02-03 11:47:55 +01:00
atlasan a347796a42 #71 2023-02-02 16:06:24 +01:00
atlasan 9496b9206b Translations and fixes
- couple missing strings
- showing error conditioned on kDebug
- debugging network errors
2023-02-02 15:45:01 +01:00
poka 1a3df7d2f8 fix build link script 2023-02-01 23:02:21 +01:00
poka 9f5a15cc40 bump 0.1.0+54 2023-02-01 22:52:28 +01:00
poka 2ea77b0fce Merge remote-tracking branch 'atlasan-PR53/master' 2023-02-01 22:49:08 +01:00
poka 46bc38a1e9 fix flutter icon 2023-02-01 22:41:40 +01:00
poka 0634335854 upgrade flutter 3.7 2023-02-01 22:25:26 +01:00
atlasan 22325f7299 remove unused import - after translations 2023-01-31 16:34:45 +01:00
atlasan 31627c2060 fix format - after translation mods 2023-01-31 16:16:43 +01:00
atlasan 5b561d52ae Translations
- added IT locale
- added some untranslated strings to locale conf files
- this is a first try run test, Doc? Marty
2023-01-31 15:24:13 +01:00
poka 9a4c1d602b fix: bad virtual keybaord for tchois (team peer programming) 2023-01-31 03:14:01 +01:00
poka 8382cbfc29 add tuto package; safe_home is stateful 2022-12-23 01:59:21 +01:00
poka 9983ea9f78 new BalanceBuilder Widget 2022-12-23 01:58:44 +01:00
poka 0ab955b2da GPT fixed this issue (fake offline detection): https://git.duniter.org/clients/gecko/-/issues/21 2022-12-22 23:53:12 +01:00
poka 60ea8ecac1 fix: bad substrate-sdk commit ref 2022-12-18 14:15:11 +01:00
poka 3d9ce9dc14 downgrade flutter_icon to 2.0.4 2022-12-18 13:18:00 +01:00
poka 9ad20184db Merge branch 'dev' 2022-12-14 20:28:15 +01:00
poka 38498d2370 fix: android icon 2022-12-14 20:27:55 +01:00
poka bd97495cd2 Merge branch 'master' into dev 2022-12-14 20:14:54 +01:00
poka 0b4f86638e Merge branch 'dev' 2022-12-14 20:14:42 +01:00
poka b0d29fceb3 fix CI 2 2022-12-14 20:12:20 +01:00
poka e1c5943667 fix CI 1 2022-12-14 20:09:25 +01:00
poka 1364b36cbf fix: flutter format 2022-12-14 20:00:20 +01:00
poka 1f1ccc0882 add hugo bootnode 2022-12-14 19:59:28 +01:00
poka a176611c83 v0.1.0 2022-12-14 19:56:21 +01:00
poka d1194d5eb5 fix: sometime on startup, app says you upgraded dataVersion (but no) and forget your safes... 2022-12-14 19:54:56 +01:00
poka 71d222307b fix: shouln't be able to see "My contacts" menu if you have no safes. 2022-12-14 19:21:51 +01:00
poka bca3082845 upgrade icons generation 2022-12-11 22:13:25 +01:00
poka 5d084f44e7 Merge branch 'dev' 2022-12-10 08:23:57 +01:00
poka d19131e86a big recto: commons Widgets 2022-12-10 08:22:52 +01:00
poka 5e4f135470 Merge branch 'dev' 2022-12-10 06:18:20 +01:00
poka 26cc024b87 UX: global improvements 2022-12-10 06:18:04 +01:00
poka 3ba04470f9 Merge branch 'dev' 2022-12-10 02:21:34 +01:00
poka ad92a06060 Merge branch 'dev-compute-transactionTile' into dev 2022-12-09 06:24:00 +01:00
poka 792ac2f715 fix: bug on delimiter redondance 2022-12-09 06:23:47 +01:00
poka f7fe3fa7df WIP: extract transaction view computation; bug on delimiter redondance 2022-12-09 05:21:00 +01:00
poka c055dbfe3a refacto: new TransactionTile widget 2022-12-09 05:19:34 +01:00
poka 613b6b282e fix: add deboune to search, and swap onChange to sync 2022-12-09 03:48:12 +01:00
poka 8ddd877131 Merge branch 'wip-fix-history' into dev 2022-12-09 03:36:58 +01:00
poka c6cfb4e548 refacto: ContactsList and SearchResult Widget 2022-12-09 03:36:46 +01:00
poka 875341a804 wip: try to fix history begginin 2022-12-08 11:38:45 +01:00
poka 70f4f151c0 safeHome: add safe image in topbar 2022-12-08 09:51:08 +01:00
pokapow c1ebfc62bc Merge branch 'dev' into 'master'
UX: search: action button is paste address if an address is present in clipboard

See merge request clients/gecko!51
2022-12-08 08:20:36 +01:00
poka 7f8d46b9e8 UX: search: action button is paste address if an address is present in clipboard 2022-12-08 08:17:36 +01:00
pokapow 7cdc13273e Merge branch 'dev' into 'master'
Big refacto

See merge request clients/gecko!50
2022-12-08 05:30:12 +01:00
poka 6155552424 Merge branch 'dev-walletsNamesWidget' into dev 2022-12-08 05:27:12 +01:00
poka 622ceda579 UX: improve appBar in safeHome 2022-12-08 05:26:55 +01:00
poka a28df90c18 fix: bad screen view canCert state 2022-12-08 01:18:09 +01:00
poka d7731504c7 big refacto: home screen stateful; walletnames refacto 2022-12-07 23:10:28 +01:00
poka cf4387a280 fix: null username on search_result screen 2022-12-06 22:42:30 +01:00
poka 82c1d5bf4c WIP: bug on walletname edition and display 2022-12-06 22:33:42 +01:00
poka c81662de83 refacto: new UdUnitDisplay Widget 2022-12-06 04:38:33 +01:00
poka 150f6892f8 refacto: new Balance and Certifications Widgets 2022-12-06 04:35:17 +01:00
poka 4ef5f77888 refacto: new WalletName Widget 2022-12-06 03:58:10 +01:00
poka c50aa53f38 refacto: new IdentityStatus Widget 2022-12-06 03:35:35 +01:00
poka 30b8b68bef fix null is not int when initCurrencyParameters
https://sentry.io/share/issue/da813434b4ba48c7b53dadaeb5d70cc1/
2022-12-06 02:47:56 +01:00
poka 535e121505 fix null avlue on indexer blockchainStartTime on app startup
https://sentry.io/share/issue/d26f6b14ddbc4dc59c5a59eaeb975780/
2022-12-06 01:39:22 +01:00
pokapow 88b34b1008 Merge branch 'dev' into 'master'
Dev

See merge request clients/gecko!49
2022-12-05 14:58:01 +01:00
poka b1a5ca748c bump 0.0.14+46 2022-12-05 14:55:44 +01:00
poka e5e71667df UX: big improvements on unlocking screen 2022-12-05 14:49:32 +01:00
poka 9a2b99977e upgrade packages 2022-12-05 06:41:19 +01:00
pokapow cd2c257779 Merge branch 'dev' into 'master'
fix: bad wallet view info

See merge request clients/gecko!48
2022-12-05 04:38:32 +01:00
poka ef7f6eff1b fix: bad wallet view info 2022-12-05 04:34:45 +01:00
pokapow 24aee6a53c Merge branch 'dev' into 'master'
Dev

See merge request clients/gecko!47
2022-12-05 04:18:51 +01:00
poka 853ad0eb6a fix: null username wor simple wallets in search view 2022-12-05 04:16:54 +01:00
poka 25c0144098 refacto: improve username cache 2022-12-05 04:03:53 +01:00
pokapow 1903b988de Merge branch 'dev' into 'master'
Dev

See merge request clients/gecko!46
2022-12-05 02:39:54 +01:00
poka 8b3ecae62f CI fix: The declaration 'callback' isn't referenced 2022-12-05 02:34:51 +01:00
poka 1ea3be788e bump 0.0.14+43 2022-12-05 02:29:52 +01:00
poka ae36f7384e UX: improve search: button and keyboard action 2022-12-05 02:25:49 +01:00
pokapow 44c8cfb9bc Merge branch 'dev' into 'master'
MR: fix bad widget ancestor when popUntil at the end of onboarding + UX: improve certification popup

See merge request clients/gecko!45
2022-12-04 23:24:59 +01:00
poka b924d644b7 UX: improve certification popup 2022-12-04 23:18:30 +01:00
poka 2ae32982f8 fix: bad widget ancestor when popUntil at the end of onboarding 2022-12-04 23:17:46 +01:00
poka 9ed76b071e improve paddings 2022-12-04 03:24:23 +01:00
pokapow 92fd504505 Merge branch 'dev' into 'master'
use new clean polkawallet_sdk fork + add certifications counter; show message if smith try to migrate identity

See merge request clients/gecko!44
2022-12-04 03:09:55 +01:00
poka d749c9a997 CI: fix unused imports 2022-12-04 03:06:35 +01:00
poka 4158a5308c add certifications counter; show message if smith try to migrate identity 2022-12-04 03:03:08 +01:00
poka b4e0f110a3 use new clean polkawallet_sdk fork 2022-12-03 23:40:03 +01:00
poka e602099cc3 Merge branch 'dev' 2022-12-03 10:45:09 +01:00
poka bc75ae114f add ability to copy mnemonic to clipboard on onboarding 2022-12-03 10:44:48 +01:00
poka 9e91408220 Merge branch 'master' into dev 2022-12-03 08:49:57 +01:00
pokapow 42801f8145 Merge branch 'dev' into 'master'
activity screen: add gdev start time delimiter

See merge request clients/gecko!43
2022-12-03 08:48:47 +01:00
poka 806a96d127 activity screen: add gdev start time delimiter 2022-12-03 08:44:44 +01:00
pokapow 5b89f661ed Merge branch 'dev' into 'master'
Dev

See merge request clients/gecko!42
2022-12-03 00:22:00 +01:00
poka 397d795e8b identity confirmation: check if username exist before valdate 2022-12-02 21:18:28 +01:00
poka 4c7326bfaa g1v1 import: display v1 pubkey instead of v2 address 2022-12-02 19:45:46 +01:00
poka 826dcf7c7c fix: double is not int; remove useless typed 2022-12-02 10:23:21 +01:00
poka f19a441af3 add itdy name to appbar; add link in wallet options 2022-12-02 06:58:18 +01:00
poka 7e98a1d063 bump 0.0.12+36 2022-12-02 06:28:46 +01:00
poka 68fe7925ac hotfix: bad parent data 2022-12-02 06:28:19 +01:00
pokapow bafd853884 Merge branch 'certsScreen' into 'master'
add certs screen

See merge request clients/gecko!41
2022-12-02 06:04:13 +01:00
poka 6b1df55ede fix: flutter format 2022-12-02 06:02:30 +01:00
poka 0241efc223 certifications screen is ok 2022-12-02 05:57:24 +01:00
poka 7a93ff4d78 received certs widget is working 2022-12-02 03:22:53 +01:00
poka 9a9bc6788c fuck git. start to implement certs screen 2022-12-02 02:11:22 +01:00
poka 413c3c708e fix: flutter format 2022-12-01 05:23:42 +01:00
poka cf6571e9da add certs screen 2022-12-01 05:23:42 +01:00
poka da0e9ba2df fix: unused imports 2022-12-01 05:21:48 +01:00
poka 80416f5753 change all providers reference to final 2022-12-01 05:21:36 +01:00
poka 96854fddb9 apply point 7 of volune rapport: remove setPreferredOrientations everywhere on app, replace by global boot instruction 2022-12-01 05:21:23 +01:00
Kapis 6c34dd2425 Update assets/onBoarding/gecko_also_can_forget_es.png 2022-12-01 05:18:49 +01:00
Kapis e65915a333 Update assets/onBoarding/forgot_password_es.png
Deleted assets/onBoarding/gecko_also_can_forget_es.png
2022-12-01 05:18:49 +01:00
Kapis b48be00149 Fixed errors and improved translations 2022-12-01 05:18:49 +01:00
Millicent Billette 1481352f6c Update .gitlab-ci.yml file 2022-12-01 03:22:54 +01:00
pokapow bae16d3a5f Merge branch 'finalProvidersReferences' into 'master'
Final providers references

See merge request clients/gecko!39
2022-11-30 06:22:38 +01:00
poka b7311970e2 fix: unused imports 2022-11-30 06:14:27 +01:00
poka 965ce0f977 fix: flutter format 2022-11-30 05:53:46 +01:00
poka 3a5674ae41 change all providers reference to final 2022-11-30 05:51:56 +01:00
pokapow 38c8b9a995 Merge branch 'voluneRapport7' into 'master'
apply point 7 of volune rapport: remove setPreferredOrientations everywhere on...

See merge request clients/gecko!38
2022-11-30 05:27:39 +01:00
poka 8169e1e840 apply point 7 of volune rapport: remove setPreferredOrientations everywhere on app, replace by global boot instruction 2022-11-30 05:22:37 +01:00
pokapow e88cf3b2f7 Merge branch 'scanlegentil-master-patch-45604' into 'master'
Update assets/translations/es.json

See merge request clients/gecko!37
2022-11-28 11:21:07 +01:00
Scan le Gentil cc36e2652d Update assets/translations/es.json, assets/translations/fr.json 2022-11-28 11:17:11 +01:00
poka 6ea827faf9 fix: homeContext randomly reset after pushNamedAndRemoveUntil 2022-11-28 07:11:39 +01:00
poka 44993557c6 add gdev.p2p.legal endpoint 2022-11-27 03:30:49 +01:00
133 changed files with 5383 additions and 3321 deletions

6
.gitignore vendored
View File

@ -47,9 +47,6 @@ android/key.properties
# Rust things # Rust things
/target /target
# Linux builds
linux/
# Custom # Custom
scripts/private/ scripts/private/
AppDir/ AppDir/
@ -59,5 +56,4 @@ android/app/build.gradle
integration_test/duniter/data/chains/ integration_test/duniter/data/chains/
# Ignore PC deps # Ignore PC deps
macos/ scripts/pushGecko
windows/

View File

@ -7,7 +7,7 @@ stages:
.env: .env:
image: axiomteam/gecko-ci:v0.0.11 image: axiomteam/gecko-ci:v0.0.11
tags: tags:
- redshift - docker
format: format:
extends: .env extends: .env
@ -28,9 +28,10 @@ build_and_test:
- if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID - if: $CI_COMMIT_TAG || $CI_MERGE_REQUEST_ID
- when: manual - when: manual
stage: build_and_test stage: build_and_test
tags:
- redshift
script: script:
- flutter clean
- rm -rf /root/.pub-cache
- flutter pub get
- flutter analyze - flutter analyze
releases:test: releases:test:

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 192 KiB

BIN
assets/party.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -71,7 +71,8 @@
"areYouSureToDeleteWallet": "Are you sure you want to delete the chest \"{}\"?", "areYouSureToDeleteWallet": "Are you sure you want to delete the chest \"{}\"?",
"areYouSureForgetAllChests": "Are you sure you want to forget all your chests?", "areYouSureForgetAllChests": "Are you sure you want to forget all your chests?",
"areYouSureToForgetWallet": "Are you sure you wan to forget the wallet \"{}\"?", "areYouSureToForgetWallet": "Are you sure you wan to forget the wallet \"{}\"?",
"areYouSureYouWantToCertify": "Are you sure you want to certify the address:\n\n{}", "areYouSureYouWantToCertify1": "Are you sure you want to certify the identity :",
"areYouSureYouWantToCertify2": "having the address :",
"yes": "Yes", "yes": "Yes",
"no": "No", "no": "No",
"keepYourMnemonicSecret": "Try to keep this phrase a secret, as it allows anyone who knows it to access all your wallets.", "keepYourMnemonicSecret": "Try to keep this phrase a secret, as it allows anyone who knows it to access all your wallets.",
@ -103,6 +104,7 @@
"identityConfirmed": "Identity confirmed", "identityConfirmed": "Identity confirmed",
"identityExpired": "Identity expired", "identityExpired": "Identity expired",
"confirmYourIdentity": "Confirm your identity", "confirmYourIdentity": "Confirm your identity",
"noResult": "No results",
"noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later", "noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later",
"youAreConnectedToNode": "You are connected to node", "youAreConnectedToNode": "You are connected to node",
"accountActivity": "Account activity", "accountActivity": "Account activity",
@ -156,7 +158,7 @@
"hours": "{} hours {}", "hours": "{} hours {}",
"days": "{} days", "days": "{} days",
"months": "{} months", "months": "{} months",
"certify": "Certify", "certify": "Certify this\nidentity",
"from": "From:", "from": "From:",
"to": "To:", "to": "To:",
"amount": "Amount:", "amount": "Amount:",
@ -168,7 +170,7 @@
"deleteThisWallet": "Delete this wallet", "deleteThisWallet": "Delete this wallet",
"cancel": "Cancel", "cancel": "Cancel",
"inBlockchainResult": "In {} blockchain", "inBlockchainResult": "In {} blockchain",
"search": "Search", "search": "Search an identity\nor an address",
"currencyNode": "{} node :", "currencyNode": "{} node :",
"contactsManagementWithNbr": "My contacts ({})", "contactsManagementWithNbr": "My contacts ({})",
"contactsManagement": "My contacts", "contactsManagement": "My contacts",
@ -195,5 +197,24 @@
"youCannotRevokeThisIdentity": "You cannot revoke this identity while\nit is member of the blacksmiths web", "youCannotRevokeThisIdentity": "You cannot revoke this identity while\nit is member of the blacksmiths web",
"showUdAmounts": "Show amounts in UD", "showUdAmounts": "Show amounts in UD",
"ud": "{}UD", "ud": "{}UD",
"chooseATargetWallet": "Choose a target wallet" "chooseATargetWallet": "Choose a target wallet",
"thisMnemonicHasBeenCopiedToClipboard": "This mnemonic has been copied to clipboard",
"smithCantMigrateIdentity":"You can't migrate this identity while you're member of smith web",
"received": "Received",
"sent": "Sent",
"createIdentity": "Create a new \nidentity",
"memberAccountOf": "Account of {}",
"pasteAddress": "Paste address from\nclipboard",
"historyStart" :"Beginning of history",
"blockchainStart": "Beginning of the ĞDev",
"networkSettings": "Network Settings",
"displaySettings": "Display Settings",
"indexer": "Indexer",
"anAutoNodeChoosed": "A secure and valid node will be automatically used from a random list.",
"rootWallet": "Root Wallet",
"blockN": "block N°{}",
"thisIsNotAGoodCode": "This is not a good code",
"youHaveToBeConnectedToValidateChest": "You have to be connected\nto validate your chest",
"thisIdentityAlreadyExist": "This identity already exists"
} }

View File

@ -1,90 +1,92 @@
{ {
"searchWallet": "Buscar\nbilletera", "searchWallet": "Buscar\nmonedero",
"manageWallets": "Gestionar\nbilleteras", "manageWallets": "Gestionar\nmonederos",
"scanQRCode": "Escanear un\ncódigo QR", "scanQRCode": "Escanear un\ncódigo QR",
"wellConnectedToNode": "Estas bien conectada al nodo\n{}", "wellConnectedToNode": "Estás bien conectado al nodo\n{}",
"networkLost": "Se ha perdido la red...", "networkLost": "Se ha perdido la red...",
"noDuniterEndointAvailable": "No hay servidor disponible...", "noDuniterEndointAvailable": "No hay servidor disponible...",
"connectionPending": "Conexión pendiente...", "connectionPending": "Conexión pendiente...",
"noLizard": "no hay lagarto ;-)", "noLizard": "no hay lagarto ;-)",
"loading": "Cargando...", "loading": "Cargando...",
"forgot_password.png": "forgot_password_en.png", "forgot_password.png": "forgot_password_es.png",
"warningForgotPassword": "In a blockchain, there is no email recovery procedure. Only your recovery phrase can allow you to recover your Ğ1 at any time.", "warningForgotPassword": "En una cadena de bloques o blockchain, no hay procedimiento de recuperación mediante correo electrónico. Sólo tu frase de recuperación puede permitirte recuperar tus Ğ1 en cualquier momento.",
"fastAppDescription": "La aplicación de pago {}\nmás rápida que un reptil de Vietnam", "fastAppDescription": "La aplicación de pago {}\nmás rápida que un reptil de Vietnam",
"createWallet": "Crear una billetera", "createWallet": "Crear un monedero",
"restoreWallet": "Restaurar mis billeteras", "restoreWallet": "Restaurar mis monederos",
"parameters": "Parámetros", "parameters": "Parámetros",
"chooseAnotherMnemonic": "Choose an other\nmnemonic sentence", "chooseAnotherMnemonic": "Elige otra frase de restauración",
"iNotedMyMnemonic": "He escrito mi frase", "iNotedMyMnemonic": "He anotado mi frase de restauración",
"printMyMnemonic": "Print my mnemonic sentence", "printMyMnemonic": "Imprimir mi frase de restauración",
"manageChest": "Configure this chest", "manageChest": "Configurar este cofre",
"changeChest": "Change chest", "changeChest": "Cambiar de cofre",
"geckoChest": "Ğecko chest", "GeckoChest": "Cofre de Ğecko",
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:", "toUnlockEnterPassword": "Para desbloquear tu cofre, introduce tu contraseña, lejos de lagartijas curiosas:",
"rememberPassword": "Keep this code in memory for 15 minutes", "rememberPassword": "Mantener en memoria mi contraseña durante 15 minutos",
"myRootWallet": "Mi billetera principal", "myRootWallet": "Mi monedero principal",
"currentWallet": "My current chest", "currentWallet": "Mi cofre actual",
"wallet": "Billetera", "wallet": "monedero",
"displayMnemonic": "Display my mnemonic sentence", "displayMnemonic": "Mostrar mi frase de restauración",
"changePassword": "Cambiar mi contraseña", "changePassword": "Cambiar mi contraseña",
"createDerivation": "Create a new derivation", "createDerivation": "Crear una nueva derivación",
"createCustomDerivation": "Create a new custom derivation", "createCustomDerivation": "Crear una nueva derivación personalizada",
"deleteChest": "Delete this chest", "deleteChest": "Borrar este cofre",
"openThisChest": "Open this chest", "openThisChest": "Abrir este cofre",
"createChest": "Create a new chest", "createChest": "Crear un nuevo cofre",
"importChest": "Import a chest", "importChest": "Importar un cofre",
"selectMyChest": "Select my chest", "selectMyChest": "Seleccionar mi cofre",
"accessMyChest": "Access my chest", "accessMyChest": "Acceder a mi cofre",
"manageMembership": "Manage my membership", "manageMembership": "Administrar mi afiliación",
"chooseThisWallet": "Elegir esta billetera", "chooseThisWallet": "Elegir este monedero",
"thisWalletIsDefault": "This wallet is the default one", "thisWalletIsDefault": "Monedero definido por defecto",
"defineWalletAsDefault": "Define this as the default one", "defineWalletAsDefault": "Definir este monedero como por defecto",
"displayActivity": "Display activity", "displayActivity": "Visualizar actividad",
"displayNActivity": "Display\nactivity", "displayNActivity": "Visualizar\nactividad",
"memberValidated": "Miembro validado!", "memberValidated": "Miembro validado!",
"copyAddress": "Copiar\ndirección", "copyAddress": "Copiar\nla dirección",
"copy": "Copiar", "copy": "Copiar",
"thisAddressHasBeenCopiedToClipboard": "Esta dirección se ha copiado al cortapapeles", "thisAddressHasBeenCopiedToClipboard": "Esta dirección se ha copiado al portapapeles",
"chooseWalletName": "Choose a new name\nfor your wallet:", "chooseWalletName": "Elige un nuevo nombre\npara tu monedero:",
"choosePassword": "Choose a random password:", "choosePassword": "Elige una contraseña aleatoria:",
"chooseDerivation": "Choose a derivation:", "chooseDerivation": "Elige una derivación:",
"validate": "Validar", "validate": "Validar",
"confirm": "Confirmar", "confirm": "Confirmar",
"confirmPayment": "Confirmar pago", "confirmPayment": "Confirmar pago",
"geckoGenerateYourWalletFromMnemonic": "Ğecko builds your wallet from a **restoration sentence**. It is a bit like the blueprint that builds your wallet.", "GeckoGenerateYourWalletFromMnemonic": "Ğecko construye tu monedero a partir de una **frase de restauración**. Es como unos planos que permiten restaurar tu monedero.",
"keepThisMnemonicSecure": "Keep this sentence carefully, because without it Ğecko will not be able to rebuild your wallets the day you change your phone.", "keepThisMnemonicSecure": "Guarda esta frase con cuidado, porque sin ella Ğecko no podrá restaurar tus monederos el día que cambies de dispositivo.",
"geckoGeneratedYourMnemonicKeepItSecret": "Ğecko generated your mnemonic successfully! Keep it secret, because anyone who knows it can access all your wallets.", "GeckoGeneratedYourMnemonicKeepItSecret": "¡Ğecko generó tu frase de restauración con éxito! Mantenla en secreto, porque cualquiera que la sepa puede acceder a todos tus monederos.",
"newWallet": "New Wallet", "newWallet": "Nuevo monedero",
"itsTimeToUseAPenAndPaper": "It's time to take a **pen and paper** in order to write down your mnemonic.", "itsTimeToUseAPenAndPaper": "Es el momento de coger un **papel y un bolígrafo** para anotar tu frase de restauración.",
"yourMnemonic": "Your mnemonic", "yourMnemonic": "tu frase de restauración",
"gecko_also_can_forget.png": "gecko_also_can_forget_en.png", "gecko_also_can_forget.png": "gecko_also_can_forget_es.png",
"didYouNoteMnemonicToBeSureTypeWord": "Did you write down your menmonic?\n\n To be sure, please type the **{}th word** of your restoration phrase in the field below:", "didYouNoteMnemonicToBeSureTypeWord": "¿Anotaste bien tu frase de restauración? Para asegurarnos, escriba la **palabra #{}** de tu frase de restauración en el cuadro de abajo:",
"geckoWillGenerateAPassword": "Gecko will now generate for you a short password that will allow you to quickly access your wallets, without having to type your recovery sentence every time.", "GeckoWillGenerateAPassword": "Ahora Ğecko te generará una contraseña corta que te permitirá acceder rápidamente a tus monederos, sin tener que escribir cada vez tu frase de recuperación.",
"myPassword": "My password", "myPassword": "Mi contraseña",
"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.", "thisPasswordProtectsYourWalletsInASecureChest": "Esta contraseña protege tus monederos en un cofre **del que sólo tú tienes acceso**, para que tus monederos no puedan ser utilizados por otros.",
"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.", "hereIsThePasswordKeepIt": "¡Y aquí está tu contraseña!\n\nMemorízala o anótala, porque Ğecko te la pedirá **cada vez** que quieras hacer un pago en este dispositivo.",
"chooseAnotherPassword": "Elige otra contraseña", "chooseAnotherPassword": "Elige otra contraseña",
"iNotedMyPassword": "I noted my password", "iNotedMyPassword": "He anotado mi contraseña",
"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.", "GeckoWillCheckPassword": "Ğecko comprobará contigo si has recordado tu contraseña. Escribe tu contraseña en el cuadro de abajo para comprobar que lo has apuntado correctamente.",
"yourChestAndWalletWereCreatedSuccessfully": "Super!\n\nYour chest and your first portfolio have been created with great success.\n\nCongratulations!", "yourChestAndWalletWereCreatedSuccessfully": "¡Genial!\n\nTu cofre y tu primer monedero han sido creados con éxito.\n\n¡Felicidades!",
"allGood": "That's all good!", "allGood": "¡Todo bien!",
"areYouSureToDeleteWallet": "Are you sure you want to delete the chest \"{}\"?", "areYouSureToDeleteWallet": "¿Seguro de que quieres eliminar el cofre \"{}\"?",
"areYouSureForgetAllChests": "Are you sure you want to forget all your chests?", "areYouSureForgetAllChests": "¿Seguro de que quieres olvidar todos tus cofres?",
"areYouSureToForgetWallet": "Are you sure you wan to forget the wallet \"{}\"?", "areYouSureToForgetWallet": "¿Seguro de que quieres olvidar el monedero \"{}\"?",
"areYouSureYouWantToCertify": "Are you sure you want to certify the address:\n\n{}", "areYouSureYouWantToCertify": "¿Seguro de que quiere certificar a la dirección\n\n{}?",
"yes": "Si", "areYouSureYouWantToCertify1": "¿Seguro de que quiere certificar a la identidad :",
"areYouSureYouWantToCertify2": " a la dirección :",
"yes": "Sí",
"no": "No", "no": "No",
"keepYourMnemonicSecret": "Try to keep this phrase a secret, as it allows anyone who knows it to access all your wallets.", "keepYourMnemonicSecret": "Intenta mantener esta frase de restauración en secreto, ya que permite a cualquiera que la conozca acceder a todas tus monederos.",
"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.", "iGeneratedYourMnemonicKeepItSecret": "¡He generado tu frase de restauración!\nIntenta mantenerla en secreto, ya que permite a cualquiera que la conozca acceder a todos tus monederos.",
"myMnemonic": "My mnemonic", "myMnemonic": "Mi frase de restauración",
"close": "Close", "close": "Cerrar",
"toRestoreEnterMnemonic": "To restore your Gecko wallets, enter in the fields below the 12 words that constitute your restoration phrase:", "toRestoreEnterMnemonic": "Para restaurar tus monederos Ğecko, introduce las 12 palabras que componen tu frase de restauración en los cuadros de abajo:",
"pasteFromClipboard": "Paste from\nclipboard", "pasteFromClipboard": "Pegar del\nportapapeles",
"restoreAChest": "Restore a chest", "restoreAChest": "Restaurar un cofre",
"restoreThisChest": "Restore this chest", "restoreThisChest": "Restaurar este cofre",
"continue": "Continuar", "continue": "Continuar",
"itsTheGoodWord": "It's the good word!", "itsTheGoodWord": "¡Es la palabra correcta!",
"nthMnemonicWord": "word of your mnemonic", "nthMnemonicWord": "palabra de tu mnemotecnia",
"1th": "Primera", "1th": "Primera",
"2th": "Segunda", "2th": "Segunda",
"3th": "Tercera", "3th": "Tercera",
@ -98,17 +100,18 @@
"11th": "Undécima", "11th": "Undécima",
"12th": "Duodécima", "12th": "Duodécima",
"yourPasswordLengthIsX": "La longitud de tu contraseña es {}", "yourPasswordLengthIsX": "La longitud de tu contraseña es {}",
"noIdentity": "No identity", "noIdentity": "Ninguna identidad",
"identityCreated": "Identidad creada", "identityCreated": "Identidad creada",
"identityConfirmed": "Identidad confirmada", "identityConfirmed": "Identidad confirmada",
"identityExpired": "Identitdad caducada", "identityExpired": "Identidad caducada",
"confirmYourIdentity": "Confirma tu identidad", "confirmYourIdentity": "Confirma tu identidad",
"noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later", "noResult": "Ningún resultado",
"youAreConnectedToNode": "You are connected to node", "noDuniterNodeAvailableTryLater": "No hay ningún nodo Duniter disponible, por favor, inténtalo más tarde",
"youAreConnectedToNode": "Estás conectado al nodo",
"accountActivity": "Actividad de la cuenta", "accountActivity": "Actividad de la cuenta",
"noNetworkNoHistory": "Network state does not allow\nto display account history", "noNetworkNoHistory": "El estado de la red no permite\nmostrar el historial de la cuenta",
"noDataToDisplay": "No data to be displayed.", "noDataToDisplay": "No hay datos que mostrar.",
"noTransactionToDisplay": "No transaction to display", "noTransactionToDisplay": "No hay transacciónes a mostrar",
"month1": "Enero", "month1": "Enero",
"month2": "Febrero", "month2": "Febrero",
"month3": "Marzo", "month3": "Marzo",
@ -124,76 +127,94 @@
"today": "Hoy", "today": "Hoy",
"yesterday": "Ayer", "yesterday": "Ayer",
"thisWeek": "Esta semana", "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.", "chestNotCompatibleMustReinstallGecko": "La versión de tus cofres no es compatible con esta versión de Ğecko.\nTodos tus cofres serán olvidados, debes importarlos de nuevo.",
"notConnectedToInternet": "No estas conectado a internet", "notConnectedToInternet": "No estás conectado a Internet",
"researchResults": "Results of your research", "researchResults": "Resultados de tu búsqueda",
"resultsFor": "Results for ", "resultsFor": "Resultados para ",
"forgetAllMyChests": "Forget all my chests", "forgetAllMyChests": "Olvida todos mis cofres",
"transaction": "Transaccion", "transaction": "Transacción",
"certification": "Certificacion", "certification": "Certificación",
"identityConfirm": "Identity confirmation", "identityConfirm": "Confirmación de la identidad",
"revokeAdhesion": "Adhesion revocation", "revokeAdhesion": "Revocación de adhesión",
"strangeTransaction": "Strange transaction", "strangeTransaction": "Transacción extraña",
"sending": "Enviando...", "sending": "Enviando...",
"propagating": "Propagando...", "propagating": "Propagando...",
"validating": "Validando...", "validating": "Validando...",
"anErrorOccurred": "Ocurrió un error", "anErrorOccured": "Ocurrió un error",
"24hbetweenCerts": "You have to wait 24h between certs", "24hbetweenCerts": "Hay que esperar 24 horas entre certificaciones",
"canNotCertifySelf": "You can not certify yourself", "canNotCertifySelf": "No puedes certificarte a ti mismo",
"nameAlreadyExist": "This name is already taken", "nameAlreadyExist": "Este nombre ya está ocupado",
"2GDtoKeepAlive": "You have to keep at least 2ĞD to keep your account alive", "2GDtoKeepAlive": "Tienes que mantener al menos 2ĞD para mantener tu cuenta viva",
"youHaveToFeedThisAccountBeforeUsing": "You have to feed this account\nbefore using it.", "youHaveToFeedThisAccountBeforeUsing": "Tienes que nutrir el balance\nde esta cuenta antes de usarla.",
"execTimeoutOver": "Execution timeout is over", "execTimeoutOver": "Se ha agotado el tiempo de ejecución",
"seeAWallet": "Ver una billetera", "seeAWallet": "Ver un monedero",
"mustWaitXBeforeCertify": "Tienes que esperar\n{} antes de\nvolver a certificar", "mustWaitXBeforeCertify": "Tienes que esperar\n{} antes de\nvolver a certificar",
"mustConfirmHisIdentity": "This person must confirm\nhis identity before can be\ncertified", "mustConfirmHisIdentity": "Esta persona debe confirmar\nsu identidad antes de poder ser certificada",
"canRenewCertInX": "You can renew\nthis certification\nin {}", "canRenewCertInX": "Podrás renovar\nla certificación\nen {}",
"executeATransfer": "Execute a transfer", "executeATransfer": "Ejecutar una transacción",
"executeTheTransfer": "Execute the transfer", "executeTheTransfer": "Ejecutar la transacción",
"doATransfer" : "Execute a\ntransfer", "doATransfer" : "Hacer una\ntransacción",
"seconds": "{} segundos", "seconds": "{} segundos",
"minutes": "{} minutos", "minutes": "{} minutos",
"hours": "{} horas {}", "hours": "{} horas {}",
"days": "{} dias", "days": "{} dias",
"months": "{} meses", "months": "{} meses",
"certify": "Certify", "certify": "Certificar esta\nidentidad",
"from": "De:", "from": "De:",
"to": "A:", "to": "A:",
"amount": "Importe:", "amount": "Importe:",
"choiceOfSourceWallet": "Choose a source wallet", "choiceOfSourceWallet": "Elige un monedero de origen",
"extrinsicInProgress": "{} en progreso", "extrinsicInProgress": "{} en progreso",
"extrinsicValidated": "{} validado !", "extrinsicValidated": "¡ {} validado !",
"fromMinus": "de", "fromMinus": "de",
"toMinus": "a", "toMinus": "a",
"deleteThisWallet": "Delete this wallet", "deleteThisWallet": "Borrar este monedero",
"cancel": "Cancelar", "cancel": "Cancelar",
"inBlockchainResult": "In {} blockchain", "inBlockchainResult": "En la blockchain {}",
"search": "Buscar", "search": "Buscar una identidad\no una dirección",
"currencyNode": "{} nodo :", "currencyNode": "Nodo {} :",
"contactsManagementWithNbr": "Mis contactos ({})", "contactsManagementWithNbr": "Mis contactos ({})",
"contactsManagement": "Mis contactos", "contactsManagement": "Mis contactos",
"noContacts": "You don't have any contact", "noContacts": "No tienes ningún contacto",
"addContact": "Add\nto contacts", "addContact": "Añadir\na contactos",
"removeContact": "Remove\nthis contact", "removeContact": "Eliminar\neste contacto",
"derivationsScanProgress": "Scan address {}/{}", "derivationsScanProgress": "Escaneado de la dirección {}/{}",
"youAreOffline": "You are offline...", "youAreOffline": "Estás desconectado...",
"importG1v1": "Import old G1v1 account", "importG1v1": "Importar la cuenta antigua de G1v1",
"selectDestWallet": "Select a target wallet:", "selectDestWallet": "Selecciona un monedero destino:",
"youMustWaitBeforeCashoutThisAccount": "You have to wait a few moment before migrate this account", "youMustWaitBeforeCashoutThisAccount": "Tienes que esperar unos minutos antes de migrar esta cuenta",
"thisAccountIsEmpty": "This account is empty", "thisAccountIsEmpty": "Esta cuenta está vacía",
"youCannotMigrateIdentityToExistingIdentity": "You cannot migrate an identity\nto an account that already has an identity", "youCannotMigrateIdentityToExistingIdentity": "No se puede migrar una identidad\na una cuenta que ya tiene una identidad",
"importOldAccount": "Import your old account", "importOldAccount": "Importar antigua cuenta",
"enterCesiumId": "Ingrese su ID de Cesium", "enterCesiumId": "Ingresa tu frase secreta de Cesium",
"enterCesiumPassword": "Ingrese su contraseña de Cesium", "enterCesiumPassword": "Ingresa tu contraseña de Cesium",
"migrateAccount": "Migrate account", "migrateAccount": "Migrar cuenta",
"migrateIdentity": "Migrate identity", "migrateIdentity": "Migrar identidad",
"identityMigration": "Identity migration", "identityMigration": "Migración de la identidad",
"areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?", "areYouSureMigrateIdentity": "¿Estás seguro de que quieres migrar permanentemente la identidad **{}** con saldo de **{}**?",
"someoneCreatedYourIdentity": "Someone created your {} identity !", "someoneCreatedYourIdentity": "¡ Alguien ha creado tu {} identidad !",
"confirmMyIdentity": "Confirmar mi identidad", "confirmMyIdentity": "Confirmar mi identidad",
"revokeMyIdentity": "Revocar mi identidad", "revokeMyIdentity": "Revocar mi identidad",
"youCannotRevokeThisIdentity": "You cannot revoke this identity while\nit is member of the blacksmiths web", "youCannotRevokeThisIdentity": "No puedes revocar esta identidad mientras\nseas miembro de la red de forjadores",
"showUdAmounts": "Show amounts in UD", "showUdAmounts": "Mostrar importes en DU",
"ud": "{}UD", "ud": "{}DU",
"chooseATargetWallet": "Elija una billetera de destino" "chooseATargetWallet": "Elige un monedero de destino",
"thisMnemonicHasBeenCopiedToClipboard": "This mnemonic has been copied to clipboard",
"smithCantMigrateIdentity":"You can't migrate this identity while you're member of smith web",
"received": "Received",
"sent": "Sent",
"createIdentity": "Create a new \nidentity",
"memberAccountOf": "Account of {}",
"pasteAddress": "Paste address from\nclipboard",
"historyStart" :"Beginning of history",
"blockchainStart": "Comienzo de la ĞDev",
"networkSettings": "Parametros de red",
"displaySettings": "Parametros interficie",
"indexer": "Indexer",
"anAutoNodeChoosed": "Se usará automáticamente un nodo seguro y valido desde una lista aleatoria.",
"rootWallet": "Monedero raíz",
"blockN": "bloque N°{}",
"thisIsNotAGoodCode": "Este codígo no es valido",
"youHaveToBeConnectedToValidateChest": "Tienes que tener conneción\npara validar tu cofre",
"thisIdentityAlreadyExist": "Esta identidad ya existe"
} }

View File

@ -2,7 +2,7 @@
"searchWallet": "Rechercher un\nportefeuille", "searchWallet": "Rechercher un\nportefeuille",
"manageWallets": "Gérer mes\nportefeuilles", "manageWallets": "Gérer mes\nportefeuilles",
"scanQRCode": "Scanner un\nQR code", "scanQRCode": "Scanner un\nQR code",
"wellConnectedToNode": "Vous êtes bien connecté aux noeud\n{}", "wellConnectedToNode": "Vous êtes bien connecté au noeud\n{}",
"networkLost": "Le réseau a été perdu...", "networkLost": "Le réseau a été perdu...",
"noDuniterEndointAvailable": "Aucun serveur disponible...", "noDuniterEndointAvailable": "Aucun serveur disponible...",
"connectionPending": "Connexion en cours...", "connectionPending": "Connexion en cours...",
@ -66,12 +66,13 @@
"chooseAnotherPassword": "Choisir un autre code secret", "chooseAnotherPassword": "Choisir un autre code secret",
"iNotedMyPassword": "J'ai noté mon code secret", "iNotedMyPassword": "J'ai noté mon code secret",
"geckoWillCheckPassword": "Gecko va vérifier avec vous si vous avez bien mémorisé votre code secret.\n\nTapez votre code secret dans le champ ci-dessous pour vérifier que vous lavez bien noté.", "geckoWillCheckPassword": "Gecko va vérifier avec vous si vous avez bien mémorisé votre code secret.\n\nTapez votre code secret dans le champ ci-dessous pour vérifier que vous lavez bien noté.",
"yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !", "yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre et votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !",
"allGood": "Cest tout bon !", "allGood": "Cest tout bon !",
"areYouSureToDeleteWallet": "Êtes-vous sûr de vouloir supprimer le coffre \"{}\" ?", "areYouSureToDeleteWallet": "Êtes-vous sûr de vouloir supprimer le coffre \"{}\" ?",
"areYouSureForgetAllChests": "Êtes-vous sûr de vouloir oublier tous vos coffres ?", "areYouSureForgetAllChests": "Êtes-vous sûr de vouloir oublier tous vos coffres ?",
"areYouSureToForgetWallet": "Êtes-vous sûr de vouloir oublier le portefeuille \"{}\" ?", "areYouSureToForgetWallet": "Êtes-vous sûr de vouloir oublier le portefeuille \"{}\" ?",
"areYouSureYouWantToCertify": "Êtes-vous certain de vouloir certifier l'adresse:\n\n{}", "areYouSureYouWantToCertify1": "Êtes-vous certain de vouloir certifier l'identité :",
"areYouSureYouWantToCertify2": "ayant pour adresse :",
"yes": "Oui", "yes": "Oui",
"no": "Non", "no": "Non",
"keepYourMnemonicSecret": "Tâchez de garder cette phrase bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.", "keepYourMnemonicSecret": "Tâchez de garder cette phrase bien secrète, car elle permet à quiconque la connaît daccéder à tous vos portefeuilles.",
@ -157,19 +158,19 @@
"hours": "{} heures {}", "hours": "{} heures {}",
"days": "{} jours", "days": "{} jours",
"months": "{} mois", "months": "{} mois",
"certify": "Certifier", "certify": "Certifier cette\nidentité",
"from": "Depuis:", "from": "Depuis:",
"to": "Vers:", "to": "Vers:",
"amount": "Montant:", "amount": "Montant:",
"choiceOfSourceWallet": "Choix du portefeuille source", "choiceOfSourceWallet": "Choix du portefeuille source",
"extrinsicInProgress": "{} en cours", "extrinsicInProgress": "{} en cours",
"extrinsicValidated": "{} validé !", "extrinsicValidated": "{} validée !",
"fromMinus": "de", "fromMinus": "de",
"toMinus": "vers", "toMinus": "vers",
"deleteThisWallet": "Supprimer ce portefeuille", "deleteThisWallet": "Supprimer ce portefeuille",
"cancel": "Annuler", "cancel": "Annuler",
"inBlockchainResult": "Dans la blockchain {}", "inBlockchainResult": "Dans la blockchain {}",
"search": "Rechercher", "search": "Rechercher une identité\nou une adresse",
"currencyNode": "Noeud {} :", "currencyNode": "Noeud {} :",
"contactsManagementWithNbr": "Mes contacts ({})", "contactsManagementWithNbr": "Mes contacts ({})",
"contactsManagement": "Mes contacts", "contactsManagement": "Mes contacts",
@ -180,7 +181,7 @@
"youAreOffline": "Vous êtes hors ligne...", "youAreOffline": "Vous êtes hors ligne...",
"importG1v1": "Importer un ancien compte G1v1", "importG1v1": "Importer un ancien compte G1v1",
"selectDestWallet": "Sélectionnez un portefeuille cible:", "selectDestWallet": "Sélectionnez un portefeuille cible:",
"youMustWaitBeforeCashoutThisAccount": "Vous devez attendre quelques minutes avant de pouvoir migrer ce compte", "youMustWaitBeforeCashoutThisAccount": "Vous devez attendre quelques minutes\navant de pouvoir migrer ce compte",
"thisAccountIsEmpty": "Ce compte est vide", "thisAccountIsEmpty": "Ce compte est vide",
"youCannotMigrateIdentityToExistingIdentity": "Vous ne pouvez pas migrer une identité\nvers un compte disposant déjà d'une identité", "youCannotMigrateIdentityToExistingIdentity": "Vous ne pouvez pas migrer une identité\nvers un compte disposant déjà d'une identité",
"importOldAccount": "Importer son ancien compte", "importOldAccount": "Importer son ancien compte",
@ -196,5 +197,23 @@
"youCannotRevokeThisIdentity": "Vous ne pouvez pas révoquer cette identité tant\nqu'elle fait partie de la toile forgerons", "youCannotRevokeThisIdentity": "Vous ne pouvez pas révoquer cette identité tant\nqu'elle fait partie de la toile forgerons",
"showUdAmounts": "Afficher les montants en DU", "showUdAmounts": "Afficher les montants en DU",
"ud": "{}DU", "ud": "{}DU",
"chooseATargetWallet": "Choisissez un portefeuille cible" "chooseATargetWallet": "Choisissez un portefeuille cible",
} "thisMnemonicHasBeenCopiedToClipboard": "Cette phrase secrète viens d'être copié dans votre presse-papier.",
"smithCantMigrateIdentity":"Vous ne pouvez pas migrer cette identité\ntant que vous êtes dans la toile forgerons",
"received": "Reçus",
"sent": "Envoyés",
"createIdentity": "Créer sa nouvelle\nidentité",
"memberAccountOf": "Compte de {}",
"pasteAddress": "Coller l'adresse depuis\nle presse-papier",
"historyStart" :"Début de l'historique",
"blockchainStart": "Début de la ĞDev",
"networkSettings": "Connectivité réseau",
"displaySettings": "Affichage",
"indexer": "Indexer",
"anAutoNodeChoosed": "Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.",
"rootWallet": "Portefeuille racine",
"blockN": "bloc N°{}",
"thisIsNotAGoodCode": "Ce n'est pas le bon code",
"youHaveToBeConnectedToValidateChest": "Vous devez vous connecter à internet\npour valider votre coffre",
"thisIdentityAlreadyExist": "Cette identité existe déjà"
}

220
assets/translations/it.json Normal file
View File

@ -0,0 +1,220 @@
{
"searchWallet": "Cerca\nportafoglio",
"manageWallets": "Gestisci\nportafogli",
"scanQRCode": "Scannerizza un\ncodice QR",
"wellConnectedToNode": "Sei ben connesso al nodo\n{}",
"networkLost": "Rete persa...",
"noDuniterEndointAvailable": "Server non disponibile...",
"connectionPending": "Connessione in corso...",
"noLizard": "non ci sono lucertole ;-)",
"loading": "Caricando...",
"forgot_password.png": "forgot_password_es.png",
"warningForgotPassword": "In una catena di blocchi o blockchain, non ci sono procedure per recupero tramite email. Solo la tua frase di recupero puó permetterti di recuperare i tuoi Ğ1 in qualunque momento.",
"fastAppDescription": "L'applicazione di pagamento {}\npiú rapida che un rettile del Vietnam",
"createWallet": "Crea un portafoglio",
"restoreWallet": "Restaura miei portafogli",
"parameters": "Parametri",
"chooseAnotherMnemonic": "Scegli un'altra frase di recupero",
"iNotedMyMnemonic": "Ho annotato la mia frase di recupero",
"printMyMnemonic": "Stampa la mia frase di recupero",
"manageChest": "Configura questo scrigno",
"changeChest": "Cambia scrigno",
"GeckoChest": "Scrigno di Ğecko",
"toUnlockEnterPassword": "Per sbloccare il tuo scrigno, introduci la password, lontano da lucertole curiose:",
"rememberPassword": "Mantieni in memoria la mia password per 15 minuti",
"myRootWallet": "Il mio portafoglio principale",
"currentWallet": "Il mio scrigno attuale",
"wallet": "portafoglio",
"displayMnemonic": "Mostra la mia frase di recupero",
"changePassword": "Cambia la mia password",
"createDerivation": "Crea una nuova derivazione",
"createCustomDerivation": "Crea una nuova derivazione personalizzata",
"deleteChest": "Elimina questo scrigno",
"openThisChest": "Apri questo scrigno",
"createChest": "Crea un nuovo scrigno",
"importChest": "Importa uno scrigno",
"selectMyChest": "Seleziona scrigno",
"accessMyChest": "Accedi a scrigno",
"manageMembership": "Amministra affiliazione",
"chooseThisWallet": "Scegli questo portafoglio",
"thisWalletIsDefault": "portafoglio predefinito",
"defineWalletAsDefault": "Imposta come predefinito",
"displayActivity": "Visualizza attivitá",
"displayNActivity": "Visualizza\nattivitá",
"memberValidated": "Membro confermato!",
"copyAddress": "Copia\nl'indirizzo",
"copy": "Copia",
"thisAddressHasBeenCopiedToClipboard": "Questo indirizzo é stato copiato negli appunti",
"chooseWalletName": "Scegli un nuovo nome\nper il tuo portafoglio:",
"choosePassword": "Scegli una password casuale:",
"chooseDerivation": "Scegli una derivazione:",
"validate": "Valida",
"confirm": "Conferma",
"confirmPayment": "Conferma pagamento",
"GeckoGenerateYourWalletFromMnemonic": "Ğecko costruisce il tuo portafoglio da una **frase di recupero**. É come una mappa che permette ricostruire il tuo portafoglio.",
"keepThisMnemonicSecure": "Sii attento nel salvare e conservare questa frase, perché senza di essa Ğecko non potrá ricostruire il tuo portafoglio il giorno che cambierai dispositivo.",
"GeckoGeneratedYourMnemonicKeepItSecret": "Ğecko ha generato la tua frase di recupero! Mantienila segreta, perché chiunque che la sappia potrá accedere al tuo portafoglio.",
"newWallet": "Nuovo portafoglio",
"itsTimeToUseAPenAndPaper": "É il momento di prendere **carta e penna** per annotare la frase di recupero.",
"yourMnemonic": "la tua frase di recupero",
"gecko_also_can_forget.png": "gecko_also_can_forget_es.png",
"didYouNoteMnemonicToBeSureTypeWord": "Ti sei segnato bene la frase di recupero? Per assicurarcene, scrivi la **parola {}** della tua frase di recupero:",
"GeckoWillGenerateAPassword": "Ora Ğecko ti creerá una password corta che ti permetterá accedere rapidamente ai tuoi portafogli, senza dover ogni volta inserire la frase di recupero.",
"myPassword": "La mia password",
"thisPasswordProtectsYourWalletsInASecureChest": "Questa password protegge i tuo portafogli e uno scrigno **di cui solo tu hai accesso**, cosicché i tuoi portafogli non possano essere usati da altri.",
"hereIsThePasswordKeepIt": "Ecco la tua password!\n\nMemorizzala e annotala, perché Ğecko te la chiederá **ogni volta** che si voglia effettuare una pagamento da questo dispositivo.",
"chooseAnotherPassword": "Scegli un'altra password",
"iNotedMyPassword": "Ho annotato la password",
"GeckoWillCheckPassword": "Ğecko controllará insieme a te se ti ricordi la password. Scrivi la password per controllare che l'hai appuntata correttamente.",
"yourChestAndWalletWereCreatedSuccessfully": "Fantastico!\n\nIl tuo scrigno e il primo portafoglio sono stati creati con successo.\n\nCongratulazioni!",
"allGood": "Tutto bene!",
"areYouSureToDeleteWallet": "Sicuro che vuoi eliminare lo scrigno \"{}\"?",
"areYouSureForgetAllChests": "Sicuro che vuoi dimenticare tutti i tuoi scrigni?",
"areYouSureToForgetWallet": "Sicuro che vuoi dimenticare il tuo portafoglio \"{}\"?",
"areYouSureYouWantToCertify": "Sicuro che vuoi certificare l'indirizzo\n\n{}?",
"areYouSureYouWantToCertify1": "Sicuro che vuoi certificare l'identitá :",
"areYouSureYouWantToCertify2": " all'indirizzo :",
"yes": "Sí",
"no": "No",
"keepYourMnemonicSecret": "Cerca di mantenere questa frase di recupero segreta, essa permette a chiunque la conosca di accedere a tutti i tuoi portafogli.",
"iGeneratedYourMnemonicKeepItSecret": "La tua frase di recupero é stata creata!\nCerca di mantenere questa frase di recupero segreta, essa permette a chiunque la conosca di accedere a tutti i tuoi portafogli.",
"myMnemonic": "la mia frase di recupero",
"close": "Chiudi",
"toRestoreEnterMnemonic": "Per recuperare i tuoi portafogli Ğecko, introduci le 12 parole che compongono la tua frase di recupero:",
"pasteFromClipboard": "Incolla dagli\nappunti",
"restoreAChest": "Recupera uno scrigno",
"restoreThisChest": "Recupera questo scrigno",
"continue": "Continua",
"itsTheGoodWord": "É la parola corretta!",
"nthMnemonicWord": "parola della tua mnemotecnia",
"1th": "Prima",
"2th": "Seconda",
"3th": "Terza",
"4th": "Quarta",
"5th": "Quinta",
"6th": "Sesta",
"7th": "Settima",
"8th": "Ottava",
"9th": "Nona",
"10th": "Decima",
"11th": "Undicesima",
"12th": "Dodicesima",
"yourPasswordLengthIsX": "La lunghezza della tua password é {}",
"noIdentity": "Nessuna identitá",
"identityCreated": "Identitá creata",
"identityConfirmed": "Identitá confermata",
"identityExpired": "Identitá scaduta",
"confirmYourIdentity": "Conferma identitá",
"noResult": "Nessun risultato",
"noDuniterNodeAvailableTryLater": "Non ci sono nodi Duniter disponibili, per favore, riprova piú tardi",
"youAreConnectedToNode": "Sei connesso al nodo",
"accountActivity": "Attivitá del conto",
"noNetworkNoHistory": "Lo stato della rete non lo permette\nmostra lo storico del conto",
"noDataToDisplay": "Non ci sono dati da mostrare.",
"noTransactionToDisplay": "Non ci sono transazioni da mostrare",
"month1": "Gennaio",
"month2": "Febbraio",
"month3": "Marzo",
"month4": "Aprile",
"month5": "Maggio",
"month6": "Giugno",
"month7": "Luglio",
"month8": "Agosto",
"month9": "Settembre",
"month10": "Ottobre",
"month11": "Novembre",
"month12": "Dicembre",
"today": "Oggi",
"yesterday": "Ieri",
"thisWeek": "Questa settimana",
"chestNotCompatibleMustReinstallGecko": "la versione dei tuoi scrigni non é compatibile con questa versione di Ğecko.\nTutti i tuoi scrigni saranno dimenticati, dovrai importarli di nuovo.",
"notConnectedToInternet": "Non connesso ad Internet",
"researchResults": "Risultati ricerca",
"resultsFor": "Risultati per ",
"forgetAllMyChests": "Dimentica tutti i miei scrigni",
"transaction": "Transazione",
"certification": "Certificazione",
"identityConfirm": "Conferma di identitá",
"revokeAdhesion": "Revocazione di adesione",
"strangeTransaction": "Transazione 'strana'",
"sending": "Inviando...",
"propagating": "Propagando...",
"validating": "Validando...",
"anErrorOccured": "Si é verificato un errore",
"24hbetweenCerts": "Bisogna aspettare 24 ore fra le certificazioni",
"canNotCertifySelf": "Non puoi certificare te stesso",
"nameAlreadyExist": "Nome giá in uso",
"2GDtoKeepAlive": "Devi mantenere almeno 2ĞD per mantenere il conto vivo",
"youHaveToFeedThisAccountBeforeUsing": "Devi incrementare il saldo\ndi questo conto prima di usarlo.",
"execTimeoutOver": "Tempo di esecuzione terminato",
"seeAWallet": "Vedi un portafoglio",
"mustWaitXBeforeCertify": "Devi aspettare\n{} prima di\ncertificare di nuovo",
"mustConfirmHisIdentity": "Questa persona deve confermare\nla sua identitá prima di essere certificata",
"canRenewCertInX": "Potrai rinnovare\nla certificazione\nin {}",
"executeATransfer": "Esegui una transazione",
"executeTheTransfer": "Esegui la transazione",
"doATransfer" : "Esegui una\ntransazione",
"seconds": "{} secondi",
"minutes": "{} minuti",
"hours": "{} ore {}",
"days": "{} giorni",
"months": "{} mesi",
"certify": "Certifica questa\nidentitá",
"from": "Da:",
"to": "A:",
"amount": "Importo:",
"choiceOfSourceWallet": "Scegli un portafoglio sorgente",
"extrinsicInProgress": "{} in corso",
"extrinsicValidated": "¡ {} validato !",
"fromMinus": "da",
"toMinus": "a",
"deleteThisWallet": "Elimina questo portafoglio",
"cancel": "Annulla",
"inBlockchainResult": "Nella blockchain {}",
"search": "Cerca una identitá\no un indirizzo",
"currencyNode": "Nodo {} :",
"contactsManagementWithNbr": "I miei contatti ({})",
"contactsManagement": "I miei contatti",
"noContacts": "Non ci sono contatti salvati",
"addContact": "Aggiungi\nun contatto",
"removeContact": "Elimina\nquesto contatto",
"derivationsScanProgress": "Scannerizzando l'indirizzo {}/{}",
"youAreOffline": "Disconnesso...",
"importG1v1": "Importa il conto antico da G1v1, versione precedente",
"selectDestWallet": "Seleziona un portafoglio di destinazione:",
"youMustWaitBeforeCashoutThisAccount": "Devi aspettare qualche minuto prima di migrare questo conto",
"thisAccountIsEmpty": "Questo conto é vuoto",
"youCannotMigrateIdentityToExistingIdentity": "Non si puó migrare un'identitá\na un conto che ne ha giá una",
"importOldAccount": "Importa conto precedente",
"enterCesiumId": "Inserisci la tua frase segreta di Cesium",
"enterCesiumPassword": "Inserisci la tua password di Cesium",
"migrateAccount": "Migra conto",
"migrateIdentity": "Migra identitá",
"identityMigration": "Migrazione dell'identitá",
"areYouSureMigrateIdentity": "Sei sicuro che vuoi permanentemente migrare l'identitá **{}** con saldo di **{}**?",
"someoneCreatedYourIdentity": "Qualcuno ha creato la tua {} identitá !",
"confirmMyIdentity": "Conferma la mia identitá",
"revokeMyIdentity": "Revoca la mia identitá",
"youCannotRevokeThisIdentity": "Non puoi revocare questa identitá fintanto che\nappartieni alla rete di forgiatori",
"showUdAmounts": "Mostra importi in DU",
"ud": "{}DU",
"chooseATargetWallet": "Scegli un portafoglio di destinazione",
"thisMnemonicHasBeenCopiedToClipboard": "Questo mnemonic é statocopiato negli appunti",
"smithCantMigrateIdentity":"Non puoi migrare questa identitá fintanto che\nappartieni alla rete di forgiatori",
"received": "Ricevuto",
"sent": "Inviato",
"createIdentity": "Crea una nuova \nidentitá",
"memberAccountOf": "Conto di {}",
"pasteAddress": "Incolla l'indirizzo \ndagli appunti",
"historyStart" :"Inizio della storia",
"blockchainStart": "Inizio di ĞDev",
"networkSettings": "Impostazioni di rete",
"displaySettings": "Impostazioni interfaccia",
"indexer": "Indexer",
"anAutoNodeChoosed": "Un nodo sicuro e valido sará automaticamente scelto da una lista casuale.",
"rootWallet": "Portafoglio radice",
"blockN": "blocco N°{}",
"thisIsNotAGoodCode": "Questo codice non é valido",
"youHaveToBeConnectedToValidateChest": "Vous devez vous connecter à internet\npour valider votre coffre",
"thisIdentityAlreadyExist": "Identitá giá esistente"
}

View File

@ -1,3 +1,7 @@
[ [
"wss://gdev.librelois.fr/ws" "wss://gdev.p2p.legal/ws",
"wss://gdev.coinduf.eu/ws",
"wss://vit.fdn.org/ws",
"wss://gdev.cgeek.fr/ws",
"wss://gdev.pini.fr/ws"
] ]

View File

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

View File

@ -0,0 +1 @@
7bd0907a4984e1ab7899edce63b2e286e8f3daad5a8e2bff40cee61ca6b036cd

View File

@ -51,7 +51,7 @@ Future payTest2() async {
await tapKey(keyConfirmPayment); await tapKey(keyConfirmPayment);
spawnBlock(duration: 500); spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1)); await waitFor('validée !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen, duration: 0); await tapKey(keyCloseTransactionScreen, duration: 0);
await waitFor('12.14'); await waitFor('12.14');
spawnBlock(duration: 500); spawnBlock(duration: 500);
@ -64,7 +64,7 @@ Future certifyTest5() async {
await tapKey(keyCertify); await tapKey(keyCertify);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 500); spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1)); await waitFor('validée !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen); await tapKey(keyCloseTransactionScreen);
await waitFor('Identité créée'); await waitFor('Identité créée');
@ -77,7 +77,7 @@ Future certifyTest5() async {
await enterText(keyEnterIdentityUsername, test5.name); await enterText(keyEnterIdentityUsername, test5.name);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 500); spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1)); await waitFor('validée !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen); await tapKey(keyCloseTransactionScreen);
await waitFor('Identité confirmée'); await waitFor('Identité confirmée');
humanRead(2); humanRead(2);
@ -103,7 +103,7 @@ Future certifyTest5() async {
await tapKey(keyCertify); await tapKey(keyCertify);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 500); spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1)); await waitFor('validée !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen); await tapKey(keyCloseTransactionScreen);
await waitFor('2'); await waitFor('2');
@ -118,7 +118,7 @@ Future certifyTest5() async {
await tapKey(keyCertify); await tapKey(keyCertify);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 500); spawnBlock(duration: 500);
await waitFor('validé !', timeout: const Duration(seconds: 1)); await waitFor('validée !', timeout: const Duration(seconds: 1));
await tapKey(keyCloseTransactionScreen); await tapKey(keyCloseTransactionScreen);
await waitFor('Vous devez attendre'); await waitFor('Vous devez attendre');

View File

@ -39,7 +39,7 @@ void main() async {
await tapKey(keyRevokeIdty); await tapKey(keyRevokeIdty);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 2000); spawnBlock(duration: 2000);
await waitFor('validé !', timeout: const Duration(seconds: 4)); await waitFor('validée !', timeout: const Duration(seconds: 4));
await tapKey(keyCloseTransactionScreen, duration: 0); await tapKey(keyCloseTransactionScreen, duration: 0);
await waitFor('Aucune identité', exactMatch: true); await waitFor('Aucune identité', exactMatch: true);
await sleep(); await sleep();
@ -60,7 +60,7 @@ void main() async {
// await waitForButtonEnabled(keyConfirm); // await waitForButtonEnabled(keyConfirm);
// await tapKey(keyConfirm, duration: 500); // await tapKey(keyConfirm, duration: 500);
// await spawnBlock(duration: 2000); // await spawnBlock(duration: 2000);
// await waitFor('validé !'); // await waitFor('validée !');
// await tapKey(keyCloseTransactionScreen, duration: 0); // await tapKey(keyCloseTransactionScreen, duration: 0);
// await sleep(5000); // await sleep(5000);
}, timeout: testTimeout()); }, timeout: testTimeout());

View File

@ -26,7 +26,7 @@ void main() async {
await tapKey(keyImportG1v1); await tapKey(keyImportG1v1);
await enterText(keyCesiumId, 'test'); await enterText(keyCesiumId, 'test');
await enterText(keyCesiumPassword, 'test'); await enterText(keyCesiumPassword, 'test');
await waitFor(cesiumTest1.shortAddress()); await waitFor('DCovzCEnQm9GUWe6mr8u42JR1JAuoj3HbQUGdCkfTzSr');
await waitFor('100.0'); await waitFor('100.0');
await waitFor('3', exactMatch: true); await waitFor('3', exactMatch: true);
@ -43,7 +43,7 @@ void main() async {
await waitForButtonEnabled(keyConfirm); await waitForButtonEnabled(keyConfirm);
await tapKey(keyConfirm); await tapKey(keyConfirm);
spawnBlock(duration: 2000); spawnBlock(duration: 2000);
await waitFor('validé !'); await waitFor('validée !');
await tapKey(keyCloseTransactionScreen, duration: 0); await tapKey(keyCloseTransactionScreen, duration: 0);
await tapKey(keyOpenWallet(test6.address), duration: 300); await tapKey(keyOpenWallet(test6.address), duration: 300);

View File

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -66,7 +67,7 @@ Future restoreChest() async {
await enterText(keyPinForm, 'AAAAA', 0); await enterText(keyPinForm, 'AAAAA', 0);
// Check if string "Accéder à mon coffre" is present in screen // Check if string "Accéder à mon coffre" is present in screen
await waitFor('Accéder à mon coffre'); await waitFor('accessMyChest'.tr());
// Go to wallets home // Go to wallets home
await tapKey(keyGoWalletsHome, duration: 0); await tapKey(keyGoWalletsHome, duration: 0);
@ -84,7 +85,7 @@ Future restoreChest() async {
await tapKey(keyCopyAddress); await tapKey(keyCopyAddress);
// Check if string "Cette adresse a été copié" is present in screen // Check if string "Cette adresse a été copié" is present in screen
await waitFor('Cette adresse a été copié'); await waitFor('thisAddressHasBeenCopiedToClipboard'.tr());
// Pop screen 2 time to go back home // Pop screen 2 time to go back home
await goBack(); await goBack();
@ -126,7 +127,7 @@ Future onboardingNewChest() async {
final askedWord = mnemonic[askedWordNumber - 1]; final askedWord = mnemonic[askedWordNumber - 1];
await enterText(keyInputWord, askedWord); await enterText(keyInputWord, askedWord);
await waitFor('Continuer', exactMatch: true); await waitFor('continue'.tr(), exactMatch: true);
await tapKey(keyGoNext); await tapKey(keyGoNext);
await tapKey(keyGoNext); await tapKey(keyGoNext);
await tapKey(keyGoNext); await tapKey(keyGoNext);
@ -143,13 +144,13 @@ Future onboardingNewChest() async {
await enterText(keyPinForm, 'AAAAA', 0); await enterText(keyPinForm, 'AAAAA', 0);
// Check if string "Accéder à mon coffre" is present in screen // Check if string "Accéder à mon coffre" is present in screen
await waitFor('Accéder à mon coffre'); await waitFor('accessMyChest'.tr());
// Go to wallets home // Go to wallets home
await tapKey(keyGoWalletsHome, duration: 0); await tapKey(keyGoWalletsHome, duration: 0);
// Check if string "Mon portefeuille co" is present in screen // Check if string "Mon portefeuille co" is present in screen
await waitFor('Mon portefeuille co'); await waitFor('currentWallet'.tr());
await waitFor('0.0', exactMatch: true); await waitFor('0.0', exactMatch: true);
// await waitFor('Scanner un'); // await waitFor('Scanner un');
} }

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
@ -135,7 +136,7 @@ Future<void> waitFor(String text,
Finder finder = exactMatch ? find.text(text) : find.textContaining(text); Finder finder = exactMatch ? find.text(text) : find.textContaining(text);
log.d('INTEGRATION TEST: Wait for: $text'); log.d('INTEGRATION TEST: Wait for: $text');
final String searchType = reverse ? 'reversed text' : 'text'; final searchType = reverse ? 'reversed text' : 'text';
do { do {
if (DateTime.now().isAfter(end)) { if (DateTime.now().isAfter(end)) {
@ -258,14 +259,14 @@ Future<WalletData> _addImportAccount(
final address = await sub.importAccount( final address = await sub.importAccount(
mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA'); mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA');
final myWallet = WalletData( final myWallet = WalletData(
version: dataVersion,
chest: chest, chest: chest,
address: address, address: address,
number: number, number: number,
name: name, name: name,
derivation: derivation, derivation: derivation,
imageDefaultPath: '${number % 4}.png'); imageDefaultPath: '${number % 4}.png',
await walletBox.add(myWallet); isOwned: true);
await walletBox.put(myWallet.address, myWallet);
return myWallet; return myWallet;
} }

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>8.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

140
ios/Podfile.lock Normal file
View File

@ -0,0 +1,140 @@
PODS:
- barcode_scan2 (0.0.1):
- Flutter
- MTBBarcodeScanner
- SwiftProtobuf
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
- Flutter (1.0.0)
- flutter_aes_ecb_pkcs5 (0.0.1):
- Flutter
- flutter_inappwebview (0.0.1):
- Flutter
- flutter_inappwebview/Core (= 0.0.1)
- OrderedSet (~> 5.0)
- flutter_inappwebview/Core (0.0.1):
- Flutter
- OrderedSet (~> 5.0)
- image_cropper (0.0.4):
- Flutter
- TOCropViewController (~> 2.6.1)
- image_picker_ios (0.0.1):
- Flutter
- integration_test (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- OrderedSet (5.0.0)
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.0.4):
- Flutter
- printing (1.0.0):
- Flutter
- ReachabilitySwift (5.0.0)
- Sentry/HybridSDK (7.31.5)
- sentry_flutter (0.0.1):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 7.31.5)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftProtobuf (1.21.0)
- TOCropViewController (2.6.1)
- url_launcher_ios (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
DEPENDENCIES:
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- Flutter (from `Flutter`)
- flutter_aes_ecb_pkcs5 (from `.symlinks/plugins/flutter_aes_ecb_pkcs5/ios`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- printing (from `.symlinks/plugins/printing/ios`)
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
SPEC REPOS:
trunk:
- MTBBarcodeScanner
- OrderedSet
- ReachabilitySwift
- Sentry
- SwiftProtobuf
- TOCropViewController
EXTERNAL SOURCES:
barcode_scan2:
:path: ".symlinks/plugins/barcode_scan2/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
Flutter:
:path: Flutter
flutter_aes_ecb_pkcs5:
:path: ".symlinks/plugins/flutter_aes_ecb_pkcs5/ios"
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
image_cropper:
:path: ".symlinks/plugins/image_cropper/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
printing:
:path: ".symlinks/plugins/printing/ios"
sentry_flutter:
:path: ".symlinks/plugins/sentry_flutter/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS:
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_aes_ecb_pkcs5: fb682a7bb13f29cfbb33f88f7e1ed2211eacf5db
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
printing: eafa00acb682c0ca029d4d98d0798f55a1e27102
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
Sentry: 4c9babff9034785067c896fd580b1f7de44da020
sentry_flutter: b10ae7a5ddcbc7f04648eeb2672b5747230172f1
shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2
webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.3

View File

@ -13,6 +13,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
FE317B9470ED5615CA3CB087 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B6BDF717F540F951CBCF3B0 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -29,12 +30,15 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0B6BDF717F540F951CBCF3B0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4C6E3D6B3826D9CF6FE74C71 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9715B8CB8C4BB6B1549A4B43 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -42,6 +46,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B7B5EAF367303889DDE6246F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -49,6 +54,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FE317B9470ED5615CA3CB087 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -72,6 +78,8 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
F45015BCA13948A291A8C8E9 /* Pods */,
ADA8E12261C2D5AFC64EEABC /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -98,6 +106,25 @@
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
ADA8E12261C2D5AFC64EEABC /* Frameworks */ = {
isa = PBXGroup;
children = (
0B6BDF717F540F951CBCF3B0 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
F45015BCA13948A291A8C8E9 /* Pods */ = {
isa = PBXGroup;
children = (
B7B5EAF367303889DDE6246F /* Pods-Runner.debug.xcconfig */,
9715B8CB8C4BB6B1549A4B43 /* Pods-Runner.release.xcconfig */,
4C6E3D6B3826D9CF6FE74C71 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -105,12 +132,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
BF832FA7B2681D407FBCCD35 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
C7115DDDD9D931A7B2E38D5D /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -127,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
@ -197,6 +226,45 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
BF832FA7B2681D407FBCCD35 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
C7115DDDD9D931A7B2E38D5D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -272,7 +340,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -295,7 +363,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
@ -355,7 +426,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -404,7 +475,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -428,7 +499,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
@ -456,7 +530,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",

View File

@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1020" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -4,4 +4,7 @@
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "group:Runner.xcodeproj">
</FileRef> </FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace> </Workspace>

View File

@ -1,122 +1,122 @@
{ {
"images" : [ "images": [
{ {
"size" : "20x20", "filename": "Icon-App-20x20@2x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-20x20@2x.png", "scale": "2x",
"scale" : "2x" "size": "20x20"
}, },
{ {
"size" : "20x20", "filename": "Icon-App-20x20@3x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-20x20@3x.png", "scale": "3x",
"scale" : "3x" "size": "20x20"
}, },
{ {
"size" : "29x29", "filename": "Icon-App-29x29@1x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-29x29@1x.png", "scale": "1x",
"scale" : "1x" "size": "29x29"
}, },
{ {
"size" : "29x29", "filename": "Icon-App-29x29@2x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-29x29@2x.png", "scale": "2x",
"scale" : "2x" "size": "29x29"
}, },
{ {
"size" : "29x29", "filename": "Icon-App-29x29@3x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-29x29@3x.png", "scale": "3x",
"scale" : "3x" "size": "29x29"
}, },
{ {
"size" : "40x40", "filename": "Icon-App-40x40@2x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-40x40@2x.png", "scale": "2x",
"scale" : "2x" "size": "40x40"
}, },
{ {
"size" : "40x40", "filename": "Icon-App-40x40@3x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-40x40@3x.png", "scale": "3x",
"scale" : "3x" "size": "40x40"
}, },
{ {
"size" : "60x60", "filename": "Icon-App-60x60@2x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-60x60@2x.png", "scale": "2x",
"scale" : "2x" "size": "60x60"
}, },
{ {
"size" : "60x60", "filename": "Icon-App-60x60@3x.png",
"idiom" : "iphone", "idiom": "iphone",
"filename" : "Icon-App-60x60@3x.png", "scale": "3x",
"scale" : "3x" "size": "60x60"
}, },
{ {
"size" : "20x20", "filename": "Icon-App-20x20@1x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-20x20@1x.png", "scale": "1x",
"scale" : "1x" "size": "20x20"
}, },
{ {
"size" : "20x20", "filename": "Icon-App-20x20@2x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-20x20@2x.png", "scale": "2x",
"scale" : "2x" "size": "20x20"
}, },
{ {
"size" : "29x29", "filename": "Icon-App-29x29@1x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-29x29@1x.png", "scale": "1x",
"scale" : "1x" "size": "29x29"
}, },
{ {
"size" : "29x29", "filename": "Icon-App-29x29@2x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-29x29@2x.png", "scale": "2x",
"scale" : "2x" "size": "29x29"
}, },
{ {
"size" : "40x40", "filename": "Icon-App-40x40@1x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-40x40@1x.png", "scale": "1x",
"scale" : "1x" "size": "40x40"
}, },
{ {
"size" : "40x40", "filename": "Icon-App-40x40@2x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-40x40@2x.png", "scale": "2x",
"scale" : "2x" "size": "40x40"
}, },
{ {
"size" : "76x76", "filename": "Icon-App-76x76@1x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-76x76@1x.png", "scale": "1x",
"scale" : "1x" "size": "76x76"
}, },
{ {
"size" : "76x76", "filename": "Icon-App-76x76@2x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-76x76@2x.png", "scale": "2x",
"scale" : "2x" "size": "76x76"
}, },
{ {
"size" : "83.5x83.5", "filename": "Icon-App-83.5x83.5@2x.png",
"idiom" : "ipad", "idiom": "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png", "scale": "2x",
"scale" : "2x" "size": "83.5x83.5"
}, },
{ {
"size" : "1024x1024", "filename": "Icon-App-1024x1024@1x.png",
"idiom" : "ios-marketing", "idiom": "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png", "scale": "1x",
"scale" : "1x" "size": "1024x1024"
} }
], ],
"info" : { "info": {
"version" : 1, "author": "icons_launcher",
"author" : "xcode" "version": 1
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -47,5 +47,7 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/g1_wallets_list.dart';
@ -7,7 +8,7 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
// Version of box data // Version of box data
const int dataVersion = 4; const int dataVersion = 6;
late String appVersion; late String appVersion;
const int pinLength = 5; const int pinLength = 5;
@ -50,3 +51,24 @@ const debugPin = true;
String indexerEndpoint = ''; String indexerEndpoint = '';
late double balanceRatio; late double balanceRatio;
late int udValue; late int udValue;
// Indexer
late DateTime startBlockchainTime;
bool startBlockchainInitialized = false;
late int currentUdIndex;
final Map<int, String> monthsInYear = {
1: "month1".tr(),
2: "month2".tr(),
3: "month3".tr(),
4: "month4".tr(),
5: "month5".tr(),
6: "month6".tr(),
7: "month7".tr(),
8: "month8".tr(),
9: "month9".tr(),
10: "month10".tr(),
11: "month11".tr(),
12: "month12".tr()
};

View File

@ -18,10 +18,11 @@ import 'dart:io';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/settings_provider.dart'; import 'package:gecko/providers/settings_provider.dart';
@ -30,7 +31,6 @@ import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/search.dart'; import 'package:gecko/providers/search.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/home.dart'; import 'package:gecko/screens/home.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -57,13 +57,12 @@ Future<void> main() async {
HomeProvider homeProvider = HomeProvider(); HomeProvider homeProvider = HomeProvider();
// DuniterIndexer _duniterIndexer = DuniterIndexer(); // DuniterIndexer _duniterIndexer = DuniterIndexer();
await initHiveForFlutter(); await initHiveForFlutter();
await homeProvider.initHive(); await homeProvider.initHive();
appVersion = await homeProvider.getAppVersion(); configBox = await Hive.openBox("configBox");
// Reset GraphQL cache appVersion = await homeProvider.getAppVersion();
// final cache = HiveStore();
// cache.reset();
// Configure Hive and open boxes // Configure Hive and open boxes
Hive.registerAdapter(WalletDataAdapter()); Hive.registerAdapter(WalletDataAdapter());
@ -71,19 +70,11 @@ Future<void> main() async {
Hive.registerAdapter(G1WalletsListAdapter()); Hive.registerAdapter(G1WalletsListAdapter());
Hive.registerAdapter(IdAdapter()); Hive.registerAdapter(IdAdapter());
walletBox = await Hive.openBox<WalletData>("walletBox");
chestBox = await Hive.openBox<ChestData>("chestBox"); chestBox = await Hive.openBox<ChestData>("chestBox");
configBox = await Hive.openBox("configBox");
await Hive.deleteBoxFromDisk('g1WalletsBox');
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
contactsBox = await Hive.openBox<G1WalletsList>("contactsBox");
await homeProvider.getValidEndpoints(); // Reset GraphQL cache
// await configBox.delete('isCacheChecked'); // final cache = HiveStore();
if (configBox.get('isCacheChecked') == null) { // cache.reset();
configBox.put('isCacheChecked', false);
}
// log.d(await configBox.get('endpoint'));
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
@ -98,31 +89,42 @@ Future<void> main() async {
// // ]); // // ]);
// Catcher(rootWidget: Gecko(endPointGVA, _store), debugConfig: debugOptions); // Catcher(rootWidget: Gecko(endPointGVA, _store), debugConfig: debugOptions);
await SentryFlutter.init( await SentryFlutter.init((options) {
(options) { options.dsn =
options.dsn = 'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110';
'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110'; },
}, appRunner: () => SystemChrome.setPreferredOrientations(
appRunner: () => runApp( [DeviceOrientation.portraitUp]).then((_) {
EasyLocalization( runApp(EasyLocalization(
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')], supportedLocales: const [
path: 'assets/translations', Locale('en'),
fallbackLocale: const Locale('en'), Locale('fr'),
child: const Gecko(), Locale('es'),
), Locale('it')
), ],
); path: 'assets/translations',
fallbackLocale: const Locale('en'),
child: const Gecko(),
));
}));
} else { } else {
log.i('Debug mode enabled: No sentry alerte'); log.i('Debug mode enabled: No sentry alert');
runApp( SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
EasyLocalization( .then((_) {
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')], runApp(EasyLocalization(
// test, force locale :: startLocale: Locale.fromSubtags(languageCode: 'it'),
supportedLocales: const [
Locale('en'),
Locale('fr'),
Locale('es'),
Locale('it')
],
path: 'assets/translations', path: 'assets/translations',
fallbackLocale: const Locale('en'), fallbackLocale: const Locale('en'),
child: const Gecko(), child: const Gecko(),
), ));
); });
} }
} }
@ -131,8 +133,6 @@ class Gecko extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// To configure multi_endpoints GraphQLProvider: https://stackoverflow.com/q/70656513/8301867 // To configure multi_endpoints GraphQLProvider: https://stackoverflow.com/q/70656513/8301867
return MultiProvider( return MultiProvider(
@ -172,8 +172,8 @@ class Gecko extends StatelessWidget {
), ),
primaryColor: const Color(0xffFFD58D), primaryColor: const Color(0xffFFD58D),
textTheme: const TextTheme( textTheme: const TextTheme(
bodyText1: TextStyle(fontSize: 16), bodyLarge: TextStyle(fontSize: 16),
bodyText2: TextStyle(fontSize: 18), bodyMedium: TextStyle(fontSize: 18),
).apply( ).apply(
bodyColor: const Color(0xFF000000), bodyColor: const Color(0xFF000000),
), ),

View File

@ -1,7 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'chest_data.g.dart'; part 'chest_data.g.dart';
@HiveType(typeId: 1) @HiveType(typeId: 1)

View File

@ -56,5 +56,43 @@ query ($address: String!, $number: Int!, $cursor: String) {
} }
'''; ''';
// To parse indexer date format const String getCertsReceived = r'''
// log.d(DateTime.parse("2022-06-13T16:51:24.001+00:00").toString()); query ($address: String!) {
certification(where: {receiver: {pubkey: {_eq: $address}}}) {
issuer {
pubkey
name
}
created_at
}
}
''';
const String getCertsSent = r'''
query ($address: String!) {
certification(where: {issuer: {pubkey: {_eq: $address}}}) {
receiver {
pubkey
name
}
created_at
}
}
''';
const String isIdtyExistQ = r'''
query ($name: String!) {
identity(where: {name: {_eq: $name}}) {
name
}
}
''';
const String getBlockchainStartQ = r'''
query {
block(limit: 1) {
created_at
number
}
}
''';

View File

@ -1,23 +0,0 @@
import 'package:flutter/material.dart';
class StatefulWrapper extends StatefulWidget {
final Function onInit;
final Widget child;
const StatefulWrapper({Key? key, required this.onInit, required this.child})
: super(key: key);
@override
StatefulWrapperState createState() => StatefulWrapperState();
}
class StatefulWrapperState extends State<StatefulWrapper> {
@override
void initState() {
widget.onInit();
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -4,38 +4,42 @@ part 'wallet_data.g.dart';
@HiveType(typeId: 0) @HiveType(typeId: 0)
class WalletData extends HiveObject { class WalletData extends HiveObject {
@HiveField(0) @HiveField(0)
int? version; String address;
@HiveField(1) @HiveField(1)
int? chest; int? chest;
@HiveField(2) @HiveField(2)
String? address;
@HiveField(3)
int? number; int? number;
@HiveField(4) @HiveField(3)
String? name; String? name;
@HiveField(5) @HiveField(4)
int? derivation; int? derivation;
@HiveField(6) @HiveField(5)
String? imageDefaultPath; String? imageDefaultPath;
@HiveField(7) @HiveField(6)
String? imageCustomPath; String? imageCustomPath;
@HiveField(7)
bool isOwned;
@HiveField(8)
bool isMember;
WalletData( WalletData(
{this.version, {required this.address,
this.chest, this.chest,
this.address,
this.number, this.number,
this.name, this.name,
this.derivation, this.derivation,
this.imageDefaultPath, this.imageDefaultPath,
this.imageCustomPath}); this.imageCustomPath,
this.isOwned = false,
this.isMember = false});
// representation of WalletData when debugging // representation of WalletData when debugging
@override @override

View File

@ -17,37 +17,40 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
}; };
return WalletData( return WalletData(
version: fields[0] as int?, address: fields[0] as String,
chest: fields[1] as int?, chest: fields[1] as int?,
address: fields[2] as String?, number: fields[2] as int?,
number: fields[3] as int?, name: fields[3] as String?,
name: fields[4] as String?, derivation: fields[4] as int?,
derivation: fields[5] as int?, imageDefaultPath: fields[5] as String?,
imageDefaultPath: fields[6] as String?, imageCustomPath: fields[6] as String?,
imageCustomPath: fields[7] as String?, isOwned: fields[7] as bool,
isMember: fields[8] as bool,
); );
} }
@override @override
void write(BinaryWriter writer, WalletData obj) { void write(BinaryWriter writer, WalletData obj) {
writer writer
..writeByte(8) ..writeByte(9)
..writeByte(0) ..writeByte(0)
..write(obj.version) ..write(obj.address)
..writeByte(1) ..writeByte(1)
..write(obj.chest) ..write(obj.chest)
..writeByte(2) ..writeByte(2)
..write(obj.address)
..writeByte(3)
..write(obj.number) ..write(obj.number)
..writeByte(4) ..writeByte(3)
..write(obj.name) ..write(obj.name)
..writeByte(5) ..writeByte(4)
..write(obj.derivation) ..write(obj.derivation)
..writeByte(6) ..writeByte(5)
..write(obj.imageDefaultPath) ..write(obj.imageDefaultPath)
..writeByte(6)
..write(obj.imageCustomPath)
..writeByte(7) ..writeByte(7)
..write(obj.imageCustomPath); ..write(obj.isOwned)
..writeByte(8)
..write(obj.isMember);
} }
@override @override

View File

@ -61,6 +61,9 @@ const keyCloseTransactionScreen = Key('keyCloseTransactionScreen');
const keyListTransactions = Key('keyListTransactions'); const keyListTransactions = Key('keyListTransactions');
const keyActivityScreen = Key('keyActivityScreen'); const keyActivityScreen = Key('keyActivityScreen');
// Certification view
const keyCertsReceived = Key('keyCertsReceived');
// Unlock wallet // Unlock wallet
const keyUnlockWallet = Key('keyUnlockWallet'); const keyUnlockWallet = Key('keyUnlockWallet');
const keyPinForm = Key('keyPinForm'); const keyPinForm = Key('keyPinForm');

View File

@ -8,8 +8,6 @@ import 'package:path_provider/path_provider.dart';
class CesiumPlusProvider with ChangeNotifier { class CesiumPlusProvider with ChangeNotifier {
TextEditingController cesiumName = TextEditingController(); TextEditingController cesiumName = TextEditingController();
Image defaultAvatar(double size) =>
Image.asset(('assets/icon_user.png'), height: size);
CancelToken avatarCancelToken = CancelToken(); CancelToken avatarCancelToken = CancelToken();
@ -156,3 +154,6 @@ class CesiumPlusProvider with ChangeNotifier {
return finalAvatar; return finalAvatar;
} }
} }
Image defaultAvatar(double size) =>
Image.asset(('assets/icon_user.png'), height: size);

View File

@ -16,11 +16,11 @@ class ChestProvider with ChangeNotifier {
Future deleteChest(context, ChestData chest) async { Future deleteChest(context, ChestData chest) async {
final bool? answer = await (_confirmDeletingChest(context, chest.name)); final bool? answer = await (_confirmDeletingChest(context, chest.name));
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
if (answer ?? false) { if (answer ?? false) {
await sub.deleteAccounts(getChestWallets(chest)); await sub.deleteAccounts(getChestWallets(chest));
await chestBox.delete(chest.key); await chestBox.delete(chest.key);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
myWalletProvider.pinCode = ''; myWalletProvider.pinCode = '';
@ -45,7 +45,7 @@ class ChestProvider with ChangeNotifier {
log.d(chest.key); log.d(chest.key);
walletBox.toMap().forEach((key, WalletData value) { walletBox.toMap().forEach((key, WalletData value) {
if (value.chest == chest.key) { if (value.chest == chest.key) {
toDelete.add(value.address!); toDelete.add(value.address);
} }
}); });
return toDelete; return toDelete;

View File

@ -5,28 +5,18 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/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/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
import 'package:truncate/truncate.dart';
class DuniterIndexer with ChangeNotifier { class DuniterIndexer with ChangeNotifier {
Map<String, String?> walletNameIndexer = {}; Map<String, String?> walletNameIndexer = {};
String? fetchMoreCursor; String? fetchMoreCursor;
Map? pageInfo; Map? pageInfo;
int nPage = 1;
int nRepositories = 20;
List? transBC; List? transBC;
List listIndexerEndpoints = []; List listIndexerEndpoints = [];
bool isLoadingIndexer = false; bool isLoadingIndexer = false;
Map<String, String> idtyStatusCache = {};
void reload() { void reload() {
notifyListeners(); notifyListeners();
@ -41,7 +31,7 @@ class DuniterIndexer with ChangeNotifier {
final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql')); final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql'));
final response = await request.close(); final response = await request.close();
if (response.statusCode != 200) { if (response.statusCode != 200) {
log.d('INDEXER IS OFFILINE'); log.d('INDEXER IS OFFLINE');
indexerEndpoint = ''; indexerEndpoint = '';
isLoadingIndexer = false; isLoadingIndexer = false;
notifyListeners(); notifyListeners();
@ -57,7 +47,7 @@ class DuniterIndexer with ChangeNotifier {
return true; return true;
} }
} catch (e) { } catch (e) {
log.d('INDEXER IS OFFILINE'); log.d('INDEXER IS OFFLINE');
indexerEndpoint = ''; indexerEndpoint = '';
isLoadingIndexer = false; isLoadingIndexer = false;
notifyListeners(); notifyListeners();
@ -93,7 +83,6 @@ class DuniterIndexer with ChangeNotifier {
if (configBox.containsKey('customIndexer')) { if (configBox.containsKey('customIndexer')) {
return configBox.get('customIndexer'); return configBox.get('customIndexer');
// listIndexerEndpoints.insert(0, configBox.get('customIndexer'));
} }
if (configBox.containsKey('indexerEndpoint')) { if (configBox.containsKey('indexerEndpoint')) {
@ -155,210 +144,8 @@ class DuniterIndexer with ChangeNotifier {
return indexerEndpoint; return indexerEndpoint;
} }
Widget getNameByAddress(BuildContext context, String address,
[WalletData? wallet,
double size = 20,
bool canEdit = false,
Color color = Colors.black,
FontWeight fontWeight = FontWeight.w400,
FontStyle fontStyle = FontStyle.italic]) {
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
if (indexerEndpoint == '') {
if (wallet == null) {
return const SizedBox();
} else {
if (canEdit) {
return walletOptions.walletName(context, wallet, size, color);
} else {
return walletOptions.walletNameController(context, wallet, size);
}
}
}
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
child: Query(
options: QueryOptions(
document: gql(
getNameByAddressQ), // this is the query string you just created
variables: {
'address': address,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return const Text('Loading');
}
walletNameIndexer[address] =
result.data?['account_by_pk']?['identity']?['name'];
g1WalletsBox.put(
address,
G1WalletsList(
address: address, username: walletNameIndexer[address]));
// log.d(g1WalletsBox.toMap().values.first.username);
if (walletNameIndexer[address] == null) {
if (wallet == null) {
return const SizedBox();
} else {
if (canEdit) {
return walletOptions.walletName(context, wallet, size, color);
} else {
return walletOptions.walletNameController(
context, wallet, size);
}
}
}
return Text(
color == Colors.grey[700]!
? '(${walletNameIndexer[address]!})'
: truncate(walletNameIndexer[address]!, 20),
style: TextStyle(
fontSize: size,
color: color,
fontWeight: fontWeight,
fontStyle: fontStyle,
),
);
}),
);
}
Widget searchIdentity(BuildContext context, String name) {
// WalletOptionsProvider _walletOptions =
// Provider.of<WalletOptionsProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfiles =
Provider.of<WalletsProfilesProvider>(context, listen: false);
if (indexerEndpoint == '') {
return const Text('Aucun résultat');
}
log.d(indexerEndpoint);
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(
store: HiveStore()), // GraphQLCache(store: HiveStore())
link: httpLink,
),
);
return GraphQLProvider(
client: client,
child: Query(
options: QueryOptions(
document: gql(
searchAddressByNameQ), // this is the query string you just created
variables: {
'name': name,
},
// pollInterval: const Duration(seconds: 10),
),
builder: (QueryResult result,
{VoidCallback? refetch, FetchMore? fetchMore}) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Text('loading'.tr());
}
final List identities = result.data?['search_identity'] ?? [];
if (identities.isEmpty) {
return Text('noResult'.tr());
}
double avatarSize = 55;
return Expanded(
child: ListView(children: <Widget>[
for (Map profile in identities)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult(profile['pubkey']),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider.defaultAvatar(avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(profile['pubkey']),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
trailing: SizedBox(
width: 110,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
balance(context, profile['pubkey'], 16),
]),
]),
),
subtitle: Row(children: <Widget>[
Text(profile['name'] ?? '',
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfiles.address = profile['pubkey'];
return WalletViewScreen(
address: profile['pubkey'],
username: g1WalletsBox
.get(profile['pubkey'])
?.id
?.username,
avatar:
g1WalletsBox.get(profile['pubkey'])?.avatar,
);
}),
);
}),
),
]),
);
}),
);
}
List parseHistory(blockchainTX, pubkey) { List parseHistory(blockchainTX, pubkey) {
var transBC = []; List transBC = [];
int i = 0; int i = 0;
for (final trans in blockchainTX) { for (final trans in blockchainTX) {
@ -369,8 +156,8 @@ class DuniterIndexer with ChangeNotifier {
transBC.add(i); transBC.add(i);
transBC[i] = []; transBC[i] = [];
transBC[i].add(DateTime.parse(transaction['created_at'])); transBC[i].add(DateTime.parse(transaction['created_at']));
final int amountBrut = transaction['amount']; final amountBrut = transaction['amount'];
final double amount = removeDecimalZero(amountBrut / 100); final amount = removeDecimalZero(amountBrut / 100);
if (direction == "RECEIVED") { if (direction == "RECEIVED") {
transBC[i].add(transaction['issuer_pubkey']); transBC[i].add(transaction['issuer_pubkey']);
transBC[i].add(transaction['issuer']['identity']?['name'] ?? ''); transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
@ -380,32 +167,21 @@ class DuniterIndexer with ChangeNotifier {
} }
transBC[i].add(amount); transBC[i].add(amount);
transBC[i].add(direction); transBC[i].add(direction);
// transBC[i].add(''); //transaction comment
i++; i++;
} }
return transBC; return transBC;
} }
FetchMoreOptions? checkQueryResult(result, opts, pubkey) { FetchMoreOptions? mergeQueryResult(result, opts, pubkey, nRepositories) {
final List<dynamic>? blockchainTX = final List<dynamic>? blockchainTX =
(result.data['transaction_connection']['edges'] as List<dynamic>?); (result.data['transaction_connection']['edges'] as List<dynamic>?);
// final List<dynamic> mempoolTX =
// (result.data['txsHistoryMp']['receiving'] as List<dynamic>);
pageInfo = result.data['transaction_connection']['pageInfo']; pageInfo = result.data['transaction_connection']['pageInfo'];
fetchMoreCursor = pageInfo!['endCursor']; fetchMoreCursor = pageInfo!['endCursor'];
if (fetchMoreCursor == null) nPage = 1; final hasNextPage = pageInfo!['hasNextPage'];
final hasPreviousPage = pageInfo!['hasPreviousPage'];
log.d(fetchMoreCursor); log.d('endCursor: $fetchMoreCursor $hasNextPage $hasPreviousPage');
if (nPage == 1) {
nRepositories = 40;
} else if (nPage == 2) {
nRepositories = 100;
}
// nRepositories = 10;
nPage++;
if (fetchMoreCursor != null) { if (fetchMoreCursor != null) {
opts = FetchMoreOptions( opts = FetchMoreOptions(
@ -418,18 +194,12 @@ class DuniterIndexer with ChangeNotifier {
as List<dynamic> as List<dynamic>
]; ];
log.d('repos: $previousResultData');
log.d('repos: $fetchMoreResultData');
log.d('repos: $repos');
fetchMoreResultData['transaction_connection']['edges'] = repos; fetchMoreResultData['transaction_connection']['edges'] = repos;
return fetchMoreResultData; return fetchMoreResultData;
}, },
); );
} }
log.d(
"###### DEBUG H Parse blockchainTX list. Cursor: $fetchMoreCursor ######");
if (fetchMoreCursor != null) { if (fetchMoreCursor != null) {
transBC = parseHistory(blockchainTX, pubkey); transBC = parseHistory(blockchainTX, pubkey);
} else { } else {
@ -443,7 +213,124 @@ class DuniterIndexer with ChangeNotifier {
String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2); String result = n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
return double.parse(result); return double.parse(result);
} }
}
// checkHistoryResult(
// QueryResult<Object?> result, FetchMoreOptions options, String address) {} //// Manuals queries
Future<bool> isIdtyExist(String name) async {
final variables = <String, dynamic>{
'name': name,
};
final result = await _execQuery(isIdtyExistQ, variables);
return result.data!['identity']?.isEmpty ?? false ? false : true;
}
Future<DateTime> getBlockStart() async {
final result = await _execQuery(getBlockchainStartQ, {});
if (!result.hasException) {
startBlockchainTime =
DateTime.parse(result.data!['block'][0]['created_at']);
startBlockchainInitialized = true;
return startBlockchainTime;
}
return DateTime(0, 0, 0, 0, 0);
}
Future<QueryResult> _execQuery(
String query, Map<String, dynamic> variables) async {
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final GraphQLClient client = GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
);
final QueryOptions options =
QueryOptions(document: gql(query), variables: variables);
return await client.query(options);
}
Map computeHistoryView(repository) {
bool isTody = false;
bool isYesterday = false;
bool isThisWeek = false;
bool isMigrationTime = false;
String? dateDelimiter;
DateTime now = DateTime.now();
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
late double amount;
late String finalAmount;
DateTime date = repository[0];
String dateForm;
bool isDelimiter = true;
if ({4, 10, 11, 12}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}";
} else if ({1, 2, 7, 9}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}";
} else {
dateForm = "${date.day} ${monthsInYear[date.month]}";
}
final transactionDate = DateTime(date.year, date.month, date.day);
final todayDate = DateTime(now.year, now.month, now.day);
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
if (transactionDate == todayDate && !isTody) {
dateDelimiter = "today".tr();
isTody = true;
} else if (transactionDate == yesterdayDate && !isYesterday) {
dateDelimiter = "yesterday".tr();
isYesterday = true;
} else if (weekNumber(date) == weekNumber(now) &&
date.year == now.year &&
transactionDate != yesterdayDate &&
transactionDate != todayDate &&
!isThisWeek) {
dateDelimiter = "thisWeek".tr();
isThisWeek = true;
} else if (dateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
transactionDate != todayDate &&
transactionDate != yesterdayDate &&
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
if (date.year == now.year) {
dateDelimiter = monthsInYear[date.month];
} else {
dateDelimiter = "${monthsInYear[date.month]} ${date.year}";
}
} else {
isDelimiter = false;
}
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
if (isUdUnit) {
amount = round(amount / balanceRatio);
finalAmount = 'ud'.tr(args: ['$amount ']);
} else {
finalAmount = '$amount $currencyName';
}
if (startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0) {
isMigrationTime = true;
} else {
isMigrationTime = false;
}
return {
'finalAmount': finalAmount,
'isMigrationTime': isMigrationTime,
'dateDelimiter': dateDelimiter ?? '',
'isDelimiter': isDelimiter,
'dateForm': dateForm,
};
}
int weekNumber(DateTime date) {
int dayOfYear = int.parse(DateFormat("D").format(date));
return ((dayOfYear - date.weekday + 10) / 7).floor();
} }

View File

@ -1,6 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:durt/durt.dart' as durt; import 'package:durt/durt.dart' as durt;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
@ -88,8 +89,7 @@ class GenerateWalletsProvider with ChangeNotifier {
log.i("Is $expectedWord equal to input $normInputWord ?"); log.i("Is $expectedWord equal to input $normInputWord ?");
if (expectedWord == normInputWord || if (expectedWord == normInputWord ||
inputWord == 'triche' || (kDebugMode && inputWord == 'triche')) {
inputWord == '3.14') {
log.d('Word is OK'); log.d('Word is OK');
isAskedWordValid = true; isAskedWordValid = true;
askedWordColor = Colors.green[600]; askedWordColor = Colors.green[600];
@ -249,7 +249,7 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
Future<List<String>> generateWordList(BuildContext context) async { Future<List<String>> generateWordList(BuildContext context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
generatedMnemonic = await sub.generateMnemonic(lang: appLang); generatedMnemonic = await sub.generateMnemonic(lang: appLang);
List<String> wordsList = []; List<String> wordsList = [];
@ -369,7 +369,7 @@ class GenerateWalletsProvider with ChangeNotifier {
} }
Future<bool> scanDerivations(BuildContext context) async { Future<bool> scanDerivations(BuildContext context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
final currentChestNumber = configBox.get('currentChest'); final currentChestNumber = configBox.get('currentChest');
bool isAlive = false; bool isAlive = false;
scanedValidWalletNumber = 0; scanedValidWalletNumber = 0;
@ -414,14 +414,14 @@ class GenerateWalletsProvider with ChangeNotifier {
password: pin.text); password: pin.text);
WalletData myWallet = WalletData( WalletData myWallet = WalletData(
version: dataVersion,
chest: currentChestNumber, chest: currentChestNumber,
address: addressData.address!, address: addressData.address!,
number: scanedValidWalletNumber, number: scanedValidWalletNumber,
name: walletName, name: walletName,
derivation: derivationNbr, derivation: derivationNbr,
imageDefaultPath: '${scanedValidWalletNumber % 4}.png'); imageDefaultPath: '${scanedValidWalletNumber % 4}.png',
await walletBox.add(myWallet); isOwned: true);
await walletBox.put(myWallet.address, myWallet);
scanedValidWalletNumber = scanedValidWalletNumber + 1; scanedValidWalletNumber = scanedValidWalletNumber + 1;
} }
scanedWalletNumber = scanedWalletNumber + 1; scanedWalletNumber = scanedWalletNumber + 1;
@ -445,6 +445,8 @@ class GenerateWalletsProvider with ChangeNotifier {
onTimeout: () => {}, onTimeout: () => {},
); );
log.d(balance);
log.d( log.d(
"${addressData.address!}: ${balance['transferableBalance']} $currencyName"); "${addressData.address!}: ${balance['transferableBalance']} $currencyName");
if (balance['transferableBalance'] != 0) { if (balance['transferableBalance'] != 0) {
@ -452,14 +454,14 @@ class GenerateWalletsProvider with ChangeNotifier {
await sub.importAccount(mnemonic: generatedMnemonic!, password: pin.text); await sub.importAccount(mnemonic: generatedMnemonic!, password: pin.text);
WalletData myWallet = WalletData( WalletData myWallet = WalletData(
version: dataVersion,
chest: currentChestNumber, chest: currentChestNumber,
address: addressData.address!, address: addressData.address!,
number: 0, number: 0,
name: walletName, name: walletName,
derivation: -1, derivation: -1,
imageDefaultPath: '0.png'); imageDefaultPath: '0.png',
await walletBox.add(myWallet); isOwned: true);
await walletBox.put(myWallet.address, myWallet);
return true; return true;
} else { } else {
return false; return false;

View File

@ -8,17 +8,11 @@ import 'dart:math';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'dart:async'; import 'dart:async';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/screens/search.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb; import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
import 'package:path_provider/path_provider.dart' as pp; import 'package:path_provider/path_provider.dart' as pp;
@ -33,6 +27,7 @@ class HomeProvider with ChangeNotifier {
Widget appBarTitle = Text('Ğecko', style: TextStyle(color: Colors.grey[850])); Widget appBarTitle = Text('Ğecko', style: TextStyle(color: Colors.grey[850]));
String homeMessage = "loading".tr(); String homeMessage = "loading".tr();
String defaultMessage = "noLizard".tr(); String defaultMessage = "noLizard".tr();
bool isWalletBoxInit = false;
Future<void> initHive() async { Future<void> initHive() async {
late Directory hivePath; late Directory hivePath;
@ -67,9 +62,11 @@ class HomeProvider with ChangeNotifier {
Future changeCurrencyUnit(BuildContext context) async { Future changeCurrencyUnit(BuildContext context) async {
final sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
final walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
final bool isUdUnit = configBox.get('isUdUnit') ?? false; final bool isUdUnit = configBox.get('isUdUnit') ?? false;
await configBox.put('isUdUnit', !isUdUnit); await configBox.put('isUdUnit', !isUdUnit);
balanceCache = {}; walletOptions.balanceCache = {};
sub.getBalanceRatio(); sub.getBalanceRatio();
notifyListeners(); notifyListeners();
} }
@ -122,114 +119,11 @@ class HomeProvider with ChangeNotifier {
return list[i]; return list[i];
} }
void handleSearchStart() {
isSearching = true;
notifyListeners();
}
// void playSound(String customSound, double volume) async { // void playSound(String customSound, double volume) async {
// await player.play('$customSound.wav', // await player.play('$customSound.wav',
// volume: volume, mode: PlayerMode.LOW_LATENCY, stayAwake: false); // volume: volume, mode: PlayerMode.LOW_LATENCY, stayAwake: false);
// } // }
Widget bottomAppBar(BuildContext context) {
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
WalletsProfilesProvider historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false);
final size = MediaQuery.of(context).size;
const bool showBottomBar = true;
return Visibility(
visible: showBottomBar,
child: Container(
color: yellowC,
width: size.width,
height: 80,
child:
// Stack(
// children: [
// // CustomPaint(
// // size: Size(size.width, 110),
// // painter: CustomRoundedButton(),
// // ),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
// SizedBox(width: 0),
const Spacer(),
const SizedBox(width: 11),
IconButton(
key: keyAppBarSearch,
iconSize: 40,
icon: const Image(image: AssetImage('assets/loupe-noire.png')),
onPressed: () {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
Navigator.push(
context,
MaterialPageRoute(builder: (homeContext) {
return const SearchScreen();
}),
);
},
),
const SizedBox(width: 22),
const Spacer(),
IconButton(
key: keyAppBarQrcode,
iconSize: 70,
icon: const Image(image: AssetImage('assets/qrcode-scan.png')),
onPressed: () async {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
historyProvider.scan(homeContext);
},
),
const Spacer(),
const SizedBox(width: 15),
IconButton(
key: keyAppBarChest,
iconSize: 60,
icon: const Image(image: AssetImage('assets/wallet.png')),
onPressed: () async {
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(wallet: defaultWallet);
},
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
Navigator.popUntil(
context,
ModalRoute.withName('/'),
);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
},
),
const Spacer(),
]),
),
);
}
void reload() { void reload() {
notifyListeners(); notifyListeners();
} }

View File

@ -4,7 +4,7 @@ import 'dart:async';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MyWalletsProvider with ChangeNotifier { class MyWalletsProvider with ChangeNotifier {
@ -15,6 +15,8 @@ class MyWalletsProvider with ChangeNotifier {
bool isNewDerivationLoading = false; bool isNewDerivationLoading = false;
String lastFlyBy = ''; String lastFlyBy = '';
String dragAddress = ''; String dragAddress = '';
bool isPinValid = false;
bool isPinLoading = true;
int getCurrentChest() { int getCurrentChest() {
if (configBox.get('currentChest') == null) { if (configBox.get('currentChest') == null) {
@ -26,7 +28,7 @@ class MyWalletsProvider with ChangeNotifier {
bool checkIfWalletExist() { bool checkIfWalletExist() {
if (chestBox.isEmpty) { if (chestBox.isEmpty) {
log.i('No wallets detected'); // log.i('No wallets detected');
return false; return false;
} else { } else {
return true; return true;
@ -46,7 +48,7 @@ class MyWalletsProvider with ChangeNotifier {
} }
WalletData? getWalletDataById(List<int?> id) { WalletData? getWalletDataById(List<int?> id) {
if (id.isEmpty) return WalletData(); if (id.isEmpty) return WalletData(address: '', isOwned: true);
int? chest = id[0]; int? chest = id[0];
int? nbr = id[1]; int? nbr = id[1];
WalletData? targetedWallet; WalletData? targetedWallet;
@ -76,18 +78,18 @@ class MyWalletsProvider with ChangeNotifier {
WalletData getDefaultWallet([int? chest]) { WalletData getDefaultWallet([int? chest]) {
if (chestBox.isEmpty) { if (chestBox.isEmpty) {
return WalletData(chest: 0, number: 0); return WalletData(address: '', chest: 0, number: 0, isOwned: true);
} else { } else {
chest ??= getCurrentChest(); chest ??= getCurrentChest();
int? defaultWalletNumber = chestBox.get(chest)!.defaultWallet; int? defaultWalletNumber = chestBox.get(chest)!.defaultWallet;
return getWalletDataById([chest, defaultWalletNumber]) ?? return getWalletDataById([chest, defaultWalletNumber]) ??
WalletData(chest: chest, number: 0); WalletData(address: '', chest: chest, number: 0, isOwned: true);
} }
} }
Future<int> deleteAllWallet(context) async { Future<int> deleteAllWallet(context) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
try { try {
log.w('DELETE ALL WALLETS ?'); log.w('DELETE ALL WALLETS ?');
@ -124,30 +126,30 @@ class MyWalletsProvider with ChangeNotifier {
int? chest = getCurrentChest(); int? chest = getCurrentChest();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = getDefaultWallet(); WalletData defaultWallet = getDefaultWallet();
final address = await sub.derive( final address = await sub.derive(
context, defaultWallet.address!, newDerivationNbr, pinCode); context, defaultWallet.address, newDerivationNbr, pinCode);
WalletData newWallet = WalletData( WalletData newWallet = WalletData(
version: dataVersion,
chest: chest, chest: chest,
address: address, address: address,
number: newWalletNbr, number: newWalletNbr,
name: name, name: name,
derivation: newDerivationNbr, derivation: newDerivationNbr,
imageDefaultPath: '${newWalletNbr % 4}.png'); imageDefaultPath: '${newWalletNbr % 4}.png',
isOwned: true);
await walletBox.add(newWallet); await walletBox.put(newWallet.address, newWallet);
isNewDerivationLoading = false; isNewDerivationLoading = false;
notifyListeners(); notifyListeners();
} }
Future<void> generateRootWallet(context, String name) async { Future<void> generateRootWallet(context, String name) async {
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
isNewDerivationLoading = true; isNewDerivationLoading = true;
@ -156,29 +158,32 @@ class MyWalletsProvider with ChangeNotifier {
int? chest = getCurrentChest(); int? chest = getCurrentChest();
List<WalletData> walletConfig = readAllWallets(chest); List<WalletData> walletConfig = readAllWallets(chest);
walletConfig.sort((p1, p2) {
return Comparable.compare(p1.number!, p2.number!);
});
if (walletConfig.isEmpty) { if (walletConfig.isEmpty) {
newWalletNbr = 0; newWalletNbr = 0;
} else { } else {
newWalletNbr = walletConfig.last.number! + 1; newWalletNbr = walletConfig.last.number! + 1;
} }
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = myWalletProvider.getDefaultWallet(); WalletData defaultWallet = myWalletProvider.getDefaultWallet();
final address = final address =
await sub.generateRootKeypair(defaultWallet.address!, pinCode); await sub.generateRootKeypair(defaultWallet.address, pinCode);
WalletData newWallet = WalletData( WalletData newWallet = WalletData(
version: dataVersion,
chest: chest, chest: chest,
address: address, address: address,
number: newWalletNbr, number: newWalletNbr,
name: name, name: name,
derivation: -1, derivation: -1,
imageDefaultPath: '${newWalletNbr % 4}.png'); imageDefaultPath: '${newWalletNbr % 4}.png',
isOwned: true);
await walletBox.add(newWallet); await walletBox.put(newWallet.address, newWallet);
isNewDerivationLoading = false; isNewDerivationLoading = false;
notifyListeners(); notifyListeners();
@ -192,6 +197,9 @@ class MyWalletsProvider with ChangeNotifier {
chestNumber ??= getCurrentChest(); chestNumber ??= getCurrentChest();
List<WalletData> walletConfig = readAllWallets(chestNumber); List<WalletData> walletConfig = readAllWallets(chestNumber);
walletConfig.sort((p1, p2) {
return Comparable.compare(p1.number!, p2.number!);
});
if (walletConfig.isEmpty) { if (walletConfig.isEmpty) {
newDerivationNbr = 2; newDerivationNbr = 2;

View File

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

View File

@ -1,6 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously, body_might_complete_normally_catch_error
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:fast_base58/fast_base58.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
@ -10,6 +11,7 @@ import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:pinenacl/ed25519.dart';
import 'package:polkawallet_sdk/api/apiKeyring.dart'; import 'package:polkawallet_sdk/api/apiKeyring.dart';
import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:polkawallet_sdk/api/types/networkParams.dart';
import 'package:polkawallet_sdk/api/types/txInfoData.dart'; import 'package:polkawallet_sdk/api/types/txInfoData.dart';
@ -39,9 +41,11 @@ class SubstrateSdk with ChangeNotifier {
TextEditingController csSalt = TextEditingController(); TextEditingController csSalt = TextEditingController();
TextEditingController csPassword = TextEditingController(); TextEditingController csPassword = TextEditingController();
String g1V1NewAddress = ''; String g1V1NewAddress = '';
String g1V1OldPubkey = '';
bool isCesiumIDVisible = false; bool isCesiumIDVisible = false;
bool isCesiumAddresLoading = false; bool isCesiumAddresLoading = false;
late int udValue; late int udValue;
Map<String, List<int>> certsCounterCache = {};
///////////////////////////////////// /////////////////////////////////////
////////// 1: API METHODS /////////// ////////// 1: API METHODS ///////////
@ -84,13 +88,27 @@ class SubstrateSdk with ChangeNotifier {
} }
Future _getStorage(String call) async { Future _getStorage(String call) async {
return await sdk.webView!.evalJavascript('api.query.$call'); try {
return await sdk.webView!.evalJavascript('api.query.$call');
} catch (e) {
log.i("catched _getStorage error");
return Future(() {});
}
} }
Future _getStorageConst(String call) async { Future<int> _getStorageConst(String call) async {
return (await sdk.webView! final result = (await sdk.webView!
.evalJavascript('api.consts.$call', wrapPromise: false) ?? .evalJavascript('api.consts.$call', wrapPromise: false) ??
[null])[0]; [null])[0];
return checkInt(result) ?? 0;
}
int? checkInt(dynamic value) {
if (value is int) return value;
if (value is double) return value.toInt();
if (value is String) return int.tryParse(value);
return null;
} }
Future<TxSenderData> _setSender(String address) async { Future<TxSenderData> _setSender(String address) async {
@ -122,12 +140,25 @@ class SubstrateSdk with ChangeNotifier {
return await _getStorage('identity.identityIndexOf("$address")') ?? 0; return await _getStorage('identity.identityIndexOf("$address")') ?? 0;
} }
Future<List<int>> getCerts(String address) async { Future<List<int>> getCertsCounter(String address) async {
final idtyIndex = await _getIdentityIndexOf(address); final idtyIndex = await _getIdentityIndexOf(address);
final certsReceiver = final certsReceiver =
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? []; await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
return [certsReceiver['receivedCount'], certsReceiver['issuedCount']]; if (certsCounterCache[address] == null) {
certsCounterCache.putIfAbsent(address, () => []);
}
try {
certsCounterCache.update(
address,
(value) => [
certsReceiver['receivedCount'] as int,
certsReceiver['issuedCount'] as int
]);
} catch (e) {
// catching String to int error .. network error?
}
return certsCounterCache[address]!;
} }
Future<int> getCertValidityPeriod(String from, String to) async { Future<int> getCertValidityPeriod(String from, String to) async {
@ -168,8 +199,6 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<Map<String, double>> getBalance(String address) async { Future<Map<String, double>> getBalance(String address) async {
// log.d('currencyParameters: $currencyParameters');
if (!nodeConnected) { if (!nodeConnected) {
return { return {
'transferableBalance': 0, 'transferableBalance': 0,
@ -186,13 +215,11 @@ class SubstrateSdk with ChangeNotifier {
final Map? idtyData = idtyIndex == null final Map? idtyData = idtyIndex == null
? null ? null
: await _getStorage('identity.identities($idtyIndex)'); : await _getStorage('identity.identities($idtyIndex)');
final int currentUdIndex =
int.parse(await _getStorage('universalDividend.currentUdIndex()'));
final List pastReevals = final List pastReevals =
await _getStorage('universalDividend.pastReevals()'); await _getStorage('universalDividend.pastReevals()');
// Compute amount of claimable UDs // Compute amount of claimable UDs
final int unclaimedUds = _computeUnclaimUds(currentUdIndex, final int unclaimedUds = _computeUnclaimUds(
idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals); idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals);
// Calculate transferable and potential balance // Calculate transferable and potential balance
@ -210,12 +237,13 @@ class SubstrateSdk with ChangeNotifier {
}; };
// log.i(finalBalances); // log.i(finalBalances);
log.d(
'${getShortPubkey(address)} --- BALANCE: ${finalBalances['transferableBalance']}');
return finalBalances; return finalBalances;
} }
int _computeUnclaimUds( int _computeUnclaimUds(int firstEligibleUd, List pastReevals) {
int currentUdIndex, int firstEligibleUd, List pastReevals) {
int totalAmount = 0; int totalAmount = 0;
if (firstEligibleUd == 0) return 0; if (firstEligibleUd == 0) return 0;
@ -239,8 +267,13 @@ class SubstrateSdk with ChangeNotifier {
return totalAmount; return totalAmount;
} }
Future<bool> isMemberGet(String address) async { Future<bool> isMember(String address) async {
return await idtyStatus(address) == 'Validated'; final isMember = await idtyStatus(address) == 'Validated';
final walletData = walletBox.get(address) ?? WalletData(address: address);
walletData.isMember = isMember;
walletBox.put(address, walletData);
// notifyListeners();
return isMember;
} }
Future<bool> isSmithGet(String address) async { Future<bool> isSmithGet(String address) async {
@ -260,7 +293,7 @@ class SubstrateSdk with ChangeNotifier {
Map<String, int> result = {}; Map<String, int> result = {};
final toStatus = await idtyStatus(to); final toStatus = await idtyStatus(to);
if (from != to && await isMemberGet(from)) { if (from != to && await isMember(from)) {
final removableOn = await getCertValidityPeriod(from, to); final removableOn = await getCertValidityPeriod(from, to);
final certMeta = await getCertMeta(from); final certMeta = await getCertMeta(from);
final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0; final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0;
@ -275,6 +308,9 @@ class SubstrateSdk with ChangeNotifier {
result.putIfAbsent('certDelay', () => certDelayDuration); result.putIfAbsent('certDelay', () => certDelayDuration);
} else if (toStatus == 'Created') { } else if (toStatus == 'Created') {
result.putIfAbsent('toStatus', () => 1); result.putIfAbsent('toStatus', () => 1);
} else if (toStatus == 'noid') {
result.putIfAbsent('toStatus', () => 2);
result.putIfAbsent('canCert', () => 0);
} else { } else {
result.putIfAbsent('canCert', () => 0); result.putIfAbsent('canCert', () => 0);
} }
@ -295,7 +331,7 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<String> idtyStatus(String address) async { Future<String> idtyStatus(String address) async {
// WalletOptionsProvider walletOptions = // final walletOptions =
// Provider.of<WalletOptionsProvider>(homeContext, listen: false); // Provider.of<WalletOptionsProvider>(homeContext, listen: false);
var idtyIndex = await _getIdentityIndexOf(address); var idtyIndex = await _getIdentityIndexOf(address);
@ -319,6 +355,15 @@ class SubstrateSdk with ChangeNotifier {
} }
} }
Future<bool> isSmith(String address) async {
var idtyIndex = await _getIdentityIndexOf(address);
if (idtyIndex == 0) return false;
final isSmith =
await _getStorage('smithsMembership.membership($idtyIndex)');
return isSmith == null ? false : true;
}
Future<String> getGenesisHash() async { Future<String> getGenesisHash() async {
final String genesisHash = await sdk.webView!.evalJavascript( final String genesisHash = await sdk.webView!.evalJavascript(
'api.genesisHash.toHex()', 'api.genesisHash.toHex()',
@ -344,21 +389,24 @@ class SubstrateSdk with ChangeNotifier {
// } // }
Future initCurrencyParameters() async { Future initCurrencyParameters() async {
currencyParameters['ss58'] = try {
await _getStorageConst('system.ss58Prefix.words'); currencyParameters['ss58'] =
currencyParameters['minCertForMembership'] = await _getStorageConst('system.ss58Prefix.words');
await _getStorageConst('wot.minCertForMembership.words'); currencyParameters['minCertForMembership'] =
currencyParameters['newAccountPrice'] = await _getStorageConst('wot.minCertForMembership.words');
await _getStorageConst('account.newAccountPrice.words'); currencyParameters['newAccountPrice'] =
currencyParameters['existentialDeposit'] = await _getStorageConst('account.newAccountPrice.words');
await _getStorageConst('balances.existentialDeposit.words'); currencyParameters['existentialDeposit'] =
currencyParameters['certPeriod'] = await _getStorageConst('balances.existentialDeposit.words');
await _getStorageConst('cert.certPeriod.words'); currencyParameters['certPeriod'] =
currencyParameters['certMaxByIssuer'] = await _getStorageConst('cert.certPeriod.words');
await _getStorageConst('cert.maxByIssuer.words'); currencyParameters['certMaxByIssuer'] =
currencyParameters['certValidityPeriod'] = await _getStorageConst('cert.maxByIssuer.words');
await _getStorageConst('cert.validityPeriod.words'); currencyParameters['certValidityPeriod'] =
await _getStorageConst('cert.validityPeriod.words');
} catch (e) {
log.i('error while getting storageVals (network?) :: $e');
}
log.i('currencyParameters: $currencyParameters'); log.i('currencyParameters: $currencyParameters');
} }
@ -380,6 +428,77 @@ class SubstrateSdk with ChangeNotifier {
return estimateFees.partialFee / 100; return estimateFees.partialFee / 100;
} }
int hexStringToUint16(String input) {
// Slice the string in 2-char substrings and parse it from hex to decimal
final bytes = sliceString(input, 2).map((s) => int.parse(s, radix: 16));
// Create a Uint8 from the 2-bytes list
final u8list = Uint8List.fromList(bytes.toList());
// Return a Uint16 little endian representation
return ByteData.view(u8list.buffer).getUint16(0, Endian.little);
}
List<String> sliceString(String input, int count) {
if (input.isEmpty) return [];
if (input.length % count != 0) {
throw ArgumentError("Cannot slice $input in $count slices.");
}
// final slices = List<String>(count);
var slices = List<String>.filled(count, '');
int len = input.length;
int sliceSize = len ~/ count;
for (var i = 0; i < count; i++) {
var start = i * sliceSize;
slices[i] = input.substring(start, start + sliceSize);
}
return List.unmodifiable(slices);
}
Future<DateFormat> getBlockchainStart() async {
////// Manu indexer
//// Extract block date. Ugly, I can't find a better way to get the date of the block ?
//// The only polkadot issue for that : https://github.com/polkadot-js/api/issues/2603
// const created_at = new Date(
// signedBlock.block.extrinsics
// .filter(
// ({ method: { section, method } }) =>
// section === 'timestamp' && method === 'set'
// )[0]
// .args[0].toNumber()
// )
//// manu rpc
// genesis: api.genesisHash.toHex(),
// chain: await api.rpc.chain.getHeader(),
// chainInfo: await api.registry.getChainProperties(),
// test: await api.rpc.state.getPairs('0x')
// query block finalisé qui ne change jamais.
// api.rpc.chain.subscribeFinalizedHeads
// events: await api.rpc.state.getStorage('0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7'),
// lastFinalizedBlock: await api.rpc.chain.getFinalizedHead()
// get block
// api.rpc.chain.getFinalizedHead
// shit
// final blockHash =
// await sdk.webView!.evalJavascript('api.rpc.chain.getBlockHash(1)');
// final Map blockContent = await sdk.webView!
// .evalJavascript('api.rpc.chain.getBlock("$blockHash")');
// final String dateBrut = blockContent['block']['extrinsics'][0];
// final dateTextByte = hex.decode(dateBrut.substring(2));
// final dateText = await sdk.webView!
// .evalJavascript('api.tx($dateTextByte)', wrapPromise: false);
// log.d('aaaaaaaaaaaaaaaaaaaaa: $dateText');
return DateFormat();
}
///////////////////////////////////// /////////////////////////////////////
////// 3: SUBSTRATE CONNECTION ////// ////// 3: SUBSTRATE CONNECTION //////
///////////////////////////////////// /////////////////////////////////////
@ -400,9 +519,8 @@ class SubstrateSdk with ChangeNotifier {
} }
Future<void> connectNode(BuildContext ctx) async { Future<void> connectNode(BuildContext ctx) async {
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false); final homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider = Provider.of<MyWalletsProvider>(ctx, listen: false);
Provider.of<MyWalletsProvider>(ctx, listen: false);
homeProvider.changeMessage("connectionPending".tr(), 0); homeProvider.changeMessage("connectionPending".tr(), 0);
@ -442,8 +560,8 @@ class SubstrateSdk with ChangeNotifier {
} }
notifyListeners(); notifyListeners();
}); });
currentUdIndex =
await initCurrencyParameters(); int.parse(await _getStorage('universalDividend.currentUdIndex()'));
await getBalanceRatio(); await getBalanceRatio();
notifyListeners(); notifyListeners();
@ -568,7 +686,7 @@ class SubstrateSdk with ChangeNotifier {
Future<KeyPairData?> changePassword(BuildContext context, String address, Future<KeyPairData?> changePassword(BuildContext context, String address,
String passOld, String passNew) async { String passOld, String passNew) async {
final account = getKeypair(address); final account = getKeypair(address);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
keyring.setCurrent(account); keyring.setCurrent(account);
myWalletProvider.resetPinCode(); myWalletProvider.resetPinCode();
@ -604,7 +722,7 @@ class SubstrateSdk with ChangeNotifier {
await chestBox.put(currentChestNumber, newChestData); await chestBox.put(currentChestNumber, newChestData);
try { try {
final acc = getKeypair(wallet.address!); final acc = getKeypair(wallet.address);
keyring.setCurrent(acc); keyring.setCurrent(acc);
return acc.address!; return acc.address!;
} catch (e) { } catch (e) {
@ -680,6 +798,9 @@ class SubstrateSdk with ChangeNotifier {
cryptoType: CryptoType.ed25519, cryptoType: CryptoType.ed25519,
rawSeed: rawSeedHex); rawSeed: rawSeedHex);
SigningKey rootKey = SigningKey(seed: rawSeed);
g1V1OldPubkey = Base58Encode(rootKey.publicKey);
g1V1NewAddress = newAddress.address!; g1V1NewAddress = newAddress.address!;
notifyListeners(); notifyListeners();
return g1V1NewAddress; return g1V1NewAddress;
@ -695,8 +816,15 @@ class SubstrateSdk with ChangeNotifier {
final fromHasConsumer = final fromHasConsumer =
fromAddress == '' ? false : await hasAccountConsumers(fromAddress); fromAddress == '' ? false : await hasAccountConsumers(fromAddress);
final toIdtyStatus = await idtyStatus(toAddress); final toIdtyStatus = await idtyStatus(toAddress);
final isSmithData = await isSmith(fromAddress);
return [fromBalance, fromIdtyStatus, toIdtyStatus, fromHasConsumer]; return [
fromBalance,
fromIdtyStatus,
toIdtyStatus,
fromHasConsumer,
isSmithData
];
} }
////////////////////////////////////// //////////////////////////////////////
@ -779,7 +907,7 @@ class SubstrateSdk with ChangeNotifier {
List txOptions = []; List txOptions = [];
String? rawParams; String? rawParams;
final toCerts = await getCerts(destAddress); final toCerts = await getCertsCounter(destAddress);
// log.d('debug: ${currencyParameters['minCertForMembership']}'); // log.d('debug: ${currencyParameters['minCertForMembership']}');
@ -1007,7 +1135,7 @@ void snackNode(BuildContext context, bool isConnected) {
if (!isConnected) { if (!isConnected) {
message = "noDuniterNodeAvailableTryLater".tr(); message = "noDuniterNodeAvailableTryLater".tr();
} else { } else {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
message = message =
"${"youAreConnectedToNode".tr()}\n${sub.getConnectedEndpoint()!.split('//')[1]}"; "${"youAreConnectedToNode".tr()}\n${sub.getConnectedEndpoint()!.split('//')[1]}";

View File

@ -11,14 +11,12 @@ import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/animated_text.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:image_cropper/image_cropper.dart'; import 'package:image_cropper/image_cropper.dart';
import 'package:truncate/truncate.dart';
class WalletOptionsProvider with ChangeNotifier { class WalletOptionsProvider with ChangeNotifier {
TextEditingController address = TextEditingController(); TextEditingController address = TextEditingController();
@ -28,12 +26,11 @@ class WalletOptionsProvider with ChangeNotifier {
TextEditingController newPin = TextEditingController(); TextEditingController newPin = TextEditingController();
bool isEditing = false; bool isEditing = false;
bool isBalanceBlur = false; bool isBalanceBlur = false;
FocusNode walletNameFocus = FocusNode();
TextEditingController nameController = TextEditingController(); TextEditingController nameController = TextEditingController();
late bool isDefaultWallet; late bool isDefaultWallet;
bool canValidateNameBool = false; bool canValidateNameBool = false;
Map<String, String> idtyStatusCache = {};
Future<NewWallet>? get badWallet => null; Future<NewWallet>? get badWallet => null;
Map<String, double> balanceCache = {};
int getPinLenght(walletNbr) { int getPinLenght(walletNbr) {
return pinLength; return pinLength;
@ -51,27 +48,27 @@ class WalletOptionsProvider with ChangeNotifier {
} }
Future<int> deleteWallet(context, WalletData wallet) async { Future<int> deleteWallet(context, WalletData wallet) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool? answer = await (confirmPopup( final bool? answer = await (confirmPopup(
context, 'areYouSureToForgetWallet'.tr(args: [wallet.name!]))); context, 'areYouSureToForgetWallet'.tr(args: [wallet.name!])));
if (answer ?? false) { if (answer ?? false) {
//Check if balance is null //Check if balance is null
final balance = await sub.getBalance(wallet.address!); final balance = await sub.getBalance(wallet.address);
if (balance != {}) { if (balance != {}) {
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
final defaultWallet = myWalletProvider.getDefaultWallet(); final defaultWallet = myWalletProvider.getDefaultWallet();
log.d(defaultWallet.address); log.d(defaultWallet.address);
sub.pay( sub.pay(
fromAddress: wallet.address!, fromAddress: wallet.address,
destAddress: defaultWallet.address!, destAddress: defaultWallet.address,
amount: -1, amount: -1,
password: myWalletProvider.pinCode); password: myWalletProvider.pinCode);
} }
await walletBox.delete(wallet.key); await walletBox.delete(wallet.key);
await sub.deleteAccounts([wallet.address!]); await sub.deleteAccounts([wallet.address]);
Navigator.pop(context); Navigator.pop(context);
} }
@ -132,98 +129,17 @@ class WalletOptionsProvider with ChangeNotifier {
} }
} }
Widget idtyStatus(BuildContext context, String address,
{bool isOwner = false, Color color = Colors.black}) {
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
showText(String text,
[double size = 18, bool bold = false, bool smooth = true]) {
log.d('$address $text');
return AnimatedFadeOutIn<String>(
data: text,
duration: Duration(milliseconds: smooth ? 200 : 0),
builder: (value) => Text(
value,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: size,
color: bold ? color : Colors.black,
fontWeight: bold ? FontWeight.w500 : FontWeight.w400),
),
);
}
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder(
future: sub.idtyStatus(address),
initialData: '',
builder: (context, snapshot) {
idtyStatusCache[address] = snapshot.data.toString();
switch (snapshot.data.toString()) {
case 'noid':
{
return showText('noIdentity'.tr());
}
case 'Created':
{
return showText('identityCreated'.tr());
}
case 'ConfirmedByOwner':
{
return isOwner
? showText('identityConfirmed'.tr())
: duniterIndexer.getNameByAddress(
context,
address,
null,
20,
true,
Colors.grey[700]!,
FontWeight.w500,
FontStyle.italic);
}
case 'Validated':
{
return isOwner
? showText('memberValidated'.tr(), 18, true)
: duniterIndexer.getNameByAddress(
context,
address,
null,
20,
true,
Colors.black,
FontWeight.w600,
FontStyle.normal);
}
case 'expired':
{
return showText('identityExpired'.tr());
}
}
return SizedBox(
child: showText('', 18, false, false),
);
});
});
}
Future<bool> isMember(BuildContext context, String address) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
return await sub.idtyStatus(address) == 'Validated';
}
Future<String?> confirmIdentityPopup(BuildContext context) async { Future<String?> confirmIdentityPopup(BuildContext context) async {
TextEditingController idtyName = TextEditingController(); TextEditingController idtyName = TextEditingController();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletOptionsProvider walletOptions = final walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
bool canValidate = false;
bool idtyExist = false;
return showDialog<String>( return showDialog<String>(
context: context, context: context,
barrierDismissible: true, // user must tap button! barrierDismissible: true, // user must tap button!
@ -240,7 +156,16 @@ class WalletOptionsProvider with ChangeNotifier {
const SizedBox(height: 20), const SizedBox(height: 20),
TextField( TextField(
key: keyEnterIdentityUsername, key: keyEnterIdentityUsername,
onChanged: (_) => notifyListeners(), onChanged: (_) async {
idtyExist = await isIdtyExist(idtyName.text);
canValidate = !idtyExist &&
!await isIdtyExist(idtyName.text) &&
idtyName.text.length >= 2 &&
idtyName.text.length <= 32;
log.d('aaaaaaaaaa: $canValidate');
notifyListeners();
},
inputFormatters: <TextInputFormatter>[ inputFormatters: <TextInputFormatter>[
// FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")), // FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")),
FilteringTextInputFormatter.deny(RegExp(r'^ ')), FilteringTextInputFormatter.deny(RegExp(r'^ ')),
@ -250,7 +175,12 @@ class WalletOptionsProvider with ChangeNotifier {
autofocus: true, autofocus: true,
controller: idtyName, controller: idtyName,
style: const TextStyle(fontSize: 19), style: const TextStyle(fontSize: 19),
) ),
const SizedBox(height: 10),
Consumer<WalletOptionsProvider>(builder: (context, wOptions, _) {
return Text(idtyExist ? "thisIdentityAlreadyExist".tr() : '',
style: TextStyle(color: Colors.red[500]));
})
]), ]),
), ),
actions: <Widget>[ actions: <Widget>[
@ -261,61 +191,65 @@ class WalletOptionsProvider with ChangeNotifier {
builder: (context, wOptions, _) { builder: (context, wOptions, _) {
return TextButton( return TextButton(
key: keyConfirm, key: keyConfirm,
onPressed: canValidate
? () async {
idtyName.text =
idtyName.text.trim().replaceAll(' ', '');
if (idtyName.text.length.clamp(3, 32) ==
idtyName.text.length) {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(
wallet: defaultWallet);
},
),
);
}
if (pin != null ||
myWalletProvider.pinCode != '') {
final wallet = myWalletProvider
.getWalletDataByAddress(address.text);
await sub.setCurrentWallet(wallet!);
sub.confirmIdentity(walletOptions.address.text,
idtyName.text, myWalletProvider.pinCode);
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transType: 'comfirmIdty',
fromAddress:
getShortPubkey(wallet.address),
toAddress: getShortPubkey(wallet.address),
);
}),
);
}
}
}
: null,
child: Text( child: Text(
"validate".tr(), "validate".tr(),
style: TextStyle( style: TextStyle(
fontSize: 21, fontSize: 21,
color: idtyName.text.length.clamp(3, 64) == color: canValidate
idtyName.text.length ? const Color(0xffD80000)
? const Color(0xffD80000) : Colors.grey[500]),
: Colors.grey,
),
), ),
onPressed: () async {
idtyName.text = idtyName.text.trim().replaceAll(' ', '');
if (idtyName.text.length.clamp(3, 64) ==
idtyName.text.length) {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(wallet: defaultWallet);
},
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
final wallet = myWalletProvider
.getWalletDataByAddress(address.text);
await sub.setCurrentWallet(wallet!);
sub.confirmIdentity(walletOptions.address.text,
idtyName.text, myWalletProvider.pinCode);
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return TransactionInProgress(
transType: 'comfirmIdty',
fromAddress: getShortPubkey(wallet.address!),
toAddress: getShortPubkey(wallet.address!),
);
}),
);
}
}
},
); );
}) })
], ],
), ),
const SizedBox(height: 20) const SizedBox(height: 5)
], ],
); );
}, },
@ -371,7 +305,7 @@ class WalletOptionsProvider with ChangeNotifier {
if (canValidateNameBool) { if (canValidateNameBool) {
nameController.text = walletName.text; nameController.text = walletName.text;
_renameWallet(wID, walletName.text, isCesium: false); _renameWallet(wID, walletName.text, isCesium: false);
// notifyListeners(); notifyListeners();
Navigator.pop(context); Navigator.pop(context);
} }
}, },
@ -405,7 +339,7 @@ class WalletOptionsProvider with ChangeNotifier {
} }
bool canValidateName(BuildContext context, TextEditingController walletName) { bool canValidateName(BuildContext context, TextEditingController walletName) {
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
bool isNameValid = walletName.text.length >= 2 && bool isNameValid = walletName.text.length >= 2 &&
@ -441,7 +375,7 @@ class WalletOptionsProvider with ChangeNotifier {
String? addressGet; String? addressGet;
walletBox.toMap().forEach((key, value) { walletBox.toMap().forEach((key, value) {
if (value.chest == chest && value.derivation == derivation) { if (value.chest == chest && value.derivation == derivation) {
addressGet = value.address!; addressGet = value.address;
return; return;
} }
}); });
@ -450,190 +384,4 @@ class WalletOptionsProvider with ChangeNotifier {
return addressGet; return addressGet;
} }
Widget walletNameController(BuildContext context, WalletData wallet,
[double size = 20]) {
nameController.text = wallet.name!;
return SizedBox(
width: 260,
child: Stack(children: <Widget>[
TextField(
key: keyWalletName,
autofocus: false,
focusNode: walletNameFocus,
enabled: isEditing,
controller: nameController,
minLines: 1,
maxLines: 3,
textAlign: TextAlign.center,
decoration: const InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(15.0),
),
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
Positioned(
right: 0,
child: InkWell(
key: keyRenameWallet,
onTap: () async {
// _isNewNameValid =
// walletProvider.editWalletName(wallet.id(), isCesium: false);
await editWalletName(context, wallet.id());
await Future.delayed(const Duration(milliseconds: 30));
walletNameFocus.requestFocus();
},
child: ClipRRect(
child: Image.asset(
isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 25,
height: 25),
),
),
),
]),
);
}
Widget walletName(BuildContext context, WalletData wallet,
[double size = 20, Color color = Colors.black]) {
double newSize = wallet.name!.length <= 15 ? size : size - 2;
return Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
truncate(wallet.name!, 20),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isTall ? newSize : newSize * 0.9,
color: color,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.italic,
),
softWrap: false,
overflow: TextOverflow.ellipsis,
),
]);
}
}
Map<String, double> balanceCache = {};
Widget balance(BuildContext context, String address, double size,
[Color color = Colors.black,
Color loadingColor = const Color(0xffd07316)]) {
return Column(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
return FutureBuilder(
future: sdk.getBalance(address),
builder: (BuildContext context,
AsyncSnapshot<Map<String, double>> globalBalance) {
if (globalBalance.connectionState != ConnectionState.done ||
globalBalance.hasError) {
if (balanceCache[address] != null &&
balanceCache[address] != -1) {
return Row(children: [
Text(balanceCache[address]!.toString(),
style: TextStyle(
fontSize: isTall ? size : size * 0.9, color: color)),
const SizedBox(width: 5),
udUnitDisplay(size, color),
]);
} else {
return SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
color: loadingColor,
strokeWidth: 2,
),
);
}
}
balanceCache[address] = globalBalance.data!['transferableBalance']!;
if (balanceCache[address] != -1) {
return Row(children: [
Text(
balanceCache[address]!.toString(),
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: color,
),
),
const SizedBox(width: 5),
udUnitDisplay(size, color),
]);
} else {
return const Text('');
}
});
}),
]);
}
Widget getCerts(BuildContext context, String address, double size,
[Color color = Colors.black]) {
return Column(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
return FutureBuilder(
future: sdk.getCerts(address),
builder: (BuildContext context, AsyncSnapshot<List<int>> certs) {
// log.d(_certs.data);
return certs.data?[0] != 0 && certs.data != null
? Row(
children: [
Image.asset('assets/medal.png', height: 20),
const SizedBox(width: 1),
Text(certs.data?[0].toString() ?? '0',
style: const TextStyle(fontSize: 20)),
const SizedBox(width: 5),
Text(
"(${certs.data?[1].toString() ?? '0'})",
style: const TextStyle(fontSize: 14),
)
],
)
: const Text('');
});
}),
]);
}
Widget udUnitDisplay(double size, [Color color = Colors.black]) {
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
return isUdUnit
? Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
'ud'.tr(args: ['']),
style:
TextStyle(fontSize: isTall ? size : size * 0.9, color: color),
),
Column(
children: [
Text(
currencyName,
style: TextStyle(
fontSize: (isTall ? size : size * 0.9) * 0.7,
fontWeight: FontWeight.w500,
color: color),
),
const SizedBox(height: 15)
],
)
],
)
: Text(currencyName,
style: TextStyle(fontSize: isTall ? size : size * 0.9, color: color));
} }

View File

@ -1,20 +1,13 @@
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/g1_wallets_list.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';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/screens/wallet_view.dart';
import 'package:jdenticon_dart/jdenticon_dart.dart'; import 'package:jdenticon_dart/jdenticon_dart.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
// import 'package:qrscan/qrscan.dart' as scanner; // import 'package:qrscan/qrscan.dart' as scanner;
import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:provider/provider.dart';
class WalletsProfilesProvider with ChangeNotifier { class WalletsProfilesProvider with ChangeNotifier {
WalletsProfilesProvider(this.address); WalletsProfilesProvider(this.address);
@ -37,14 +30,17 @@ class WalletsProfilesProvider with ChangeNotifier {
try { try {
barcode = await BarcodeScanner.scan(); barcode = await BarcodeScanner.scan();
} catch (e) { } catch (e) {
log.e(e); log.e("BarcodeScanner ERR: $e");
return 'false'; return 'false';
} }
if (isAddress(barcode.rawContent)) { if (isAddress(barcode.rawContent)) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return WalletViewScreen(address: barcode!.rawContent); return WalletViewScreen(
address: barcode!.rawContent,
username: '',
);
}), }),
); );
} else { } else {
@ -129,102 +125,6 @@ class WalletsProfilesProvider with ChangeNotifier {
return _balance; return _balance;
} }
Widget headerProfileView(
BuildContext context, String address, String? username) {
const double avatarSize = 140;
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
return Stack(children: <Widget>[
Consumer<SubstrateSdk>(builder: (context, sub, _) {
bool isAccountExist = balanceCache[address] != 0;
return Container(
height: 180,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
isAccountExist ? yellowC : Colors.grey[400]!,
isAccountExist ? const Color(0xFFE7811A) : Colors.grey[600]!,
],
),
));
}),
Padding(
padding: const EdgeInsets.only(left: 30, right: 40),
child: Row(children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 10,
color: yellowC, // Colors.grey[400],
),
Row(children: [
GestureDetector(
key: keyCopyAddress,
onTap: () {
Clipboard.setData(ClipboardData(text: address));
snackCopyKey(context);
},
child: Text(
getShortPubkey(address),
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w800,
),
),
),
]),
const SizedBox(height: 25),
balance(context, address, 22),
const SizedBox(height: 10),
walletOptions.idtyStatus(context, address,
isOwner: false, color: Colors.black),
getCerts(context, address, 14),
// if (username == null &&
// g1WalletsBox.get(address)?.username != null)
// SizedBox(
// width: 230,
// child: Text(
// g1WalletsBox.get(address)?.username ?? '',
// style: const TextStyle(
// fontSize: 27,
// color: Color(0xff814C00),
// ),
// ),
// ),
// if (username != null)
// SizedBox(
// width: 230,
// child: Text(
// username,
// style: const TextStyle(
// fontSize: 27,
// color: Color(0xff814C00),
// ),
// ),
// ),
const SizedBox(height: 55),
]),
const Spacer(),
Column(children: <Widget>[
ClipOval(
child: cesiumPlusProvider.defaultAvatar(avatarSize),
),
const SizedBox(height: 25),
]),
]),
),
CommonElements().offlineInfo(context),
]);
}
bool isContact(String address) { bool isContact(String address) {
return contactsBox.containsKey(address); return contactsBox.containsKey(address);
} }
@ -244,6 +144,15 @@ class WalletsProfilesProvider with ChangeNotifier {
} }
} }
snackMessage(context,
{required String message, int duration = 2, double fontSize = 16}) {
final snackBar = SnackBar(
padding: const EdgeInsets.all(20),
content: Text(message, style: TextStyle(fontSize: fontSize)),
duration: Duration(seconds: duration));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
snackCopyKey(context) { snackCopyKey(context) {
final snackBar = SnackBar( final snackBar = SnackBar(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
@ -252,3 +161,12 @@ snackCopyKey(context) {
duration: const Duration(seconds: 2)); duration: const Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar); ScaffoldMessenger.of(context).showSnackBar(snackBar);
} }
snackCopySeed(context) {
final snackBar = SnackBar(
padding: const EdgeInsets.all(20),
content: Text("thisMnemonicHasBeenCopiedToClipboard".tr(),
style: const TextStyle(fontSize: 17)),
duration: const Duration(seconds: 4));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

View File

@ -1,44 +1,24 @@
// ignore_for_file: must_be_immutable // ignore_for_file: must_be_immutable
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/queries_indexer.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:gecko/widgets/header_profile.dart';
import 'package:provider/provider.dart'; import 'package:gecko/widgets/history_query.dart';
class ActivityScreen extends StatelessWidget with ChangeNotifier { class ActivityScreen extends StatelessWidget with ChangeNotifier {
ActivityScreen({required this.address, required this.avatar, this.username}) ActivityScreen({required this.address, required this.avatar, this.username})
: super(key: keyActivityScreen); : super(key: keyActivityScreen);
final ScrollController scrollController = ScrollController();
final double avatarsSize = 80;
final String address; final String address;
final String? username; final String? username;
final Image avatar; final Image avatar;
FetchMore? fetchMore;
FetchMoreOptions? opts;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider walletProfile =
Provider.of<WalletsProfilesProvider>(context, listen: false);
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
return Scaffold( return Scaffold(
key: _scaffoldKey,
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
@ -47,319 +27,10 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier {
child: Text('accountActivity'.tr()), child: Text('accountActivity'.tr()),
), ),
), ),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: Column(children: <Widget>[ body: Column(children: <Widget>[
walletProfile.headerProfileView(context, address, username), HeaderProfile(address: address, username: username),
historyQuery(context), HistoryQuery(address: address),
])); ]));
} }
Widget historyQuery(context) {
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
if (indexerEndpoint == '') {
Column(children: <Widget>[
const SizedBox(height: 50),
Text(
"noNetworkNoHistory".tr(),
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18),
)
]);
}
final httpLink = HttpLink(
'$indexerEndpoint/v1beta1/relay',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistoryByAddressQ),
variables: <String, dynamic>{
'address': address,
'number': 20,
'cursor': null
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading && result.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (result.hasException) {
log.e('Error Indexer: ${result.exception}');
return Column(children: <Widget>[
const SizedBox(height: 50),
Text(
"noNetworkNoHistory".tr(),
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 18),
)
]);
} else if (result
.data?['transaction_connection']?['edges'].isEmpty) {
return Column(children: <Widget>[
const SizedBox(height: 50),
Text(
"noDataToDisplay".tr(),
style: const TextStyle(fontSize: 18),
)
]);
}
if (result.isNotLoading) {
// log.d(result.data);
opts = duniterIndexer.checkQueryResult(result, opts, address);
}
// Build history list
return NotificationListener(
child: Builder(
builder: (context) => Expanded(
child: ListView(
key: keyListTransactions,
controller: scrollController,
children: <Widget>[historyView(context, result)],
),
),
),
onNotification: (dynamic t) {
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7 &&
duniterIndexer.pageInfo!['hasNextPage'] &&
result.isNotLoading) {
fetchMore!(opts!);
}
return true;
});
},
),
],
)),
);
}
Widget historyView(context, result) {
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return duniterIndexer.transBC == null
? Column(children: <Widget>[
const SizedBox(height: 50),
Text(
"noTransactionToDisplay".tr(),
style: const TextStyle(fontSize: 18),
)
])
: Column(children: <Widget>[
getTransactionTile(context, duniterIndexer),
if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
],
),
if (!duniterIndexer.pageInfo!['hasNextPage'])
Column(
children: const <Widget>[
SizedBox(height: 15),
Text("Début de l'historique.",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20)),
SizedBox(height: 15)
],
)
]);
}
Widget getTransactionTile(
BuildContext context, DuniterIndexer duniterIndexer) {
CesiumPlusProvider cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
int keyID = 0;
String? dateDelimiter;
String? lastDateDelimiter;
const double avatarSize = 200;
bool isTody = false;
bool isYesterday = false;
bool isThisWeek = false;
final Map<int, String> monthsInYear = {
1: "month1".tr(),
2: "month2".tr(),
3: "month3".tr(),
4: "month4".tr(),
5: "month5".tr(),
6: "month6".tr(),
7: "month7".tr(),
8: "month8".tr(),
9: "month9".tr(),
10: "month10".tr(),
11: "month11".tr(),
12: "month12".tr()
};
return Column(
children: duniterIndexer.transBC!.map((repository) {
// log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString());
DateTime now = DateTime.now();
DateTime date = repository[0];
String dateForm;
if ({4, 10, 11, 12}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}.";
} else if ({1, 2, 7, 9}.contains(date.month)) {
dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}.";
} else {
dateForm = "${date.day} ${monthsInYear[date.month]}";
}
int weekNumber(DateTime date) {
int dayOfYear = int.parse(DateFormat("D").format(date));
return ((dayOfYear - date.weekday + 10) / 7).floor();
}
final transactionDate = DateTime(date.year, date.month, date.day);
final todayDate = DateTime(now.year, now.month, now.day);
final yesterdayDate = DateTime(now.year, now.month, now.day - 1);
if (transactionDate == todayDate && !isTody) {
dateDelimiter = lastDateDelimiter = "today".tr();
isTody = true;
} else if (transactionDate == yesterdayDate && !isYesterday) {
dateDelimiter = lastDateDelimiter = "yesterday".tr();
isYesterday = true;
} else if (weekNumber(date) == weekNumber(now) &&
date.year == now.year &&
lastDateDelimiter != "thisWeek".tr() &&
transactionDate != yesterdayDate &&
transactionDate != todayDate &&
!isThisWeek) {
dateDelimiter = lastDateDelimiter = "thisWeek".tr();
isThisWeek = true;
} else if (lastDateDelimiter != monthsInYear[date.month] &&
lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
transactionDate != todayDate &&
transactionDate != yesterdayDate &&
!(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
if (date.year == now.year) {
dateDelimiter = lastDateDelimiter = monthsInYear[date.month];
} else {
dateDelimiter =
lastDateDelimiter = "${monthsInYear[date.month]} ${date.year}";
}
} else {
dateDelimiter = null;
}
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
late double amount;
late String finalAmount;
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
if (isUdUnit) {
amount = round(amount / balanceRatio);
finalAmount = 'ud'.tr(args: ['$amount ']);
} else {
finalAmount = '$amount $currencyName';
}
return Column(children: <Widget>[
if (dateDelimiter != null)
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Text(
dateDelimiter!,
style: const TextStyle(
fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
),
),
Padding(
padding: const EdgeInsets.only(right: 0),
child:
// Row(children: [Column(children: [],)],)
ListTile(
key: keyTransaction(keyID++),
contentPadding: const EdgeInsets.only(
left: 20, right: 30, top: 15, bottom: 15),
leading: ClipOval(
child: cesiumPlusProvider.defaultAvatar(avatarSize),
),
title: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Text(getShortPubkey(repository[1]),
style: const TextStyle(
fontSize: 18, fontFamily: 'Monospace')),
),
subtitle: RichText(
text: TextSpan(
style: TextStyle(
fontSize: 16,
color: Colors.grey[700],
),
children: <TextSpan>[
TextSpan(
text: dateForm,
),
if (repository[2] != '')
TextSpan(
text: ' · ',
style: TextStyle(
fontSize: 20,
color: Colors.grey[550],
),
),
TextSpan(
text: repository[2],
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.grey[600],
),
),
],
),
),
trailing: Text(finalAmount,
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.w500),
textAlign: TextAlign.justify),
dense: false,
isThreeLine: false,
onTap: () {
duniterIndexer.nPage = 1;
// _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(address: repository[1]);
}),
);
// Navigator.pop(context);
}),
),
]);
}).toList());
}
} }

View File

@ -0,0 +1,76 @@
import 'package:accordion/controllers.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:gecko/globals.dart';
import 'package:flutter/material.dart';
import 'package:gecko/widgets/certs_received.dart';
import 'package:gecko/widgets/certs_counter.dart';
import 'package:gecko/widgets/certs_sent.dart';
import 'package:accordion/accordion.dart';
class CertificationsScreen extends StatelessWidget {
const CertificationsScreen(
{Key? key, required this.address, required this.username})
: super(key: key);
final String address;
final String username;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
elevation: 0,
toolbarHeight: 60 * ratio,
title: SizedBox(
height: 22,
child: Text('Certifications de $username'),
)),
body: SafeArea(
child: Accordion(
paddingListTop: 10,
paddingListBottom: 10,
maxOpenSections: 1,
headerBackgroundColorOpened: orangeC,
scaleWhenAnimating: true,
openAndCloseAnimation: true,
headerPadding:
const EdgeInsets.symmetric(vertical: 7, horizontal: 15),
sectionOpeningHapticFeedback: SectionHapticFeedback.heavy,
sectionClosingHapticFeedback: SectionHapticFeedback.light,
children: [
AccordionSection(
isOpen: true,
leftIcon:
const Icon(Icons.insights_rounded, color: Colors.black),
headerBackgroundColor: yellowC,
headerBackgroundColorOpened: orangeC,
header: Row(children: [
Text('received'.tr()),
const SizedBox(width: 5),
CertsCounter(address: address)
]),
content: CertsReceived(address: address),
contentHorizontalPadding: 0,
contentBorderWidth: 1,
),
AccordionSection(
isOpen: false,
leftIcon:
const Icon(Icons.insights_rounded, color: Colors.black),
headerBackgroundColor: yellowC,
headerBackgroundColorOpened: orangeC,
header: Row(children: [
Text('sent'.tr()),
const SizedBox(width: 5),
CertsCounter(address: address, isSent: true)
]),
content: CertsSent(address: address),
contentHorizontalPadding: 20,
contentBorderWidth: 1,
// onOpenSection: () => print('onOpenSection ...'),
// onCloseSection: () => print('onCloseSection ...'),
),
]),
));
}
}

View File

@ -1,338 +0,0 @@
import 'package:dots_indicator/dots_indicator.dart';
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';
class CommonElements {
// Exemple de Widget
Widget exemple(String data) {
return const Text('Coucou');
}
Widget buildImage(String assetName,
[double boxHeight = 440, double imageWidth = 350]) {
return Container(
padding: const EdgeInsets.all(0),
width: 440,
height: isTall ? boxHeight : boxHeight * 0.9,
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xffd2d4cf),
Color(0xffeaeae7),
],
),
border: Border.all(color: Colors.grey[900]!)),
child: Image.asset('assets/onBoarding/$assetName', width: imageWidth));
}
Widget buildText(String text, [double size = 20, bool isMd = false]) {
final mdStyle = MarkdownStyleSheet(
p: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: Colors.black,
letterSpacing: 0.3),
textAlign: WrapAlignment.spaceBetween,
);
return Container(
padding: const EdgeInsets.all(12),
width: 440,
decoration: BoxDecoration(
color: Colors.white, border: Border.all(color: Colors.grey[900]!)),
child: isMd
? MarkdownBody(data: text, styleSheet: mdStyle)
: Text(text,
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: isTall ? size : size * 0.9,
color: Colors.black,
letterSpacing: 0.3)),
);
}
Widget nextButton(
BuildContext context, String text, nextScreen, bool isFast) {
return SizedBox(
width: 380 * ratio,
height: 60 * ratio,
child: ElevatedButton(
key: keyGoNext,
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, backgroundColor: orangeC,
elevation: 4, // foreground
),
onPressed: () {
Navigator.push(
context, FaderTransition(page: nextScreen, isFast: isFast));
},
child: Text(
text,
style: TextStyle(fontSize: 23 * ratio, fontWeight: FontWeight.w600),
),
),
);
}
Widget buildProgressBar(double pagePosition) {
return DotsIndicator(
dotsCount: 10,
position: pagePosition,
decorator: DotsDecorator(
spacing: const EdgeInsets.symmetric(horizontal: 10),
color: Colors.grey[300]!, // Inactive color
activeColor: orangeC,
),
);
}
Widget infoIntro(
BuildContext context,
String text,
String assetName,
String buttonText,
nextScreen,
double pagePosition, {
bool isMd = false,
bool isFast = false,
double boxHeight = 440,
double imageWidth = 350,
double textSize = 20,
}) {
return Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20),
buildProgressBar(pagePosition),
SizedBox(height: isTall ? 40 : 20),
buildText(text, textSize, isMd),
buildImage(assetName, boxHeight, imageWidth),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: nextButton(context, buttonText, nextScreen, false),
),
),
// const SizedBox(height: 40),
SizedBox(height: isTall ? 40 : 20),
]);
}
Widget roundButton(
AssetImage image,
ontap,
isAsync,
double imgHight,
EdgeInsets padding,
) {
return Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(2.0, 2.5),
spreadRadius: 0.5)
],
),
child: ClipOval(
child: Material(
color: const Color(0xffFFD58D), // button color
child: InkWell(
splashColor: orangeC, // inkwell color
child: Padding(
padding: padding,
child: Image(image: image, height: imgHight)),
onTap: () async {
await ontap;
}),
),
),
);
}
Widget offlineInfo(BuildContext context) {
final double screenWidth = MediaQuery.of(homeContext).size.width;
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
return Visibility(
visible: !sub.nodeConnected,
child: Positioned(
top: 0,
child: Container(
height: 30,
width: screenWidth,
color: Colors.grey[800],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'youAreOffline'.tr(),
style: TextStyle(color: Colors.grey[50]),
textAlign: TextAlign.center,
),
],
)),
),
);
});
}
}
class SmoothTransition extends PageRouteBuilder {
final Widget page;
SmoothTransition({required this.page})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
TweenAnimationBuilder(
duration: const Duration(seconds: 5),
tween: Tween(begin: 200, end: 200),
builder: (BuildContext context, dynamic value, Widget? child) {
return page;
},
),
);
}
class FaderTransition extends PageRouteBuilder {
final Widget page;
final bool isFast;
FaderTransition({required this.page, required this.isFast})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
FadeTransition(
opacity:
Tween(begin: 0.0, end: isFast ? 3.0 : 1.0).animate(animation),
child: child,
),
);
}
Future<bool?> confirmPopup(BuildContext context, String title) async {
return showDialog<bool>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: backgroundColor,
content: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
key: keyConfirm,
child: Text(
"yes".tr(),
style: const TextStyle(
fontSize: 21,
color: Color(0xffD80000),
),
),
onPressed: () {
Navigator.pop(context, true);
},
),
const SizedBox(width: 20),
TextButton(
child: Text(
"no".tr(),
style: const TextStyle(fontSize: 21),
),
onPressed: () {
Navigator.pop(context, false);
},
),
const SizedBox(height: 120)
],
)
],
);
},
);
}
Future<void> infoPopup(BuildContext context, String title) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: backgroundColor,
content: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
key: keyInfoPopup,
child: const Text(
"D'accord",
style: TextStyle(
fontSize: 21,
color: Color(0xffD80000),
),
),
onPressed: () {
Navigator.pop(context, true);
},
),
],
)
],
);
},
);
}
// Widget geckoAppBar() {
// return AppBar(
// toolbarHeight: 60 * ratio,
// elevation: 0,
// leading: IconButton(
// icon: const Icon(Icons.arrow_back, color: Colors.black),
// onPressed: () {
// _walletOptions.isEditing = false;
// _walletOptions.isBalanceBlur = false;
// Navigator.pop(context);
// }),
// title: SizedBox(
// height: 22,
// child: Consumer<WalletOptionsProvider>(
// builder: (context, walletProvider, _) {
// return Text(_walletOptions.nameController.text);
// }),
// ),
// );
// }

View File

@ -3,8 +3,10 @@
import 'package:bubble/bubble.dart'; import 'package:bubble/bubble.dart';
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/duniter_indexer.dart';
@ -14,30 +16,124 @@ import 'package:gecko/providers/wallets_profiles.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/screens/animated_text.dart'; import 'package:gecko/widgets/commons/animated_text.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:gecko/screens/myWallets/restore_chest.dart'; import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/screens/onBoarding/1.dart'; import 'package:gecko/screens/onBoarding/1.dart';
import 'package:gecko/screens/search.dart'; import 'package:gecko/screens/search.dart';
import 'package:gecko/screens/settings.dart'; import 'package:gecko/screens/settings.dart';
import 'package:flutter/services.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gecko/screens/my_contacts.dart'; import 'package:gecko/screens/my_contacts.dart';
class HomeScreen extends StatelessWidget { class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key); const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
final homeProviderInit =
Provider.of<HomeProvider>(context, listen: false);
final sub = Provider.of<SubstrateSdk>(context, listen: false);
final duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
// Check if versionData non compatible, drop everything
if (configBox.get('dataVersion') == null) {
configBox.put('dataVersion', dataVersion);
}
if (isWalletsExists && (configBox.get('dataVersion')) < dataVersion) {
if (!sub.sdkReady && !sub.sdkLoading) sub.initApi();
await infoPopup(context, "chestNotCompatibleMustReinstallGecko".tr());
await Hive.deleteBoxFromDisk('walletBox');
await Hive.deleteBoxFromDisk('chestBox');
chestBox = await Hive.openBox<ChestData>("chestBox");
await configBox.delete('defaultWallet');
if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi();
await sub.deleteAllAccounts();
configBox.put('dataVersion', dataVersion);
myWalletProvider.reload();
} else {
if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi();
}
if (sub.sdkReady && !sub.nodeConnected) {
walletBox = await Hive.openBox<WalletData>("walletBox");
await Hive.deleteBoxFromDisk('g1WalletsBox');
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
contactsBox = await Hive.openBox<G1WalletsList>("contactsBox");
homeProviderInit.isWalletBoxInit = true;
myWalletProvider.reload();
duniterIndexer.getValidIndexerEndpoint();
await homeProviderInit.getValidEndpoints();
// await configBox.delete('isCacheChecked');
if (configBox.get('isCacheChecked') == null) {
configBox.put('isCacheChecked', false);
}
// log.d(await configBox.get('endpoint'));
// var connectivityResult =
// await (Connectivity().checkConnectivity());
// if (connectivityResult != ConnectivityResult.mobile &&
// connectivityResult != ConnectivityResult.wifi) {
// homeProvider.changeMessage(
// "notConnectedToInternet".tr(), 0);
// sub.nodeConnected = false;
// }
// Améliore ce code car il y a un bug: parfois l'app se croit hors ligne, alors que c'est faux, le téléphone est bien connecté à internet
// (GPT vscode extension fixed it for my...)
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
log.d('Network changed: $result');
if (result == ConnectivityResult.none) {
sub.nodeConnected = false;
await sub.sdk.api.setting.unsubscribeBestNumber();
homeProvider.changeMessage("notConnectedToInternet".tr(), 0);
sub.reload();
} else {
// Check if the phone is actually connected to the internet
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult != ConnectivityResult.none) {
await sub.connectNode(context);
// Currency parameters
await sub.initCurrencyParameters();
// Indexer Blockchain start
getBlockStart();
}
}
});
// await sub.connectNode(ctx);
}
// _duniterIndexer.checkIndexerEndpointBackground();
});
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
homeContext = context; homeContext = context;
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
final myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<ChestProvider>(context);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
isTall = false; isTall = false;
@ -47,148 +143,85 @@ class HomeScreen extends StatelessWidget {
ratio = 1.125; ratio = 1.125;
} }
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
drawer: Drawer( drawer: Drawer(
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: ListView(padding: EdgeInsets.zero, children: <Widget>[ child: ListView(padding: EdgeInsets.zero, children: <Widget>[
DrawerHeader( DrawerHeader(
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: orangeC, color: orangeC,
),
child: Column(children: const <Widget>[
SizedBox(height: 0),
Image(
image: AssetImage('assets/icon/gecko_final.png'),
height: 130),
]),
), ),
child: Column(children: const <Widget>[ ListTile(
SizedBox(height: 0), key: keyParameters,
Image( title: Text('parameters'.tr()),
image: AssetImage('assets/icon/gecko_final.png'), onTap: () {
height: 130), Navigator.pop(context);
]), Navigator.push(
), context,
ListTile( MaterialPageRoute(builder: (context) {
key: keyParameters, return SettingsScreen();
title: Text('parameters'.tr()), }),
onTap: () { );
Navigator.pop(context); },
Navigator.push( ),
context, if (isWalletsExists)
MaterialPageRoute(builder: (context) { ListTile(
return SettingsScreen(); key: keyContacts,
}), title: Text('contactsManagement'.tr()),
); onTap: () {
}, Navigator.pop(context);
), Navigator.push(
ListTile( context,
key: keyContacts, MaterialPageRoute(builder: (context) {
title: Text('contactsManagement'.tr()), return const ContactsScreen();
onTap: () { }),
Navigator.pop(context); );
Navigator.push( },
context, ),
MaterialPageRoute(builder: (context) { ])),
return const ContactsScreen(); Align(
}),
);
},
),
])),
Align(
alignment: FractionalOffset.bottomCenter, alignment: FractionalOffset.bottomCenter,
child: Text('Ğecko v$appVersion')), child: InkWell(
const SizedBox(height: 20) key: keyCopyAddress,
], splashColor: orangeC,
child: Padding(
padding: const EdgeInsets.all(20),
child: Text('Ğecko v$appVersion')),
onTap: () {
Clipboard.setData(
ClipboardData(text: 'Ğecko v$appVersion'));
snackMessage(context,
message:
'Le numéro de version de Ğecko a été copié dans votre presse papier',
duration: 4);
}),
),
const SizedBox(height: 20)
],
),
), ),
), backgroundColor: const Color(0xffF9F9F1),
// bottomNavigationBar: _homeProvider.bottomBar(context, 1), body: isWalletsExists ? geckHome(context) : welcomeHome(context));
backgroundColor: const Color(0xffF9F9F1),
body: Builder(
builder: (ctx) => StatefulWrapper(
onInit: () {
WidgetsBinding.instance.addPostFrameCallback((_) async {
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(ctx, listen: false);
duniterIndexer.getValidIndexerEndpoint();
if (!sub.sdkReady && !sub.sdkLoading) await sub.initApi();
if (sub.sdkReady && !sub.nodeConnected) {
// Check if versionData non compatible, drop everything
if (walletBox.isNotEmpty &&
walletBox.getAt(0)!.version! < dataVersion) {
await infoPopup(
context, "chestNotCompatibleMustReinstallGecko".tr());
await walletBox.clear();
await chestBox.clear();
await configBox.delete('defaultWallet');
await sub.deleteAllAccounts();
myWalletProvider.reload();
}
// var connectivityResult =
// await (Connectivity().checkConnectivity());
// if (connectivityResult != ConnectivityResult.mobile &&
// connectivityResult != ConnectivityResult.wifi) {
// homeProvider.changeMessage(
// "notConnectedToInternet".tr(), 0);
// sub.nodeConnected = false;
// }
// TODO: fix random bad network status on startup
HomeProvider homeProvider =
Provider.of<HomeProvider>(ctx, listen: false);
Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
log.d('Network changed: $result');
if (result == ConnectivityResult.none) {
sub.nodeConnected = false;
await sub.sdk.api.setting.unsubscribeBestNumber();
homeProvider.changeMessage(
"notConnectedToInternet".tr(), 0);
sub.reload();
} else {
await sub.connectNode(ctx);
}
});
// await sub.connectNode(ctx);
}
// _duniterIndexer.checkIndexerEndpointBackground();
});
},
child: isWalletsExists ? geckHome(context) : welcomeHome(context)
// bottomNavigationBar: BottomNavigationBar(
// backgroundColor: backgroundColor,
// fixedColor: Colors.grey[850],
// unselectedItemColor: const Color(0xffBD935C),
// type: BottomNavigationBarType.fixed,
// onTap: (index) {
// _homeProvider.currentIndex = index;
// },
// currentIndex: _homeProvider.currentIndex,
// items: [
// BottomNavigationBarItem(
// icon: Image.asset('assets/block-space-disabled.png', height: 26),
// activeIcon: Image.asset('assets/blockchain.png', height: 26),
// label: 'Explorateur',
// ),
// const BottomNavigationBarItem(
// icon: Icon(Icons.lock),
// label: 'Mes portefeuilles',
// ),
// ],
// ),
),
),
);
} }
} }
Widget geckHome(context) { Widget geckHome(context) {
MyWalletsProvider myWalletProvider = Provider.of<MyWalletsProvider>(context); final myWalletProvider = Provider.of<MyWalletsProvider>(context);
final homeProvider = Provider.of<HomeProvider>(context, listen: false);
Provider.of<ChestProvider>(context); Provider.of<ChestProvider>(context);
WalletsProfilesProvider historyProvider = WalletsProfilesProvider historyProvider =
Provider.of<WalletsProfilesProvider>(context); Provider.of<WalletsProfilesProvider>(context);
final double statusBarHeight = MediaQuery.of(context).padding.top; final statusBarHeight = MediaQuery.of(context).padding.top;
return Container( return Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( image: DecorationImage(
@ -330,42 +363,47 @@ Widget geckHome(context) {
child: ClipOval( child: ClipOval(
key: keyOpenWalletsHomme, key: keyOpenWalletsHomme,
child: Material( child: Material(
color: orangeC, // button color color: homeProvider.isWalletBoxInit
? orangeC
: Colors.grey[500], // button color
child: InkWell( child: InkWell(
onTap: !homeProvider.isWalletBoxInit
? null
: () async {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(
wallet: defaultWallet);
},
),
);
}
if (pin != null ||
myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
// log.d(_myWalletProvider.pinCode);
// Navigator.pushNamed(
// context, '/mywallets')));
},
child: Padding( child: Padding(
padding: const EdgeInsets.all(18), padding: const EdgeInsets.all(18),
child: Image( child: Image(
image: const AssetImage( image: const AssetImage(
'assets/home/wallet.png'), 'assets/home/wallet.png'),
height: 68 * ratio)), height: 68 * ratio))),
onTap: () async {
WalletData? defaultWallet =
myWalletProvider.getDefaultWallet();
String? pin;
if (myWalletProvider.pinCode == '') {
pin = await Navigator.push(
context,
MaterialPageRoute(
builder: (homeContext) {
return UnlockingWallet(
wallet: defaultWallet);
},
),
);
}
if (pin != null || myWalletProvider.pinCode != '') {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const WalletsHome();
}),
);
}
// log.d(_myWalletProvider.pinCode);
// Navigator.pushNamed(
// context, '/mywallets')));
}),
), ),
), ),
), ),
@ -434,7 +472,7 @@ Widget geckHome(context) {
} }
Widget welcomeHome(context) { Widget welcomeHome(context) {
final double statusBarHeight = MediaQuery.of(context).padding.top; final statusBarHeight = MediaQuery.of(context).padding.top;
return Container( return Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(

View File

@ -3,9 +3,8 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:durt/durt.dart'; import 'package:durt/durt.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/stateful_wrapper.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
@ -13,7 +12,7 @@ import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChangePinScreen extends StatelessWidget with ChangeNotifier { class ChangePinScreen extends StatefulWidget with ChangeNotifier {
ChangePinScreen( ChangePinScreen(
{Key? keyMyWallets, {Key? keyMyWallets,
required this.walletName, required this.walletName,
@ -22,13 +21,23 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
final String? walletName; final String? walletName;
final MyWalletsProvider walletProvider; final MyWalletsProvider walletProvider;
@override
State<ChangePinScreen> createState() => _ChangePinScreenState();
}
class _ChangePinScreenState extends State<ChangePinScreen> {
final TextEditingController newPin = TextEditingController(); final TextEditingController newPin = TextEditingController();
@override
void initState() {
newPin.text = randomSecretCode(pinLength);
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final myWalletProvider =
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
return WillPopScope( return WillPopScope(
@ -49,18 +58,12 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
}), }),
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text(walletName!), child: Text(widget.walletName!),
), ),
), ),
body: Center( body: Center(
child: SafeArea( child: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
StatefulWrapper(
onInit: () {
newPin.text = randomSecretCode(pinLength);
},
child: Container(),
),
const SizedBox(height: 80), const SizedBox(height: 80),
Text( Text(
'choosePassword'.tr(), 'choosePassword'.tr(),
@ -118,9 +121,9 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
); );
} }
if (pin != null || myWalletProvider.pinCode != '') { if (pin != null || myWalletProvider.pinCode != '') {
await sub.changePassword(context, defaultWallet.address!, await sub.changePassword(context, defaultWallet.address,
walletProvider.pinCode, newPin.text); widget.walletProvider.pinCode, newPin.text);
walletProvider.pinCode = newPin.text; widget.walletProvider.pinCode = newPin.text;
newPin.text = ''; newPin.text = '';
Navigator.pop(context); Navigator.pop(context);
} }

View File

@ -4,18 +4,17 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/chest_provider.dart';
import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/myWallets/change_pin.dart';
import 'package:gecko/screens/myWallets/custom_derivations.dart'; import 'package:gecko/screens/myWallets/custom_derivations.dart';
import 'package:gecko/screens/myWallets/show_seed.dart'; import 'package:gecko/screens/myWallets/show_seed.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ChestOptions extends StatelessWidget { class ChestOptions extends StatelessWidget {
@ -25,11 +24,7 @@ class ChestOptions extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final chestProvider = Provider.of<ChestProvider>(context, listen: false);
ChestProvider chestProvider =
Provider.of<ChestProvider>(context, listen: false);
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
ChestData currentChest = chestBox.get(configBox.get('currentChest'))!; ChestData currentChest = chestBox.get(configBox.get('currentChest'))!;
@ -52,7 +47,7 @@ class ChestOptions extends StatelessWidget {
height: 22, height: 22,
child: Text(currentChest.name!), child: Text(currentChest.name!),
)), )),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: Stack(children: [ body: Stack(children: [
Builder( Builder(
builder: (ctx) => SafeArea( builder: (ctx) => SafeArea(
@ -61,7 +56,7 @@ class ChestOptions extends StatelessWidget {
InkWell( InkWell(
key: keyShowSeed, key: keyShowSeed,
onTap: () async { onTap: () async {
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
WalletData? defaultWallet = WalletData? defaultWallet =
myWalletProvider.getDefaultWallet(); myWalletProvider.getDefaultWallet();
@ -110,26 +105,27 @@ class ChestOptions extends StatelessWidget {
Consumer<SubstrateSdk>(builder: (context, sub, _) { Consumer<SubstrateSdk>(builder: (context, sub, _) {
return InkWell( return InkWell(
key: keyChangePin, key: keyChangePin,
onTap: sub.nodeConnected onTap: null,
? () async { // sub.nodeConnected
// await _chestProvider.changePin(context, cesiumWallet); // ? () async {
String? pinResult = await Navigator.push( // // await _chestProvider.changePin(context, cesiumWallet);
context, // String? pinResult = await Navigator.push(
MaterialPageRoute( // context,
builder: (context) { // MaterialPageRoute(
return ChangePinScreen( // builder: (context) {
walletName: currentChest.name, // return ChangePinScreen(
walletProvider: walletProvider, // walletName: currentChest.name,
); // walletProvider: walletProvider,
}, // );
), // },
); // ),
// );
if (pinResult != null) { // if (pinResult != null) {
walletProvider.pinCode = pinResult; // walletProvider.pinCode = pinResult;
} // }
} // }
: null, // : null,
child: SizedBox( child: SizedBox(
height: 50, height: 50,
child: Row(children: <Widget>[ child: Row(children: <Widget>[
@ -144,7 +140,7 @@ class ChestOptions extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
color: sub.nodeConnected color: sub.nodeConnected
? Colors.black ? Colors.grey[500]
: Colors.grey[500]), : Colors.grey[500]),
), ),
])), ])),
@ -215,7 +211,7 @@ class ChestOptions extends StatelessWidget {
]), ]),
), ),
), ),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
); );
} }

View File

@ -1,7 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
@ -30,9 +30,7 @@ class _ChooseChestState extends State<ChooseChest> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final myWalletProvider = Provider.of<MyWalletsProvider>(context);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,

View File

@ -3,15 +3,15 @@
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/myWallets/wallets_home.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart';
import 'package:gecko/widgets/balance.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart'; // import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart'; // import 'package:provider/provider.dart';
@ -23,8 +23,7 @@ class ChooseWalletScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
final int chest = configBox.get('currentChest'); final int chest = configBox.get('currentChest');
return Scaffold( return Scaffold(
@ -73,9 +72,7 @@ class ChooseWalletScreen extends StatelessWidget {
} }
Widget myWalletsTiles(BuildContext context, int currentChest) { Widget myWalletsTiles(BuildContext context, int currentChest) {
MyWalletsProvider myWalletProvider = final myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<MyWalletsProvider>(context);
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
@ -97,8 +94,11 @@ class ChooseWalletScreen extends StatelessWidget {
]); ]);
} }
List listWallets = myWalletProvider.listWallets; List<WalletData> listWallets = myWalletProvider.listWallets;
final double screenWidth = MediaQuery.of(context).size.width; listWallets.sort((p1, p2) {
return Comparable.compare(p1.number!, p2.number!);
});
final screenWidth = MediaQuery.of(context).size.width;
int nTule = 2; int nTule = 2;
if (screenWidth >= 900) { if (screenWidth >= 900) {
@ -116,11 +116,11 @@ class ChooseWalletScreen extends StatelessWidget {
crossAxisSpacing: 0, crossAxisSpacing: 0,
mainAxisSpacing: 0, mainAxisSpacing: 0,
children: <Widget>[ children: <Widget>[
for (WalletData repository in listWallets as Iterable<WalletData>) for (WalletData repository in listWallets)
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: GestureDetector( child: GestureDetector(
key: keySelectThisWallet(repository.address!), key: keySelectThisWallet(repository.address),
onTap: () { onTap: () {
selectedWallet = repository; selectedWallet = repository;
myWalletProvider.reload(); myWalletProvider.reload();
@ -169,8 +169,8 @@ class ChooseWalletScreen extends StatelessWidget {
), ),
), ),
)), )),
balanceBuilder(context, repository.address!, balanceBuilder(context, repository.address,
selectedWallet!.address == repository.address!), selectedWallet!.address == repository.address),
ListTile( ListTile(
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical( borderRadius: BorderRadius.vertical(
@ -225,8 +225,10 @@ class ChooseWalletScreen extends StatelessWidget {
// style: TextStyle(color: isDefault ? Colors.white : Colors.black), // style: TextStyle(color: isDefault ? Colors.white : Colors.black),
// ), // ),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [
balance( Balance(
context, address, 16, isDefault ? Colors.white : Colors.black), address: address,
size: 16,
color: isDefault ? Colors.white : Colors.black),
]) ])
]), ]),
), ),

View File

@ -1,7 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
@ -27,8 +27,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final myWalletProvider =
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
final derivationList = <String>[ final derivationList = <String>[
@ -130,7 +129,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
if (dropdownValue == 'root') { if (dropdownValue == 'root') {
await myWalletProvider.generateRootWallet( await myWalletProvider.generateRootWallet(
context, 'Portefeuille racine'); context, 'rootWallet'.tr());
} else { } else {
await myWalletProvider.generateNewDerivation( await myWalletProvider.generateNewDerivation(
context, context,

View File

@ -4,16 +4,18 @@ import 'dart:async';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.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/providers/wallets_profiles.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:gecko/widgets/certifications.dart';
import 'package:gecko/widgets/idty_status.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ImportG1v1 extends StatelessWidget { class ImportG1v1 extends StatelessWidget {
@ -21,10 +23,7 @@ class ImportG1v1 extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final myWalletProvider =
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
Timer? debounce; Timer? debounce;
@ -57,7 +56,7 @@ class ImportG1v1 extends StatelessWidget {
child: Consumer<SubstrateSdk>(builder: (context, sub, _) { child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder( return FutureBuilder(
future: sub.getBalanceAndIdtyStatus( future: sub.getBalanceAndIdtyStatus(
sub.g1V1NewAddress, selectedWallet.address!), sub.g1V1NewAddress, selectedWallet.address),
builder: (BuildContext context, AsyncSnapshot<List> status) { builder: (BuildContext context, AsyncSnapshot<List> status) {
// log.d(_certs.data); // log.d(_certs.data);
@ -83,6 +82,7 @@ class ImportG1v1 extends StatelessWidget {
final String idtyStatus = status.data?[1]; final String idtyStatus = status.data?[1];
final String myIdtyStatus = status.data?[2]; final String myIdtyStatus = status.data?[2];
final bool hasConsumer = status.data?[3] ?? false; final bool hasConsumer = status.data?[3] ?? false;
final bool isSmith = status.data?[4] ?? false;
// log.d('hasconsumer: $hasConsumer'); // log.d('hasconsumer: $hasConsumer');
@ -92,7 +92,7 @@ class ImportG1v1 extends StatelessWidget {
} else { } else {
canValidate = false; canValidate = false;
validationStatus = hasConsumer validationStatus = hasConsumer
? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X']) ? 'youMustWaitBeforeCashoutThisAccount'.tr()
: 'thisAccountIsEmpty'.tr(); : 'thisAccountIsEmpty'.tr();
} }
@ -102,6 +102,11 @@ class ImportG1v1 extends StatelessWidget {
'youCannotMigrateIdentityToExistingIdentity'.tr(); 'youCannotMigrateIdentityToExistingIdentity'.tr();
} }
if (isSmith) {
canValidate = false;
validationStatus = 'smithCantMigrateIdentity'.tr();
}
if (sub.g1V1NewAddress == '') { if (sub.g1V1NewAddress == '') {
validationStatus = ''; validationStatus = '';
} }
@ -185,13 +190,13 @@ class ImportG1v1 extends StatelessWidget {
key: keyCopyAddress, key: keyCopyAddress,
onTap: () { onTap: () {
Clipboard.setData( Clipboard.setData(
ClipboardData(text: sub.g1V1NewAddress)); ClipboardData(text: sub.g1V1OldPubkey));
snackCopyKey(context); snackCopyKey(context);
}, },
child: Text( child: Text(
getShortPubkey(sub.g1V1NewAddress), sub.g1V1OldPubkey,
style: const TextStyle( style: const TextStyle(
fontSize: 20, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),
@ -204,10 +209,12 @@ class ImportG1v1 extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
walletOptions.idtyStatus(context, sub.g1V1NewAddress, IdentityStatus(
isOwner: false, color: Colors.black), address: sub.g1V1NewAddress,
isOwner: false,
color: Colors.black),
const SizedBox(width: 10), const SizedBox(width: 10),
getCerts(context, sub.g1V1NewAddress, 14) Certifications(address: sub.g1V1NewAddress, size: 14)
], ],
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
@ -221,7 +228,7 @@ class ImportG1v1 extends StatelessWidget {
icon: const Icon(Icons.keyboard_arrow_down), icon: const Icon(Icons.keyboard_arrow_down),
items: myWalletProvider.listWallets.map((wallet) { items: myWalletProvider.listWallets.map((wallet) {
return DropdownMenuItem( return DropdownMenuItem(
key: keySelectThisWallet(wallet.address!), key: keySelectThisWallet(wallet.address),
value: wallet, value: wallet,
child: Text( child: Text(
wallet.name!, wallet.name!,
@ -263,10 +270,8 @@ class ImportG1v1 extends StatelessWidget {
); );
} }
sub.migrateCsToV2( sub.migrateCsToV2(sub.csSalt.text,
sub.csSalt.text, sub.csPassword.text, selectedWallet.address,
sub.csPassword.text,
selectedWallet.address!,
destPassword: destPassword:
pin ?? myWalletProvider.pinCode, pin ?? myWalletProvider.pinCode,
balance: balance, balance: balance,
@ -279,7 +284,7 @@ class ImportG1v1 extends StatelessWidget {
fromAddress: fromAddress:
getShortPubkey(sub.g1V1NewAddress), getShortPubkey(sub.g1V1NewAddress),
toAddress: getShortPubkey( toAddress: getShortPubkey(
selectedWallet.address!)); selectedWallet.address));
}), }),
); );
resetScreen(context); resetScreen(context);
@ -308,7 +313,7 @@ class ImportG1v1 extends StatelessWidget {
} }
void resetScreen(BuildContext context) { void resetScreen(BuildContext context) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
sub.csSalt.text = ''; sub.csSalt.text = '';
sub.csPassword.text = ''; sub.csPassword.text = '';

View File

@ -1,14 +1,14 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:gecko/screens/myWallets/migrate_identity.dart'; import 'package:gecko/screens/myWallets/migrate_identity.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/screens/transaction_in_progress.dart';
@ -27,7 +27,6 @@ class ManageMembership extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
final sub = Provider.of<SubstrateSdk>(context); final sub = Provider.of<SubstrateSdk>(context);
return Scaffold( return Scaffold(
@ -116,9 +115,9 @@ class ManageMembership extends StatelessWidget {
false; false;
if (answer) { if (answer) {
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
// MyWalletsProvider mw = MyWalletsProvider(); // MyWalletsProvider mw = MyWalletsProvider();
// final wallet = mw.getWalletDataByAddress(address); // final wallet = mw.getWalletDataByAddress(address);

View File

@ -1,7 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,14 +20,12 @@ class MigrateIdentityScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); // final _homeProvider = Provider.of<HomeProvider>(context);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context); final walletOptions =
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
DuniterIndexer duniterIndexer = final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
Provider.of<DuniterIndexer>(context, listen: false);
final fromAddress = walletOptions.address.text; final fromAddress = walletOptions.address.text;
final defaultWallet = myWalletProvider.getDefaultWallet(); final defaultWallet = myWalletProvider.getDefaultWallet();
@ -77,7 +75,7 @@ class MigrateIdentityScreen extends StatelessWidget {
child: Consumer<SubstrateSdk>(builder: (context, sub, _) { child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
return FutureBuilder( return FutureBuilder(
future: sub.getBalanceAndIdtyStatus( future: sub.getBalanceAndIdtyStatus(
fromAddress, selectedWallet.address!), fromAddress, selectedWallet.address),
builder: (BuildContext context, AsyncSnapshot<List> status) { builder: (BuildContext context, AsyncSnapshot<List> status) {
if (status.data == null) { if (status.data == null) {
return Column(children: [ return Column(children: [
@ -103,12 +101,21 @@ class MigrateIdentityScreen extends StatelessWidget {
final String idtyStatus = status.data?[1]; final String idtyStatus = status.data?[1];
final String myIdtyStatus = status.data?[2]; final String myIdtyStatus = status.data?[2];
final bool hasConsumer = status.data?[3] ?? false; final bool hasConsumer = status.data?[3] ?? false;
final bool isSmith = status.data?[4] ?? false;
// log.d('hasconsumer: $hasConsumer'); // log.d('hasconsumer: $hasConsumer');
if (balance['transferableBalance'] != 0 && !hasConsumer) { if (isSmith) {
canValidate = false;
validationStatus = 'smithCantMigrateIdentity'.tr();
} else if (balance['transferableBalance'] != 0 &&
!hasConsumer) {
canValidate = true; canValidate = true;
validationStatus = ''; validationStatus = '';
} else if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
canValidate = false;
validationStatus =
'youCannotMigrateIdentityToExistingIdentity'.tr();
} else { } else {
canValidate = false; canValidate = false;
validationStatus = hasConsumer validationStatus = hasConsumer
@ -116,14 +123,8 @@ class MigrateIdentityScreen extends StatelessWidget {
: 'thisAccountIsEmpty'.tr(); : 'thisAccountIsEmpty'.tr();
} }
if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
canValidate = false;
validationStatus =
'youCannotMigrateIdentityToExistingIdentity'.tr();
}
log.d( log.d(
'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus'); 'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address}, $balance, $idtyStatus, $myIdtyStatus');
final walletsList = myWalletProvider.listWallets.toList(); final walletsList = myWalletProvider.listWallets.toList();
@ -176,7 +177,7 @@ class MigrateIdentityScreen extends StatelessWidget {
icon: const Icon(Icons.keyboard_arrow_down), icon: const Icon(Icons.keyboard_arrow_down),
items: walletsList.map((wallet) { items: walletsList.map((wallet) {
return DropdownMenuItem( return DropdownMenuItem(
key: keySelectThisWallet(wallet.address!), key: keySelectThisWallet(wallet.address),
value: wallet, value: wallet,
child: Text( child: Text(
wallet.name!, wallet.name!,
@ -221,7 +222,7 @@ class MigrateIdentityScreen extends StatelessWidget {
sub.migrateIdentity( sub.migrateIdentity(
fromAddress: fromAddress, fromAddress: fromAddress,
destAddress: selectedWallet.address!, destAddress: selectedWallet.address,
fromPassword: pin ?? myWalletProvider.pinCode, fromPassword: pin ?? myWalletProvider.pinCode,
destPassword: pin ?? myWalletProvider.pinCode, destPassword: pin ?? myWalletProvider.pinCode,
withBalance: true, withBalance: true,
@ -233,7 +234,7 @@ class MigrateIdentityScreen extends StatelessWidget {
transType: 'identityMigration', transType: 'identityMigration',
fromAddress: getShortPubkey(fromAddress), fromAddress: getShortPubkey(fromAddress),
toAddress: getShortPubkey( toAddress: getShortPubkey(
selectedWallet.address!)); selectedWallet.address));
}), }),
); );
} }

View File

@ -1,14 +1,17 @@
// ignore_for_file: use_build_context_synchronously
import 'package:bubble/bubble.dart'; import 'package:bubble/bubble.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/7.dart';
import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/screens/onBoarding/9.dart';
import 'package:gecko/widgets/commons/fader_transition.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart'; // import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart'; // import 'package:provider/provider.dart';
@ -19,10 +22,8 @@ class RestoreChest extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final genW = Provider.of<GenerateWalletsProvider>(context, listen: false);
GenerateWalletsProvider genW = final sub = Provider.of<SubstrateSdk>(context, listen: false);
Provider.of<GenerateWalletsProvider>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
genW.actualWallet = null; genW.actualWallet = null;
if (genW.isSentenceComplete(context)) { if (genW.isSentenceComplete(context)) {
@ -157,7 +158,7 @@ class RestoreChest extends StatelessWidget {
) )
]) ])
]), ]),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
), ),
@ -183,7 +184,7 @@ class RestoreChest extends StatelessWidget {
} }
Widget arrayCell(BuildContext context, TextEditingController cellCtl) { Widget arrayCell(BuildContext context, TextEditingController cellCtl) {
GenerateWalletsProvider generateWalletProvider = final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
return Container( return Container(

View File

@ -1,12 +1,14 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/widgets/commons/build_text.dart';
import 'package:pdf/pdf.dart'; import 'package:pdf/pdf.dart';
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -23,12 +25,9 @@ class ShowSeed extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final myWalletProvider =
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
CommonElements common = CommonElements(); final sub = Provider.of<SubstrateSdk>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
WalletData defaultWallet = myWalletProvider.getDefaultWallet(); WalletData defaultWallet = myWalletProvider.getDefaultWallet();
@ -45,7 +44,7 @@ class ShowSeed extends StatelessWidget {
const Spacer(flex: 1), const Spacer(flex: 1),
FutureBuilder( FutureBuilder(
future: future:
sub.getSeed(defaultWallet.address!, walletProvider.pinCode), sub.getSeed(defaultWallet.address, walletProvider.pinCode),
builder: (BuildContext context, AsyncSnapshot<String?> seed) { builder: (BuildContext context, AsyncSnapshot<String?> seed) {
if (seed.connectionState != ConnectionState.done || if (seed.connectionState != ConnectionState.done ||
seed.hasError) { seed.hasError) {
@ -65,7 +64,7 @@ class ShowSeed extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Column(children: [ Column(children: [
common.buildText('keepYourMnemonicSecret'.tr()), BuildText(text: 'keepYourMnemonicSecret'.tr()),
SizedBox(height: 35 * ratio), SizedBox(height: 35 * ratio),
sentanceArray(context, seed.data!.split(' ')), sentanceArray(context, seed.data!.split(' ')),
const SizedBox(height: 20), const SizedBox(height: 20),
@ -83,7 +82,7 @@ class ShowSeed extends StatelessWidget {
onPressed: () { onPressed: () {
Clipboard.setData( Clipboard.setData(
ClipboardData(text: seed.data)); ClipboardData(text: seed.data));
snackCopyKey(context); snackCopySeed(context);
}, },
child: Row(children: <Widget>[ child: Row(children: <Widget>[
Image.asset( Image.asset(
@ -141,16 +140,6 @@ class ShowSeed extends StatelessWidget {
)); ));
} }
snackCopyKey(context) {
const snackBar = SnackBar(
padding: EdgeInsets.all(20),
content: Text(
"Votre phrase de restauration a été copié dans votre presse-papier.",
style: TextStyle(fontSize: 16)),
duration: Duration(seconds: 2));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
Widget sentanceArray(BuildContext context, List mnemonic) { Widget sentanceArray(BuildContext context, List mnemonic) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 3), padding: const EdgeInsets.symmetric(horizontal: 3),

View File

@ -3,7 +3,7 @@
import 'dart:async'; import 'dart:async';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
@ -11,7 +11,7 @@ import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/screens/myWallets/choose_chest.dart'; // import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
@ -22,6 +22,8 @@ class UnlockingWallet extends StatelessWidget {
late int currentChestNumber; late int currentChestNumber;
late ChestData currentChest; late ChestData currentChest;
bool canUnlock = true; bool canUnlock = true;
TextEditingController enterPin = TextEditingController();
FocusNode pinFocus = FocusNode(debugLabel: 'pinFocusNode');
// ignore: close_sinks // ignore: close_sinks
StreamController<ErrorAnimationType>? errorController; StreamController<ErrorAnimationType>? errorController;
@ -30,10 +32,10 @@ class UnlockingWallet extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final walletOptions =
WalletOptionsProvider walletOptions = Provider.of<WalletOptionsProvider>(context, listen: false);
Provider.of<WalletOptionsProvider>(context); final myWalletProvider =
// final double statusBarHeight = MediaQuery.of(context).padding.top; Provider.of<MyWalletsProvider>(context, listen: false);
currentChestNumber = configBox.get('currentChest'); currentChestNumber = configBox.get('currentChest');
currentChest = chestBox.get(currentChestNumber)!; currentChest = chestBox.get(currentChestNumber)!;
@ -41,154 +43,168 @@ class UnlockingWallet extends StatelessWidget {
int pinLenght = walletOptions.getPinLenght(wallet.number); int pinLenght = walletOptions.getPinLenght(wallet.number);
errorController = StreamController<ErrorAnimationType>(); errorController = StreamController<ErrorAnimationType>();
return Scaffold( // if (enterPin.text == '') myWalletProvider.isPinLoading = true;
backgroundColor: backgroundColor,
body: SafeArea( return WillPopScope(
child: Column( onWillPop: () {
crossAxisAlignment: CrossAxisAlignment.start, myWalletProvider.isPinValid = false;
children: <Widget>[ myWalletProvider.isPinLoading = true;
Stack(children: <Widget>[ return Future<bool>.value(true);
Positioned( },
top: 10, //statusBarHeight + 10, child: Scaffold(
left: 15, backgroundColor: backgroundColor,
child: Builder( body: SafeArea(
builder: (context) => IconButton( child: Column(
key: keyPopButton, crossAxisAlignment: CrossAxisAlignment.start,
icon: const Icon( children: <Widget>[
Icons.arrow_back, Stack(children: <Widget>[
color: Colors.black, Positioned(
size: 30, top: 10, //statusBarHeight + 10,
left: 15,
child: Builder(
builder: (context) => IconButton(
key: keyPopButton,
icon: const Icon(
Icons.arrow_back,
color: Colors.black,
size: 30,
),
onPressed: () {
myWalletProvider.isPinValid = false;
myWalletProvider.isPinLoading = true;
Navigator.pop(context);
},
), ),
onPressed: () => Navigator.pop(context),
), ),
), ),
), Column(children: <Widget>[
Column(children: <Widget>[ SizedBox(height: isTall ? 100 : 20),
SizedBox(height: isTall ? 100 : 20), Row(
Row( mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
children: <Widget>[ currentChest.imageFile == null
currentChest.imageFile == null ? Image.asset(
? Image.asset( 'assets/chests/${currentChest.imageName}',
'assets/chests/${currentChest.imageName}', width: isTall ? 130 : 100,
width: isTall ? 130 : 100, )
) : Image.file(
: Image.file( currentChest.imageFile!,
currentChest.imageFile!, width: isTall ? 130 : 100,
width: isTall ? 130 : 100, ),
), const SizedBox(width: 5),
const SizedBox(width: 5), SizedBox(
SizedBox( width: 250,
width: 250, child: Text(
child: Text( currentChest.name!,
currentChest.name!, textAlign: TextAlign.center,
textAlign: TextAlign.center, style: const TextStyle(
style: const TextStyle( fontSize: 25,
fontSize: 25, color: Colors.black,
color: Colors.black, fontWeight: FontWeight.w700),
fontWeight: FontWeight.w700), )),
)), ]),
]), SizedBox(height: 30 * ratio),
SizedBox(height: 30 * ratio), SizedBox(
SizedBox(
width: 400,
child: Text(
'toUnlockEnterPassword'.tr(),
style: const TextStyle(
fontSize: 19,
color: Colors.black,
fontWeight: FontWeight.w400),
)),
SizedBox(height: 40 * ratio),
pinForm(context, pinLenght),
SizedBox(height: 3 * ratio),
if (canUnlock)
InkWell(
key: keyCachePassword,
onTap: () {
walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
const Spacer(),
Icon(
configBox.get('isCacheChecked')
? Icons.check_box
: Icons.check_box_outline_blank,
color: orangeC,
),
const SizedBox(width: 8),
Text(
'rememberPassword'.tr(),
style: TextStyle(
fontSize: 16, color: Colors.grey[700]),
),
const Spacer()
]),
),
const SizedBox(height: 10),
// if (canUnlock)
InkWell(
key: keyChangeChest,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const ChooseChest();
}),
);
},
child: SizedBox(
width: 400, width: 400,
height: 50, child: Text(
child: Center( 'toUnlockEnterPassword'.tr(),
child: Text( style: const TextStyle(
'changeChest'.tr(), fontSize: 19,
style: const TextStyle( color: Colors.black,
fontSize: 22, fontWeight: FontWeight.w400),
color: orangeC, )),
fontWeight: FontWeight.w600), SizedBox(height: 30 * ratio),
if (!myWalletProvider.isPinValid &&
!myWalletProvider.isPinLoading)
Text(
"thisIsNotAGoodCode".tr(),
style: const TextStyle(
color: Colors.red, fontWeight: FontWeight.w500),
),
SizedBox(height: 10 * ratio),
pinForm(context, pinLenght),
SizedBox(height: 3 * ratio),
if (canUnlock)
Consumer<WalletOptionsProvider>(
builder: (context, sub, _) {
return InkWell(
key: keyCachePassword,
onTap: () {
walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
const Spacer(),
Icon(
configBox.get('isCacheChecked')
? Icons.check_box
: Icons.check_box_outline_blank,
color: orangeC,
),
const SizedBox(width: 8),
Text(
'rememberPassword'.tr(),
style: TextStyle(
fontSize: 16, color: Colors.grey[700]),
),
const Spacer()
]),
);
}),
const SizedBox(height: 10),
// if (canUnlock)
InkWell(
key: keyChangeChest,
onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) {
// return const ChooseChest();
// }),
// );
},
child: SizedBox(
width: 400,
height: 50,
child: Center(
child: Text(
'changeChest'.tr(),
style: const TextStyle(
fontSize: 22,
color: Colors.grey, // orangeC
fontWeight: FontWeight.w600),
),
), ),
), )),
)), ]),
]), ]),
]), ]),
]), )),
)); );
} }
Widget pinForm(context, pinLenght) { Widget pinForm(context, pinLenght) {
// var _walletPin = ''; final myWalletProvider = Provider.of<MyWalletsProvider>(context);
// ignore: close_sinks final sub = Provider.of<SubstrateSdk>(context, listen: false);
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController enterPin = TextEditingController();
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context);
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
FocusNode pinFocus = FocusNode();
WalletData defaultWallet = myWalletProvider.getDefaultWallet(); WalletData defaultWallet = myWalletProvider.getDefaultWallet();
// defaultWallet.address = null; // if (defaultWallet.address == null) {
if (defaultWallet.address == null) { // canUnlock = false;
canUnlock = false; // return Text(
return Text( // 'Impossible de retrouver votre\nportefeuille par défaut.\nID: ${defaultWallet.id()}',
'Impossible de retrouver votre\nportefeuille par défaut.\nID: ${defaultWallet.id()}', // textAlign: TextAlign.center,
textAlign: TextAlign.center, // style: const TextStyle(
style: const TextStyle( // color: Colors.redAccent, fontWeight: FontWeight.w500),
color: Colors.redAccent, fontWeight: FontWeight.w500), // );
); // }
}
return Form( return Form(
// key: keyPinForm,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30), padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30),
child: PinCodeTextField( child: PinCodeTextField(
key: keyPinForm, key: keyPinForm,
textCapitalization: TextCapitalization.characters,
focusNode: pinFocus, focusNode: pinFocus,
autoFocus: true, autoFocus: true,
appContext: context, appContext: context,
@ -199,7 +215,8 @@ class UnlockingWallet extends StatelessWidget {
length: pinLenght, length: pinLenght,
obscureText: true, obscureText: true,
obscuringCharacter: '*', obscuringCharacter: '*',
animationType: AnimationType.fade, animationType: AnimationType.slide,
animationDuration: const Duration(milliseconds: 40),
validator: (v) { validator: (v) {
if (v!.length < pinLenght) { if (v!.length < pinLenght) {
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]); return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
@ -218,11 +235,9 @@ class UnlockingWallet extends StatelessWidget {
), ),
showCursor: kDebugMode ? false : true, showCursor: kDebugMode ? false : true,
cursorColor: Colors.black, cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300), textStyle: const TextStyle(fontSize: 27, height: 1.6),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1), backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false, enableActiveFill: false,
errorAnimationController: errorController,
controller: enterPin, controller: enterPin,
keyboardType: TextInputType.visiblePassword, keyboardType: TextInputType.visiblePassword,
boxShadows: const [ boxShadows: const [
@ -233,28 +248,32 @@ class UnlockingWallet extends StatelessWidget {
) )
], ],
onCompleted: (pin) async { onCompleted: (pin) async {
myWalletProvider.isPinLoading = true;
myWalletProvider.pinCode = pin.toUpperCase(); myWalletProvider.pinCode = pin.toUpperCase();
final isValid = await sub.checkPassword( final isValid = await sub.checkPassword(
defaultWallet.address!, pin.toUpperCase()); defaultWallet.address, pin.toUpperCase());
if (!isValid) { if (!isValid) {
await Future.delayed(const Duration(milliseconds: 50)); await Future.delayed(const Duration(milliseconds: 20));
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
pinColor = Colors.red[600]; pinColor = Colors.red[600];
myWalletProvider.isPinLoading = false;
myWalletProvider.isPinValid = false;
myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; myWalletProvider.pinCode = myWalletProvider.mnemonic = '';
walletOptions.reload(); enterPin.text = '';
pinFocus.requestFocus(); pinFocus.requestFocus();
} else { } else {
myWalletProvider.isPinValid = true;
myWalletProvider.isPinLoading = false;
pinColor = Colors.green[400]; pinColor = Colors.green[400];
myWalletProvider.resetPinCode(); myWalletProvider.resetPinCode();
Navigator.pop(context, pin.toUpperCase()); Navigator.pop(context, pin.toUpperCase());
} }
}, },
onChanged: (value) { onChanged: (value) {
if (enterPin.text != '') myWalletProvider.isPinLoading = true;
if (pinColor != const Color(0xFFA4B600)) { if (pinColor != const Color(0xFFA4B600)) {
pinColor = const Color(0xFFA4B600); pinColor = const Color(0xFFA4B600);
} }
myWalletProvider.reload();
}, },
)), )),
); );

View File

@ -2,21 +2,28 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.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/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/certifications.dart';
import 'package:gecko/screens/activity.dart'; import 'package:gecko/screens/activity.dart';
import 'package:gecko/screens/myWallets/manage_membership.dart'; import 'package:gecko/screens/myWallets/manage_membership.dart';
import 'package:gecko/screens/qrcode_fullscreen.dart'; import 'package:gecko/screens/qrcode_fullscreen.dart';
import 'package:gecko/widgets/balance.dart';
import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/widgets/certifications.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:gecko/widgets/idty_status.dart';
import 'package:gecko/widgets/name_by_address.dart';
import 'package:gecko/widgets/page_route_no_transition.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
class WalletOptions extends StatelessWidget { class WalletOptions extends StatelessWidget {
@ -26,25 +33,24 @@ class WalletOptions extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final walletOptions =
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
WalletsProfilesProvider historyProvider = WalletsProfilesProvider historyProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false); Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
HomeProvider homeProvider = final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
Provider.of<HomeProvider>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
// SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); // final sub = Provider.of<SubstrateSdk>(context, listen: false);
// sub.spawnBlock(); // sub.spawnBlock();
// sub.spawnBlock(0, 20); // sub.spawnBlock(0, 20);
log.d(walletOptions.address.text); log.d(walletOptions.address.text);
final int currentChest = myWalletProvider.getCurrentChest(); final currentChest = myWalletProvider.getCurrentChest();
bool isWalletNameIndexed =
duniterIndexer.walletNameIndexer[walletOptions.address.text] != null;
// final currentWallet = _myWalletProvider.getDefaultWallet(); // final currentWallet = _myWalletProvider.getDefaultWallet();
// log.d(_walletOptions.getAddress(_currentChest, 3)); // log.d(_walletOptions.getAddress(_currentChest, 3));
@ -76,7 +82,10 @@ class WalletOptions extends StatelessWidget {
height: 22, height: 22,
child: Consumer<WalletOptionsProvider>( child: Consumer<WalletOptionsProvider>(
builder: (context, walletProvider, _) { builder: (context, walletProvider, _) {
return Text(wallet.name!); return Text(isWalletNameIndexed
? duniterIndexer
.walletNameIndexer[walletOptions.address.text]!
: wallet.name!);
}), }),
), ),
actions: [ actions: [
@ -99,7 +108,7 @@ class WalletOptions extends StatelessWidget {
), ),
], ],
), ),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: Stack(children: [ body: Stack(children: [
Builder( Builder(
builder: (ctx) => SafeArea( builder: (ctx) => SafeArea(
@ -120,44 +129,95 @@ class WalletOptions extends StatelessWidget {
backgroundColor, backgroundColor,
], ],
)), )),
child: Row( child: Row(children: <Widget>[
// mainAxisAlignment: MainAxisAlignment.end, const Spacer(flex: 1),
children: <Widget>[ avatar(walletProvider),
const Spacer(flex: 1), const Spacer(flex: 1),
avatar(walletProvider), Column(
const Spacer(flex: 1), crossAxisAlignment: CrossAxisAlignment.center,
Column( children: <Widget>[
crossAxisAlignment: CrossAxisAlignment.center, Stack(children: [
children: <Widget>[ SizedBox(
duniterIndexer.getNameByAddress( width: 250,
context, child: Row(
walletProvider.address.text, mainAxisAlignment: MainAxisAlignment.center,
wallet, children: [
27, Consumer<WalletOptionsProvider>(
false, builder: (context, walletProvider, _) {
Colors.black, return NameByAddress(
FontWeight.w400, wallet: wallet,
FontStyle.normal), size: 27,
// SizedBox(height: isTall ? 5 : 0), color: Colors.black,
fontWeight: wallet.isMember
SizedBox(height: isTall ? 5 : 0), ? FontWeight.w500
balance( : FontWeight.w400,
context, walletProvider.address.text, 21), fontStyle: FontStyle.normal);
const SizedBox(width: 30), })
Column( ],
crossAxisAlignment: ),
CrossAxisAlignment.center, ),
children: [ const SizedBox(width: 10),
walletOptions.idtyStatus( if (duniterIndexer
context, walletOptions.address.text, .walletNameIndexer[wallet.address] ==
isOwner: true, color: orangeC), null)
getCerts(context, Positioned(
walletProvider.address.text, 15), right: 0,
]), child: InkWell(
SizedBox(height: 10 * ratio), key: keyRenameWallet,
]), onTap: () async {
const Spacer(flex: 2), await walletOptions.editWalletName(
]), context, wallet.id());
await Future.delayed(
const Duration(milliseconds: 30));
},
child: ClipRRect(
child: Image.asset(
walletOptions.isEditing
? 'assets/walletOptions/android-checkmark.png'
: 'assets/walletOptions/edit.png',
width: 25,
height: 25),
),
),
),
]),
SizedBox(height: isTall ? 5 : 0),
Balance(
address: walletProvider.address.text, size: 21),
const SizedBox(width: 30),
InkWell(
onTap: () => isWalletNameIndexed
? {
Navigator.push(
context,
PageNoTransit(builder: (context) {
return CertificationsScreen(
address:
walletProvider.address.text,
username: duniterIndexer
.walletNameIndexer[
walletProvider
.address.text]!);
}),
),
}
: null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IdentityStatus(
address: walletOptions.address.text,
isOwner: true,
color: orangeC),
Certifications(
address: walletProvider.address.text,
size: 15)
]),
),
SizedBox(height: 10 * ratio),
]),
const Spacer(flex: 2),
]),
); );
}), }),
Expanded( Expanded(
@ -201,8 +261,8 @@ class WalletOptions extends StatelessWidget {
SizedBox(height: 17 * ratio), SizedBox(height: 17 * ratio),
// walletProvider.isMember(context, _walletOptions.address.text) // walletProvider.isMember(context, _walletOptions.address.text)
FutureBuilder( FutureBuilder(
future: walletProvider.isMember( future:
context, walletOptions.address.text), sub.isMember(walletOptions.address.text),
builder: (BuildContext context, builder: (BuildContext context,
AsyncSnapshot<bool> isMember) { AsyncSnapshot<bool> isMember) {
if (isMember.connectionState != if (isMember.connectionState !=
@ -229,7 +289,7 @@ class WalletOptions extends StatelessWidget {
]), ]),
), ),
), ),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );
@ -302,7 +362,7 @@ class WalletOptions extends StatelessWidget {
foregroundColor: Colors.white, elevation: 4, foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground backgroundColor: orangeC, // foreground
), ),
onPressed: () { onPressed: () async {
walletProvider.confirmIdentityPopup(context); walletProvider.confirmIdentityPopup(context);
// Navigator.push( // Navigator.push(
// context, // context,
@ -337,7 +397,7 @@ class WalletOptions extends StatelessWidget {
} }
Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) { Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) {
final String shortPubkey = getShortPubkey(walletProvider.address.text); final shortPubkey = getShortPubkey(walletProvider.address.text);
return GestureDetector( return GestureDetector(
key: keyCopyAddress, key: keyCopyAddress,
onTap: () { onTap: () {
@ -404,7 +464,7 @@ class WalletOptions extends StatelessWidget {
// _historyProvider.nPage = 1; // _historyProvider.nPage = 1;
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { PageNoTransit(builder: (context) {
return ActivityScreen( return ActivityScreen(
address: walletProvider.address.text, address: walletProvider.address.text,
avatar: wallet.imageCustomPath == null avatar: wallet.imageCustomPath == null
@ -437,7 +497,7 @@ class WalletOptions extends StatelessWidget {
} }
Widget manageMembership(BuildContext context) { Widget manageMembership(BuildContext context) {
WalletOptionsProvider walletOptions = final walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
return InkWell( return InkWell(
key: keyManageMembership, key: keyManageMembership,
@ -469,8 +529,8 @@ class WalletOptions extends StatelessWidget {
Widget setDefaultWalletWidget( Widget setDefaultWalletWidget(
BuildContext context, BuildContext context,
WalletOptionsProvider walletProvider, WalletOptionsProvider walletProvider,
MyWalletsProvider myWalletProvider, final myWalletProvider,
WalletOptionsProvider walletOptions, final walletOptions,
int currentChest) { int currentChest) {
return Consumer<MyWalletsProvider>(builder: (context, myWalletProvider, _) { return Consumer<MyWalletsProvider>(builder: (context, myWalletProvider, _) {
WalletData defaultWallet = myWalletProvider.getDefaultWallet(); WalletData defaultWallet = myWalletProvider.getDefaultWallet();
@ -511,10 +571,10 @@ class WalletOptions extends StatelessWidget {
} }
Future setDefaultWallet(BuildContext context, int currentChest) async { Future setDefaultWallet(BuildContext context, int currentChest) async {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
WalletOptionsProvider walletOptions = final walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
// WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!; // WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
@ -525,26 +585,26 @@ class WalletOptions extends StatelessWidget {
walletOptions.reload(); walletOptions.reload();
} }
Widget deleteWallet(BuildContext context, Widget deleteWallet(BuildContext context, WalletOptionsProvider walletOptions,
WalletOptionsProvider walletProvider, int currentChest) { int currentChest) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
final defaultWallet = myWalletProvider.getDefaultWallet(); final defaultWallet = myWalletProvider.getDefaultWallet();
final bool isDefaultWallet = final bool isDefaultWallet =
walletProvider.address.text == defaultWallet.address; walletOptions.address.text == defaultWallet.address;
// return Consumer<MyWalletsProvider>( // return Consumer<MyWalletsProvider>(
// builder: (context, _myWalletProvider, _) { // builder: (context, _myWalletProvider, _) {
return FutureBuilder( return FutureBuilder(
future: sub.hasAccountConsumers(wallet.address!), future: sub.hasAccountConsumers(wallet.address),
builder: (BuildContext context, AsyncSnapshot<bool> hasConsumers) { builder: (BuildContext context, AsyncSnapshot<bool> hasConsumers) {
if (hasConsumers.connectionState != ConnectionState.done || if (hasConsumers.connectionState != ConnectionState.done ||
hasConsumers.hasError) { hasConsumers.hasError) {
return const Text(''); return const Text('');
} }
final double balance = final double balance =
balanceCache[walletProvider.address.text] ?? -1; walletOptions.balanceCache[walletOptions.address.text] ?? -1;
final bool canDelete = !isDefaultWallet && final bool canDelete = !isDefaultWallet &&
!hasConsumers.data! && !hasConsumers.data! &&
(balance > 2 || balance == 0); (balance > 2 || balance == 0);
@ -552,7 +612,7 @@ class WalletOptions extends StatelessWidget {
key: keyDeleteWallet, key: keyDeleteWallet,
onTap: canDelete onTap: canDelete
? () async { ? () async {
await walletProvider.deleteWallet(context, wallet); await walletOptions.deleteWallet(context, wallet);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
myWalletProvider.listWallets = myWalletProvider.listWallets =
myWalletProvider.readAllWallets(currentChest); myWalletProvider.readAllWallets(currentChest);

View File

@ -1,41 +1,78 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/chest_data.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.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/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart'; 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/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/import_g1_v1.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/myWallets/wallet_options.dart'; import 'package:gecko/screens/myWallets/wallet_options.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/screens/wallet_view.dart';
// import 'package:gecko/screens/myWallets/choose_chest.dart';
import 'package:gecko/widgets/balance.dart';
import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:gecko/widgets/commons/smooth_transition.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:truncate/truncate.dart';
// import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
class WalletsHome extends StatelessWidget { class WalletsHome extends StatefulWidget {
const WalletsHome({Key? key}) : super(key: key); const WalletsHome({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { State<WalletsHome> createState() => _WalletsHomeState();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); }
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
final int currentChestNumber = myWalletProvider.getCurrentChest(); class _WalletsHomeState extends State<WalletsHome> {
final safeKey = GlobalKey();
// List<TargetFocus> targets = [];
@override
void initState() {
// targets
// .add(TargetFocus(identify: "Target 1", keyTarget: safeKey, contents: [
// TargetContent(
// align: ContentAlign.right,
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: const <Widget>[
// Text(
// "Titulo lorem ipsum",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// color: Colors.white,
// fontSize: 20.0),
// ),
// Padding(
// padding: EdgeInsets.only(top: 10.0),
// child: Text(
// "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pulvinar tortor eget maximus iaculis.",
// style: TextStyle(color: Colors.white),
// ),
// )
// ],
// ))
// ]));
super.initState();
}
@override
Widget build(BuildContext context) {
final myWalletProvider = Provider.of<MyWalletsProvider>(context);
final currentChestNumber = myWalletProvider.getCurrentChest();
final ChestData currentChest = chestBox.get(currentChestNumber)!; final ChestData currentChest = chestBox.get(currentChestNumber)!;
myWalletProvider.listWallets = myWalletProvider.listWallets =
myWalletProvider.readAllWallets(currentChestNumber); myWalletProvider.readAllWallets(currentChestNumber);
@ -61,17 +98,28 @@ class WalletsHome extends StatelessWidget {
ModalRoute.withName('/'), ModalRoute.withName('/'),
); );
}), }),
title: Text(currentChest.name!, title: Row(
style: TextStyle(color: Colors.grey[850])), children: [
Image.asset(
'assets/chests/${currentChest.imageName}',
height: 32,
),
const SizedBox(width: 17),
Text(currentChest.name!,
style: TextStyle(color: Colors.grey[850])),
],
),
backgroundColor: const Color(0xffFFD58D), backgroundColor: const Color(0xffFFD58D),
), ),
bottomNavigationBar: myWalletProvider.lastFlyBy == '' bottomNavigationBar: myWalletProvider.lastFlyBy == ''
? homeProvider.bottomAppBar(context) ? const GeckoBottomAppBar(
actualRoute: 'safeHome',
)
: dragInfo(context), : dragInfo(context),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
myWalletsTiles(context, currentChestNumber), myWalletsTiles(context, currentChestNumber),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
), ),
@ -90,7 +138,7 @@ class WalletsHome extends StatelessWidget {
final bool isSameAddress = final bool isSameAddress =
myWalletProvider.dragAddress == myWalletProvider.lastFlyBy; myWalletProvider.dragAddress == myWalletProvider.lastFlyBy;
final double screenWidth = MediaQuery.of(homeContext).size.width; final screenWidth = MediaQuery.of(homeContext).size.width;
return Container( return Container(
color: yellowC, color: yellowC,
width: screenWidth, width: screenWidth,
@ -109,8 +157,7 @@ class WalletsHome extends StatelessWidget {
); );
} }
Widget chestOptions( Widget chestOptions(BuildContext context, final myWalletProvider) {
BuildContext context, MyWalletsProvider myWalletProvider) {
return Column(children: [ return Column(children: [
const SizedBox(height: 50), const SizedBox(height: 50),
SizedBox( SizedBox(
@ -141,37 +188,48 @@ class WalletsHome extends StatelessWidget {
), ),
)), )),
const SizedBox(height: 30), const SizedBox(height: 30),
InkWell( Row(
key: keyImportG1v1, mainAxisAlignment: MainAxisAlignment.center,
onTap: () { children: [
Navigator.push( SvgPicture.asset(
context, 'assets/cesium_bw2.svg',
MaterialPageRoute(builder: (context) { semanticsLabel: 'CS',
return const ImportG1v1(); height: 50,
}), ),
); const SizedBox(width: 5),
}, InkWell(
child: SizedBox( key: keyImportG1v1,
width: 400, onTap: () {
height: 60, Navigator.push(
child: Center( context,
child: Text('importG1v1'.tr(), MaterialPageRoute(builder: (context) {
style: TextStyle( return const ImportG1v1();
fontSize: 22, }),
color: Colors.blue[900], );
fontWeight: FontWeight.w500))), },
), child: SizedBox(
width: 350,
height: 60,
child: Center(
child: Text('importG1v1'.tr(),
style: TextStyle(
fontSize: 22,
color: Colors.blue[900],
fontWeight: FontWeight.w500))),
),
),
],
), ),
const SizedBox(height: 5), const SizedBox(height: 20),
InkWell( InkWell(
key: keyChangeChest, key: keyChangeChest,
onTap: () { onTap: () {
Navigator.push( // Navigator.push(
context, // context,
MaterialPageRoute(builder: (context) { // MaterialPageRoute(builder: (context) {
return const ChooseChest(); // return const ChooseChest();
}), // }),
); // );
}, },
child: SizedBox( child: SizedBox(
width: 400, width: 400,
@ -180,7 +238,7 @@ class WalletsHome extends StatelessWidget {
child: Text('changeChest'.tr(), child: Text('changeChest'.tr(),
style: const TextStyle( style: const TextStyle(
fontSize: 22, fontSize: 22,
color: orangeC, color: Colors.grey, //orangeC
fontWeight: FontWeight.w500))), fontWeight: FontWeight.w500))),
), ),
), ),
@ -189,12 +247,12 @@ class WalletsHome extends StatelessWidget {
} }
Widget myWalletsTiles(BuildContext context, int currentChestNumber) { Widget myWalletsTiles(BuildContext context, int currentChestNumber) {
MyWalletsProvider myWalletProvider = final myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<MyWalletsProvider>(context); final walletOptions =
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false); Provider.of<WalletOptionsProvider>(context, listen: false);
final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
if (!isWalletsExists) { if (!isWalletsExists) {
return const Text(''); return const Text('');
@ -211,21 +269,31 @@ class WalletsHome extends StatelessWidget {
])); ]));
} }
List listWallets = myWalletProvider.listWallets; // Get wallet list and sort by derivation number
List<WalletData> listWallets = myWalletProvider.listWallets;
listWallets.sort((p1, p2) {
return Comparable.compare(p1.number!, p2.number!);
});
WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
final double screenWidth = MediaQuery.of(context).size.width; final screenWidth = MediaQuery.of(context).size.width;
int nTule = 2; int nTule;
if (screenWidth >= 900) { if (screenWidth >= 900) {
nTule = 4; nTule = 4;
} else if (screenWidth >= 650) { } else if (screenWidth >= 650) {
nTule = 3; nTule = 3;
} else {
nTule = 2;
} }
// Offset followDragAnchorStrategy( // Offset followDragAnchorStrategy(
// Draggable<Object> d, BuildContext context, Offset point) { // Draggable<Object> d, BuildContext context, Offset point) {
// return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0); // return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0);
// } // }
// showTutorial();
// Future.delayed(const Duration(seconds: 1), showTutorial);
return CustomScrollView(slivers: <Widget>[ return CustomScrollView(slivers: <Widget>[
const SliverToBoxAdapter(child: SizedBox(height: 20)), const SliverToBoxAdapter(child: SizedBox(height: 20)),
SliverGrid.count( SliverGrid.count(
@ -235,17 +303,17 @@ class WalletsHome extends StatelessWidget {
crossAxisSpacing: 0, crossAxisSpacing: 0,
mainAxisSpacing: 0, mainAxisSpacing: 0,
children: <Widget>[ children: <Widget>[
for (WalletData repository in listWallets as Iterable<WalletData>) for (WalletData repository in listWallets)
LongPressDraggable<String>( LongPressDraggable<String>(
delay: const Duration(milliseconds: 200), delay: const Duration(milliseconds: 200),
data: repository.address!, data: repository.address,
dragAnchorStrategy: dragAnchorStrategy:
(Draggable<Object> _, BuildContext __, Offset ___) => (Draggable<Object> _, BuildContext __, Offset ___) =>
const Offset(0, 0), const Offset(0, 0),
// feedbackOffset: const Offset(-500, -500), // feedbackOffset: const Offset(-500, -500),
// dragAnchorStrategy: childDragAnchorStrategy, // dragAnchorStrategy: childDragAnchorStrategy,
onDragStarted: () => onDragStarted: () =>
myWalletProvider.dragAddress = repository.address!, myWalletProvider.dragAddress = repository.address,
onDragEnd: (_) { onDragEnd: (_) {
myWalletProvider.lastFlyBy = ''; myWalletProvider.lastFlyBy = '';
myWalletProvider.dragAddress = ''; myWalletProvider.dragAddress = '';
@ -266,21 +334,21 @@ class WalletsHome extends StatelessWidget {
child: DragTarget<String>( child: DragTarget<String>(
onAccept: (senderAddress) async { onAccept: (senderAddress) async {
log.d( log.d(
'INTERPAY: sender: $senderAddress --- receiver: ${repository.address!}'); 'INTERPAY: sender: $senderAddress --- receiver: ${repository.address}');
final walletData = myWalletProvider final walletData = myWalletProvider
.getWalletDataByAddress(senderAddress); .getWalletDataByAddress(senderAddress);
await sub.setCurrentWallet(walletData!); await sub.setCurrentWallet(walletData!);
sub.reload(); sub.reload();
paymentPopup(context, repository.address!); paymentPopup(context, repository.address);
}, },
onMove: (details) { onMove: (details) {
if (repository.address! != myWalletProvider.lastFlyBy) { if (repository.address != myWalletProvider.lastFlyBy) {
myWalletProvider.lastFlyBy = repository.address!; myWalletProvider.lastFlyBy = repository.address;
myWalletProvider.reload(); myWalletProvider.reload();
} }
}, },
onWillAccept: (senderAddress) => onWillAccept: (senderAddress) =>
senderAddress != repository.address!, senderAddress != repository.address,
builder: ( builder: (
BuildContext context, BuildContext context,
List<dynamic> accepted, List<dynamic> accepted,
@ -289,7 +357,7 @@ class WalletsHome extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: GestureDetector( child: GestureDetector(
key: keyOpenWallet(repository.address!), key: keyOpenWallet(repository.address),
onTap: () { onTap: () {
walletOptions.getAddress( walletOptions.getAddress(
currentChestNumber, repository.derivation!); currentChestNumber, repository.derivation!);
@ -317,14 +385,15 @@ class WalletsHome extends StatelessWidget {
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
decoration: BoxDecoration( decoration: const BoxDecoration(
gradient: RadialGradient( gradient: RadialGradient(
radius: 0.6, radius: 0.8,
colors: [ colors: [
Colors.green[400]!, Color.fromARGB(255, 255, 255, 211),
const Color(0xFFE7E7A6), yellowC,
], ],
)), ),
),
child: child:
// SvgPicture.asset('assets/chopp-gecko2.png', // SvgPicture.asset('assets/chopp-gecko2.png',
// semanticsLabel: 'Gecko', height: 48), // semanticsLabel: 'Gecko', height: 48),
@ -350,13 +419,46 @@ class WalletsHome extends StatelessWidget {
), ),
)), )),
Stack(children: <Widget>[ Stack(children: <Widget>[
balanceBuilder( BalanceBuilder(
context, address: repository.address,
repository.address!, isDefault: repository.address ==
repository.address ==
defaultWallet.address), defaultWallet.address),
nameBuilder(context, repository, Row(
defaultWallet, currentChestNumber), mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
const SizedBox(height: 7),
Opacity(
opacity: 0.7,
child: Text(
duniterIndexer.walletNameIndexer[
repository.address] ??
truncate(
repository.name!, 20),
style: TextStyle(
fontSize: 20,
color:
defaultWallet.address ==
repository.address
? Colors.white
: Colors.black,
fontWeight: FontWeight.w500),
),
)
// NameByAddress(
// wallet: repository,
// address: repository.address,
// size: 20,
// color: defaultWallet.address ==
// repository.address
// ? Colors.white
// : Colors.black,
// ),
],
),
],
),
]), ]),
]), ]),
), ),
@ -375,69 +477,8 @@ class WalletsHome extends StatelessWidget {
]); ]);
} }
Widget balanceBuilder(context, String address, bool isDefault) {
return Container(
width: double.infinity,
color: isDefault ? orangeC : yellowC,
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 38),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
balance(
context,
address,
15,
isDefault ? Colors.white : Colors.black,
isDefault ? yellowC : orangeC)
],
)),
);
}
Widget nameBuilder(BuildContext context, WalletData repository,
WalletData defaultWallet, int currentChestNumber) {
WalletOptionsProvider walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
return ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))),
tileColor: repository.address == defaultWallet.address
? orangeC
: const Color(0xffFFD58D),
title: Center(
child: Padding(
padding: const EdgeInsets.only(left: 5, right: 5, bottom: 35, top: 5),
child: duniterIndexer.getNameByAddress(
context,
repository.address!,
repository,
20,
true,
repository.id()[1] == defaultWallet.id()[1]
? const Color(0xffF9F9F1)
: Colors.black),
),
),
onTap: () {
walletOptions.getAddress(currentChestNumber, repository.derivation!);
Navigator.push(
context,
SmoothTransition(
page: WalletOptions(
wallet: repository,
),
),
);
},
);
}
Widget addNewDerivation(context) { Widget addNewDerivation(context) {
MyWalletsProvider myWalletProvider = final myWalletProvider = Provider.of<MyWalletsProvider>(context);
Provider.of<MyWalletsProvider>(context);
String newDerivationName = String newDerivationName =
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}'; '${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
@ -497,6 +538,41 @@ class WalletsHome extends StatelessWidget {
} }
} }
class BalanceBuilder extends StatelessWidget {
const BalanceBuilder({
Key? key,
required this.address,
required this.isDefault,
}) : super(key: key);
final String address;
final bool isDefault;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: isDefault ? orangeC : yellowC,
child: Padding(
padding:
const EdgeInsets.only(left: 5, right: 5, top: 38, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Opacity(
opacity: 0.7,
child: Balance(
address: address,
size: 16,
color: isDefault ? Colors.white : Colors.black,
loadingColor: isDefault ? yellowC : orangeC),
)
],
)),
);
}
}
class CustomClipperOval extends CustomClipper<Rect> { class CustomClipperOval extends CustomClipper<Rect> {
@override @override
Rect getClip(Size size) { Rect getClip(Size size) {

View File

@ -1,17 +1,12 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.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'; import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.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/providers/wallets_profiles.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:gecko/widgets/contacts_list.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ContactsScreen extends StatelessWidget { class ContactsScreen extends StatelessWidget {
@ -19,24 +14,12 @@ class ContactsScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CesiumPlusProvider cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfilesClass = WalletsProfilesProvider walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: true); Provider.of<WalletsProfilesProvider>(context, listen: true);
HomeProvider homeProvider = final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
Provider.of<HomeProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
double avatarSize = 55; double avatarSize = 55;
final myContacts = contactsBox.toMap().values.toList(); final myContacts = contactsBox.toMap().values.toList();
// for (var element in myContacts) {
// log.d('yooo: ${element.pubkey} ${element.username}');
// }
myContacts.sort((p1, p2) { myContacts.sort((p1, p2) {
return Comparable.compare(p1.username?.toLowerCase() ?? 'zz', return Comparable.compare(p1.username?.toLowerCase() ?? 'zz',
p2.username?.toLowerCase() ?? 'zz'); p2.username?.toLowerCase() ?? 'zz');
@ -53,87 +36,15 @@ class ContactsScreen extends StatelessWidget {
'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])), 'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])),
), ),
), ),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
Padding( ContactsList(
padding: const EdgeInsets.symmetric(horizontal: 20), myContacts: myContacts,
child: Column( avatarSize: avatarSize,
crossAxisAlignment: CrossAxisAlignment.start, walletsProfilesClass: walletsProfilesClass,
children: <Widget>[ duniterIndexer: duniterIndexer),
const SizedBox(height: 20), const OfflineInfo(),
if (myContacts.isEmpty)
Text('noContacts'.tr())
else
Expanded(
child: ListView(children: <Widget>[
for (G1WalletsList g1Wallet in myContacts)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult('keyID++'),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider
.defaultAvatar(avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(g1Wallet.address),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 110,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
balance(context,
g1Wallet.address, 16),
]),
]),
),
]),
subtitle: Row(children: <Widget>[
duniterIndexer.getNameByAddress(
context, g1Wallet.address)
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfilesClass.address =
g1Wallet.address;
return WalletViewScreen(
address: g1Wallet.address,
username: g1WalletsBox
.get(g1Wallet.address)
?.id
?.username,
avatar: g1WalletsBox
.get(g1Wallet.address)
?.avatar,
);
}),
);
}),
),
]),
)
]),
),
CommonElements().offlineInfo(context),
]), ]),
), ),
); );

View File

@ -1,18 +1,17 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/2.dart'; import 'package:gecko/screens/onBoarding/2.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepOne extends StatelessWidget { class OnboardingStepOne extends StatelessWidget {
const OnboardingStepOne({Key? key}) : super(key: key); const OnboardingStepOne({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -28,16 +27,15 @@ class OnboardingStepOne extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro( InfoIntro(
context, text: 'geckoGenerateYourWalletFromMnemonic'.tr(),
'geckoGenerateYourWalletFromMnemonic'.tr(), assetName: 'fabrication-de-portefeuille.png',
'fabrication-de-portefeuille.png', buttonText: '>',
'>', nextScreen: const OnboardingStepTwo(),
const OnboardingStepTwo(), pagePosition: 0,
0,
isMd: true, isMd: true,
), ),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -4,7 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
@ -13,8 +13,11 @@ import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart';
import 'package:gecko/widgets/commons/build_text.dart';
import 'package:gecko/screens/onBoarding/11_congratulations.dart'; import 'package:gecko/screens/onBoarding/11_congratulations.dart';
import 'package:gecko/widgets/commons/fader_transition.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -26,126 +29,149 @@ class OnboardingStepTen extends StatelessWidget {
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
Color? pinColor = const Color(0xFFA4B600); Color? pinColor = const Color(0xFFA4B600);
bool hasError = false; bool hasError = false;
TextEditingController enterPin = TextEditingController();
FocusNode pinFocus = FocusNode(debugLabel: 'pinFocusNode');
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final generateWalletProvider =
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
WalletOptionsProvider walletOptions = final walletOptions = Provider.of<WalletOptionsProvider>(context);
Provider.of<WalletOptionsProvider>(context); final sub = Provider.of<SubstrateSdk>(context);
CommonElements common = CommonElements(); final myWalletProvider =
final int pinLenght = generateWalletProvider.pin.text.length; Provider.of<MyWalletsProvider>(context, listen: false);
final pinLenght = generateWalletProvider.pin.text.length;
return Scaffold( return WillPopScope(
backgroundColor: backgroundColor, onWillPop: () {
appBar: AppBar( myWalletProvider.isPinValid = false;
toolbarHeight: 60 * ratio, myWalletProvider.isPinLoading = true;
title: SizedBox( return Future<bool>.value(true);
height: 22, },
child: Text( child: Scaffold(
'myPassword'.tr(), backgroundColor: backgroundColor,
style: const TextStyle(fontWeight: FontWeight.w600), appBar: AppBar(
toolbarHeight: 60 * ratio,
title: SizedBox(
height: 22,
child: Text(
'myPassword'.tr(),
style: const TextStyle(fontWeight: FontWeight.w600),
),
), ),
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
myWalletProvider.isPinValid = false;
myWalletProvider.isPinLoading = true;
Navigator.of(context).pop();
}),
), ),
), extendBodyBehindAppBar: true,
extendBodyBehindAppBar: true, body: SafeArea(
body: SafeArea( child: Stack(children: [
child: Stack(children: [ Column(children: <Widget>[
Column(children: <Widget>[ SizedBox(height: isTall ? 40 : 20),
SizedBox(height: isTall ? 40 : 20), const BuildProgressBar(pagePosition: 9),
common.buildProgressBar(9), SizedBox(height: isTall ? 40 : 20),
SizedBox(height: isTall ? 40 : 20), BuildText(text: "geckoWillCheckPassword".tr()),
common.buildText("geckoWillCheckPassword".tr()), SizedBox(height: isTall ? 60 : 10),
SizedBox(height: isTall ? 80 : 20), Visibility(
Visibility( visible: generateWalletProvider.scanedValidWalletNumber != -1,
visible: generateWalletProvider.scanedValidWalletNumber != -1, child: Padding(
child: Padding( padding: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.only(bottom: 15), child: Row(
child: Row( mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, children: [
children: [ Text("derivationsScanProgress".tr(args: [
Text("derivationsScanProgress".tr(args: [ '${generateWalletProvider.scanedWalletNumber}',
'${generateWalletProvider.scanedWalletNumber}', '${generateWalletProvider.numberScan + 1}'
'${generateWalletProvider.numberScan + 1}' ])),
])), const SizedBox(width: 10),
const SizedBox(width: 10), const SizedBox(
const SizedBox( height: 22,
height: 22, width: 22,
width: 22, child: CircularProgressIndicator(
child: CircularProgressIndicator( color: orangeC,
color: orangeC, strokeWidth: 3,
strokeWidth: 3, ),
), ),
), ],
], ),
), ),
), ),
), Consumer<MyWalletsProvider>(builder: (context, mw, _) {
Consumer<SubstrateSdk>(builder: (context, sub, _) { return Visibility(
return sub.nodeConnected visible: !myWalletProvider.isPinValid &&
? pinForm(context, walletOptions, pinLenght, 1, 2) !myWalletProvider.isPinLoading,
: Row( child: Text(
mainAxisAlignment: MainAxisAlignment.center, "thisIsNotAGoodCode".tr(),
children: const [ style: const TextStyle(
Text( color: Colors.red, fontWeight: FontWeight.w500),
'Vous devez vous connecter à internet\npour valider votre coffre', ),
style: TextStyle( );
fontSize: 20, }),
color: Colors.redAccent, SizedBox(height: isTall ? 20 : 10),
fontWeight: FontWeight.w500, Consumer<SubstrateSdk>(builder: (context, sub, _) {
return sub.nodeConnected
? pinForm(context, walletOptions, pinLenght, 1, 2)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"youHaveToBeConnectedToValidateChest".tr(),
style: const TextStyle(
fontSize: 20,
color: Colors.redAccent,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
), ),
textAlign: TextAlign.center, ]);
}),
Consumer<WalletOptionsProvider>(
builder: (context, walletOptions, _) {
return sub.nodeConnected
? InkWell(
key: keyCachePassword,
onTap: () {
walletOptions.changePinCacheChoice();
},
child: Row(children: [
const SizedBox(height: 30),
const Spacer(),
Icon(
configBox.get('isCacheChecked') ?? false
? Icons.check_box
: Icons.check_box_outline_blank,
color: orangeC,
), ),
]); const SizedBox(width: 8),
}), Text(
Consumer<SubstrateSdk>(builder: (context, sub, _) { 'rememberPassword'.tr(),
return sub.nodeConnected style: TextStyle(
? InkWell( fontSize: 16, color: Colors.grey[700]),
key: keyCachePassword, ),
onTap: () { const Spacer()
walletOptions.changePinCacheChoice(); ]))
}, : const Text('');
child: Row(children: [ }),
const SizedBox(height: 30), const SizedBox(height: 10),
const Spacer(), ]),
Icon( const OfflineInfo(),
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),
]), ]),
CommonElements().offlineInfo(context), )),
]), );
));
} }
Widget pinForm(context, WalletOptionsProvider walletOptions, pinLenght, Widget pinForm(
int walletNbr, int derivation) { context, final walletOptions, pinLenght, int walletNbr, int derivation) {
// var _walletPin = ''; final myWalletProvider = Provider.of<MyWalletsProvider>(context);
// ignore: close_sinks final generateWalletProvider =
StreamController<ErrorAnimationType> errorController =
StreamController<ErrorAnimationType>();
TextEditingController enterPin = TextEditingController();
MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context);
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
final int currentChest = myWalletProvider.getCurrentChest(); final currentChest = myWalletProvider.getCurrentChest();
return Form( return Form(
key: formKey, key: formKey,
@ -153,6 +179,9 @@ class OnboardingStepTen extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30), padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: PinCodeTextField( child: PinCodeTextField(
key: keyPinForm, key: keyPinForm,
textCapitalization: TextCapitalization.characters,
// autoDisposeControllers: false,
focusNode: pinFocus,
autoFocus: true, autoFocus: true,
appContext: context, appContext: context,
pastedTextStyle: TextStyle( pastedTextStyle: TextStyle(
@ -162,7 +191,8 @@ class OnboardingStepTen extends StatelessWidget {
length: pinLenght, length: pinLenght,
obscureText: true, obscureText: true,
obscuringCharacter: '*', obscuringCharacter: '*',
animationType: AnimationType.fade, animationType: AnimationType.slide,
animationDuration: const Duration(milliseconds: 40),
validator: (v) { validator: (v) {
if (v!.length < pinLenght) { if (v!.length < pinLenght) {
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]); return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
@ -175,17 +205,15 @@ class OnboardingStepTen extends StatelessWidget {
borderWidth: 4, borderWidth: 4,
shape: PinCodeFieldShape.box, shape: PinCodeFieldShape.box,
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
fieldHeight: 60, fieldHeight: 50 * ratio,
fieldWidth: 50, fieldWidth: 50,
activeFillColor: hasError ? Colors.blueAccent : Colors.black, activeFillColor: Colors.black,
), ),
showCursor: kDebugMode ? false : true, showCursor: kDebugMode ? false : true,
cursorColor: Colors.black, cursorColor: Colors.black,
animationDuration: const Duration(milliseconds: 300), textStyle: const TextStyle(fontSize: 27, height: 1.6),
textStyle: const TextStyle(fontSize: 20, height: 1.6),
backgroundColor: const Color(0xffF9F9F1), backgroundColor: const Color(0xffF9F9F1),
enableActiveFill: false, enableActiveFill: false,
errorAnimationController: errorController,
controller: enterPin, controller: enterPin,
keyboardType: TextInputType.visiblePassword, keyboardType: TextInputType.visiblePassword,
boxShadows: const [ boxShadows: const [
@ -201,6 +229,8 @@ class OnboardingStepTen extends StatelessWidget {
log.d('$pin || ${generateWalletProvider.pin.text}'); log.d('$pin || ${generateWalletProvider.pin.text}');
if (pin.toUpperCase() == generateWalletProvider.pin.text) { if (pin.toUpperCase() == generateWalletProvider.pin.text) {
pinColor = Colors.green[500]; pinColor = Colors.green[500];
myWalletProvider.isPinLoading = false;
myWalletProvider.isPinValid = true;
await generateWalletProvider.storeHDWChest(context); await generateWalletProvider.storeHDWChest(context);
bool isAlive = false; bool isAlive = false;
@ -214,14 +244,14 @@ class OnboardingStepTen extends StatelessWidget {
derivePath: '//2', derivePath: '//2',
password: generateWalletProvider.pin.text); password: generateWalletProvider.pin.text);
WalletData myWallet = WalletData( WalletData myWallet = WalletData(
version: dataVersion,
chest: configBox.get('currentChest'), chest: configBox.get('currentChest'),
address: address, address: address,
number: 0, number: 0,
name: 'currentWallet'.tr(), name: 'currentWallet'.tr(),
derivation: 2, derivation: 2,
imageDefaultPath: '0.png'); imageDefaultPath: '0.png',
await walletBox.add(myWallet); isOwned: true);
await walletBox.put(myWallet.address, myWallet);
} }
myWalletProvider.readAllWallets(currentChest); myWalletProvider.readAllWallets(currentChest);
myWalletProvider.reload(); myWalletProvider.reload();
@ -235,17 +265,21 @@ class OnboardingStepTen extends StatelessWidget {
page: const OnboardingStepEleven(), isFast: false), page: const OnboardingStepEleven(), isFast: false),
); );
} else { } else {
errorController.add(ErrorAnimationType
.shake); // Triggering error shake animation
hasError = true; hasError = true;
myWalletProvider.isPinLoading = false;
myWalletProvider.isPinValid = false;
pinColor = Colors.red[600]; pinColor = Colors.red[600];
walletOptions.reload(); enterPin.text = '';
// myWalletProvider.reload();
pinFocus.requestFocus();
} }
}, },
onChanged: (value) { onChanged: (value) {
if (enterPin.text != '') myWalletProvider.isPinLoading = true;
if (pinColor != const Color(0xFFA4B600)) { if (pinColor != const Color(0xFFA4B600)) {
pinColor = const Color(0xFFA4B600); pinColor = const Color(0xFFA4B600);
} }
myWalletProvider.reload();
}, },
)), )),
); );

View File

@ -1,20 +1,17 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/build_text.dart';
class OnboardingStepEleven extends StatelessWidget { class OnboardingStepEleven extends StatelessWidget {
const OnboardingStepEleven({Key? key}) : super(key: key); const OnboardingStepEleven({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -31,7 +28,7 @@ class OnboardingStepEleven extends StatelessWidget {
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
const SizedBox(height: 40), const SizedBox(height: 40),
common.buildText("yourChestAndWalletWereCreatedSuccessfully".tr()), BuildText(text: "yourChestAndWalletWereCreatedSuccessfully".tr()),
SizedBox(height: isTall ? 20 : 10), SizedBox(height: isTall ? 20 : 10),
Image.asset( Image.asset(
'assets/onBoarding/gecko-clin.gif', 'assets/onBoarding/gecko-clin.gif',
@ -59,22 +56,8 @@ Widget finishButton(BuildContext context) {
backgroundColor: orangeC, // foreground backgroundColor: orangeC, // foreground
), ),
onPressed: () { onPressed: () {
//TODO: fix bad widget ancestor when pupUntil (multi_chest test failed)
// Navigator.popUntil(homeContext, ModalRoute.withName('/'));
// Navigator.of(homeContext, rootNavigator: true)
// .popUntil(ModalRoute.withName('/'));
// while (Navigator.of(homeContext).canPop()) {
// Navigator.of(homeContext).pop();
// }
// Navigator.pushNamed(homeContext, '/mywallets');
Navigator.pushNamedAndRemoveUntil( Navigator.pushNamedAndRemoveUntil(
context, '/mywallets', (route) => route.isFirst); context, '/mywallets', ModalRoute.withName('/'));
// Navigator.pushNamedAndRemoveUntil(
// homeContext, '/mywallets', ModalRoute.withName('/'));
}, },
child: Text("accessMyChest".tr(), child: Text("accessMyChest".tr(),
style: style:

View File

@ -1,20 +1,18 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/3.dart'; import 'package:gecko/screens/onBoarding/3.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepTwo extends StatelessWidget { class OnboardingStepTwo extends StatelessWidget {
const OnboardingStepTwo({Key? key}) : super(key: key); const OnboardingStepTwo({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -30,14 +28,14 @@ class OnboardingStepTwo extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro( InfoIntro(
context, text: 'keepThisMnemonicSecure'.tr(),
'keepThisMnemonicSecure'.tr(), assetName:
'fabrication-de-portefeuille-impossible-sans-phrase.png', 'fabrication-de-portefeuille-impossible-sans-phrase.png',
'>', buttonText: '>',
const OnboardingStepThree(), nextScreen: const OnboardingStepThree(),
1), pagePosition: 1),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,20 +1,18 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/4.dart'; import 'package:gecko/screens/onBoarding/4.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepThree extends StatelessWidget { class OnboardingStepThree extends StatelessWidget {
const OnboardingStepThree({Key? key}) : super(key: key); const OnboardingStepThree({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -30,9 +28,13 @@ class OnboardingStepThree extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro(context, 'warningForgotPassword'.tr(), InfoIntro(
'forgot_password.png'.tr(), '>', const OnboardingStepFor(), 2), text: 'warningForgotPassword'.tr(),
CommonElements().offlineInfo(context), assetName: 'forgot_password.png'.tr(),
buttonText: '>',
nextScreen: const OnboardingStepFor(),
pagePosition: 2),
const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,20 +1,18 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/5.dart'; import 'package:gecko/screens/onBoarding/5.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepFor extends StatelessWidget { class OnboardingStepFor extends StatelessWidget {
const OnboardingStepFor({Key? key}) : super(key: key); const OnboardingStepFor({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -30,15 +28,14 @@ class OnboardingStepFor extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro( InfoIntro(
context, text: 'itsTimeToUseAPenAndPaper'.tr(),
'itsTimeToUseAPenAndPaper'.tr(), assetName: 'gecko_also_can_forget.png'.tr(),
'gecko_also_can_forget.png'.tr(), buttonText: '>',
'>', nextScreen: const OnboardingStepFive(),
const OnboardingStepFive(), pagePosition: 3,
3,
isMd: true), isMd: true),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,14 +1,19 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/widgets/commons/build_progress_bar.dart';
import 'package:gecko/widgets/commons/build_text.dart';
import 'package:gecko/screens/onBoarding/6.dart'; import 'package:gecko/screens/onBoarding/6.dart';
import 'package:gecko/widgets/commons/fader_transition.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -29,12 +34,9 @@ class OnboardingStepFive extends StatefulWidget {
class _ChooseChestState extends State<OnboardingStepFive> { class _ChooseChestState extends State<OnboardingStepFive> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final generateWalletProvider =
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
final CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -52,26 +54,63 @@ class _ChooseChestState extends State<OnboardingStepFive> {
child: Stack(children: [ child: Stack(children: [
Column(children: [ Column(children: [
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(4), const BuildProgressBar(pagePosition: 4),
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildText('geckoGeneratedYourMnemonicKeepItSecret'.tr()), BuildText(text: 'geckoGeneratedYourMnemonicKeepItSecret'.tr()),
SizedBox(height: 35 * ratio), SizedBox(height: 35 * ratio),
sentanceArray(context), sentanceArray(context),
SizedBox(height: 17 * ratio), SizedBox(height: 17 * ratio),
GestureDetector( Row(
onTap: () { mainAxisAlignment: MainAxisAlignment.spaceEvenly,
Navigator.push( children: [
context, // const SizedBox(height: 10),
MaterialPageRoute(builder: (context) { GestureDetector(
return PrintWallet( onTap: () {
generateWalletProvider.generatedMnemonic); Navigator.push(
}), context,
); MaterialPageRoute(builder: (context) {
}, return PrintWallet(
child: Image.asset( generateWalletProvider.generatedMnemonic);
'assets/printer.png', }),
height: 42 * ratio, );
), },
child: Image.asset(
'assets/printer.png',
height: 42 * ratio,
),
),
SizedBox(
height: 40,
width: 120,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
backgroundColor: orangeC,
elevation: 1, // foreground
),
onPressed: () {
Clipboard.setData(ClipboardData(
text: generateWalletProvider.generatedMnemonic));
snackCopySeed(context);
},
child: Row(children: <Widget>[
Image.asset(
'assets/walletOptions/copy-white.png',
height: 25,
),
const SizedBox(width: 7),
Text(
'copy'.tr(),
style: TextStyle(fontSize: 15, color: Colors.grey[50]),
)
]),
),
),
],
), ),
const SizedBox(height: 40), const SizedBox(height: 40),
Expanded( Expanded(
@ -104,7 +143,7 @@ class _ChooseChestState extends State<OnboardingStepFive> {
const Spacer(), const Spacer(),
// SizedBox(height: 35 * ratio), // SizedBox(height: 35 * ratio),
]), ]),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );
@ -112,7 +151,7 @@ class _ChooseChestState extends State<OnboardingStepFive> {
} }
Widget sentanceArray(BuildContext context) { Widget sentanceArray(BuildContext context) {
GenerateWalletsProvider generateWalletProvider = final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
return Padding( return Padding(
@ -189,7 +228,7 @@ class PrintWallet extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
GenerateWalletsProvider generateWalletProvider = final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
return MaterialApp( return MaterialApp(
home: Scaffold( home: Scaffold(
@ -222,9 +261,9 @@ class PrintWallet extends StatelessWidget {
Widget nextButton( Widget nextButton(
BuildContext context, String text, bool isFast, bool skipIntro) { BuildContext context, String text, bool isFast, bool skipIntro) {
GenerateWalletsProvider generateWalletProvider = final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
return SizedBox( return SizedBox(
width: 380 * ratio, width: 380 * ratio,

View File

@ -2,14 +2,17 @@
// ignore_for_file: must_be_immutable // ignore_for_file: must_be_immutable
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart';
import 'package:gecko/widgets/commons/build_text.dart';
import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/7.dart';
import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/screens/onBoarding/9.dart';
import 'package:gecko/widgets/commons/fader_transition.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class OnboardingStepSix extends StatelessWidget { class OnboardingStepSix extends StatelessWidget {
@ -24,11 +27,9 @@ class OnboardingStepSix extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final generateWalletProvider =
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: true); Provider.of<GenerateWalletsProvider>(context, listen: true);
CommonElements common = CommonElements();
_mnemonicController.text = generatedMnemonic!; _mnemonicController.text = generatedMnemonic!;
return WillPopScope( return WillPopScope(
@ -57,14 +58,14 @@ class OnboardingStepSix extends StatelessWidget {
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
child: Column(children: [ child: Column(children: [
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(5), const BuildProgressBar(pagePosition: 5),
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildText( BuildText(
"didYouNoteMnemonicToBeSureTypeWord".tr(args: [ text: "didYouNoteMnemonicToBeSureTypeWord".tr(args: [
(generateWalletProvider.nbrWord + 1).toString() (generateWalletProvider.nbrWord + 1).toString()
]), ]),
20, size: 20,
true), isMd: true),
SizedBox(height: isTall ? 70 : 20), SizedBox(height: isTall ? 70 : 20),
Text('${generateWalletProvider.nbrWord + 1}', Text('${generateWalletProvider.nbrWord + 1}',
key: keyAskedWord, key: keyAskedWord,
@ -136,7 +137,7 @@ class OnboardingStepSix extends StatelessWidget {
SizedBox(height: 35 * ratio), SizedBox(height: 35 * ratio),
]), ]),
), ),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
), ),
@ -145,7 +146,7 @@ class OnboardingStepSix extends StatelessWidget {
} }
Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) { Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) {
GenerateWalletsProvider generateWalletProvider = final generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context, listen: false); Provider.of<GenerateWalletsProvider>(context, listen: false);
generateWalletProvider.isAskedWordValid = false; generateWalletProvider.isAskedWordValid = false;

View File

@ -1,10 +1,11 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/8.dart'; import 'package:gecko/screens/onBoarding/8.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepSeven extends StatelessWidget { class OnboardingStepSeven extends StatelessWidget {
const OnboardingStepSeven({Key? key, this.scanDerivation = false}) const OnboardingStepSeven({Key? key, this.scanDerivation = false})
@ -13,8 +14,6 @@ class OnboardingStepSeven extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -30,15 +29,14 @@ class OnboardingStepSeven extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro( InfoIntro(
context, text: 'geckoWillGenerateAPassword'.tr(),
'geckoWillGenerateAPassword'.tr(), assetName: 'coffre-fort-code-secret-dans-telephone.png',
'coffre-fort-code-secret-dans-telephone.png', buttonText: '>',
'>', nextScreen: OnboardingStepEight(scanDerivation: scanDerivation),
OnboardingStepEight(scanDerivation: scanDerivation), pagePosition: 6,
6,
boxHeight: 400), boxHeight: 400),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,10 +1,11 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/screens/common_elements.dart';
import 'package:gecko/screens/onBoarding/9.dart'; import 'package:gecko/screens/onBoarding/9.dart';
import 'package:gecko/widgets/commons/intro_info.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
class OnboardingStepEight extends StatelessWidget { class OnboardingStepEight extends StatelessWidget {
const OnboardingStepEight({Key? key, this.scanDerivation = false}) const OnboardingStepEight({Key? key, this.scanDerivation = false})
@ -13,8 +14,6 @@ class OnboardingStepEight extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
CommonElements common = CommonElements();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
@ -30,15 +29,14 @@ class OnboardingStepEight extends StatelessWidget {
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
common.infoIntro( InfoIntro(
context, text: 'thisPasswordProtectsYourWalletsInASecureChest'.tr(),
'thisPasswordProtectsYourWalletsInASecureChest'.tr(), assetName: 'coffre-fort-protege-les-portefeuilles.png',
'coffre-fort-protege-les-portefeuilles.png', buttonText: '>',
'>', nextScreen: OnboardingStepNine(scanDerivation: scanDerivation),
OnboardingStepNine(scanDerivation: scanDerivation), pagePosition: 7,
7,
isMd: true), isMd: true),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,12 +1,15 @@
// ignore_for_file: file_names // ignore_for_file: file_names
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/generate_wallets.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/build_progress_bar.dart';
import 'package:gecko/widgets/commons/build_text.dart';
import 'package:gecko/screens/onBoarding/10.dart'; import 'package:gecko/screens/onBoarding/10.dart';
import 'package:gecko/widgets/commons/next_button.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class OnboardingStepNine extends StatelessWidget { class OnboardingStepNine extends StatelessWidget {
@ -16,12 +19,10 @@ class OnboardingStepNine extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final generateWalletProvider =
GenerateWalletsProvider generateWalletProvider =
Provider.of<GenerateWalletsProvider>(context); Provider.of<GenerateWalletsProvider>(context);
// MyWalletsProvider myWalletProvider = // final myWalletProvider =
// Provider.of<MyWalletsProvider>(context); // Provider.of<MyWalletsProvider>(context);
CommonElements common = CommonElements();
generateWalletProvider.pin.text = debugPin // kDebugMode && generateWalletProvider.pin.text = debugPin // kDebugMode &&
? 'AAAAA' ? 'AAAAA'
@ -44,15 +45,16 @@ class OnboardingStepNine extends StatelessWidget {
child: Stack(children: [ child: Stack(children: [
Column(children: <Widget>[ Column(children: <Widget>[
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildProgressBar(8), const BuildProgressBar(pagePosition: 8),
SizedBox(height: isTall ? 40 : 20), SizedBox(height: isTall ? 40 : 20),
common.buildText("hereIsThePasswordKeepIt".tr(), 20, true), BuildText(text: "hereIsThePasswordKeepIt".tr()),
const SizedBox(height: 100), const SizedBox(height: 100),
Stack( Stack(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
children: <Widget>[ children: <Widget>[
TextField( TextField(
key: keyGeneratedPin, key: keyGeneratedPin,
textCapitalization: TextCapitalization.characters,
enabled: false, enabled: false,
controller: generateWalletProvider.pin, controller: generateWalletProvider.pin,
maxLines: 1, maxLines: 1,
@ -72,6 +74,12 @@ class OnboardingStepNine extends StatelessWidget {
), ),
], ],
), ),
const SizedBox(height: 30),
Text(
'Pendant la phase de test de Ğecko,\nles codes secrets\nsont systématiquement AAAAA.'
.tr(),
style: TextStyle(color: Colors.grey[700], fontSize: 15),
textAlign: TextAlign.center),
Expanded( Expanded(
child: Align( child: Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
@ -96,11 +104,13 @@ class OnboardingStepNine extends StatelessWidget {
fontWeight: FontWeight.w600))), fontWeight: FontWeight.w600))),
))), ))),
SizedBox(height: 22 * ratio), SizedBox(height: 22 * ratio),
common.nextButton(context, "iNotedMyPassword".tr(), NextButton(
OnboardingStepTen(scanDerivation: scanDerivation), false), text: "iNotedMyPassword".tr(),
nextScreen: OnboardingStepTen(scanDerivation: scanDerivation),
isFast: false),
SizedBox(height: 35 * ratio), SizedBox(height: 35 * ratio),
]), ]),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
)); ));
} }

View File

@ -1,6 +1,5 @@
// ignore_for_file: must_be_immutable // ignore_for_file: must_be_immutable
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
@ -17,7 +16,6 @@ class QrCodeFullscreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,

View File

@ -1,26 +1,53 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:async';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
// import 'package:gecko/providers/home.dart';
import 'package:gecko/providers/search.dart'; import 'package:gecko/providers/search.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:gecko/screens/search_result.dart'; import 'package:gecko/screens/search_result.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
// import 'package:gecko/models/home.dart';
// import 'package:provider/provider.dart';
class SearchScreen extends StatelessWidget { class SearchScreen extends StatefulWidget {
const SearchScreen({Key? key}) : super(key: key); const SearchScreen({Key? key}) : super(key: key);
@override
State<SearchScreen> createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
bool canPasteAddress = false;
String pastedAddress = '';
Timer? debounce;
final int debouneTime = 50;
Future getClipBoard() async {
final clipboard = await Clipboard.getData('text/plain');
pastedAddress = clipboard?.text ?? '';
canPasteAddress = isAddress(pastedAddress);
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await getClipBoard();
});
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final searchProvider = Provider.of<SearchProvider>(context);
SearchProvider searchProvider = Provider.of<SearchProvider>(context); final screenHeight = MediaQuery.of(context).size.height;
final double screenHeight = MediaQuery.of(context).size.height;
// HomeProvider _homeProvider = final canValidate = searchProvider.searchController.text.length >= 2;
// Provider.of<HomeProvider>(context, listen: false); // final canPasteAddress = false;
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
@ -29,7 +56,6 @@ class SearchScreen extends StatelessWidget {
}, },
child: Scaffold( child: Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
appBar: AppBar( appBar: AppBar(
elevation: 1, elevation: 1,
toolbarHeight: 60 * ratio, toolbarHeight: 60 * ratio,
@ -44,7 +70,6 @@ class SearchScreen extends StatelessWidget {
Navigator.of(context).pop(); Navigator.of(context).pop();
}), }),
), ),
// bottomNavigationBar: _homeProvider.bottomAppBar(context),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
Column(children: <Widget>[ Column(children: <Widget>[
@ -52,18 +77,52 @@ class SearchScreen extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 17), padding: const EdgeInsets.symmetric(horizontal: 17),
child: TextField( child: TextField(
onSubmitted: searchProvider.searchController.text.length >= 2
? (_) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return const SearchResultScreen();
}),
);
}
: (value) {},
textInputAction: TextInputAction.search,
key: keySearchField, key: keySearchField,
controller: searchProvider.searchController, controller: searchProvider.searchController,
autofocus: true, autofocus: true,
maxLines: 1, maxLines: 1,
textAlign: TextAlign.left, textAlign: TextAlign.left,
onChanged: (v) => searchProvider.reload(), onChanged: (v) => {
if (debounce?.isActive ?? false) {debounce!.cancel()},
debounce = Timer(Duration(milliseconds: debouneTime), () {
getClipBoard();
searchProvider.reload();
})
},
decoration: InputDecoration( decoration: InputDecoration(
filled: true, filled: true,
fillColor: Colors.white, fillColor: Colors.white,
prefixIconConstraints: const BoxConstraints( prefixIconConstraints: const BoxConstraints(
minHeight: 32, minHeight: 32,
), ),
suffixIcon: searchProvider.searchController.text == ''
? null
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 17),
child: IconButton(
onPressed: (() async => {
searchProvider.searchController.text = '',
await getClipBoard(),
searchProvider.reload(),
}),
icon: Icon(
Icons.close,
color: Colors.grey[600],
size: 30,
),
),
),
prefixIcon: const Padding( prefixIcon: const Padding(
padding: EdgeInsets.symmetric(horizontal: 17), padding: EdgeInsets.symmetric(horizontal: 17),
child: Image( child: Image(
@ -90,15 +149,15 @@ class SearchScreen extends StatelessWidget {
), ),
const Spacer(flex: 1), const Spacer(flex: 1),
SizedBox( SizedBox(
width: 410, width: 320,
height: 70, height: 90,
child: ElevatedButton( child: ElevatedButton(
key: keyConfirmSearch, key: keyConfirmSearch,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
foregroundColor: Colors.white, elevation: 4, foregroundColor: Colors.white, elevation: 4,
backgroundColor: orangeC, // foreground backgroundColor: orangeC, // foreground
), ),
onPressed: searchProvider.searchController.text.length >= 2 onPressed: canValidate
? () { ? () {
Navigator.push( Navigator.push(
context, context,
@ -107,17 +166,32 @@ class SearchScreen extends StatelessWidget {
}), }),
); );
} }
: null, : canPasteAddress
? () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return WalletViewScreen(
address: pastedAddress, username: '');
}),
);
}
: null,
child: Text( child: Text(
'search'.tr(), canValidate
? 'search'.tr()
: canPasteAddress
? 'pasteAddress'.tr()
: 'search'.tr(),
textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.w600), fontSize: 21, fontWeight: FontWeight.w600),
), ),
), ),
), ),
Spacer(flex: screenHeight <= 800 ? 1 : 2), Spacer(flex: screenHeight <= 800 ? 1 : 2),
]), ]),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
), ),

View File

@ -1,18 +1,13 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.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'; import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.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/providers/wallets_profiles.dart';
import 'package:gecko/providers/search.dart'; import 'package:gecko/providers/search.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/screens/wallet_view.dart'; import 'package:gecko/widgets/commons/offline_info.dart';
import 'package:gecko/widgets/search_result_list.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class SearchResultScreen extends StatelessWidget { class SearchResultScreen extends StatelessWidget {
@ -20,19 +15,19 @@ class SearchResultScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final searchProvider = Provider.of<SearchProvider>(context, listen: false);
SearchProvider searchProvider =
Provider.of<SearchProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider =
Provider.of<CesiumPlusProvider>(context, listen: false);
WalletsProfilesProvider walletsProfilesClass = WalletsProfilesProvider walletsProfilesClass =
Provider.of<WalletsProfilesProvider>(context, listen: false); Provider.of<WalletsProfilesProvider>(context, listen: false);
HomeProvider homeProvider = final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
Provider.of<HomeProvider>(context, listen: false);
DuniterIndexer duniterIndexer =
Provider.of<DuniterIndexer>(context, listen: false);
double avatarSize = 55; double avatarSize = 55;
// List<G1WalletsList> myContacts = contactsBox.toMap().values.toList();
// myContacts = myContacts
// .where((map) =>
// (map.username ?? '').contains(searchProvider.searchController.text))
// .toList();
// final searchProvider.resultLenght.toString();
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
@ -44,7 +39,7 @@ class SearchResultScreen extends StatelessWidget {
child: Text('researchResults'.tr()), child: Text('researchResults'.tr()),
), ),
), ),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: SafeArea( body: SafeArea(
child: Stack(children: [ child: Stack(children: [
Padding( Padding(
@ -53,129 +48,45 @@ class SearchResultScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
const SizedBox(height: 30), const SizedBox(height: 30),
RichText( Center(
text: TextSpan( child: Column(
style: TextStyle( children: <Widget>[
fontSize: 18, Text(
color: Colors.grey[700], "resultsFor".tr(),
), style: TextStyle(color: Colors.grey[600]),
children: <TextSpan>[
TextSpan(
text: "resultsFor".tr(),
),
TextSpan(
text: '"${searchProvider.searchController.text}"',
style: const TextStyle(fontStyle: FontStyle.italic),
), ),
Text(
'"${searchProvider.searchController.text}"',
style: const TextStyle(
fontStyle: FontStyle.italic, fontSize: 21),
)
], ],
), ),
), ),
// const SizedBox(height: 40),
// Text(
// 'Dans mes contacts'.tr(args: [currencyName]),
// style: const TextStyle(fontSize: 20),
// ),
// ContactsList(
// myContacts: myContacts,
// avatarSize: avatarSize,
// walletsProfilesClass: walletsProfilesClass,
// duniterIndexer: duniterIndexer),
const SizedBox(height: 40), const SizedBox(height: 40),
Text( Text(
'inBlockchainResult'.tr(args: [currencyName]), 'inBlockchainResult'.tr(args: [currencyName]),
style: const TextStyle(fontSize: 20), style: const TextStyle(fontSize: 20),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
FutureBuilder( SearchResult(
future: searchProvider.searchAddress(), searchProvider: searchProvider,
builder: (context, AsyncSnapshot<List?> snapshot) { duniterIndexer: duniterIndexer,
if (snapshot.connectionState == ConnectionState.done) { avatarSize: avatarSize,
if (snapshot.data?.isEmpty ?? true) { walletsProfilesClass: walletsProfilesClass),
return duniterIndexer.searchIdentity(
context, searchProvider.searchController.text);
// const Text('Aucun résultat');
} else {
return Expanded(
child: ListView(children: <Widget>[
for (G1WalletsList g1Wallet
in snapshot.data ?? [])
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 5),
child: ListTile(
key: keySearchResult(g1Wallet.address),
horizontalTitleGap: 40,
contentPadding: const EdgeInsets.all(5),
leading: cesiumPlusProvider
.defaultAvatar(avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(g1Wallet.address),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Monospace',
fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
]),
trailing: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SizedBox(
width: 110,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
balance(
context,
g1Wallet.address,
16),
]),
]),
),
]),
subtitle: Row(children: <Widget>[
duniterIndexer.getNameByAddress(
context, g1Wallet.address)
]),
dense: false,
isThreeLine: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfilesClass.address =
g1Wallet.address;
return WalletViewScreen(
address: g1Wallet.address,
username: g1WalletsBox
.get(g1Wallet.address)
?.id
?.username,
avatar: g1WalletsBox
.get(g1Wallet.address)
?.avatar,
);
}),
);
}),
),
]),
);
}
}
return const Center(
heightFactor: 5,
child: CircularProgressIndicator(
strokeWidth: 3,
backgroundColor: yellowC,
color: orangeC,
),
);
},
),
// Text(
// _searchProvider.searchResult.toString(),
// )
]), ]),
), ),
CommonElements().offlineInfo(context), const OfflineInfo(),
]), ]),
), ),
); );

View File

@ -1,6 +1,6 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/home.dart';
@ -18,8 +18,6 @@ class SettingsScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
const double buttonHigh = 50; const double buttonHigh = 50;
const double buttonWidth = 240; const double buttonWidth = 240;
const double fontSize = 16; const double fontSize = 16;
@ -35,7 +33,7 @@ class SettingsScreen extends StatelessWidget {
body: Column(children: <Widget>[ body: Column(children: <Widget>[
const SizedBox(height: 30), const SizedBox(height: 30),
Text( Text(
'Connectivité réseau', 'networkSettings'.tr(),
style: TextStyle(color: Colors.grey[500], fontSize: 22), style: TextStyle(color: Colors.grey[500], fontSize: 22),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
@ -44,7 +42,7 @@ class SettingsScreen extends StatelessWidget {
indexerEndpointSelection(context), indexerEndpointSelection(context),
const SizedBox(height: 40), const SizedBox(height: 40),
Text( Text(
'Affichage', 'displaySettings'.tr(),
style: TextStyle(color: Colors.grey[500], fontSize: 22), style: TextStyle(color: Colors.grey[500], fontSize: 22),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
@ -110,7 +108,7 @@ class SettingsScreen extends StatelessWidget {
} }
Widget duniterEndpointSelection(BuildContext context) { Widget duniterEndpointSelection(BuildContext context) {
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false); final sub = Provider.of<SubstrateSdk>(context, listen: false);
String? selectedDuniterEndpoint; String? selectedDuniterEndpoint;
// List of items in our dropdown menu // List of items in our dropdown menu
@ -251,7 +249,8 @@ class SettingsScreen extends StatelessWidget {
height: sub.getConnectedEndpoint() == null ? 60 : 20, height: sub.getConnectedEndpoint() == null ? 60 : 20,
child: Text( child: Text(
sub.getConnectedEndpoint() ?? sub.getConnectedEndpoint() ??
"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.", "anAutoNodeChoosed"
.tr(), //"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.",
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
@ -261,7 +260,9 @@ class SettingsScreen extends StatelessWidget {
); );
}), }),
Text( Text(
'bloc N°${sub.blocNumber}', 'blockN'.tr(args: [
sub.blocNumber.toString()
]), //'bloc N°${sub.blocNumber}',
style: TextStyle(fontSize: 14, color: Colors.grey[700]), style: TextStyle(fontSize: 14, color: Colors.grey[700]),
) )
], ],
@ -271,8 +272,7 @@ class SettingsScreen extends StatelessWidget {
} }
Widget indexerEndpointSelection(BuildContext context) { Widget indexerEndpointSelection(BuildContext context) {
DuniterIndexer indexer = final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
Provider.of<DuniterIndexer>(context, listen: false);
String? selectedIndexerEndpoint; String? selectedIndexerEndpoint;
if (configBox.containsKey('customIndexer')) { if (configBox.containsKey('customIndexer')) {
@ -282,7 +282,7 @@ class SettingsScreen extends StatelessWidget {
} }
if (selectedIndexerEndpoint == '') { if (selectedIndexerEndpoint == '') {
selectedIndexerEndpoint = indexer.listIndexerEndpoints[0]; selectedIndexerEndpoint = duniterIndexer.listIndexerEndpoints[0];
} }
TextEditingController indexerEndpointController = TextEditingController( TextEditingController indexerEndpointController = TextEditingController(
@ -300,7 +300,8 @@ class SettingsScreen extends StatelessWidget {
const SizedBox(width: 10), const SizedBox(width: 10),
const SizedBox( const SizedBox(
width: 100, width: 100,
child: Text('Indexer : '), // child: Text('indexer'.tr()), // why translation does not work??
child: Text('Indexer'),
), ),
const Spacer(), const Spacer(),
Icon(indexerEndpoint != '' ? Icons.check : Icons.close), Icon(indexerEndpoint != '' ? Icons.check : Icons.close),
@ -388,7 +389,8 @@ class SettingsScreen extends StatelessWidget {
height: 60, height: 60,
child: Text( child: Text(
sub.getConnectedEndpoint() ?? sub.getConnectedEndpoint() ??
"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.", "anAutoNodeChoosed"
.tr(), //"Un noeud sûr et valide sera choisi automatiquement parmis une liste aléatoire.",
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,

View File

@ -1,4 +1,3 @@
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -7,8 +6,7 @@ class TemplateScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); // final _homeProvider = Provider.of<HomeProvider>(context);
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,

View File

@ -1,5 +1,5 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
@ -20,11 +20,10 @@ class TransactionInProgress extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final sub = Provider.of<SubstrateSdk>(context, listen: true);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: true); final walletProfiles =
WalletsProfilesProvider walletViewProvider =
Provider.of<WalletsProfilesProvider>(context, listen: false); Provider.of<WalletsProfilesProvider>(context, listen: false);
MyWalletsProvider myWalletProvider = final myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
bool isValid = false; bool isValid = false;
@ -35,14 +34,16 @@ class TransactionInProgress extends StatelessWidget {
// sub.spawnBlock(); // sub.spawnBlock();
log.d(walletViewProvider.address); log.d(walletProfiles.address);
final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!; final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!;
final to = toAddress ?? getShortPubkey(walletViewProvider.address); final to = toAddress ?? getShortPubkey(walletProfiles.address);
final amount = walletViewProvider.payAmount.text; final amount = walletProfiles.payAmount.text;
String actionName = ''; String actionName = '';
final bool isUdUnit = configBox.get('isUdUnit') ?? false; final bool isUdUnit = configBox.get('isUdUnit') ?? false;
log.d("$transType :: $actionName :: $result");
switch (transType) { switch (transType) {
case 'pay': case 'pay':
{ {
@ -95,7 +96,6 @@ class TransactionInProgress extends StatelessWidget {
{ {
isLoading = false; isLoading = false;
// jsonResult = json.decode(_result); // jsonResult = json.decode(_result);
log.d(result);
if (result.contains('blockHash: ')) { if (result.contains('blockHash: ')) {
isValid = true; isValid = true;
resultText = 'extrinsicValidated'.tr(args: [actionName]); resultText = 'extrinsicValidated'.tr(args: [actionName]);
@ -111,7 +111,7 @@ class TransactionInProgress extends StatelessWidget {
} else { } else {
exception = exceptionSplit[0]; exception = exceptionSplit[0];
} }
// log.d('expection: $_exception'); log.d('expection: $exceptionSplit');
switch (exception) { switch (exception) {
case 'cert.NotRespectCertPeriod': case 'cert.NotRespectCertPeriod':
case 'identity.CreatorNotAllowedToCreateIdty': case 'identity.CreatorNotAllowedToCreateIdty':

View File

@ -2,53 +2,56 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:gecko/globals.dart'; import 'package:gecko/globals.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/g1_wallets_list.dart';
import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/my_wallets.dart';
import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/wallet_options.dart';
import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/providers/wallets_profiles.dart';
import 'package:gecko/screens/activity.dart'; import 'package:gecko/screens/activity.dart';
import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/widgets/commons/common_elements.dart';
import 'package:gecko/screens/myWallets/choose_wallet.dart'; import 'package:gecko/screens/myWallets/choose_wallet.dart';
import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
import 'package:gecko/screens/qrcode_fullscreen.dart'; import 'package:gecko/screens/qrcode_fullscreen.dart';
import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/screens/transaction_in_progress.dart';
import 'package:gecko/widgets/balance.dart';
import 'package:gecko/widgets/bottom_app_bar.dart';
import 'package:gecko/widgets/header_profile.dart';
import 'package:gecko/widgets/page_route_no_transition.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
class WalletViewScreen extends StatelessWidget { class WalletViewScreen extends StatelessWidget {
const WalletViewScreen( const WalletViewScreen(
{required this.address, this.username, this.avatar, Key? key}) {required this.address, required this.username, this.avatar, Key? key})
: super(key: key); : super(key: key);
final String address; final String address;
final String? username; final String username;
final Image? avatar; final Image? avatar;
final double buttonSize = 100; final double buttonSize = 100;
final double buttonFontSize = 18; final double buttonFontSize = 18;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WalletsProfilesProvider walletProfile = WalletsProfilesProvider walletProfile =
Provider.of<WalletsProfilesProvider>(context, listen: false); Provider.of<WalletsProfilesProvider>(context, listen: false);
CesiumPlusProvider cesiumPlusProvider = final sub = Provider.of<SubstrateSdk>(context, listen: false);
Provider.of<CesiumPlusProvider>(context, listen: false); final myWalletProvider =
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); Provider.of<MyWalletsProvider>(context, listen: false);
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
walletProfile.address = address;
sub.setCurrentWallet(defaultWallet); sub.setCurrentWallet(defaultWallet);
log.d('aaaaaaaaaaaaaaaaaaa: $username');
return Scaffold( return Scaffold(
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
@ -100,15 +103,21 @@ class WalletViewScreen extends StatelessWidget {
) )
], ],
title: SizedBox( title: SizedBox(
height: 22, height: 22,
child: Text('seeAWallet'.tr()), child: Text(duniterIndexer
), .walletNameIndexer[walletProfile.address] ==
null
? 'seeAWallet'.tr()
: 'memberAccountOf'.tr(args: [
duniterIndexer.walletNameIndexer[walletProfile.address] ??
'?'
]))),
), ),
bottomNavigationBar: homeProvider.bottomAppBar(context), bottomNavigationBar: const GeckoBottomAppBar(),
body: SafeArea( body: SafeArea(
child: Column(children: <Widget>[ child: Column(children: <Widget>[
walletProfile.headerProfileView(context, address, username), HeaderProfile(address: address, username: username),
SizedBox(height: isTall ? 10 : 0), SizedBox(height: isTall ? 30 : 15),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
Column(children: <Widget>[ Column(children: <Widget>[
SizedBox( SizedBox(
@ -128,11 +137,10 @@ class WalletViewScreen extends StatelessWidget {
onTap: () { onTap: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { PageNoTransit(builder: (context) {
return ActivityScreen( return ActivityScreen(
address: address, address: address,
avatar: avatar: defaultAvatar(50));
cesiumPlusProvider.defaultAvatar(50));
}), }),
); );
}), }),
@ -150,20 +158,20 @@ class WalletViewScreen extends StatelessWidget {
Consumer<SubstrateSdk>(builder: (context, sub, _) { Consumer<SubstrateSdk>(builder: (context, sub, _) {
WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
return FutureBuilder( return FutureBuilder(
future: sub.certState(defaultWallet.address!, address), future: sub.certState(defaultWallet.address, address),
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) { builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
if (snapshot.data == null) return const SizedBox(); if (snapshot.data == null) return const SizedBox();
String duration = ''; String duration = '';
log.d('certDelay ${snapshot.data!['certDelay']}'); log.d(
log.d('certRenewable ${snapshot.data!['certRenewable']}'); '${getShortPubkey(address)} --- certDelay ${snapshot.data!['certDelay']} --- certRenewable ${snapshot.data!['certRenewable']}');
if (snapshot.data!['certDelay'] != null || if (snapshot.data!['certDelay'] != null ||
snapshot.data!['certRenewable'] != null) { snapshot.data!['certRenewable'] != null) {
final Duration durationSeconds = Duration( final Duration durationSeconds = Duration(
seconds: snapshot.data!['certDelay'] ?? seconds: snapshot.data!['certDelay'] ??
snapshot.data!['certRenewable']!); snapshot.data!['certRenewable']!);
final int seconds = durationSeconds.inSeconds; final seconds = durationSeconds.inSeconds;
final int minutes = durationSeconds.inMinutes; final minutes = durationSeconds.inMinutes;
if (seconds <= 0) { if (seconds <= 0) {
duration = 'seconds'.tr(args: ['0']); duration = 'seconds'.tr(args: ['0']);
@ -172,8 +180,8 @@ class WalletViewScreen extends StatelessWidget {
} else if (seconds <= 3600) { } else if (seconds <= 3600) {
duration = 'minutes'.tr(args: [minutes.toString()]); duration = 'minutes'.tr(args: [minutes.toString()]);
} else if (seconds <= 86400) { } else if (seconds <= 86400) {
final int hours = durationSeconds.inHours; final hours = durationSeconds.inHours;
final int minutesLeft = minutes - hours * 60; final minutesLeft = minutes - hours * 60;
String showMinutes = ''; String showMinutes = '';
if (minutesLeft < 60) {} if (minutesLeft < 60) {}
showMinutes = showMinutes =
@ -181,11 +189,10 @@ class WalletViewScreen extends StatelessWidget {
duration = duration =
'hours'.tr(args: [hours.toString(), showMinutes]); 'hours'.tr(args: [hours.toString(), showMinutes]);
} else if (seconds <= 2592000) { } else if (seconds <= 2592000) {
final int days = durationSeconds.inDays; final days = durationSeconds.inDays;
duration = 'days'.tr(args: [days.toString()]); duration = 'days'.tr(args: [days.toString()]);
} else { } else {
final int months = final months = (durationSeconds.inDays / 30).round();
(durationSeconds.inDays / 30).round();
duration = 'months'.tr(args: [months.toString()]); duration = 'months'.tr(args: [months.toString()]);
} }
} }
@ -213,12 +220,18 @@ class WalletViewScreen extends StatelessWidget {
'assets/gecko_certify.png')), 'assets/gecko_certify.png')),
), ),
onTap: () async { onTap: () async {
final bool? result = await confirmPopup( final bool? result =
context, await confirmPopupCertification(
"areYouSureYouWantToCertify".tr( context,
args: [ 'areYouSureYouWantToCertify1'
getShortPubkey(address) .tr(),
])); duniterIndexer
.walletNameIndexer[
address] ??
"noIdentity".tr(),
'areYouSureYouWantToCertify2'
.tr(),
getShortPubkey(address));
if (result ?? false) { if (result ?? false) {
String? pin; String? pin;
@ -262,7 +275,9 @@ class WalletViewScreen extends StatelessWidget {
), ),
const SizedBox(height: 9), const SizedBox(height: 9),
Text( Text(
"certify".tr(), toStatus == 0
? "certify".tr()
: "createIdentity".tr(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: buttonFontSize, fontSize: buttonFontSize,
@ -422,9 +437,7 @@ void paymentPopup(BuildContext context, String toAddress) {
log.d(pin); log.d(pin);
if (pin != null || myWalletProvider.pinCode != '') { if (pin != null || myWalletProvider.pinCode != '') {
// Payment workflow ! // Payment workflow !
WalletsProfilesProvider walletViewProvider = final sub = Provider.of<SubstrateSdk>(context, listen: false);
Provider.of<WalletsProfilesProvider>(context, listen: false);
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
final acc = sub.getCurrentWallet(); final acc = sub.getCurrentWallet();
log.d( log.d(
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin"); "fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin");
@ -453,16 +466,19 @@ void paymentPopup(BuildContext context, String toAddress) {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false); final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
final walletOptions =
Provider.of<WalletOptionsProvider>(context, listen: false);
double fees = 0; double fees = 0;
return StatefulBuilder( return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) { builder: (BuildContext context, StateSetter setState) {
if (walletViewProvider.payAmount.text != '' && if (walletViewProvider.payAmount.text != '' &&
(double.parse(walletViewProvider.payAmount.text) + (double.parse(walletViewProvider.payAmount.text) +
2 / balanceRatio) <= 2 / balanceRatio) <=
(balanceCache[defaultWallet.address] ?? 0) && (walletOptions.balanceCache[defaultWallet.address] ?? 0) &&
toAddress != defaultWallet.address) { toAddress != defaultWallet.address) {
if ((balanceCache[toAddress] == 0 || if ((walletOptions.balanceCache[toAddress] == 0 ||
balanceCache[toAddress] == null) && walletOptions.balanceCache[toAddress] == null) &&
double.parse(walletViewProvider.payAmount.text) < double.parse(walletViewProvider.payAmount.text) <
5 / balanceRatio) { 5 / balanceRatio) {
canValidate = false; canValidate = false;
@ -557,7 +573,7 @@ void paymentPopup(BuildContext context, String toAddress) {
child: Row(children: [ child: Row(children: [
Text(defaultWallet.name!), Text(defaultWallet.name!),
const Spacer(), const Spacer(),
balance(context, defaultWallet.address!, 20) Balance(address: defaultWallet.address, size: 20),
]), ]),
), ),
); );
@ -621,10 +637,11 @@ void paymentPopup(BuildContext context, String toAddress) {
autofocus: true, autofocus: true,
maxLines: 1, maxLines: 1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
keyboardType: TextInputType.number, keyboardType: const TextInputType.numberWithOptions(
decimal: true),
onChanged: (_) async { onChanged: (_) async {
fees = await sub.txFees( fees = await sub.txFees(
defaultWallet.address!, defaultWallet.address,
toAddress, toAddress,
double.parse( double.parse(
walletViewProvider.payAmount.text == '' walletViewProvider.payAmount.text == ''

40
lib/styles.dart Normal file
View File

@ -0,0 +1,40 @@
// import 'dart:io';
import 'package:flutter/material.dart';
// import 'package:logger/logger.dart';
// --- THIS IS WIP ---
class GeckoStyles {
TextStyle successBold(List<String> pars) {
return TextStyle(
color: Colors.green.shade600,
fontWeight: FontWeight.bold,
);
}
TextStyle success() {
return TextStyle(color: Colors.green.shade600);
}
TextStyle error500(List<String> pars) {
return const TextStyle(
fontSize: 20,
color: Colors.redAccent,
fontWeight: FontWeight.w500,
);
}
TextStyle error() {
return const TextStyle(fontSize: 20, color: Colors.redAccent);
}
TextStyle builder(Map<String, dynamic> pars) {
// pars["hola"] = 20;
// //int a = double.tryParse(source) pars["hola"];
// return const TextStyle( fontSize: double.tryParse(pars["hola"]),
// color: Colors.redAccent,
// fontWeight: FontWeight.w500
// );
return const TextStyle();
}
}

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