Compare commits
262 Commits
Author | SHA1 | Date |
---|---|---|
|
22e7cf17b2 | |
|
56a6213e9c | |
|
258cd11819 | |
|
694c682aba | |
|
2f180d2d01 | |
|
41dcf91217 | |
|
e485af5194 | |
|
6b5bcadded | |
|
5bc261509a | |
|
02b59e39b3 | |
|
5950088bca | |
|
bfce822b17 | |
|
b1f9067c36 | |
|
f1208846fc | |
|
de341c3a07 | |
|
bbec988c5c | |
|
6cb085851f | |
|
1127f773fb | |
|
232f89319a | |
|
2bef9c1790 | |
|
ebf7420615 | |
|
3177392604 | |
|
bc415b56e8 | |
|
ef9e7b30f1 | |
|
b37b9ad804 | |
|
93c9b377ba | |
|
20590a944c | |
|
ce68216684 | |
|
70b4c8a96d | |
|
3cabd84815 | |
|
9337052cb5 | |
|
55eb61fb7d | |
|
639b376dc1 | |
|
ee88042b0e | |
|
5718d170f3 | |
|
007d62054b | |
|
8ca0b00a60 | |
|
2830a9d005 | |
|
6d284b7ff8 | |
|
225d2b342b | |
|
a6ed10c6b7 | |
|
ff29ff8086 | |
|
8df05ea069 | |
|
cb840b947a | |
|
3ec18ba00e | |
|
bde2b0cb1e | |
|
65b5a9f3e6 | |
|
fe75821ba3 | |
|
a1d8627443 | |
|
9a171a7766 | |
|
c29417734d | |
|
d9c30d337a | |
|
9f0144803f | |
|
bad65f559b | |
|
19fdf9715d | |
|
5dbec1ac53 | |
|
6d16b99cbf | |
|
db5358ace8 | |
|
4614f81dac | |
|
fc03d4de75 | |
|
80cbde7271 | |
|
cf9f55773e | |
|
db13c4a580 | |
|
cab22eb4ae | |
|
5ccacea46d | |
|
a35d6b5cf2 | |
|
a13d19177b | |
|
e3dc579da7 | |
|
6be89a3622 | |
|
b436341808 | |
|
7514eb7299 | |
|
b916c44db4 | |
|
1b1c5ab7f0 | |
|
f65b194e2d | |
|
6f2d33b76e | |
|
08ea8445ad | |
|
dbdfd0c4fb | |
|
0c562bb5ab | |
|
b3fc3e7a8b | |
|
433452dc0f | |
|
e47211f139 | |
|
a751b1ebf3 | |
|
fadc3c0cdc | |
|
1f72710b27 | |
|
ea43d66ce0 | |
|
acd838788a | |
|
4cbb0bba20 | |
|
b835c701b1 | |
|
dc1b54a09c | |
|
6b42aab079 | |
|
7a459683fb | |
|
fe76beaaef | |
|
5e2d4c465a | |
|
2301472567 | |
|
611d715ded | |
|
0a47c3b2e3 | |
|
abb2810e47 | |
|
c316c0d630 | |
|
5b04c5b19e | |
|
21a56bbc96 | |
|
777fa39ad2 | |
|
2264a9fc81 | |
|
f4ed793e56 | |
|
ea94b4570b | |
|
f7fd90ed78 | |
|
09c869e67c | |
|
33635d92aa | |
|
f41443622a | |
|
5ab9377f82 | |
|
c6a7474c78 | |
|
9d63e6e522 | |
|
6ec550e7ec | |
|
00b81d530e | |
|
840932cbc2 | |
|
d878fd8b37 | |
|
fcff3e6076 | |
|
c25673d754 | |
|
8050a44454 | |
|
f76edf006d | |
|
105d32a8a0 | |
|
6523bceb2b | |
|
8570c0a341 | |
|
c304999e61 | |
|
51774acad0 | |
|
fd5d20ece9 | |
|
c4b9eaf2ea | |
|
edaf0655ad | |
|
e56d6d5686 | |
|
ddcd47c076 | |
|
ac1157f12a | |
|
c60a8ad489 | |
|
2571baa958 | |
|
b31fbc9375 | |
|
472a4c1e5d | |
|
c8933fd5be | |
|
532a004fd9 | |
|
22c59613ee | |
|
60427463b5 | |
|
83764194e7 | |
|
721e26ce05 | |
|
f5904e4f88 | |
|
a0a3910adc | |
|
d4740ab647 | |
|
975614d873 | |
|
8e128963ad | |
|
515a058377 | |
|
2d9e8025c0 | |
|
2cb7f234e5 | |
|
a347796a42 | |
|
9496b9206b | |
|
1a3df7d2f8 | |
|
9f5a15cc40 | |
|
2ea77b0fce | |
|
46bc38a1e9 | |
|
0634335854 | |
|
22325f7299 | |
|
31627c2060 | |
|
5b561d52ae | |
|
9a4c1d602b | |
|
8382cbfc29 | |
|
9983ea9f78 | |
|
0ab955b2da | |
|
60ea8ecac1 | |
|
3d9ce9dc14 | |
|
9ad20184db | |
|
38498d2370 | |
|
bd97495cd2 | |
|
0b4f86638e | |
|
b0d29fceb3 | |
|
e1c5943667 | |
|
1364b36cbf | |
|
1f1ccc0882 | |
|
a176611c83 | |
|
d1194d5eb5 | |
|
71d222307b | |
|
bca3082845 | |
|
5d084f44e7 | |
|
d19131e86a | |
|
5e4f135470 | |
|
26cc024b87 | |
|
3ba04470f9 | |
|
ad92a06060 | |
|
792ac2f715 | |
|
f7fe3fa7df | |
|
c055dbfe3a | |
|
613b6b282e | |
|
8ddd877131 | |
|
c6cfb4e548 | |
|
875341a804 | |
|
70f4f151c0 | |
|
c1ebfc62bc | |
|
7f8d46b9e8 | |
|
7cdc13273e | |
|
6155552424 | |
|
622ceda579 | |
|
a28df90c18 | |
|
d7731504c7 | |
|
cf4387a280 | |
|
82c1d5bf4c | |
|
c81662de83 | |
|
150f6892f8 | |
|
4ef5f77888 | |
|
c50aa53f38 | |
|
30b8b68bef | |
|
535e121505 | |
|
88b34b1008 | |
|
b1a5ca748c | |
|
e5e71667df | |
|
9a2b99977e | |
|
cd2c257779 | |
|
ef7f6eff1b | |
|
24aee6a53c | |
|
853ad0eb6a | |
|
25c0144098 | |
|
1903b988de | |
|
8b3ecae62f | |
|
1ea3be788e | |
|
ae36f7384e | |
|
44c8cfb9bc | |
|
b924d644b7 | |
|
2ae32982f8 | |
|
9ed76b071e | |
|
92fd504505 | |
|
d749c9a997 | |
|
4158a5308c | |
|
b4e0f110a3 | |
|
e602099cc3 | |
|
bc75ae114f | |
|
9e91408220 | |
|
42801f8145 | |
|
806a96d127 | |
|
5b89f661ed | |
|
397d795e8b | |
|
4c7326bfaa | |
|
826dcf7c7c | |
|
f19a441af3 | |
|
7e98a1d063 | |
|
68fe7925ac | |
|
bafd853884 | |
|
6b1df55ede | |
|
0241efc223 | |
|
7a93ff4d78 | |
|
9a9bc6788c | |
|
413c3c708e | |
|
cf6571e9da | |
|
da0e9ba2df | |
|
80416f5753 | |
|
96854fddb9 | |
|
6c34dd2425 | |
|
e65915a333 | |
|
b48be00149 | |
|
1481352f6c | |
|
bae16d3a5f | |
|
b7311970e2 | |
|
965ce0f977 | |
|
3a5674ae41 | |
|
38c8b9a995 | |
|
8169e1e840 | |
|
e88cf3b2f7 | |
|
cc36e2652d | |
|
6ea827faf9 | |
|
44993557c6 |
|
@ -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,5 @@ android/app/build.gradle
|
||||||
integration_test/duniter/data/chains/
|
integration_test/duniter/data/chains/
|
||||||
|
|
||||||
# Ignore PC deps
|
# Ignore PC deps
|
||||||
macos/
|
scripts/pushGecko
|
||||||
windows/
|
android-old
|
|
@ -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:
|
||||||
|
|
25
.metadata
|
@ -4,7 +4,7 @@
|
||||||
# This file should be version controlled.
|
# This file should be version controlled.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: 85684f9300908116a78138ea4c6036c35c9a1236
|
revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
@ -13,11 +13,26 @@ project_type: app
|
||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 85684f9300908116a78138ea4c6036c35c9a1236
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
base_revision: 85684f9300908116a78138ea4c6036c35c9a1236
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
- platform: android
|
- platform: android
|
||||||
create_revision: 85684f9300908116a78138ea4c6036c35c9a1236
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
base_revision: 85684f9300908116a78138ea4c6036c35c9a1236
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
- platform: ios
|
||||||
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
- platform: linux
|
||||||
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
- platform: macos
|
||||||
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
- platform: web
|
||||||
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
- platform: windows
|
||||||
|
create_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
base_revision: c07f7888888435fd9df505aa2efc38d3cf65681b
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|
92
README.md
|
@ -1,12 +1,13 @@
|
||||||
# Ğecko
|
# Ğecko
|
||||||
|
|
||||||
Ğecko is a transaction client owned by [Axiom-Team association] and written in Dart. It is fast and secure thanks to native code compilation. It is not intended to manage member accounts, but rather simple wallets.
|
Ğecko is mobile client for Duniter v2s blockchain (Ḡ1v2): https://duniter.org/blog/duniter-substrate<br>
|
||||||
|
It use polkawallet_sdk package to interact with Duniter: https://github.com/polkawallet-io/sdk
|
||||||
|
|
||||||
The development is quite early, you can participate in the discussion [on the Duniter forum](https://forum.duniter.org/t/gecko-nouveau-client-de-paiements-1-sur-mobile-en-cours-de-developpement-dart-flutter/7857) (mostly FR)
|
This application is maintained by [Axiom-Team association](https://axiom-team.fr/).
|
||||||
|
|
||||||
[Axiom-Team association]: https://axiom-team.fr/
|
You can download the last version of the app [here](https://forum.duniter.org/t/gecko-gdev-last-build/9367/last).<br>
|
||||||
|
You can ask questions about Ḡecko developpement in our [Duniter forum](https://forum.duniter.org/t/gecko-talks-user-support/9372/last).
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
|
@ -17,73 +18,78 @@ The development is quite early, you can participate in the discussion [on the Du
|
||||||
|
|
||||||
## Develop
|
## Develop
|
||||||
|
|
||||||
To contribute to the code, we advise you to install the following development environment.
|
To contribute to the code, we advise you to install the following development environment:
|
||||||
|
|
||||||
1. Android Studio
|
1. [Android Studio](https://developer.android.com/studio/install)
|
||||||
- Android VM
|
2. [Flutter](https://docs.flutter.dev/get-started/install)
|
||||||
- Android NDK
|
3. [VSCode](https://code.visualstudio.com/docs/setup/linux) or [VSCodium](https://vscodium.com/)
|
||||||
1. Flutter SDK
|
|
||||||
1. VSCode/Codium Flutter extension
|
|
||||||
|
|
||||||
This will take about 12GB on your drive and 30 min of your time (with a good connection). Don't hesitate to ask on the forum for a peer-coding session if you are stuck.
|
This will take about 12GB on your drive and 20 min of your time (with a good connection). Don't
|
||||||
|
hesitate to ask on the forum for a peer-coding session if you are stuck.
|
||||||
|
|
||||||
|
At the end, `flutter doctor` command should be OK for what you need.
|
||||||
|
|
||||||
### Android Studio
|
### Android Studio
|
||||||
|
|
||||||
Android Studio will let you set up an Android VM and install tools you need.
|
Android Studio will let you set up an Android VM and install tools you need.
|
||||||
|
|
||||||
- Install [Android Studio](https://developer.android.com/studio/) using your favorite installation method.
|
- Install [Android Studio](https://developer.android.com/studio/) using your favorite installation
|
||||||
|
method.
|
||||||
- At startup, do not open a project but click "configure" at the bottom of the "Welcome" menu
|
- At startup, do not open a project but click "configure" at the bottom of the "Welcome" menu
|
||||||
- In "SDK Manager"
|
- In "SDK Manager"
|
||||||
- SDK Platforms Ttab
|
- SDK Platforms tab
|
||||||
- note your SDK folder location (later used for Rust environment variables)
|
- select Android 11 (R) API level 30 (default) or higher
|
||||||
- select Android 11 (R) API level 30 (default)
|
|
||||||
- SDK Tools
|
|
||||||
- select NDK (native development kit used to compile Rust to native target)
|
|
||||||
- In "AVD Manager"
|
- In "AVD Manager"
|
||||||
- create a virtual machine (ours is Pixel 4 32bits machine)
|
- create a virtual machine
|
||||||
- launch it in the emulator
|
|
||||||
|
|
||||||
If you reach this point without trouble, you're good to go for the next step.
|
If you reach this point without trouble, you're good to go for the next step.
|
||||||
|
|
||||||
|
### iOS (Xcode on Mac)
|
||||||
|
TODO: documentation
|
||||||
|
|
||||||
### Flutter SDK
|
### Flutter SDK
|
||||||
|
|
||||||
Flutter is a powerfull SDK to develop Android apps. [Install it](https://flutter.dev/docs/get-started/install/linux) with your favorite installation method.
|
Flutter is a powerfull SDK to develop Android
|
||||||
|
apps. [Install it](https://flutter.dev/docs/get-started/install/linux) with your favorite
|
||||||
|
installation method.
|
||||||
|
|
||||||
### VSCode
|
### VSCode
|
||||||
|
|
||||||
We are using VSCode and therefore document the process for this IDE. Of course you're free to use whatever you want.
|
We are using VSCode and therefore document the process for this IDE. Of course you're free to use
|
||||||
Clone the ğecko repo and open a dart file (e.g. `lib/main.dart`). VSCode will suggest you to insall relevant extensions.
|
whatever you want.
|
||||||
|
Clone the ğecko repo and open a dart file (e.g. `lib/main.dart`). VSCode will suggest you to insall
|
||||||
|
relevant extensions.
|
||||||
|
|
||||||
### Build the app
|
### Launch the app in debug mode
|
||||||
|
|
||||||
In a dart file (e.g. `lib/main.dart`), type the `F5` key to build the code. The app should open automatically in your VM which is running.
|
Start a VM, then open a dart file (e.g. `lib/main.dart`), type the `F5` key to build the code. The app should open
|
||||||
|
automatically in your VM which is running.
|
||||||
|
|
||||||
### Build your app for Desktop
|
### Build APK
|
||||||
|
|
||||||
#### Linux
|
You will need to generate PlayStore key or disable signing APK before continue.
|
||||||
|
Then, check this script and launch it:
|
||||||
Install dependancies:
|
|
||||||
|
|
||||||
`sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev`
|
|
||||||
|
|
||||||
Then build debug for linux:
|
|
||||||
|
|
||||||
`flutter run -d linux`
|
|
||||||
|
|
||||||
If you get this error:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
flutter /usr/share/cmake-3.16/Modules/FindPkgConfig.cmake:643 (_pkg_check_modules_internal)
|
./scripts/build-apk.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Please try:
|
### Integration tests
|
||||||
|
|
||||||
`sudo apt install liblzma-dev`
|
Open an android or iOS emulator, then launch this script:
|
||||||
|
|
||||||
then
|
```
|
||||||
|
./integration_test/launch_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
`flutter clean && flutter run -d linux`
|
It will start the [default test scenario](https://git.duniter.org/clients/gecko/-/blob/master/integration_test/scenarios/gecko_complete.dart).
|
||||||
|
|
||||||
## Roadmap
|
You can start another scenario defined [here](https://git.duniter.org/clients/gecko/-/tree/master/integration_test/scenarios) specifying the name of the file without its extension, for example to run migrate_cesium_identity.dart test:
|
||||||
|
|
||||||
-> https://pad.p2p.legal/gecko-roadmap-2022?view
|
```
|
||||||
|
./integration_test/launch_test.sh migrate_cesium_identity
|
||||||
|
```
|
||||||
|
|
||||||
|
### A problem ?
|
||||||
|
|
||||||
|
Please open an issue here: https://git.duniter.org/clients/gecko/-/boards
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
plugins {
|
||||||
|
id 'com.android.application'
|
||||||
|
id 'kotlin-android'
|
||||||
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
|
}
|
||||||
|
|
||||||
def localProperties = new Properties()
|
def localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
|
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = '1'
|
||||||
|
@ -21,10 +22,6 @@ if (flutterVersionName == null) {
|
||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
if (keystorePropertiesFile.exists()) {
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
@ -32,21 +29,30 @@ if (keystorePropertiesFile.exists()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
namespace "gecko.axiomteam.fr"
|
||||||
|
compileSdk flutter.compileSdkVersion
|
||||||
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs += 'src/main/kotlin'
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
|
||||||
disable 'InvalidPackage'
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "gecko.axiomteam.fr"
|
applicationId "gecko.axiomteam.fr"
|
||||||
minSdkVersion 19
|
// You can update the following values to match your application needs.
|
||||||
targetSdkVersion 33
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||||
|
minSdkVersion flutter.minSdkVersion
|
||||||
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
@ -65,7 +71,7 @@ android {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
// TODO: Add your own signing config for the release build.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig signingConfigs.release //poka: comment this to build unsigned release, or set to signingConfigs.debug to sign with debug keys
|
signingConfig signingConfigs.release
|
||||||
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
@ -76,11 +82,9 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
source '../..'
|
source '../..'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {}
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.7.0'
|
|
||||||
}
|
|
||||||
|
|
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -1,20 +1,7 @@
|
||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.7.10'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +13,6 @@ subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#Fri Jun 23 08:50:38 CEST 2017
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
include ':app'
|
pluginManagement {
|
||||||
|
def flutterSdkPath = {
|
||||||
|
def properties = new Properties()
|
||||||
|
file("local.properties").withInputStream { properties.load(it) }
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
return flutterSdkPath
|
||||||
|
}
|
||||||
|
settings.ext.flutterSdkPath = flutterSdkPath()
|
||||||
|
|
||||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
id "com.android.application" version "7.3.0" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include ":app"
|
||||||
|
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 246 KiB |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 192 KiB |
After Width: | Height: | Size: 21 KiB |
|
@ -23,7 +23,7 @@
|
||||||
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:",
|
"toUnlockEnterPassword": "To unlock your safe, enter your secret code, away from prying lizards:",
|
||||||
"rememberPassword": "Keep this code in memory for 15 minutes",
|
"rememberPassword": "Keep this code in memory for 15 minutes",
|
||||||
"myRootWallet": "My root wallet",
|
"myRootWallet": "My root wallet",
|
||||||
"currentWallet": "My current chest",
|
"currentWallet": "My current wallet",
|
||||||
"wallet": "Wallet",
|
"wallet": "Wallet",
|
||||||
"displayMnemonic": "Display my mnemonic sentence",
|
"displayMnemonic": "Display my mnemonic sentence",
|
||||||
"changePassword": "Change my password",
|
"changePassword": "Change my password",
|
||||||
|
@ -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.",
|
||||||
|
@ -102,7 +103,9 @@
|
||||||
"identityCreated": "Identity created",
|
"identityCreated": "Identity created",
|
||||||
"identityConfirmed": "Identity confirmed",
|
"identityConfirmed": "Identity confirmed",
|
||||||
"identityExpired": "Identity expired",
|
"identityExpired": "Identity expired",
|
||||||
|
"identityRevoked": "Identity revoked",
|
||||||
"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",
|
||||||
|
@ -150,35 +153,38 @@
|
||||||
"canRenewCertInX": "You can renew\nthis certification\nin {}",
|
"canRenewCertInX": "You can renew\nthis certification\nin {}",
|
||||||
"executeATransfer": "Execute a transfer",
|
"executeATransfer": "Execute a transfer",
|
||||||
"executeTheTransfer": "Execute the transfer",
|
"executeTheTransfer": "Execute the transfer",
|
||||||
"doATransfer" : "Execute a\ntransfer",
|
"doATransfer": "Execute a\ntransfer",
|
||||||
"seconds": "{} seconds",
|
"seconds": "{} seconds",
|
||||||
"minutes": "{} minutes",
|
"minutes": "{} minutes",
|
||||||
"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:",
|
||||||
"choiceOfSourceWallet": "Choose a source wallet",
|
"choiceOfSourceWallet": "Choose a source wallet",
|
||||||
"extrinsicInProgress": "{} in progress",
|
"extrinsicInProgress": "{} in progress",
|
||||||
"extrinsicValidated": "{} validated !",
|
"extrinsicValidated": "{} validated !",
|
||||||
|
"extrinsicFinalized": "{} finalized !",
|
||||||
"fromMinus": "from",
|
"fromMinus": "from",
|
||||||
"toMinus": "to",
|
"toMinus": "to",
|
||||||
"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",
|
||||||
"noContacts": "You don't have any contact",
|
"noContacts": "You don't have any contact",
|
||||||
"addContact": "Add\nto contacts",
|
"addContact": "Add\nto contacts",
|
||||||
"removeContact": "Remove\nthis contact",
|
"removeContact": "Remove\nthis contact",
|
||||||
"derivationsScanProgress": "Scan address {}/{}",
|
"scanRootDerivationInProgress": "Scan root address",
|
||||||
|
"derivationsScanProgress": "Scan {} firsts addresses",
|
||||||
|
"importDerivationsInProgress": "Import address {}/{}",
|
||||||
"youAreOffline": "You are offline...",
|
"youAreOffline": "You are offline...",
|
||||||
"importG1v1": "Import old G1v1 account",
|
"importG1v1": "Import old G1v1 account",
|
||||||
"selectDestWallet": "Select a target wallet:",
|
"migrateToThisWallet": "Migrate to this wallet:",
|
||||||
"youMustWaitBeforeCashoutThisAccount": "You have to wait a few moment before migrate this account",
|
"youMustWaitBeforeCashoutThisAccount": "You have to wait a few moment before migrate this account",
|
||||||
"thisAccountIsEmpty": "This account is empty",
|
"thisAccountIsEmpty": "This account is empty",
|
||||||
"youCannotMigrateIdentityToExistingIdentity": "You cannot migrate an identity\nto an account that already has an identity",
|
"youCannotMigrateIdentityToExistingIdentity": "You cannot migrate an identity\nto an account that already has an identity",
|
||||||
|
@ -195,5 +201,40 @@
|
||||||
"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",
|
||||||
|
"removedFromcontacts": "Removed from contacts",
|
||||||
|
"addedToContacts": "Added to contacts",
|
||||||
|
"certificationsOf": "Certifications of {}",
|
||||||
|
"explainDraggableWallet": "Drag and drop a tile onto another to make a transaction, by holding down the tile.",
|
||||||
|
"skip": "Skip",
|
||||||
|
"fees": "fees: {} {}",
|
||||||
|
"feesExplanation": "To ensure network security, an execution fee is charged on each transaction.",
|
||||||
|
"feesExplanationDetails": "These fees are transferred to the common treasury account.",
|
||||||
|
"gotit": "Got it",
|
||||||
|
"moreInfo": "More information",
|
||||||
|
"keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.",
|
||||||
|
"fundsUnavailable": "Insufficient funds",
|
||||||
|
"addressNotBelongToMnemonic": "The address you provided does not belong to this recovery sentence",
|
||||||
|
"enterYourNewMnemonic": "Enter your new recovery sentence",
|
||||||
|
"enterYourNewAddress": "Enter your new address {}",
|
||||||
|
"youCanMigrateThisIdentity": "You can migrate this identity !",
|
||||||
|
"identityMigrated": "Identity migrated"
|
||||||
}
|
}
|
|
@ -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 monedero 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,19 @@
|
||||||
"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",
|
||||||
|
"identityRevoked": "Identidad revocada",
|
||||||
"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 +128,114 @@
|
||||||
"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 !",
|
||||||
|
"extrinsicFinalized": "{} finalized !",
|
||||||
"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 {}/{}",
|
"scanRootDerivationInProgress": "Scan root address",
|
||||||
"youAreOffline": "You are offline...",
|
"derivationsScanProgress": "Scan {} firsts addresses",
|
||||||
"importG1v1": "Import old G1v1 account",
|
"importDerivationsInProgress": "Import address {}/{}",
|
||||||
"selectDestWallet": "Select a target wallet:",
|
"youAreOffline": "Estás desconectado...",
|
||||||
"youMustWaitBeforeCashoutThisAccount": "You have to wait a few moment before migrate this account",
|
"importG1v1": "Importar la cuenta antigua de G1v1",
|
||||||
"thisAccountIsEmpty": "This account is empty",
|
"migrateToThisWallet": "Migrate to this wallet:",
|
||||||
"youCannotMigrateIdentityToExistingIdentity": "You cannot migrate an identity\nto an account that already has an identity",
|
"youMustWaitBeforeCashoutThisAccount": "Tienes que esperar unos minutos antes de migrar esta cuenta",
|
||||||
"importOldAccount": "Import your old account",
|
"thisAccountIsEmpty": "Esta cuenta está vacía",
|
||||||
"enterCesiumId": "Ingrese su ID de Cesium",
|
"youCannotMigrateIdentityToExistingIdentity": "No se puede migrar una identidad\na una cuenta que ya tiene una identidad",
|
||||||
"enterCesiumPassword": "Ingrese su contraseña de Cesium",
|
"importOldAccount": "Importar antigua cuenta",
|
||||||
"migrateAccount": "Migrate account",
|
"enterCesiumId": "Ingresa tu frase secreta de Cesium",
|
||||||
"migrateIdentity": "Migrate identity",
|
"enterCesiumPassword": "Ingresa tu contraseña de Cesium",
|
||||||
"identityMigration": "Identity migration",
|
"migrateAccount": "Migrar cuenta",
|
||||||
"areYouSureMigrateIdentity": "Are you sure you want to permanently migrate identity **{}** with balance of **{}** ?",
|
"migrateIdentity": "Migrar identidad",
|
||||||
"someoneCreatedYourIdentity": "Someone created your {} identity !",
|
"identityMigration": "Migración de la identidad",
|
||||||
|
"areYouSureMigrateIdentity": "¿Estás seguro de que quieres migrar permanentemente la identidad **{}** con saldo de **{}**?",
|
||||||
|
"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",
|
||||||
|
"removedFromcontacts": "Removed from contacts",
|
||||||
|
"addedToContacts": "Added to contacts",
|
||||||
|
"certificationsOf": "Certifications of {}",
|
||||||
|
"explainDraggableWallet": "Drag and drop a tile onto another to make a transaction, by holding down the tile.",
|
||||||
|
"skip": "Skip",
|
||||||
|
"fees": "fees: {} {}",
|
||||||
|
"feesExplanation": "To ensure network security, an execution fee is charged on each transaction.",
|
||||||
|
"feesExplanationDetails": "These fees are transferred to the common treasury account.",
|
||||||
|
"gotit": "Got it",
|
||||||
|
"moreInfo": "More information",
|
||||||
|
"keepThisPaperSafe": "Keep this sheet safe from prying lizards.\nIt will allow you to restore all your wallets at any time.",
|
||||||
|
"fundsUnavailable": "Insufficient funds",
|
||||||
|
"addressNotBelongToMnemonic": "The address you provided does not belong to this recovery sentence",
|
||||||
|
"enterYourNewMnemonic": "Enter your new recovery sentence",
|
||||||
|
"enterYourNewAddress": "Enter your new address {}",
|
||||||
|
"youCanMigrateThisIdentity": "You can migrate this identity !",
|
||||||
|
"identityMigrated": "Identity migrated"
|
||||||
|
}
|
|
@ -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 l’avez 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 l’avez bien noté.",
|
||||||
"yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !",
|
"yourChestAndWalletWereCreatedSuccessfully": "Top !\n\nVotre coffre et votre premier portefeuille ont été créés avec un immense succès.\n\nFélicitations !",
|
||||||
"allGood": "C’est tout bon !",
|
"allGood": "C’est 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 d’accéder à tous vos portefeuilles.",
|
"keepYourMnemonicSecret": "Tâchez de garder cette phrase bien secrète, car elle permet à quiconque la connaît d’accéder à tous vos portefeuilles.",
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
"identityCreated": "Identité créée",
|
"identityCreated": "Identité créée",
|
||||||
"identityConfirmed": "Identité confirmée",
|
"identityConfirmed": "Identité confirmée",
|
||||||
"identityExpired": "Identité expirée",
|
"identityExpired": "Identité expirée",
|
||||||
|
"identityRevoked": "Identité révoqué",
|
||||||
"confirmYourIdentity": "Confirmez votre identité",
|
"confirmYourIdentity": "Confirmez votre identité",
|
||||||
"noResult": "Aucun résultat",
|
"noResult": "Aucun résultat",
|
||||||
"noDuniterNodeAvailableTryLater": "Aucun noeud Duniter disponible, veuillez réessayer ultérieurement",
|
"noDuniterNodeAvailableTryLater": "Aucun noeud Duniter disponible, veuillez réessayer ultérieurement",
|
||||||
|
@ -157,30 +159,33 @@
|
||||||
"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 !",
|
||||||
|
"extrinsicFinalized": "{} finalisé !",
|
||||||
"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",
|
||||||
"noContacts": "Vous n'avez aucun contact",
|
"noContacts": "Vous n'avez aucun contact",
|
||||||
"addContact": "Ajouter\naux contacts",
|
"addContact": "Ajouter\naux contacts",
|
||||||
"removeContact": "Supprimer\nce contact",
|
"removeContact": "Supprimer\nce contact",
|
||||||
"derivationsScanProgress": "Scan de l'adresse {}/{}",
|
"scanRootDerivationInProgress": "Scan de l'adresse racine",
|
||||||
|
"derivationsScanProgress": "Scan des {} premières adresses",
|
||||||
|
"importDerivationsInProgress": "Importation de l'adresse {}/{}",
|
||||||
"youAreOffline": "Vous êtes hors ligne...",
|
"youAreOffline": "Vous êtes hors ligne...",
|
||||||
"importG1v1": "Importer un ancien compte G1v1",
|
"importG1v1": "Importer un ancien compte G1v1",
|
||||||
"selectDestWallet": "Sélectionnez un portefeuille cible:",
|
"migrateToThisWallet": "Migrer vers ce portefeuille:",
|
||||||
"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 +201,40 @@
|
||||||
"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à",
|
||||||
|
"removedFromcontacts": "Retiré des contact",
|
||||||
|
"addedToContacts": "Ajouté au contacts",
|
||||||
|
"certificationsOf": "Certifications de {}",
|
||||||
|
"explainDraggableWallet": "Faites glisser et déposez une tuile sur une autre pour effectuer une transaction, avec un appui long.",
|
||||||
|
"skip": "Passer",
|
||||||
|
"fees": "frais: {} {}",
|
||||||
|
"feesExplanation": "Pour garantir la sécurité du réseau, des frais d'exécution sont prélevés sur chaque transaction.",
|
||||||
|
"feesExplanationDetails": "Ces frais sont transférés vers le compte de trésorerie commune.",
|
||||||
|
"gotit": "J'ai compris",
|
||||||
|
"moreInfo": "Plus d'info",
|
||||||
|
"keepThisPaperSafe": "Gardez cette feuille précieusement, à l’abri des lézards indiscrets.\nElle vous permettra de restaurer tous vos portefeuilles à tout moment.",
|
||||||
|
"fundsUnavailable": "Fonds insuffisants",
|
||||||
|
"addressNotBelongToMnemonic": "L'adresse que vous avez fournit n'appartient pas à cette phrase de restauration",
|
||||||
|
"enterYourNewMnemonic": "Entrez votre nouvelle phrase de restauration",
|
||||||
|
"enterYourNewAddress": "Entrez votre nouvelle adresse {}",
|
||||||
|
"youCanMigrateThisIdentity": "Vous pouvez migrer vers cette identité !",
|
||||||
|
"identityMigrated": "Identité migré"
|
||||||
}
|
}
|
|
@ -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",
|
||||||
|
"migrateToThisWallet": "Seleziona un portafoglio di destinazione:",
|
||||||
|
"youMustWaitBeforeCashoutThisAccount": "Devi aspettare qualche minuto prima di migrare questo conto",
|
||||||
|
"thisAccountIsEmpty": "Questo conto é vuoto",
|
||||||
|
"youCannotMigrateIdentityToExistingIdentity": "Non si puó migrare un'identitá\na un conto che ne ha giá una",
|
||||||
|
"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"
|
||||||
|
}
|
|
@ -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"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[
|
[
|
||||||
"https://gdev-indexer.p2p.legal",
|
"gdev-squid.axiom-team.fr"
|
||||||
"https://idx.gdev.cgeek.fr",
|
|
||||||
"https://duniter-indexer.coinduf.eu",
|
|
||||||
"http://192.168.1.72:8080"
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
extensions:
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"ud": 1000,
|
||||||
|
"first_ud": null,
|
||||||
|
"first_ud_reeval": null,
|
||||||
|
"genesis_parameters": {
|
||||||
|
"genesis_certs_expire_on": 1000,
|
||||||
|
"genesis_certs_min_received": 2,
|
||||||
|
"genesis_memberships_expire_on": 1000,
|
||||||
|
"genesis_smith_certs_expire_on": 1000,
|
||||||
|
"genesis_smith_certs_min_received": 2,
|
||||||
|
"genesis_smith_memberships_expire_on": 100000
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"babe_epoch_duration": 30,
|
||||||
|
"cert_period": 15,
|
||||||
|
"cert_max_by_issuer": 10,
|
||||||
|
"cert_min_received_cert_to_issue_cert": 2,
|
||||||
|
"cert_validity_period": 1000,
|
||||||
|
"idty_confirm_period": 40,
|
||||||
|
"idty_creation_period": 50,
|
||||||
|
"membership_period": 1000,
|
||||||
|
"membership_renewal_period": 1000,
|
||||||
|
"pending_membership_period": 500,
|
||||||
|
"ud_creation_period": 10,
|
||||||
|
"ud_reeval_period": 50,
|
||||||
|
"smith_cert_period": 15,
|
||||||
|
"smith_cert_max_by_issuer": 8,
|
||||||
|
"smith_cert_min_received_cert_to_issue_cert": 2,
|
||||||
|
"smith_cert_validity_period": 1000,
|
||||||
|
"smith_membership_period": 1000,
|
||||||
|
"smith_inactivity_max_duration": 1000,
|
||||||
|
"smith_pending_membership_period": 500,
|
||||||
|
"smith_wot_first_cert_issuable_on": 4,
|
||||||
|
"smith_wot_min_cert_for_membership": 3,
|
||||||
|
"wot_first_cert_issuable_on": 0,
|
||||||
|
"wot_min_cert_for_create_idty_right": 3,
|
||||||
|
"wot_min_cert_for_membership": 3
|
||||||
|
},
|
||||||
|
"clique_smiths": [
|
||||||
|
{ "name": "test1" },
|
||||||
|
{ "name": "test2" },
|
||||||
|
{ "name": "test3" },
|
||||||
|
{ "name": "test4" },
|
||||||
|
{ "name": "Alice" }
|
||||||
|
],
|
||||||
|
"sudo_key": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa",
|
||||||
|
"treasury_funder_address": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa",
|
||||||
|
"technical_committee": ["test1", "test2", "test3"]
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
{
|
||||||
|
"initial_monetary_mass": 90100,
|
||||||
|
"current_block": {
|
||||||
|
"number": 0,
|
||||||
|
"medianTime": 1700000000
|
||||||
|
},
|
||||||
|
"identities": {
|
||||||
|
"test1": {
|
||||||
|
"index": 7,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test3": 2700000000,
|
||||||
|
"test4": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "BgC76sdA6zxPSAMW6sZ1e3NEntLrkLT8DY3z2MEmJJgK"
|
||||||
|
},
|
||||||
|
"test2": {
|
||||||
|
"index": 1,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test3": 2700000000,
|
||||||
|
"test4": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "6xNFhRFHKyx9iZ3ucc3AFf5cjsWw5jH3p6EnFXw3D8T6"
|
||||||
|
},
|
||||||
|
"test3": {
|
||||||
|
"index": 2,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test4": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "BpSSPEVE1yze9wrfjkU4wfnFa7WgKNysHxe3H9iT9fvx"
|
||||||
|
},
|
||||||
|
"test4": {
|
||||||
|
"index": 3,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test3": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "5LqbvutJtRTHvnforyndwPbkC4Kf5cJtdRQaDcHoMi8S"
|
||||||
|
},
|
||||||
|
"test5": {
|
||||||
|
"index": 4,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test3": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "6FgzG8NwatTWHo7rM7sPP6P4Q95R2ZQNqYiHCs38RT21"
|
||||||
|
},
|
||||||
|
"test6": {
|
||||||
|
"index": 5,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "FZ8URw5rPqpWegWnufpcBDkg6tMpc2JmNZVCuPA9g3nq"
|
||||||
|
},
|
||||||
|
"testCesium1": {
|
||||||
|
"index": 6,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"next_cert_issuable_on": 0,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test3": 2700000000
|
||||||
|
},
|
||||||
|
"owner_pubkey": "DCovzCEnQm9GUWe6mr8u42JR1JAuoj3HbQUGdCkfTzSr"
|
||||||
|
},
|
||||||
|
"Alice": {
|
||||||
|
"index": 8,
|
||||||
|
"balance": 10000,
|
||||||
|
"revoked": false,
|
||||||
|
"membership_expire_on": 2700000000,
|
||||||
|
"membership_revokes_on": 2700000001,
|
||||||
|
"certs_received": {
|
||||||
|
"test1": 2700000000,
|
||||||
|
"test2": 2700000000,
|
||||||
|
"test3": 2700000000,
|
||||||
|
"test4": 2700000000,
|
||||||
|
"test5": 2700000000,
|
||||||
|
"test6": 2700000000,
|
||||||
|
"testCesium1": 2700000000
|
||||||
|
},
|
||||||
|
"owner_address": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||||
|
"next_cert_issuable_on": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wallets": {
|
||||||
|
"BPKBoTrrLD1XWmpZdRsfDnDT1M6PBBvgzPxAKNdutVV2": 10000
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,79 +0,0 @@
|
||||||
{
|
|
||||||
"first_ud": 10000,
|
|
||||||
"first_ud_reeval": 50,
|
|
||||||
"genesis_parameters": {
|
|
||||||
"genesis_certs_expire_on": 10,
|
|
||||||
"genesis_certs_min_received": 3,
|
|
||||||
"genesis_memberships_expire_on": 1051200,
|
|
||||||
"genesis_smith_certs_expire_on": 2102400,
|
|
||||||
"genesis_smith_certs_min_received": 3,
|
|
||||||
"genesis_smith_memberships_expire_on": 1051200
|
|
||||||
},
|
|
||||||
"identities": {
|
|
||||||
"test1": {
|
|
||||||
"balance": 10000,
|
|
||||||
"certs": ["test2", "test3", "test4"],
|
|
||||||
"pubkey": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa"
|
|
||||||
},
|
|
||||||
"test2": {
|
|
||||||
"balance": 10000,
|
|
||||||
"certs": ["test1", "test3", "test4"],
|
|
||||||
"pubkey": "5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb"
|
|
||||||
},
|
|
||||||
"test3": {
|
|
||||||
"balance": 10000,
|
|
||||||
"certs": ["test1", "test2", "test4"],
|
|
||||||
"pubkey": "5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p"
|
|
||||||
},
|
|
||||||
"test4": {
|
|
||||||
"balance": 10000,
|
|
||||||
"certs": ["test1", "test2", "test3"],
|
|
||||||
"pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5"
|
|
||||||
},
|
|
||||||
"testCesium1": {
|
|
||||||
"balance": 10000,
|
|
||||||
"certs": ["test1", "test2", "test3"],
|
|
||||||
"pubkey": "5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"babe_epoch_duration": 30,
|
|
||||||
"cert_period": 15,
|
|
||||||
"cert_max_by_issuer": 10,
|
|
||||||
"cert_min_received_cert_to_issue_cert": 2,
|
|
||||||
"cert_validity_period": 1000,
|
|
||||||
"idty_confirm_period": 40,
|
|
||||||
"idty_creation_period": 50,
|
|
||||||
"membership_period": 1000,
|
|
||||||
"pending_membership_period": 500,
|
|
||||||
"ud_creation_period": 10,
|
|
||||||
"ud_reeval_period": 50,
|
|
||||||
"smith_cert_period": 15,
|
|
||||||
"smith_cert_max_by_issuer": 8,
|
|
||||||
"smith_cert_min_received_cert_to_issue_cert": 2,
|
|
||||||
"smith_cert_validity_period": 1000,
|
|
||||||
"smith_membership_period": 1000,
|
|
||||||
"smith_pending_membership_period": 500,
|
|
||||||
"smiths_wot_first_cert_issuable_on": 4,
|
|
||||||
"smiths_wot_min_cert_for_membership": 3,
|
|
||||||
"wot_first_cert_issuable_on": 0,
|
|
||||||
"wot_min_cert_for_create_idty_right": 3,
|
|
||||||
"wot_min_cert_for_membership": 3
|
|
||||||
},
|
|
||||||
"smiths": {
|
|
||||||
"test1": {
|
|
||||||
"certs": ["test2", "test3", "test4"]
|
|
||||||
},
|
|
||||||
"test2": {
|
|
||||||
"certs": ["test1", "test3", "test4"]
|
|
||||||
},
|
|
||||||
"test3": {
|
|
||||||
"certs": ["test1", "test2", "test4"]
|
|
||||||
},
|
|
||||||
"test4": {
|
|
||||||
"certs": ["test1", "test2", "test3"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sudo_key": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa",
|
|
||||||
"technical_committee": ["test1", "test2", "test3"]
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
7bd0907a4984e1ab7899edce63b2e286e8f3daad5a8e2bff40cee61ca6b036cd
|
|
@ -3,8 +3,10 @@ version: "3.5"
|
||||||
services:
|
services:
|
||||||
duniter-v2s-gecko-tests:
|
duniter-v2s-gecko-tests:
|
||||||
container_name: duniter-v2s-gecko-tests
|
container_name: duniter-v2s-gecko-tests
|
||||||
image: duniter/duniter-v2s:debug-latest
|
# image: duniter/duniter-v2s:debug-sha-4d5e08be
|
||||||
command: --sealing=manual
|
image: duniter/duniter-v2s:debug-sha-44b09061
|
||||||
|
command: --alice --force-authoring --reserved-only --no-mdns
|
||||||
|
#--sealing=manual
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:9615:9615"
|
- "127.0.0.1:9615:9615"
|
||||||
- "127.0.0.1:9933:9933"
|
- "127.0.0.1:9933:9933"
|
||||||
|
@ -12,7 +14,8 @@ services:
|
||||||
- "30333:30333"
|
- "30333:30333"
|
||||||
environment:
|
environment:
|
||||||
DUNITER_INSTANCE_NAME: "gecko_tests"
|
DUNITER_INSTANCE_NAME: "gecko_tests"
|
||||||
DUNITER_CHAIN_NAME: "dev"
|
DUNITER_CHAIN_NAME: "gdev_dev"
|
||||||
DUNITER_GENESIS_CONFIG: "/var/lib/duniter/gecko_tests.json"
|
DUNITER_GENESIS_CONFIG: "/var/lib/duniter/gecko_config.json"
|
||||||
|
DUNITER_GENESIS_DATA: "/var/lib/duniter/gecko_data.json"
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/var/lib/duniter
|
- ./data:/var/lib/duniter
|
||||||
|
|
|
@ -5,8 +5,9 @@ option=$2
|
||||||
[[ ! $testName ]] && testName='gecko_complete'
|
[[ ! $testName ]] && testName='gecko_complete'
|
||||||
|
|
||||||
# Get local IP and set .env
|
# Get local IP and set .env
|
||||||
ip_address=$(hostname -I | awk '{print $1}')
|
#ip_address=$(hostname -I 2>/dev/null || ipconfig 2>&1 | grep "IPv4 Address" | head -n1 | awk -F ':' '{ print $2}' | tr -d ' ') # old fashion style...
|
||||||
echo "ip_address=$ip_address" > .env
|
#ip_address="10.0.2.2"
|
||||||
|
#echo "ip_address=$ip_address" > .env
|
||||||
[[ $option == 'human' ]] && echo "isHumanReading=true" >> .env
|
[[ $option == 'human' ]] && echo "isHumanReading=true" >> .env
|
||||||
|
|
||||||
## Start local Duniter node
|
## Start local Duniter node
|
||||||
|
@ -20,10 +21,10 @@ cd ../..
|
||||||
flutter test integration_test/scenarios/$testName.dart && echo '0' > /tmp/geckoTestResult || echo '1' > /tmp/geckoTestResult
|
flutter test integration_test/scenarios/$testName.dart && echo '0' > /tmp/geckoTestResult || echo '1' > /tmp/geckoTestResult
|
||||||
|
|
||||||
# Reset .env
|
# Reset .env
|
||||||
echo "ip_address=127.0.0.1" > .env
|
# echo "ip_address=127.0.0.1" > .env # not used anymore, host IP is 10.0.2.2
|
||||||
|
|
||||||
# Stop Duniter
|
# Stop Duniter
|
||||||
cd integration_test/duniter
|
cd integration_test/duniter
|
||||||
docker compose down
|
docker compose down
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -7,7 +7,7 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Certifications state', (testerLoc) async {
|
testWidgets('Certifications state', (testerLoc) async {
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
@ -25,9 +25,9 @@ void main() async {
|
||||||
await tapKey(keyConfirmSearch);
|
await tapKey(keyConfirmSearch);
|
||||||
await waitFor(test5.shortAddress());
|
await waitFor(test5.shortAddress());
|
||||||
await tapKey(keySearchResult(test5.address));
|
await tapKey(keySearchResult(test5.address));
|
||||||
await waitFor('Certifier');
|
await waitFor('createIdentity'.tr());
|
||||||
await waitFor('Vous devez ', reverse: true);
|
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 6), reverse: true);
|
||||||
await waitFor('Vous pourrez renouveler ', reverse: true);
|
await waitFor('canRenewCertInX'.tr().substring(0, 8), reverse: true);
|
||||||
|
|
||||||
// Background pay 25
|
// Background pay 25
|
||||||
await bkPay(
|
await bkPay(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -7,9 +8,10 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Gecko complete', (testerLoc) async {
|
testWidgets('Gecko complete', (testerLoc) async {
|
||||||
|
FlutterError.onError = ignoreOverflowErrors;
|
||||||
// Share WidgetTester to test provider
|
// Share WidgetTester to test provider
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
|
||||||
|
@ -35,7 +37,7 @@ void main() async {
|
||||||
|
|
||||||
Future payTest2() async {
|
Future payTest2() async {
|
||||||
spawnBlock(until: 13);
|
spawnBlock(until: 13);
|
||||||
await waitFor('Rechercher');
|
await waitFor('searchWallet'.tr());
|
||||||
await tapKey(keyOpenSearch);
|
await tapKey(keyOpenSearch);
|
||||||
final addressToSearch = await clipPaste();
|
final addressToSearch = await clipPaste();
|
||||||
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
||||||
|
@ -50,8 +52,11 @@ Future payTest2() async {
|
||||||
await enterText(keyAmountField, '12.14');
|
await enterText(keyAmountField, '12.14');
|
||||||
await tapKey(keyConfirmPayment);
|
await tapKey(keyConfirmPayment);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 500);
|
||||||
|
await tester.pump(const Duration(seconds: 2));
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, timeout: const Duration(seconds: 20));
|
||||||
|
await waitFor('extrinsicValidated'.tr(args: ['transaction'.tr()]),
|
||||||
|
timeout: const Duration(seconds: 12));
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
await waitFor('12.14');
|
await waitFor('12.14');
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 500);
|
||||||
|
@ -61,12 +66,17 @@ Future payTest2() async {
|
||||||
|
|
||||||
Future certifyTest5() async {
|
Future certifyTest5() async {
|
||||||
// Create identity with Test1 account
|
// Create identity with Test1 account
|
||||||
|
await pump(number: 8);
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
await pump(number: 3);
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, timeout: const Duration(seconds: 20));
|
||||||
|
await waitFor('extrinsicValidated'.tr(args: ['certification'.tr()]),
|
||||||
|
timeout: const Duration(seconds: 6));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('Identité créée');
|
await waitFor('identityCreated'.tr());
|
||||||
|
|
||||||
// Confirm Identity Test5
|
// Confirm Identity Test5
|
||||||
await tapKey(keyAppBarChest, duration: 300);
|
await tapKey(keyAppBarChest, duration: 300);
|
||||||
|
@ -76,19 +86,21 @@ Future certifyTest5() async {
|
||||||
await tapKey(keyConfirmIdentity);
|
await tapKey(keyConfirmIdentity);
|
||||||
await enterText(keyEnterIdentityUsername, test5.name);
|
await enterText(keyEnterIdentityUsername, test5.name);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
await pump(number: 3);
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('Identité confirmée');
|
await waitFor('identityConfirmed'.tr());
|
||||||
humanRead(2);
|
humanRead(2);
|
||||||
// Set wallet 2 as default wallet
|
// Set wallet 2 as default wallet
|
||||||
await goBack();
|
await goBack();
|
||||||
await tapKey(keyOpenWallet(test2.address));
|
await tapKey(keyOpenWallet(test2.address));
|
||||||
await tapKey(keySetDefaultWallet);
|
await tapKey(keySetDefaultWallet);
|
||||||
await waitFor('Ce portefeuille est celui par defaut');
|
await waitFor('thisWalletIsDefault'.tr());
|
||||||
|
|
||||||
// Search Wallet 5 again
|
// Search Wallet 5 again
|
||||||
await tapKey(keyAppBarSearch);
|
await tapKey(keyAppBarHome);
|
||||||
final addressToSearch = await clipPaste();
|
final addressToSearch = await clipPaste();
|
||||||
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
final endAddress = addressToSearch.substring(addressToSearch.length - 6);
|
||||||
expect(addressToSearch, test5.address);
|
expect(addressToSearch, test5.address);
|
||||||
|
@ -102,30 +114,34 @@ Future certifyTest5() async {
|
||||||
// Certify with test2 account
|
// Certify with test2 account
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
await pump(number: 3);
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('2');
|
await waitFor('2');
|
||||||
|
|
||||||
// Change default wallet to test3
|
// Change default wallet to test3
|
||||||
await tapKey(keyPay);
|
await tapKey(keyPay);
|
||||||
await tapKey(keyChangeChest);
|
await tapKey(keyDropdownWallets);
|
||||||
await tapKey(keySelectThisWallet(test3.address));
|
await tapKey(keySelectThisWallet(test3.address));
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyPopButton);
|
||||||
await sleep();
|
await sleep();
|
||||||
|
|
||||||
// Certify with test3 account
|
// Certify with test3 account
|
||||||
await tapKey(keyCertify);
|
await tapKey(keyCertify);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 500);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 1));
|
await pump(number: 3);
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen);
|
await tapKey(keyCloseTransactionScreen);
|
||||||
await waitFor('Vous devez attendre');
|
await waitFor('mustWaitXBeforeCertify'.tr().substring(0, 8));
|
||||||
|
|
||||||
// Check if test5 is member
|
// Check if test5 is member
|
||||||
await tapKey(keyAppBarChest, duration: 300);
|
await tapKey(keyAppBarChest, duration: 300);
|
||||||
await tapKey(keyOpenWallet(test5.address));
|
await tapKey(keyOpenWallet(test5.address));
|
||||||
await waitFor('Membre validé !');
|
await waitFor('memberValidated'.tr());
|
||||||
|
|
||||||
// spawn 20 blocs and check if ud is creating
|
// spawn 20 blocs and check if ud is creating
|
||||||
await spawnBlock(until: 20);
|
await spawnBlock(until: 20);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -7,7 +7,7 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Identity revocation', (testerLoc) async {
|
testWidgets('Identity revocation', (testerLoc) async {
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
@ -32,36 +32,27 @@ void main() async {
|
||||||
await bkConfirmIdentity(fromAddress: test5.address, name: test5.name);
|
await bkConfirmIdentity(fromAddress: test5.address, name: test5.name);
|
||||||
await bkCertify(fromAddress: test2.address, destAddress: test5.address);
|
await bkCertify(fromAddress: test2.address, destAddress: test5.address);
|
||||||
await bkCertify(fromAddress: test3.address, destAddress: test5.address);
|
await bkCertify(fromAddress: test3.address, destAddress: test5.address);
|
||||||
await waitFor('Membre validé !', exactMatch: true);
|
await waitFor('memberValidated'.tr(), exactMatch: true);
|
||||||
|
|
||||||
// Revoke test5
|
// Revoke test5
|
||||||
await tapKey(keyManageMembership, duration: 1000);
|
await goBack();
|
||||||
|
await tapKey(keyOpenWallet(test5.address));
|
||||||
|
await tapKey(keyManageMembership, duration: 100);
|
||||||
await tapKey(keyRevokeIdty);
|
await tapKey(keyRevokeIdty);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 2000);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !', timeout: const Duration(seconds: 4));
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
await waitFor('Aucune identité', exactMatch: true);
|
await waitFor('noIdentity'.tr(), exactMatch: true);
|
||||||
await sleep();
|
await sleep();
|
||||||
|
|
||||||
// Check test1 cannot be revoked
|
// Check test1 cannot be revoked
|
||||||
await goBack();
|
await goBack();
|
||||||
await tapKey(keyAddDerivation);
|
await tapKey(keyAddDerivation);
|
||||||
await tapKey(keyOpenWallet(test1.address), duration: 500);
|
await tapKey(keyOpenWallet(test1.address), duration: 300);
|
||||||
await tapKey(keyManageMembership, duration: 1000);
|
await tapKey(keyManageMembership, duration: 300);
|
||||||
await waitFor('Vous ne pouvez pas révoquer cette identité');
|
await waitFor('youCannotRevokeThisIdentity'.tr().substring(0, 15));
|
||||||
|
|
||||||
// // Try migrate test1 identity to test6 address
|
|
||||||
// await tapKey(keyMigrateIdentity);
|
|
||||||
// await tapKey(keySelectWallet);
|
|
||||||
// await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
|
||||||
// await spawnBlock(number: 100);
|
|
||||||
// await waitFor('Vous devez attendre', reverse: true);
|
|
||||||
// await waitForButtonEnabled(keyConfirm);
|
|
||||||
// await tapKey(keyConfirm, duration: 500);
|
|
||||||
// await spawnBlock(duration: 2000);
|
|
||||||
// await waitFor('validé !');
|
|
||||||
// await tapKey(keyCloseTransactionScreen, duration: 0);
|
|
||||||
// await sleep(5000);
|
|
||||||
}, timeout: testTimeout());
|
}, timeout: testTimeout());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
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_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -8,7 +8,7 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Migrate Cesium identity and balance', (testerLoc) async {
|
testWidgets('Migrate Cesium identity and balance', (testerLoc) async {
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
@ -19,14 +19,15 @@ void main() async {
|
||||||
await firstOpenChest();
|
await firstOpenChest();
|
||||||
|
|
||||||
// Go to test1 options and check if balance growup with UDs creations
|
// Go to test1 options and check if balance growup with UDs creations
|
||||||
|
await scrollUntil(keyAddDerivation);
|
||||||
await tapKey(keyAddDerivation);
|
await tapKey(keyAddDerivation);
|
||||||
await waitFor('Portefeuille 6');
|
await waitFor(' 6');
|
||||||
|
|
||||||
await scrollUntil(keyImportG1v1);
|
await scrollUntil(keyImportG1v1);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -42,15 +43,19 @@ void main() async {
|
||||||
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
await tapKey(keySelectThisWallet(test6.address), selectLast: true);
|
||||||
await waitForButtonEnabled(keyConfirm);
|
await waitForButtonEnabled(keyConfirm);
|
||||||
await tapKey(keyConfirm);
|
await tapKey(keyConfirm);
|
||||||
spawnBlock(duration: 2000);
|
spawnBlock(duration: 1000);
|
||||||
await waitFor('validé !');
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await tester.pump(const Duration(seconds: 1));
|
||||||
|
await waitFor('sending'.tr(),
|
||||||
|
reverse: true, settle: false, timeout: const Duration(seconds: 20));
|
||||||
await tapKey(keyCloseTransactionScreen, duration: 0);
|
await tapKey(keyCloseTransactionScreen, duration: 0);
|
||||||
|
|
||||||
await tapKey(keyOpenWallet(test6.address), duration: 300);
|
await tapKey(keyOpenWallet(test6.address), duration: 300);
|
||||||
|
await pump(number: 4);
|
||||||
await waitFor('3', exactMatch: true);
|
await waitFor('3', exactMatch: true);
|
||||||
await waitFor('Membre validé !');
|
await waitFor('memberValidated'.tr());
|
||||||
|
|
||||||
await waitFor('99.98', exactMatch: true);
|
await waitFor('110.01', exactMatch: true);
|
||||||
}, timeout: testTimeout());
|
}, timeout: testTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import '../utility/general_actions.dart';
|
import '../utility/general_actions.dart';
|
||||||
|
@ -6,7 +5,7 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('Onboarding and multi chest', (testerLoc) async {
|
testWidgets('Onboarding and multi chest', (testerLoc) async {
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
import 'package:gecko/models/widgets_keys.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -7,7 +6,7 @@ import '../utility/tests_utility.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
|
|
||||||
testWidgets('UDs creation state', (testerLoc) async {
|
testWidgets('UDs creation state', (testerLoc) async {
|
||||||
tester = testerLoc;
|
tester = testerLoc;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
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_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.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';
|
||||||
|
@ -10,8 +10,7 @@ import 'tests_utility.dart';
|
||||||
// GENERAL ACTIONS
|
// GENERAL ACTIONS
|
||||||
|
|
||||||
Future changeNode() async {
|
Future changeNode() async {
|
||||||
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
|
const ipAddress = '10.0.2.2';
|
||||||
log.d('ip address: $ipAddress');
|
|
||||||
|
|
||||||
await tapKey(keyDrawerMenu);
|
await tapKey(keyDrawerMenu);
|
||||||
await tapKey(keyParameters);
|
await tapKey(keyParameters);
|
||||||
|
@ -25,7 +24,7 @@ Future changeNode() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future deleteAllWallets() async {
|
Future deleteAllWallets() async {
|
||||||
if (await isPresent('Rechercher')) {
|
if (await isPresent('searchWallet'.tr())) {
|
||||||
await tapKey(keyDrawerMenu);
|
await tapKey(keyDrawerMenu);
|
||||||
await tapKey(keyParameters);
|
await tapKey(keyParameters);
|
||||||
|
|
||||||
|
@ -65,12 +64,18 @@ Future restoreChest() async {
|
||||||
// Enter password
|
// Enter password
|
||||||
await enterText(keyPinForm, 'AAAAA', 0);
|
await enterText(keyPinForm, 'AAAAA', 0);
|
||||||
|
|
||||||
|
// pump a few frame
|
||||||
|
await pump(duration: const Duration(milliseconds: 500), number: 10);
|
||||||
|
|
||||||
// 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(), settle: false);
|
||||||
|
|
||||||
// Go to wallets home
|
// Go to wallets home
|
||||||
await tapKey(keyGoWalletsHome, duration: 0);
|
await tapKey(keyGoWalletsHome, duration: 0);
|
||||||
|
|
||||||
|
// Skip tutorial
|
||||||
|
await skipWalletDragTutorial();
|
||||||
|
|
||||||
// Check if string "ĞD" is present in screen
|
// Check if string "ĞD" is present in screen
|
||||||
await waitFor('ĞD');
|
await waitFor('ĞD');
|
||||||
|
|
||||||
|
@ -84,7 +89,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 +131,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,20 +148,19 @@ 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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future addDerivation() async {
|
Future addDerivation() async {
|
||||||
await tapKey(keyAddDerivation);
|
await tapKey(keyAddDerivation);
|
||||||
await waitFor('Portefeuille 5');
|
await waitFor(' 5');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future firstOpenChest() async {
|
Future firstOpenChest() async {
|
||||||
|
@ -165,5 +169,15 @@ Future firstOpenChest() async {
|
||||||
final isCached = await isIconPresent(Icons.check_box);
|
final isCached = await isIconPresent(Icons.check_box);
|
||||||
if (!isCached) await tapKey(keyCachePassword, duration: 0);
|
if (!isCached) await tapKey(keyCachePassword, duration: 0);
|
||||||
await enterText(keyPinForm, 'AAAAA', 0);
|
await enterText(keyPinForm, 'AAAAA', 0);
|
||||||
await waitFor('100.0', exactMatch: true);
|
await skipWalletDragTutorial();
|
||||||
|
await waitFor(test1.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future skipWalletDragTutorial() async {
|
||||||
|
await pump(duration: const Duration(milliseconds: 500), number: 6);
|
||||||
|
await pump(duration: const Duration(seconds: 2));
|
||||||
|
if (await isPresent('explainDraggableWallet'.tr().substring(0, 13),
|
||||||
|
timeout: const Duration(seconds: 5), settle: false)) {
|
||||||
|
await tapKey(keyDragAndDrop, duration: 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
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: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';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
@ -11,8 +11,7 @@ import 'package:provider/provider.dart';
|
||||||
import 'dart:io' as io;
|
import 'dart:io' as io;
|
||||||
import 'package:gecko/main.dart' as app;
|
import 'package:gecko/main.dart' as app;
|
||||||
|
|
||||||
final bool isHumanReading =
|
const isHumanReading = false;
|
||||||
dotenv.env['isHumanReading'] == 'true' ? true : false;
|
|
||||||
Timeout testTimeout([int seconds = 120]) =>
|
Timeout testTimeout([int seconds = 120]) =>
|
||||||
Timeout(Duration(seconds: isHumanReading ? 600 : seconds));
|
Timeout(Duration(seconds: isHumanReading ? 600 : seconds));
|
||||||
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
@ -52,6 +51,15 @@ Future sleep([int time = 1000]) async {
|
||||||
await Future.delayed(Duration(milliseconds: time));
|
await Future.delayed(Duration(milliseconds: time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future pump(
|
||||||
|
{Duration duration = const Duration(milliseconds: 300),
|
||||||
|
int number = 1}) async {
|
||||||
|
for (int i = 0; i < number; i++) {
|
||||||
|
log.i("pump $i");
|
||||||
|
await tester.pump(duration = duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> clipPaste() async =>
|
Future<String> clipPaste() async =>
|
||||||
(await Clipboard.getData('text/plain'))?.text ?? '';
|
(await Clipboard.getData('text/plain'))?.text ?? '';
|
||||||
|
|
||||||
|
@ -68,7 +76,7 @@ Future tapKey(Key buttonKey,
|
||||||
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
||||||
}
|
}
|
||||||
final Finder finder = customFinder ?? find.byKey(buttonKey);
|
final Finder finder = customFinder ?? find.byKey(buttonKey);
|
||||||
log.d('INTEGRATION TEST: Tap on ${finder.description}}');
|
log.i('INTEGRATION TEST: Tap on ${finder.describeMatch(Plurality.zero)}}');
|
||||||
await tester.tap(selectLast ? finder.last : finder);
|
await tester.tap(selectLast ? finder.last : finder);
|
||||||
humanRead();
|
humanRead();
|
||||||
}
|
}
|
||||||
|
@ -96,7 +104,7 @@ Future<void> waitForButtonEnabled(Key key,
|
||||||
bool reverse = false}) async {
|
bool reverse = false}) async {
|
||||||
final end = DateTime.now().add(timeout);
|
final end = DateTime.now().add(timeout);
|
||||||
|
|
||||||
log.d('INTEGRATION TEST: Wait for $key to be enabled');
|
log.i('INTEGRATION TEST: Wait for $key to be enabled');
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (DateTime.now().isAfter(end)) {
|
if (DateTime.now().isAfter(end)) {
|
||||||
|
@ -111,9 +119,9 @@ Future<void> waitForButtonEnabled(Key key,
|
||||||
|
|
||||||
Future goBack() async {
|
Future goBack() async {
|
||||||
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
final NavigatorState navigator = tester.state(find.byType(Navigator));
|
||||||
log.d('INTEGRATION TEST: Go back');
|
log.i('INTEGRATION TEST: Go back');
|
||||||
navigator.pop();
|
navigator.pop();
|
||||||
await tester.pump();
|
await tester.pumpAndSettle();
|
||||||
humanRead();
|
humanRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,28 +129,33 @@ Future enterText(Key fieldKey, String textIn, [int duration = 200]) async {
|
||||||
if (duration != 0) {
|
if (duration != 0) {
|
||||||
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
await tester.pumpAndSettle(Duration(milliseconds: duration));
|
||||||
}
|
}
|
||||||
log.d('INTEGRATION TEST: Enter text: $textIn');
|
log.i('INTEGRATION TEST: Enter text: $textIn');
|
||||||
await tester.enterText(find.byKey(fieldKey), textIn);
|
await tester.enterText(find.byKey(fieldKey), textIn);
|
||||||
humanRead();
|
humanRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> waitFor(String text,
|
Future<void> waitFor(String text,
|
||||||
{Duration timeout = const Duration(seconds: 5),
|
{Duration timeout = const Duration(seconds: 5),
|
||||||
bool reverse = false,
|
final bool reverse = false,
|
||||||
bool exactMatch = false}) async {
|
final bool exactMatch = false,
|
||||||
|
final bool settle = true,
|
||||||
|
final int pumpDuration = 100}) async {
|
||||||
final end = DateTime.now().add(timeout);
|
final end = DateTime.now().add(timeout);
|
||||||
|
|
||||||
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.i('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)) {
|
||||||
throw Exception('Timed out waiting for $searchType : "$text"');
|
throw Exception('Timed out waiting for $searchType : "$text"');
|
||||||
}
|
}
|
||||||
|
|
||||||
await tester.pumpAndSettle();
|
if (settle) {
|
||||||
|
await tester.pumpAndSettle(Duration(milliseconds: pumpDuration),
|
||||||
|
EnginePhase.sendSemanticsUpdate, timeout);
|
||||||
|
}
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
} while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty);
|
||||||
humanRead();
|
humanRead();
|
||||||
|
@ -150,9 +163,9 @@ Future<void> waitFor(String text,
|
||||||
|
|
||||||
// Test if text is visible on screen, return a boolean
|
// Test if text is visible on screen, return a boolean
|
||||||
Future<bool> isPresent(String text,
|
Future<bool> isPresent(String text,
|
||||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
{Duration timeout = const Duration(seconds: 1), bool settle = true}) async {
|
||||||
try {
|
try {
|
||||||
await waitFor(text, timeout: timeout);
|
await waitFor(text, timeout: timeout, settle: settle);
|
||||||
humanRead();
|
humanRead();
|
||||||
return true;
|
return true;
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
|
@ -166,9 +179,8 @@ Future<bool> isIconPresent(IconData icon,
|
||||||
{Duration timeout = const Duration(seconds: 1)}) async {
|
{Duration timeout = const Duration(seconds: 1)}) async {
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
final finder = find.byIcon(icon);
|
final finder = find.byIcon(icon);
|
||||||
log.d('tatatatatatata: ${finder.evaluate()}');
|
|
||||||
humanRead();
|
humanRead();
|
||||||
return finder.evaluate().isEmpty ? false : true;
|
return finder.evaluate().isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future spawnBlock({int number = 1, int duration = 200, int? until}) async {
|
Future spawnBlock({int number = 1, int duration = 200, int? until}) async {
|
||||||
|
@ -222,11 +234,11 @@ Future bkConfirmIdentity(
|
||||||
// Change node in background
|
// Change node in background
|
||||||
Future bkSetNode([String? endpoint]) async {
|
Future bkSetNode([String? endpoint]) async {
|
||||||
if (endpoint == null) {
|
if (endpoint == null) {
|
||||||
final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1';
|
const ipAddress = '10.0.2.2';
|
||||||
endpoint = 'ws://$ipAddress:9944';
|
endpoint = 'ws://$ipAddress:9944';
|
||||||
}
|
}
|
||||||
configBox.put('customEndpoint', endpoint);
|
configBox.put('customEndpoint', endpoint);
|
||||||
sub.connectNode(homeContext);
|
sub.connectNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore chest in background
|
// Restore chest in background
|
||||||
|
@ -258,14 +270,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;
|
||||||
}
|
}
|
||||||
|
@ -274,8 +286,8 @@ Future<WalletData> _addImportAccount(
|
||||||
Future bkDeleteAllWallets() async {
|
Future bkDeleteAllWallets() async {
|
||||||
final myWalletProvider =
|
final myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
||||||
final isWalletsPresents =
|
final isWalletsPresents = await isPresent('scanQRCode'.tr(),
|
||||||
await isPresent('Scanner un', timeout: const Duration(milliseconds: 300));
|
timeout: const Duration(milliseconds: 300));
|
||||||
if (isWalletsPresents) {
|
if (isWalletsPresents) {
|
||||||
await walletBox.clear();
|
await walletBox.clear();
|
||||||
await chestBox.clear();
|
await chestBox.clear();
|
||||||
|
@ -301,14 +313,14 @@ Future bkFastStart([bool restoreChest = true]) async {
|
||||||
if (restoreChest) {
|
if (restoreChest) {
|
||||||
// Restore the test chest
|
// Restore the test chest
|
||||||
await bkRestoreChest();
|
await bkRestoreChest();
|
||||||
await waitFor("y'a pas de lézard");
|
await waitFor("noLizard".tr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future startWait() async {
|
Future startWait() async {
|
||||||
app.main();
|
app.main();
|
||||||
await waitFor('Test starting...', reverse: true);
|
await waitFor('Test starting...', reverse: true);
|
||||||
await tester.pumpAndSettle(const Duration(milliseconds: 300));
|
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||||
await sleep(3000);
|
await sleep(3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +329,32 @@ String getWidgetText(Key key) {
|
||||||
return (word4Finder.evaluate().single.widget as Text).data!;
|
return (word4Finder.evaluate().single.widget as Text).data!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ignoreOverflowErrors(
|
||||||
|
FlutterErrorDetails details, {
|
||||||
|
bool forceReport = false,
|
||||||
|
}) {
|
||||||
|
bool ifIsOverflowError = false;
|
||||||
|
bool isUnableToLoadAsset = false;
|
||||||
|
|
||||||
|
// Detect overflow error.
|
||||||
|
var exception = details.exception;
|
||||||
|
if (exception is FlutterError) {
|
||||||
|
ifIsOverflowError = !exception.diagnostics.any(
|
||||||
|
(e) => e.value.toString().startsWith("A RenderFlex overflowed by"),
|
||||||
|
);
|
||||||
|
isUnableToLoadAsset = !exception.diagnostics.any(
|
||||||
|
(e) => e.value.toString().startsWith("Unable to load asset"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore if is overflow error.
|
||||||
|
if (ifIsOverflowError || isUnableToLoadAsset) {
|
||||||
|
debugPrint('Ignored Error');
|
||||||
|
} else {
|
||||||
|
FlutterError.dumpErrorToConsole(details, forceReport: forceReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TestWallet {
|
class TestWallet {
|
||||||
String address;
|
String address;
|
||||||
String name;
|
String name;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
@ -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",
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,5 +47,7 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -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,10 +8,11 @@ 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 = 9;
|
||||||
|
|
||||||
late String appVersion;
|
late String appVersion;
|
||||||
const int pinLength = 5;
|
const int pinLength = 5;
|
||||||
|
const int maxWalletsInSafe = 30;
|
||||||
const String appLang = 'english';
|
const String appLang = 'english';
|
||||||
|
|
||||||
late Box<WalletData> walletBox;
|
late Box<WalletData> walletBox;
|
||||||
|
@ -19,15 +21,16 @@ late Box configBox;
|
||||||
late Box<G1WalletsList> g1WalletsBox;
|
late Box<G1WalletsList> g1WalletsBox;
|
||||||
late Box<G1WalletsList> contactsBox;
|
late Box<G1WalletsList> contactsBox;
|
||||||
// late Box keystoreBox;
|
// late Box keystoreBox;
|
||||||
late Directory imageDirectory;
|
late Directory avatarsDirectory;
|
||||||
|
late Directory avatarsCacheDirectory;
|
||||||
|
late bool isTall;
|
||||||
|
|
||||||
// String cesiumPod = "https://g1.data.le-sou.org";
|
const cesiumPod = "https://g1.data.le-sou.org";
|
||||||
String cesiumPod = "https://g1.data.presles.fr";
|
// String cesiumPod = "https://g1.data.presles.fr";
|
||||||
// String cesiumPod = "https://g1.data.e-is.pro";
|
// String cesiumPod = "https://g1.data.e-is.pro";
|
||||||
|
|
||||||
// Responsive ratios
|
const datapodEndpoint = 'gdev-datapod.p2p.legal';
|
||||||
late bool isTall;
|
// const datapodEndpoint = '10.0.2.2:8080';
|
||||||
late double ratio;
|
|
||||||
|
|
||||||
// Contexts
|
// Contexts
|
||||||
late BuildContext homeContext;
|
late BuildContext homeContext;
|
||||||
|
@ -50,3 +53,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()
|
||||||
|
};
|
||||||
|
|
130
lib/main.dart
|
@ -16,21 +16,20 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.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/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';
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/providers/v2s_datapod.dart';
|
||||||
import 'package:gecko/providers/wallets_profiles.dart';
|
import 'package:gecko/providers/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';
|
||||||
|
@ -51,78 +50,67 @@ Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await EasyLocalization.ensureInitialized();
|
await EasyLocalization.ensureInitialized();
|
||||||
|
|
||||||
if (kDebugMode) {
|
// if (kDebugMode) {
|
||||||
await dotenv.load();
|
// await dotenv.load();
|
||||||
}
|
// }
|
||||||
|
|
||||||
HomeProvider homeProvider = HomeProvider();
|
final 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());
|
||||||
Hive.registerAdapter(ChestDataAdapter());
|
Hive.registerAdapter(ChestDataAdapter());
|
||||||
Hive.registerAdapter(G1WalletsListAdapter());
|
Hive.registerAdapter(G1WalletsListAdapter());
|
||||||
Hive.registerAdapter(IdAdapter());
|
Hive.registerAdapter(IdAdapter());
|
||||||
|
Hive.registerAdapter(IdtyStatusAdapter());
|
||||||
|
|
||||||
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();
|
|
||||||
// await configBox.delete('isCacheChecked');
|
|
||||||
if (configBox.get('isCacheChecked') == null) {
|
|
||||||
configBox.put('isCacheChecked', false);
|
|
||||||
}
|
|
||||||
// log.d(await configBox.get('endpoint'));
|
|
||||||
|
|
||||||
HttpOverrides.global = MyHttpOverrides();
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
|
|
||||||
if (kReleaseMode && enableSentry) {
|
if (kReleaseMode && enableSentry) {
|
||||||
// CatcherOptions debugOptions = CatcherOptions(DialogReportMode(), [
|
await SentryFlutter.init((options) {
|
||||||
// SentryHandler(SentryClient(SentryOptions(
|
options.dsn =
|
||||||
// dsn:
|
'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110';
|
||||||
// "https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110")))
|
},
|
||||||
// ]);
|
appRunner: () => SystemChrome.setPreferredOrientations(
|
||||||
// // CatcherOptions releaseOptions = CatcherOptions(NotificationReportMode(), [
|
[DeviceOrientation.portraitUp]).then((_) {
|
||||||
// // EmailManualHandler(["poka@p2p.legal"])
|
runApp(EasyLocalization(
|
||||||
// // ]);
|
supportedLocales: const [
|
||||||
// Catcher(rootWidget: Gecko(endPointGVA, _store), debugConfig: debugOptions);
|
Locale('en'),
|
||||||
|
Locale('fr'),
|
||||||
await SentryFlutter.init(
|
Locale('es'),
|
||||||
(options) {
|
Locale('it')
|
||||||
options.dsn =
|
],
|
||||||
'https://c09587b46eaa42e8b9fda28d838ed180@o496840.ingest.sentry.io/5572110';
|
path: 'assets/translations',
|
||||||
},
|
fallbackLocale: const Locale('en'),
|
||||||
appRunner: () => runApp(
|
child: const Gecko(),
|
||||||
EasyLocalization(
|
));
|
||||||
supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')],
|
}));
|
||||||
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 +119,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(
|
||||||
|
@ -144,26 +130,23 @@ class Gecko extends StatelessWidget {
|
||||||
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
|
ChangeNotifierProvider(create: (_) => GenerateWalletsProvider()),
|
||||||
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
|
ChangeNotifierProvider(create: (_) => WalletOptionsProvider()),
|
||||||
ChangeNotifierProvider(create: (_) => SearchProvider()),
|
ChangeNotifierProvider(create: (_) => SearchProvider()),
|
||||||
ChangeNotifierProvider(create: (_) => CesiumPlusProvider()),
|
|
||||||
ChangeNotifierProvider(create: (_) => SubstrateSdk()),
|
ChangeNotifierProvider(create: (_) => SubstrateSdk()),
|
||||||
ChangeNotifierProvider(create: (_) => DuniterIndexer()),
|
ChangeNotifierProvider(create: (_) => DuniterIndexer()),
|
||||||
ChangeNotifierProvider(create: (_) => SettingsProvider())
|
ChangeNotifierProvider(create: (_) => SettingsProvider()),
|
||||||
|
ChangeNotifierProvider(create: (_) => V2sDatapodProvider())
|
||||||
],
|
],
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
builder: (context, widget) => ResponsiveWrapper.builder(
|
builder: (context, child) => ResponsiveBreakpoints.builder(
|
||||||
BouncingScrollWrapper.builder(context, widget!),
|
child: child!,
|
||||||
maxWidth: 1200,
|
breakpoints: [
|
||||||
minWidth: 480,
|
const Breakpoint(start: 0, end: 450, name: MOBILE),
|
||||||
defaultScale: true,
|
const Breakpoint(start: 451, end: 800, name: TABLET),
|
||||||
breakpoints: [
|
const Breakpoint(start: 801, end: double.infinity, name: DESKTOP),
|
||||||
const ResponsiveBreakpoint.resize(480, name: MOBILE),
|
],
|
||||||
const ResponsiveBreakpoint.autoScale(800, name: TABLET),
|
),
|
||||||
const ResponsiveBreakpoint.resize(1000, name: DESKTOP),
|
|
||||||
],
|
|
||||||
background: Container(color: backgroundColor)),
|
|
||||||
title: 'Ğecko',
|
title: 'Ğecko',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
appBarTheme: const AppBarTheme(
|
appBarTheme: const AppBarTheme(
|
||||||
|
@ -171,18 +154,21 @@ class Gecko extends StatelessWidget {
|
||||||
foregroundColor: Color(0xFF000000),
|
foregroundColor: Color(0xFF000000),
|
||||||
),
|
),
|
||||||
primaryColor: const Color(0xffFFD58D),
|
primaryColor: const Color(0xffFFD58D),
|
||||||
|
scaffoldBackgroundColor: backgroundColor,
|
||||||
|
canvasColor: backgroundColor,
|
||||||
|
dialogBackgroundColor: backgroundColor,
|
||||||
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),
|
||||||
),
|
),
|
||||||
colorScheme:
|
colorScheme:
|
||||||
ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]),
|
ColorScheme.fromSwatch().copyWith(secondary: Colors.grey[850]),
|
||||||
),
|
),
|
||||||
home: const HomeScreen(),
|
|
||||||
initialRoute: "/",
|
initialRoute: "/",
|
||||||
routes: {
|
routes: {
|
||||||
|
'/': (context) => const HomeScreen(),
|
||||||
'/mywallets': (context) => const WalletsHome(),
|
'/mywallets': (context) => const WalletsHome(),
|
||||||
'/search': (context) => const SearchScreen(),
|
'/search': (context) => const SearchScreen(),
|
||||||
'/searchResult': (context) => const SearchResultScreen(),
|
'/searchResult': (context) => const SearchResultScreen(),
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
|
||||||
part 'g1_wallets_list.g.dart';
|
part 'g1_wallets_list.g.dart';
|
||||||
|
@ -15,22 +14,18 @@ class G1WalletsList {
|
||||||
Id? id;
|
Id? id;
|
||||||
|
|
||||||
@HiveField(3)
|
@HiveField(3)
|
||||||
Image? avatar;
|
|
||||||
|
|
||||||
@HiveField(4)
|
|
||||||
String? username;
|
String? username;
|
||||||
|
|
||||||
@HiveField(5)
|
@HiveField(4)
|
||||||
String? csName;
|
String? csName;
|
||||||
|
|
||||||
@HiveField(6)
|
@HiveField(5)
|
||||||
bool? isMembre;
|
bool? isMembre;
|
||||||
|
|
||||||
G1WalletsList({
|
G1WalletsList({
|
||||||
required this.address,
|
required this.address,
|
||||||
this.balance,
|
this.balance,
|
||||||
this.id,
|
this.id,
|
||||||
this.avatar,
|
|
||||||
this.username,
|
this.username,
|
||||||
this.csName,
|
this.csName,
|
||||||
this.isMembre,
|
this.isMembre,
|
||||||
|
|
|
@ -20,17 +20,16 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
|
||||||
address: fields[0] as String,
|
address: fields[0] as String,
|
||||||
balance: fields[1] as double?,
|
balance: fields[1] as double?,
|
||||||
id: fields[2] as Id?,
|
id: fields[2] as Id?,
|
||||||
avatar: fields[3] as Image?,
|
username: fields[3] as String?,
|
||||||
username: fields[4] as String?,
|
csName: fields[4] as String?,
|
||||||
csName: fields[5] as String?,
|
isMembre: fields[5] as bool?,
|
||||||
isMembre: fields[6] as bool?,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, G1WalletsList obj) {
|
void write(BinaryWriter writer, G1WalletsList obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(7)
|
..writeByte(6)
|
||||||
..writeByte(0)
|
..writeByte(0)
|
||||||
..write(obj.address)
|
..write(obj.address)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
|
@ -38,12 +37,10 @@ class G1WalletsListAdapter extends TypeAdapter<G1WalletsList> {
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
..write(obj.id)
|
..write(obj.id)
|
||||||
..writeByte(3)
|
..writeByte(3)
|
||||||
..write(obj.avatar)
|
|
||||||
..writeByte(4)
|
|
||||||
..write(obj.username)
|
..write(obj.username)
|
||||||
..writeByte(5)
|
..writeByte(4)
|
||||||
..write(obj.csName)
|
..write(obj.csName)
|
||||||
..writeByte(6)
|
..writeByte(5)
|
||||||
..write(obj.isMembre);
|
..write(obj.isMembre);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import 'package:gecko/models/wallet_data.dart';
|
||||||
|
|
||||||
|
class MigrateWalletChecks {
|
||||||
|
final Map balance;
|
||||||
|
final IdtyStatus idtyStatus;
|
||||||
|
final String validationStatus;
|
||||||
|
final bool canValidate;
|
||||||
|
|
||||||
|
const MigrateWalletChecks({
|
||||||
|
required this.balance,
|
||||||
|
required this.idtyStatus,
|
||||||
|
required this.validationStatus,
|
||||||
|
required this.canValidate,
|
||||||
|
});
|
||||||
|
|
||||||
|
const MigrateWalletChecks.defaultValues({
|
||||||
|
this.balance = const {'transferableBalance': 0},
|
||||||
|
this.idtyStatus = IdtyStatus.none,
|
||||||
|
this.validationStatus = '',
|
||||||
|
this.canValidate = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return {
|
||||||
|
'balance': balance,
|
||||||
|
'idtyStatus': idtyStatus,
|
||||||
|
'validationStatus': validationStatus,
|
||||||
|
'canValidate': canValidate,
|
||||||
|
}.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
const String updateProfileQ = r'''
|
||||||
|
mutation ($address: String!, $hash: String!, $signature: String!, $title: String, $description: String, $avatarBase64: String, $geoloc: GeolocInput, $city: String, $socials: [SocialInput!]) {
|
||||||
|
updateProfile(address: $address, hash: $hash, signature: $signature, title: $title, description: $description, avatarBase64: $avatarBase64, geoloc: $geoloc, city: $city, socials: $socials) {
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String deleteProfileQ = r'''
|
||||||
|
mutation ($address: String!, $hash: String!, $signature: String!) {
|
||||||
|
deleteProfile(address: $address, hash: $hash, signature: $signature) {
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String migrateProfileQ = r'''
|
||||||
|
mutation ($addressOld: String!, $addressNew: String!, $hash: String!, $signature: String!) {
|
||||||
|
migrateProfile(addressOld: $addressOld, addressNew: $addressNew, hash: $hash, signature: $signature) {
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String addTransactionCommentQ = r'''
|
||||||
|
mutation ($id: String!, $address: String!, $hash: String!, $signature: String!, $comment: String!) {
|
||||||
|
addTransaction(id: $id, address: $address, hash: $hash, signature: $signature, comment: $comment) {
|
||||||
|
message
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String getAvatarQ = r'''
|
||||||
|
query ($address: String!) {
|
||||||
|
profiles_by_pk(address: $address) {
|
||||||
|
avatar64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String profileEditedAtQ = r'''
|
||||||
|
query ($address: String!) {
|
||||||
|
profiles_by_pk(address: $address) {
|
||||||
|
updated_at
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
|
@ -1,45 +1,55 @@
|
||||||
const String getNameByAddressQ = r'''
|
const String getNameByAddressQ = r'''
|
||||||
query ($address: String!) {
|
query ($address: String!) {
|
||||||
account_by_pk(pubkey: $address) {
|
identityConnection(
|
||||||
identity {
|
where: { accountId: { _eq: $address } }
|
||||||
name
|
orderBy: { name: ASC }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
name
|
||||||
|
accountId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pubkey
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
const String searchAddressByNameQ = r'''
|
const String searchAddressByNameQ = r'''
|
||||||
query ($name: String!) {
|
query ($name: String!) {
|
||||||
search_identity(args: {name: $name}) {
|
identityConnection(
|
||||||
pubkey
|
where: { name: { _ilike: $name } }
|
||||||
name
|
orderBy: { name: ASC }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
name
|
||||||
|
accountId
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
const String getHistoryByAddressQ = r'''
|
const String getHistoryByAddressRelayQ = r'''
|
||||||
query ($address: String!, $number: Int!, $cursor: String) {
|
query ($address: String!, $first: Int!, $after: String) {
|
||||||
transaction_connection(where:
|
transferConnection(
|
||||||
{_or: [
|
after: $after
|
||||||
{issuer_pubkey: {_eq: $address}},
|
first: $first
|
||||||
{receiver_pubkey: {_eq: $address}}
|
orderBy: { timestamp: DESC }
|
||||||
]},
|
where: { _or: [{ fromId: { _eq: $address } }, { toId: { _eq: $address } }] }
|
||||||
order_by: {created_at: desc},
|
) {
|
||||||
first: $number,
|
|
||||||
after: $cursor) {
|
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
amount
|
amount
|
||||||
created_at
|
timestamp
|
||||||
issuer_pubkey
|
fromId
|
||||||
receiver_pubkey
|
from {
|
||||||
issuer {
|
|
||||||
identity {
|
identity {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
receiver {
|
toId
|
||||||
|
to {
|
||||||
identity {
|
identity {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
@ -49,12 +59,87 @@ query ($address: String!, $number: Int!, $cursor: String) {
|
||||||
pageInfo {
|
pageInfo {
|
||||||
endCursor
|
endCursor
|
||||||
hasNextPage
|
hasNextPage
|
||||||
hasPreviousPage
|
|
||||||
startCursor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
// 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!) {
|
||||||
|
certConnection(
|
||||||
|
where: {receiver: {accountId: {_eq: $address}}}
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
createdOn
|
||||||
|
issuer {
|
||||||
|
accountId
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String getCertsSent = r'''
|
||||||
|
query ($address: String!) {
|
||||||
|
certConnection(
|
||||||
|
where: {issuer: {accountId: {_eq: $address}}}
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
createdOn
|
||||||
|
receiver {
|
||||||
|
accountId
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String isIdtyExistQ = r'''
|
||||||
|
query ($name: String!) {
|
||||||
|
identityConnection(where: {name: {_eq: ""}}) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String getBlockchainStartQ = r'''
|
||||||
|
query {
|
||||||
|
blockConnection(first: 1) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
height
|
||||||
|
timestamp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String subscribeHistoryIssuedQ = r'''
|
||||||
|
subscription ($address: String!) {
|
||||||
|
accountConnection(
|
||||||
|
where: {id: {_eq: $address}}
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
transfersIssued(limit: 1, orderBy: {timestamp: DESC}) {
|
||||||
|
toId
|
||||||
|
amount
|
||||||
|
timestamp
|
||||||
|
blockNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
|
||||||
|
double scaleSize(double size) {
|
||||||
|
final scale = MediaQuery.of(homeContext).size.width / 375;
|
||||||
|
return size * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextStyle scaledTextStyle({
|
||||||
|
double fontSize = 16,
|
||||||
|
double? height,
|
||||||
|
FontStyle? fontStyle,
|
||||||
|
FontWeight? fontWeight,
|
||||||
|
Color? color,
|
||||||
|
List<Shadow>? shadows,
|
||||||
|
String? fontFamily,
|
||||||
|
double? letterSpacing,
|
||||||
|
}) {
|
||||||
|
return TextStyle(
|
||||||
|
fontSize: scaleSize(fontSize),
|
||||||
|
height: height,
|
||||||
|
fontWeight: fontWeight,
|
||||||
|
fontStyle: fontStyle,
|
||||||
|
color: color,
|
||||||
|
shadows: shadows,
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
letterSpacing: letterSpacing,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScaledSizedBox extends SizedBox {
|
||||||
|
ScaledSizedBox({
|
||||||
|
Key? key,
|
||||||
|
double? width,
|
||||||
|
double? height,
|
||||||
|
Widget? child,
|
||||||
|
}) : super(
|
||||||
|
key: key,
|
||||||
|
width: width != null ? scaleSize(width) : null,
|
||||||
|
height: height != null ? scaleSize(height) : null,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import 'package:gecko/widgets/transaction_status.dart';
|
||||||
|
|
||||||
|
class TransactionContent {
|
||||||
|
final String transactionId;
|
||||||
|
TransactionStatus status;
|
||||||
|
final String from;
|
||||||
|
final String to;
|
||||||
|
final double amount;
|
||||||
|
String? error;
|
||||||
|
|
||||||
|
TransactionContent({
|
||||||
|
required this.transactionId,
|
||||||
|
required this.status,
|
||||||
|
required this.from,
|
||||||
|
required this.to,
|
||||||
|
required this.amount,
|
||||||
|
this.error,
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,41 +1,66 @@
|
||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/providers/v2s_datapod.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
part 'wallet_data.g.dart';
|
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;
|
||||||
|
|
||||||
WalletData(
|
@HiveField(7)
|
||||||
{this.version,
|
bool isOwned;
|
||||||
this.chest,
|
|
||||||
this.address,
|
@HiveField(8)
|
||||||
this.number,
|
IdtyStatus identityStatus;
|
||||||
this.name,
|
|
||||||
this.derivation,
|
@HiveField(9)
|
||||||
this.imageDefaultPath,
|
double balance;
|
||||||
this.imageCustomPath});
|
|
||||||
|
@HiveField(10)
|
||||||
|
List<int>? certs;
|
||||||
|
|
||||||
|
@HiveField(11)
|
||||||
|
DateTime? profileUpdatedTime;
|
||||||
|
|
||||||
|
WalletData({
|
||||||
|
required this.address,
|
||||||
|
this.chest,
|
||||||
|
this.number,
|
||||||
|
this.name,
|
||||||
|
this.derivation,
|
||||||
|
this.imageDefaultPath,
|
||||||
|
this.imageCustomPath,
|
||||||
|
this.profileUpdatedTime,
|
||||||
|
this.isOwned = false,
|
||||||
|
this.identityStatus = IdtyStatus.unknown,
|
||||||
|
this.balance = 0,
|
||||||
|
this.certs,
|
||||||
|
});
|
||||||
|
|
||||||
// representation of WalletData when debugging
|
// representation of WalletData when debugging
|
||||||
@override
|
@override
|
||||||
|
@ -45,18 +70,89 @@ class WalletData extends HiveObject {
|
||||||
|
|
||||||
// creates the ':'-separated string from the WalletData
|
// creates the ':'-separated string from the WalletData
|
||||||
String inLine() {
|
String inLine() {
|
||||||
return "$chest:$number:$name:$derivation:$imageDefaultPath";
|
return "$chest:$number:$name:$derivation:$imageDefaultPath:$imageCustomPath:$identityStatus";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasIdentity() {
|
||||||
|
return identityStatus == IdtyStatus.unconfirmed ||
|
||||||
|
identityStatus == IdtyStatus.unvalidated ||
|
||||||
|
identityStatus == IdtyStatus.member;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMembre() {
|
||||||
|
return identityStatus == IdtyStatus.member;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exist() {
|
||||||
|
return balance != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<DateTime?> getUpdatedTime() async {
|
||||||
|
final datapod = Provider.of<V2sDatapodProvider>(homeContext, listen: false);
|
||||||
|
return await datapod.profileEditedAt(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> shouldUpdateProfile() async {
|
||||||
|
final remoteUpdatedProfile = await getUpdatedTime();
|
||||||
|
late Duration difference;
|
||||||
|
if (profileUpdatedTime != null && remoteUpdatedProfile != null) {
|
||||||
|
difference = profileUpdatedTime!.difference(remoteUpdatedProfile);
|
||||||
|
} else if (remoteUpdatedProfile != null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
difference = Duration.zero;
|
||||||
|
}
|
||||||
|
return difference.inSeconds.abs() >= 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This method get the remote avatar on v2s-datapod only if needed, and store it on disk
|
||||||
|
Future getDatapodAvatar() async {
|
||||||
|
if (!await shouldUpdateProfile()) return;
|
||||||
|
|
||||||
|
final datapod = Provider.of<V2sDatapodProvider>(homeContext, listen: false);
|
||||||
|
final avatarUuid = const Uuid().v4();
|
||||||
|
|
||||||
|
await datapod.getRemoteAvatar(address, uuid: avatarUuid);
|
||||||
|
|
||||||
|
final avatarPath = '${avatarsDirectory.path}/$address-$avatarUuid';
|
||||||
|
if (!await File(avatarPath).exists()) return;
|
||||||
|
|
||||||
|
profileUpdatedTime = await getUpdatedTime();
|
||||||
|
imageCustomPath = avatarPath;
|
||||||
|
|
||||||
|
walletBox.put(address, this);
|
||||||
|
datapod.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasCustomImage() {
|
||||||
|
return imageCustomPath != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns only the id part of the ':'-separated string
|
|
||||||
List<int?> id() {
|
List<int?> id() {
|
||||||
return [chest, number];
|
return [chest, number];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewWallet {
|
@HiveType(typeId: 5)
|
||||||
final String address;
|
enum IdtyStatus {
|
||||||
final String password;
|
@HiveField(0)
|
||||||
|
none,
|
||||||
|
|
||||||
NewWallet._(this.address, this.password);
|
@HiveField(1)
|
||||||
|
unconfirmed,
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
unvalidated,
|
||||||
|
|
||||||
|
@HiveField(3)
|
||||||
|
member,
|
||||||
|
|
||||||
|
@HiveField(4)
|
||||||
|
notMember,
|
||||||
|
|
||||||
|
@HiveField(5)
|
||||||
|
revoked,
|
||||||
|
|
||||||
|
@HiveField(6)
|
||||||
|
unknown
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,37 +17,49 @@ 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?,
|
profileUpdatedTime: fields[11] as DateTime?,
|
||||||
|
isOwned: fields[7] as bool,
|
||||||
|
identityStatus: fields[8] as IdtyStatus,
|
||||||
|
balance: fields[9] as double,
|
||||||
|
certs: (fields[10] as List?)?.cast<int>(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, WalletData obj) {
|
void write(BinaryWriter writer, WalletData obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(8)
|
..writeByte(12)
|
||||||
..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.identityStatus)
|
||||||
|
..writeByte(9)
|
||||||
|
..write(obj.balance)
|
||||||
|
..writeByte(10)
|
||||||
|
..write(obj.certs)
|
||||||
|
..writeByte(11)
|
||||||
|
..write(obj.profileUpdatedTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -60,3 +72,67 @@ class WalletDataAdapter extends TypeAdapter<WalletData> {
|
||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
typeId == other.typeId;
|
typeId == other.typeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IdtyStatusAdapter extends TypeAdapter<IdtyStatus> {
|
||||||
|
@override
|
||||||
|
final int typeId = 5;
|
||||||
|
|
||||||
|
@override
|
||||||
|
IdtyStatus read(BinaryReader reader) {
|
||||||
|
switch (reader.readByte()) {
|
||||||
|
case 0:
|
||||||
|
return IdtyStatus.none;
|
||||||
|
case 1:
|
||||||
|
return IdtyStatus.unconfirmed;
|
||||||
|
case 2:
|
||||||
|
return IdtyStatus.unvalidated;
|
||||||
|
case 3:
|
||||||
|
return IdtyStatus.member;
|
||||||
|
case 4:
|
||||||
|
return IdtyStatus.notMember;
|
||||||
|
case 5:
|
||||||
|
return IdtyStatus.revoked;
|
||||||
|
case 6:
|
||||||
|
return IdtyStatus.unknown;
|
||||||
|
default:
|
||||||
|
return IdtyStatus.none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void write(BinaryWriter writer, IdtyStatus obj) {
|
||||||
|
switch (obj) {
|
||||||
|
case IdtyStatus.none:
|
||||||
|
writer.writeByte(0);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.unconfirmed:
|
||||||
|
writer.writeByte(1);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.unvalidated:
|
||||||
|
writer.writeByte(2);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.member:
|
||||||
|
writer.writeByte(3);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.notMember:
|
||||||
|
writer.writeByte(4);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.revoked:
|
||||||
|
writer.writeByte(5);
|
||||||
|
break;
|
||||||
|
case IdtyStatus.unknown:
|
||||||
|
writer.writeByte(6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => typeId.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is IdtyStatusAdapter &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
typeId == other.typeId;
|
||||||
|
}
|
||||||
|
|
|
@ -5,12 +5,13 @@ const keyInfoPopup = Key('keyInfoPopup');
|
||||||
const keyGoNext = Key('keyGoNext');
|
const keyGoNext = Key('keyGoNext');
|
||||||
const keyCancel = Key('keyCancel');
|
const keyCancel = Key('keyCancel');
|
||||||
const keyConfirm = Key('keyConfirm');
|
const keyConfirm = Key('keyConfirm');
|
||||||
const keyAppBarSearch = Key('keyAppBarSearch');
|
const keyAppBarHome = Key('keyAppBarSearch');
|
||||||
const keyAppBarQrcode = Key('keyAppBarQrcode');
|
const keyAppBarQrcode = Key('keyAppBarQrcode');
|
||||||
const keyAppBarChest = Key('keyAppBarChest');
|
const keyAppBarChest = Key('keyAppBarChest');
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
const keyParameters = Key('keyParameters');
|
const keyParameters = Key('keyParameters');
|
||||||
|
const keyDebugScreen = Key('keyDebugScreen');
|
||||||
const keyContacts = Key('keyContacts');
|
const keyContacts = Key('keyContacts');
|
||||||
const keyDrawerMenu = Key('keyDrawerMenu');
|
const keyDrawerMenu = Key('keyDrawerMenu');
|
||||||
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
const keyOpenWalletsHomme = Key('keyOpenWalletsHomme');
|
||||||
|
@ -23,9 +24,11 @@ const keyImportG1v1 = Key('keyImportG1v1');
|
||||||
const keyChangeChest = Key('keyChangeChest');
|
const keyChangeChest = Key('keyChangeChest');
|
||||||
const keyListWallets = Key('keyListWallets');
|
const keyListWallets = Key('keyListWallets');
|
||||||
const keyAddDerivation = Key('keyAddDerivation');
|
const keyAddDerivation = Key('keyAddDerivation');
|
||||||
|
final keyDragAndDrop = GlobalKey(debugLabel: 'keyDragAndDrop');
|
||||||
|
|
||||||
// Wallet options
|
// Wallet options
|
||||||
const keyCopyAddress = Key('keyCopyAddress');
|
const keyCopyAddress = Key('keyCopyAddress');
|
||||||
|
const keyCopyPubkey = Key('keyCopyPubkey');
|
||||||
const keyOpenActivity = Key('keyOpenActivity');
|
const keyOpenActivity = Key('keyOpenActivity');
|
||||||
const keyManageMembership = Key('keyManageMembership');
|
const keyManageMembership = Key('keyManageMembership');
|
||||||
const keySetDefaultWallet = Key('keySetDefaultWallet');
|
const keySetDefaultWallet = Key('keySetDefaultWallet');
|
||||||
|
@ -61,6 +64,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');
|
||||||
|
@ -93,6 +99,8 @@ const keyCesiumPassword = Key('keyCesiumPassword');
|
||||||
const keySelectWallet = Key('keySelectWallet');
|
const keySelectWallet = Key('keySelectWallet');
|
||||||
const keyCesiumIdVisible = Key('keyCesiumIdVisible');
|
const keyCesiumIdVisible = Key('keyCesiumIdVisible');
|
||||||
|
|
||||||
|
const keyDropdownWallets = Key('keyDropdownKey');
|
||||||
|
|
||||||
// Items keys
|
// Items keys
|
||||||
Key keyTransaction(int keyId) => Key('keyTransaction$keyId');
|
Key keyTransaction(int keyId) => Key('keyTransaction$keyId');
|
||||||
Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word');
|
Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word');
|
||||||
|
|
|
@ -1,158 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:dio/dio.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:gecko/globals.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
// import 'package:http/http.dart' as http;
|
|
||||||
|
|
||||||
class CesiumPlusProvider with ChangeNotifier {
|
|
||||||
TextEditingController cesiumName = TextEditingController();
|
|
||||||
Image defaultAvatar(double size) =>
|
|
||||||
Image.asset(('assets/icon_user.png'), height: size);
|
|
||||||
|
|
||||||
CancelToken avatarCancelToken = CancelToken();
|
|
||||||
|
|
||||||
Future<List> _buildQuery(pubkey) async {
|
|
||||||
var queryGetAvatar = json.encode({
|
|
||||||
"query": {
|
|
||||||
"bool": {
|
|
||||||
"should": [
|
|
||||||
{
|
|
||||||
"match": {
|
|
||||||
'_id': {"query": pubkey, "boost": 2}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"prefix": {'_id': pubkey}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"highlight": {
|
|
||||||
"fields": {"title": {}, "tags": {}}
|
|
||||||
},
|
|
||||||
"from": 0,
|
|
||||||
"size": 100,
|
|
||||||
"_source": [
|
|
||||||
"title",
|
|
||||||
"avatar",
|
|
||||||
"avatar._content_type",
|
|
||||||
"description",
|
|
||||||
"city",
|
|
||||||
"address",
|
|
||||||
"socials.url",
|
|
||||||
"creationTime",
|
|
||||||
"membersCount",
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"indices_boost": {"user": 100, "page": 1, "group": 0.01}
|
|
||||||
});
|
|
||||||
|
|
||||||
String requestUrl = "/user,page,group/profile,record/_search";
|
|
||||||
String podRequest = cesiumPod + requestUrl;
|
|
||||||
|
|
||||||
Map<String, String> headers = {
|
|
||||||
'Content-type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
};
|
|
||||||
|
|
||||||
return [podRequest, queryGetAvatar, headers];
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> getName(String? pubkey) async {
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
if (g1WalletsBox.get(pubkey)?.csName != null) {
|
|
||||||
return g1WalletsBox.get(pubkey)!.csName!;
|
|
||||||
}
|
|
||||||
|
|
||||||
List queryOptions = await _buildQuery(pubkey);
|
|
||||||
|
|
||||||
var dio = Dio();
|
|
||||||
late Response response;
|
|
||||||
try {
|
|
||||||
response = await dio.post(
|
|
||||||
queryOptions[0],
|
|
||||||
data: queryOptions[1],
|
|
||||||
options: Options(
|
|
||||||
headers: queryOptions[2],
|
|
||||||
sendTimeout: 3000,
|
|
||||||
receiveTimeout: 5000,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// response = await http.post((Uri.parse(queryOptions[0])),
|
|
||||||
// body: queryOptions[1], headers: queryOptions[2]);
|
|
||||||
} catch (e) {
|
|
||||||
log.e(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.data['hits']['hits'].toString() == '[]') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
final bool nameExist =
|
|
||||||
response.data['hits']['hits'][0]['_source'].containsKey("title");
|
|
||||||
if (!nameExist) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
name = response.data['hits']['hits'][0]['_source']['title'];
|
|
||||||
|
|
||||||
name ??= '';
|
|
||||||
g1WalletsBox.get(pubkey)!.csName = name;
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Image?> getAvatar(String? pubkey, double size) async {
|
|
||||||
if (g1WalletsBox.get(pubkey)?.avatar != null) {
|
|
||||||
return g1WalletsBox.get(pubkey)!.avatar;
|
|
||||||
}
|
|
||||||
var dio = Dio();
|
|
||||||
|
|
||||||
// log.d(_pubkey);
|
|
||||||
|
|
||||||
List queryOptions = await _buildQuery(pubkey);
|
|
||||||
|
|
||||||
late Response response;
|
|
||||||
try {
|
|
||||||
response = await dio
|
|
||||||
.post(queryOptions[0],
|
|
||||||
data: queryOptions[1],
|
|
||||||
options: Options(
|
|
||||||
headers: queryOptions[2],
|
|
||||||
sendTimeout: 4000,
|
|
||||||
receiveTimeout: 15000,
|
|
||||||
),
|
|
||||||
cancelToken: avatarCancelToken)
|
|
||||||
.timeout(
|
|
||||||
const Duration(seconds: 15),
|
|
||||||
);
|
|
||||||
// response = await http.post((Uri.parse(queryOptions[0])),
|
|
||||||
// body: queryOptions[1], headers: queryOptions[2]);
|
|
||||||
} catch (e) {
|
|
||||||
log.e(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.data['hits']['hits'].toString() == '[]' ||
|
|
||||||
!response.data['hits']['hits'][0]['_source'].containsKey("avatar")) {
|
|
||||||
return defaultAvatar(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
final avatar =
|
|
||||||
response.data['hits']['hits'][0]['_source']['avatar']['_content'];
|
|
||||||
|
|
||||||
var avatarFile =
|
|
||||||
File('${(await getTemporaryDirectory()).path}/avatar_$pubkey.png');
|
|
||||||
await avatarFile.writeAsBytes(base64.decode(avatar));
|
|
||||||
|
|
||||||
final finalAvatar = Image.file(
|
|
||||||
avatarFile,
|
|
||||||
height: size,
|
|
||||||
fit: BoxFit.fitWidth,
|
|
||||||
);
|
|
||||||
|
|
||||||
g1WalletsBox.get(pubkey)!.avatar = finalAvatar;
|
|
||||||
|
|
||||||
return finalAvatar;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ 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:gecko/models/scale_functions.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';
|
||||||
|
@ -16,11 +17,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 = '';
|
||||||
|
@ -42,10 +43,9 @@ class ChestProvider with ChangeNotifier {
|
||||||
|
|
||||||
List<String> getChestWallets(ChestData chest) {
|
List<String> getChestWallets(ChestData chest) {
|
||||||
List<String> toDelete = [];
|
List<String> toDelete = [];
|
||||||
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;
|
||||||
|
@ -54,19 +54,27 @@ class ChestProvider with ChangeNotifier {
|
||||||
Future<bool?> _confirmDeletingChest(context, String? walletName) async {
|
Future<bool?> _confirmDeletingChest(context, String? walletName) async {
|
||||||
return showDialog<bool>(
|
return showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true, // user must tap button!
|
barrierDismissible: true,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])),
|
title: Text(
|
||||||
|
'areYouSureToDeleteWallet'.tr(args: [walletName!]),
|
||||||
|
style: scaledTextStyle(fontSize: 17),
|
||||||
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text("no".tr(), key: keyCancel),
|
child: Text("no".tr(),
|
||||||
|
style:
|
||||||
|
scaledTextStyle(fontSize: 17, color: Colors.blueAccent),
|
||||||
|
key: keyCancel),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, false);
|
Navigator.pop(context, false);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text("yes".tr(), key: keyConfirm),
|
child: Text("yes".tr(),
|
||||||
|
style: scaledTextStyle(fontSize: 17, color: Colors.red),
|
||||||
|
key: keyConfirm),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,28 +5,19 @@ 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;
|
||||||
|
Future<QueryResult<Object?>?> Function()? refetch;
|
||||||
|
late GraphQLClient indexerClient;
|
||||||
|
|
||||||
void reload() {
|
void reload() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -38,10 +29,11 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
final client = HttpClient();
|
final client = HttpClient();
|
||||||
client.connectionTimeout = const Duration(milliseconds: 4000);
|
client.connectionTimeout = const Duration(milliseconds: 4000);
|
||||||
try {
|
try {
|
||||||
final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql'));
|
final request =
|
||||||
|
await client.postUrl(Uri.parse('https://$endpoint/v1beta1/relay'));
|
||||||
final response = await request.close();
|
final response = await request.close();
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
log.d('INDEXER IS OFFILINE');
|
log.w('Indexer $endpoint is offline');
|
||||||
indexerEndpoint = '';
|
indexerEndpoint = '';
|
||||||
isLoadingIndexer = false;
|
isLoadingIndexer = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -57,7 +49,7 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.d('INDEXER IS OFFILINE');
|
log.w('Indexer $endpoint is offline');
|
||||||
indexerEndpoint = '';
|
indexerEndpoint = '';
|
||||||
isLoadingIndexer = false;
|
isLoadingIndexer = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -65,21 +57,6 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future checkIndexerEndpointBackground() async {
|
|
||||||
// final oldEndpoint = indexerEndpoint;
|
|
||||||
// while (true) {
|
|
||||||
// await Future.delayed(const Duration(seconds: 30));
|
|
||||||
// final isValid = await checkIndexerEndpoint(oldEndpoint);
|
|
||||||
// if (!isValid) {
|
|
||||||
// log.d('INDEXER IS OFFILINE');
|
|
||||||
// indexerEndpoint = '';
|
|
||||||
// } else {
|
|
||||||
// // log.d('Indexer is online');
|
|
||||||
// indexerEndpoint = oldEndpoint;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
Future<String> getValidIndexerEndpoint() async {
|
Future<String> getValidIndexerEndpoint() async {
|
||||||
// await configBox.delete('indexerEndpoint');
|
// await configBox.delete('indexerEndpoint');
|
||||||
|
|
||||||
|
@ -88,15 +65,14 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
.then((jsonStr) => jsonDecode(jsonStr));
|
.then((jsonStr) => jsonDecode(jsonStr));
|
||||||
// _listEndpoints.shuffle();
|
// _listEndpoints.shuffle();
|
||||||
|
|
||||||
log.d(listIndexerEndpoints);
|
|
||||||
listIndexerEndpoints.add('Personnalisé');
|
listIndexerEndpoints.add('Personnalisé');
|
||||||
|
|
||||||
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') &&
|
||||||
|
listIndexerEndpoints.contains(configBox.get('indexerEndpoint'))) {
|
||||||
if (await checkIndexerEndpoint(configBox.get('indexerEndpoint'))) {
|
if (await checkIndexerEndpoint(configBox.get('indexerEndpoint'))) {
|
||||||
return configBox.get('indexerEndpoint');
|
return configBox.get('indexerEndpoint');
|
||||||
}
|
}
|
||||||
|
@ -110,7 +86,7 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
client.connectionTimeout = const Duration(milliseconds: 3000);
|
client.connectionTimeout = const Duration(milliseconds: 3000);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int listLenght = listIndexerEndpoints.length - 1;
|
final listLenght = listIndexerEndpoints.length - 1;
|
||||||
if (i >= listLenght) {
|
if (i >= listLenght) {
|
||||||
log.e('NO VALID INDEXER ENDPOINT FOUND');
|
log.e('NO VALID INDEXER ENDPOINT FOUND');
|
||||||
indexerEndpoint = '';
|
indexerEndpoint = '';
|
||||||
|
@ -123,7 +99,7 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String endpointPath = '${listIndexerEndpoints[i]}/v1/graphql';
|
final endpointPath = 'https://${listIndexerEndpoints[i]}/v1beta1/relay';
|
||||||
|
|
||||||
final request = await client.postUrl(Uri.parse(endpointPath));
|
final request = await client.postUrl(Uri.parse(endpointPath));
|
||||||
final response = await request.close();
|
final response = await request.close();
|
||||||
|
@ -151,291 +127,70 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
}
|
}
|
||||||
} while (statusCode != 200);
|
} while (statusCode != 200);
|
||||||
|
|
||||||
log.i('INDEXER: $indexerEndpoint');
|
log.i('Indexer: $indexerEndpoint');
|
||||||
return indexerEndpoint;
|
return indexerEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getNameByAddress(BuildContext context, String address,
|
List parseHistory(List blockchainTX, String address) {
|
||||||
[WalletData? wallet,
|
List transBC = [];
|
||||||
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) {
|
|
||||||
var transBC = [];
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (final trans in blockchainTX) {
|
for (final transactionNode in blockchainTX) {
|
||||||
final transaction = trans['node'];
|
final transaction = transactionNode['node'];
|
||||||
final direction =
|
final direction = transaction['fromId'] != address ? 'RECEIVED' : 'SENT';
|
||||||
transaction['issuer_pubkey'] != pubkey ? 'RECEIVED' : 'SENT';
|
|
||||||
|
|
||||||
transBC.add(i);
|
transBC.add(i);
|
||||||
transBC[i] = [];
|
transBC[i] = [];
|
||||||
transBC[i].add(DateTime.parse(transaction['created_at']));
|
transBC[i].add(DateTime.parse(transaction['timestamp']));
|
||||||
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['fromId']);
|
||||||
transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
|
transBC[i].add(transaction['from']['identity']?['name'] ?? '');
|
||||||
} else if (direction == "SENT") {
|
} else if (direction == "SENT") {
|
||||||
transBC[i].add(transaction['receiver_pubkey']);
|
transBC[i].add(transaction['toId']);
|
||||||
transBC[i].add(transaction['receiver']['identity']?['name'] ?? '');
|
transBC[i].add(transaction['to']['identity']?['name'] ?? '');
|
||||||
}
|
}
|
||||||
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(QueryResult result, FetchMoreOptions? opts,
|
||||||
final List<dynamic>? blockchainTX =
|
String address, int nRepositories) {
|
||||||
(result.data['transaction_connection']['edges'] as List<dynamic>?);
|
final List<dynamic> blockchainTX =
|
||||||
// final List<dynamic> mempoolTX =
|
(result.data!['transferConnection']['edges'] as List<dynamic>);
|
||||||
// (result.data['txsHistoryMp']['receiving'] as List<dynamic>);
|
|
||||||
|
|
||||||
pageInfo = result.data['transaction_connection']['pageInfo'];
|
pageInfo = result.data!['transferConnection']['pageInfo'];
|
||||||
fetchMoreCursor = pageInfo!['endCursor'];
|
fetchMoreCursor = pageInfo!['endCursor'];
|
||||||
if (fetchMoreCursor == null) nPage = 1;
|
// final hasNextPage = pageInfo!['hasNextPage'];
|
||||||
|
// log.d('endCursor: $fetchMoreCursor $hasNextPage');
|
||||||
log.d(fetchMoreCursor);
|
|
||||||
|
|
||||||
if (nPage == 1) {
|
|
||||||
nRepositories = 40;
|
|
||||||
} else if (nPage == 2) {
|
|
||||||
nRepositories = 100;
|
|
||||||
}
|
|
||||||
// nRepositories = 10;
|
|
||||||
nPage++;
|
|
||||||
|
|
||||||
if (fetchMoreCursor != null) {
|
if (fetchMoreCursor != null) {
|
||||||
opts = FetchMoreOptions(
|
opts = FetchMoreOptions(
|
||||||
variables: {'cursor': fetchMoreCursor, 'number': nRepositories},
|
variables: {'after': fetchMoreCursor, 'first': nRepositories},
|
||||||
updateQuery: (previousResultData, fetchMoreResultData) {
|
updateQuery: (previousResultData, fetchMoreResultData) {
|
||||||
final List<dynamic> repos = [
|
final List<dynamic> repos = [
|
||||||
...previousResultData!['transaction_connection']['edges']
|
...previousResultData!['transferConnection']['edges']
|
||||||
as List<dynamic>,
|
as List<dynamic>,
|
||||||
...fetchMoreResultData!['transaction_connection']['edges']
|
...fetchMoreResultData!['transferConnection']['edges']
|
||||||
as List<dynamic>
|
as List<dynamic>
|
||||||
];
|
];
|
||||||
|
|
||||||
log.d('repos: $previousResultData');
|
fetchMoreResultData['transferConnection']['edges'] = repos;
|
||||||
log.d('repos: $fetchMoreResultData');
|
|
||||||
log.d('repos: $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, address);
|
||||||
} else {
|
} else {
|
||||||
log.i("###### DEBUG H - Début de l'historique");
|
log.d("Activity start of $address");
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +199,119 @@ class DuniterIndexer with ChangeNotifier {
|
||||||
return double.parse(result);
|
return double.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkHistoryResult(
|
//// Manuals queries
|
||||||
// QueryResult<Object?> result, FetchMoreOptions options, String address) {}
|
|
||||||
|
Future<bool> isIdtyExist(String name) async {
|
||||||
|
final variables = <String, dynamic>{
|
||||||
|
'name': name,
|
||||||
|
};
|
||||||
|
final result = await _execQuery(isIdtyExistQ, variables);
|
||||||
|
log.d(result.data);
|
||||||
|
return result.data?['identity']?.isNotEmpty ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<DateTime> getBlockStart() async {
|
||||||
|
final result = await _execQuery(getBlockchainStartQ, {});
|
||||||
|
if (!result.hasException) {
|
||||||
|
startBlockchainTime = DateTime.parse(
|
||||||
|
result.data!['blockConnection']['edges'][0]['node']['timestamp']);
|
||||||
|
startBlockchainInitialized = true;
|
||||||
|
return startBlockchainTime;
|
||||||
|
}
|
||||||
|
return DateTime(0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<QueryResult> _execQuery(
|
||||||
|
String query, Map<String, dynamic> variables) async {
|
||||||
|
final options = QueryOptions(document: gql(query), variables: variables);
|
||||||
|
|
||||||
|
// 5GMyvKsTNk9wDBy9jwKaX6mhSzmFFtpdK9KNnmrLoSTSuJHv
|
||||||
|
|
||||||
|
return await indexerClient.query(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<QueryResult> subscribeHistoryIssued(String address) {
|
||||||
|
final variables = <String, dynamic>{
|
||||||
|
'address': address,
|
||||||
|
};
|
||||||
|
|
||||||
|
final options = SubscriptionOptions(
|
||||||
|
document: gql(subscribeHistoryIssuedQ),
|
||||||
|
variables: variables,
|
||||||
|
);
|
||||||
|
|
||||||
|
return indexerClient.subscribe(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map computeHistoryView(repository, String address) {
|
||||||
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
late double amount;
|
||||||
|
late String finalAmount;
|
||||||
|
final DateTime date = repository[0];
|
||||||
|
|
||||||
|
final dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, {
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
7,
|
||||||
|
9
|
||||||
|
}.contains(date.month) ? 4 : 3)}";
|
||||||
|
|
||||||
|
DateTime normalizeDate(DateTime inputDate) {
|
||||||
|
return DateTime(inputDate.year, inputDate.month, inputDate.day);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDateDelimiter() {
|
||||||
|
DateTime now = DateTime.now();
|
||||||
|
final transactionDate = normalizeDate(date.toLocal());
|
||||||
|
final todayDate = normalizeDate(now);
|
||||||
|
final yesterdayDate =
|
||||||
|
normalizeDate(now.subtract(const Duration(days: 1)));
|
||||||
|
final isSameWeek = weekNumber(transactionDate) == weekNumber(now) &&
|
||||||
|
transactionDate.year == now.year;
|
||||||
|
final isTodayOrYesterday =
|
||||||
|
transactionDate == todayDate || transactionDate == yesterdayDate;
|
||||||
|
|
||||||
|
if (transactionDate == todayDate) {
|
||||||
|
return "today".tr();
|
||||||
|
} else if (transactionDate == yesterdayDate) {
|
||||||
|
return "yesterday".tr();
|
||||||
|
} else if (isSameWeek && !isTodayOrYesterday) {
|
||||||
|
return "thisWeek".tr();
|
||||||
|
} else if (!isSameWeek && !isTodayOrYesterday) {
|
||||||
|
if (transactionDate.year == now.year) {
|
||||||
|
return monthsInYear[transactionDate.month]!;
|
||||||
|
} else {
|
||||||
|
return "${monthsInYear[transactionDate.month]} ${transactionDate.year}";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final dateDelimiter = getDateDelimiter();
|
||||||
|
|
||||||
|
amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;
|
||||||
|
|
||||||
|
if (isUdUnit) {
|
||||||
|
amount = round(amount / balanceRatio);
|
||||||
|
finalAmount = 'ud'.tr(args: ['$amount ']);
|
||||||
|
} else {
|
||||||
|
finalAmount = '$amount $currencyName';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMigrationTime =
|
||||||
|
startBlockchainInitialized && date.compareTo(startBlockchainTime) < 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
'finalAmount': finalAmount,
|
||||||
|
'isMigrationTime': isMigrationTime,
|
||||||
|
'dateDelimiter': dateDelimiter,
|
||||||
|
'dateForm': dateForm,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int weekNumber(DateTime date) {
|
||||||
|
int dayOfYear = int.parse(DateFormat("D").format(date));
|
||||||
|
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
@ -8,23 +9,21 @@ import 'package:gecko/models/bip39_words.dart';
|
||||||
import 'package:gecko/models/chest_data.dart';
|
import 'package:gecko/models/chest_data.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:pdf/pdf.dart';
|
import 'package:gecko/widgets/scan_derivations_info.dart';
|
||||||
import 'package:pdf/widgets.dart' as pw;
|
|
||||||
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import "package:unorm_dart/unorm_dart.dart" as unorm;
|
import "package:unorm_dart/unorm_dart.dart" as unorm;
|
||||||
|
|
||||||
class GenerateWalletsProvider with ChangeNotifier {
|
class GenerateWalletsProvider with ChangeNotifier {
|
||||||
GenerateWalletsProvider();
|
GenerateWalletsProvider();
|
||||||
// NewWallet generatedWallet;
|
|
||||||
durt.NewWallet? actualWallet;
|
|
||||||
|
|
||||||
FocusNode walletNameFocus = FocusNode();
|
final walletNameFocus = FocusNode();
|
||||||
Color? askedWordColor = Colors.black;
|
Color? askedWordColor = Colors.black;
|
||||||
bool isAskedWordValid = false;
|
bool isAskedWordValid = false;
|
||||||
|
var scanStatus = ScanDerivationsStatus.none;
|
||||||
int scanedValidWalletNumber = -1;
|
int scanedValidWalletNumber = -1;
|
||||||
int scanedWalletNumber = -1;
|
int scanedWalletNumber = -1;
|
||||||
int numberScan = 20;
|
int numberScan = 60;
|
||||||
|
|
||||||
late int nbrWord;
|
late int nbrWord;
|
||||||
String? nbrWordAlpha;
|
String? nbrWordAlpha;
|
||||||
|
@ -32,31 +31,31 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
String? generatedMnemonic;
|
String? generatedMnemonic;
|
||||||
bool walletIsGenerated = true;
|
bool walletIsGenerated = true;
|
||||||
|
|
||||||
TextEditingController mnemonicController = TextEditingController();
|
final mnemonicController = TextEditingController();
|
||||||
TextEditingController pin = TextEditingController();
|
final pin = TextEditingController();
|
||||||
|
|
||||||
// Import wallet
|
// Import wallet
|
||||||
TextEditingController cesiumID = TextEditingController();
|
final cesiumID = TextEditingController();
|
||||||
TextEditingController cesiumPWD = TextEditingController();
|
final cesiumPWD = TextEditingController();
|
||||||
TextEditingController cesiumPubkey = TextEditingController();
|
final cesiumPubkey = TextEditingController();
|
||||||
bool isCesiumIDVisible = false;
|
bool isCesiumIDVisible = false;
|
||||||
bool isCesiumPWDVisible = false;
|
bool isCesiumPWDVisible = false;
|
||||||
bool canImport = false;
|
bool canImport = false;
|
||||||
late durt.CesiumWallet cesiumWallet;
|
late durt.CesiumWallet cesiumWallet;
|
||||||
|
|
||||||
// Import Chest
|
// Import Chest
|
||||||
TextEditingController cellController0 = TextEditingController();
|
final cellController0 = TextEditingController();
|
||||||
TextEditingController cellController1 = TextEditingController();
|
final cellController1 = TextEditingController();
|
||||||
TextEditingController cellController2 = TextEditingController();
|
final cellController2 = TextEditingController();
|
||||||
TextEditingController cellController3 = TextEditingController();
|
final cellController3 = TextEditingController();
|
||||||
TextEditingController cellController4 = TextEditingController();
|
final cellController4 = TextEditingController();
|
||||||
TextEditingController cellController5 = TextEditingController();
|
final cellController5 = TextEditingController();
|
||||||
TextEditingController cellController6 = TextEditingController();
|
final cellController6 = TextEditingController();
|
||||||
TextEditingController cellController7 = TextEditingController();
|
final cellController7 = TextEditingController();
|
||||||
TextEditingController cellController8 = TextEditingController();
|
final cellController8 = TextEditingController();
|
||||||
TextEditingController cellController9 = TextEditingController();
|
final cellController9 = TextEditingController();
|
||||||
TextEditingController cellController10 = TextEditingController();
|
final cellController10 = TextEditingController();
|
||||||
TextEditingController cellController11 = TextEditingController();
|
final cellController11 = TextEditingController();
|
||||||
bool isFirstTimeSentenceComplete = true;
|
bool isFirstTimeSentenceComplete = true;
|
||||||
|
|
||||||
Future storeHDWChest(BuildContext context) async {
|
Future storeHDWChest(BuildContext context) async {
|
||||||
|
@ -86,19 +85,14 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
final expectedWord = mnemo.split(' ')[nbrWord];
|
final expectedWord = mnemo.split(' ')[nbrWord];
|
||||||
final normInputWord = unorm.nfkd(inputWord);
|
final normInputWord = unorm.nfkd(inputWord);
|
||||||
|
|
||||||
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');
|
|
||||||
isAskedWordValid = true;
|
isAskedWordValid = true;
|
||||||
askedWordColor = Colors.green[600];
|
askedWordColor = Colors.green[600];
|
||||||
// walletNameFocus.nextFocus();
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} else {
|
} else {
|
||||||
isAskedWordValid = false;
|
isAskedWordValid = false;
|
||||||
}
|
}
|
||||||
// notifyListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String removeDiacritics(String str) {
|
String removeDiacritics(String str) {
|
||||||
|
@ -151,84 +145,12 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
return pin.text;
|
return pin.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> printWallet(AsyncSnapshot<List>? mnemoList) async {
|
|
||||||
final ByteData fontData =
|
|
||||||
await rootBundle.load("assets/OpenSans-Regular.ttf");
|
|
||||||
final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData());
|
|
||||||
final pdf = pw.Document();
|
|
||||||
|
|
||||||
// const imageProvider = AssetImage('assets/icon/gecko_final.png');
|
|
||||||
// final geckoLogo = await flutterImageProvider(imageProvider);
|
|
||||||
|
|
||||||
pw.Widget arrayCell(dataWord) {
|
|
||||||
return pw.SizedBox(
|
|
||||||
width: 120,
|
|
||||||
child: pw.Column(children: <pw.Widget>[
|
|
||||||
pw.Text(
|
|
||||||
dataWord.split(':')[0],
|
|
||||||
style: pw.TextStyle(
|
|
||||||
fontSize: 15, color: const PdfColor(0.5, 0, 0), font: ttf),
|
|
||||||
),
|
|
||||||
pw.Text(
|
|
||||||
dataWord.split(':')[1],
|
|
||||||
style: pw.TextStyle(
|
|
||||||
fontSize: 20, color: const PdfColor(0, 0, 0), font: ttf),
|
|
||||||
),
|
|
||||||
pw.SizedBox(height: 10)
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pdf.addPage(
|
|
||||||
pw.Page(
|
|
||||||
pageFormat: PdfPageFormat.a4,
|
|
||||||
build: (context) {
|
|
||||||
return pw.Column(
|
|
||||||
// mainAxisAlignment: pw.MainAxisAlignment.center,
|
|
||||||
// mainAxisSize: pw.MainAxisSize.max,
|
|
||||||
// crossAxisAlignment: pw.CrossAxisAlignment.center,
|
|
||||||
children: <pw.Widget>[
|
|
||||||
pw.Row(children: <pw.Widget>[
|
|
||||||
arrayCell(mnemoList!.data![0]),
|
|
||||||
arrayCell(mnemoList.data![1]),
|
|
||||||
arrayCell(mnemoList.data![2]),
|
|
||||||
arrayCell(mnemoList.data![3]),
|
|
||||||
]),
|
|
||||||
pw.Row(children: <pw.Widget>[
|
|
||||||
arrayCell(mnemoList.data![4]),
|
|
||||||
arrayCell(mnemoList.data![5]),
|
|
||||||
arrayCell(mnemoList.data![6]),
|
|
||||||
arrayCell(mnemoList.data![7]),
|
|
||||||
]),
|
|
||||||
pw.Row(children: <pw.Widget>[
|
|
||||||
arrayCell(mnemoList.data![8]),
|
|
||||||
arrayCell(mnemoList.data![9]),
|
|
||||||
arrayCell(mnemoList.data![10]),
|
|
||||||
arrayCell(mnemoList.data![11])
|
|
||||||
]),
|
|
||||||
pw.Expanded(
|
|
||||||
child: pw.Align(
|
|
||||||
alignment: pw.Alignment.bottomCenter,
|
|
||||||
child: pw.Text(
|
|
||||||
"Gardez cette feuille préciseusement, à l’abri des lézards indiscrets.",
|
|
||||||
style: pw.TextStyle(fontSize: 15, font: ttf),
|
|
||||||
)))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return pdf.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> generateCesiumWalletPubkey(
|
Future<void> generateCesiumWalletPubkey(
|
||||||
String cesiumID, String cesiumPWD) async {
|
String cesiumID, String cesiumPWD) async {
|
||||||
cesiumWallet = durt.CesiumWallet(cesiumID, cesiumPWD);
|
cesiumWallet = durt.CesiumWallet(cesiumID, cesiumPWD);
|
||||||
String walletPubkey = cesiumWallet.pubkey;
|
String walletPubkey = cesiumWallet.pubkey;
|
||||||
|
|
||||||
cesiumPubkey.text = walletPubkey;
|
cesiumPubkey.text = walletPubkey;
|
||||||
log.d(walletPubkey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cesiumIDisVisible() {
|
void cesiumIDisVisible() {
|
||||||
|
@ -244,12 +166,11 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
void resetCesiumImportView() {
|
void resetCesiumImportView() {
|
||||||
cesiumID.text = cesiumPWD.text = cesiumPubkey.text = pin.text = '';
|
cesiumID.text = cesiumPWD.text = cesiumPubkey.text = pin.text = '';
|
||||||
canImport = isCesiumIDVisible = isCesiumPWDVisible = false;
|
canImport = isCesiumIDVisible = isCesiumPWDVisible = false;
|
||||||
actualWallet = null;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = [];
|
||||||
|
@ -276,7 +197,7 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
if (bip39Words(appLang).contains(word.toLowerCase())) {
|
if (bip39Words(appLang).contains(word.toLowerCase())) {
|
||||||
for (var bipWord in bip39Words(appLang)) {
|
for (var bipWord in bip39Words(appLang)) {
|
||||||
if (bipWord.startsWith(word)) {
|
if (bipWord.startsWith(word)) {
|
||||||
isValid = nbrMatch == 0 ? true : false;
|
isValid = nbrMatch == 0;
|
||||||
if (checkRedondance) nbrMatch = nbrMatch + 1;
|
if (checkRedondance) nbrMatch = nbrMatch + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,67 +290,70 @@ 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;
|
|
||||||
scanedWalletNumber = 0;
|
scanedWalletNumber = 0;
|
||||||
|
Map<String, int> addressToScan = {};
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
if (!sub.nodeConnected) {
|
if (!sub.nodeConnected) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanStatus = ScanDerivationsStatus.rootScanning;
|
||||||
final hasRoot = await scanRootBalance(sub, currentChestNumber);
|
final hasRoot = await scanRootBalance(sub, currentChestNumber);
|
||||||
scanedWalletNumber = 1;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
if (hasRoot) {
|
if (hasRoot) {
|
||||||
scanedValidWalletNumber = 1;
|
|
||||||
isAlive = true;
|
isAlive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
|
scanStatus = ScanDerivationsStatus.scanning;
|
||||||
|
for (int derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
|
||||||
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
||||||
sub.currencyParameters['ss58']!,
|
sub.currencyParameters['ss58']!,
|
||||||
cryptoType: CryptoType.sr25519,
|
cryptoType: CryptoType.sr25519,
|
||||||
mnemonic: generatedMnemonic!,
|
mnemonic: generatedMnemonic!,
|
||||||
derivePath: '//$derivationNbr');
|
derivePath: '//$derivationNbr');
|
||||||
|
addressToScan.putIfAbsent(addressData.address!, () => derivationNbr);
|
||||||
|
}
|
||||||
|
|
||||||
final Map balance = await sub.getBalance(addressData.address!).timeout(
|
final balanceList =
|
||||||
const Duration(seconds: 1),
|
await sub.getBalanceMulti(addressToScan.keys.toList()).timeout(
|
||||||
onTimeout: () => {'transferableBalance': 0},
|
const Duration(seconds: 20),
|
||||||
);
|
onTimeout: () => {},
|
||||||
// const balance = 0;
|
);
|
||||||
|
|
||||||
log.d(
|
// Remove unused wallets
|
||||||
"${addressData.address!}: ${balance['transferableBalance']} $currencyName");
|
balanceList.removeWhere((key, value) => value['transferableBalance'] == 0);
|
||||||
if (balance['transferableBalance'] != 0) {
|
scanedValidWalletNumber = balanceList.length + scanedWalletNumber;
|
||||||
isAlive = true;
|
|
||||||
String walletName = scanedValidWalletNumber == 0
|
|
||||||
? 'currentWallet'.tr()
|
|
||||||
: '${'wallet'.tr()} ${scanedValidWalletNumber + 1}';
|
|
||||||
await sub.importAccount(
|
|
||||||
mnemonic: generatedMnemonic!,
|
|
||||||
derivePath: '//$derivationNbr',
|
|
||||||
password: pin.text);
|
|
||||||
|
|
||||||
WalletData myWallet = WalletData(
|
scanStatus = ScanDerivationsStatus.import;
|
||||||
version: dataVersion,
|
for (String scannedWallet in balanceList.keys) {
|
||||||
chest: currentChestNumber,
|
isAlive = true;
|
||||||
address: addressData.address!,
|
String walletName = scanedWalletNumber == 0
|
||||||
number: scanedValidWalletNumber,
|
? 'currentWallet'.tr()
|
||||||
name: walletName,
|
: '${'wallet'.tr()} ${scanedWalletNumber + 1}';
|
||||||
derivation: derivationNbr,
|
await sub.importAccount(
|
||||||
imageDefaultPath: '${scanedValidWalletNumber % 4}.png');
|
mnemonic: generatedMnemonic!,
|
||||||
await walletBox.add(myWallet);
|
derivePath: "//${addressToScan[scannedWallet]}",
|
||||||
scanedValidWalletNumber = scanedValidWalletNumber + 1;
|
password: pin.text);
|
||||||
}
|
|
||||||
scanedWalletNumber = scanedWalletNumber + 1;
|
WalletData myWallet = WalletData(
|
||||||
|
chest: currentChestNumber,
|
||||||
|
address: scannedWallet,
|
||||||
|
number: scanedWalletNumber,
|
||||||
|
name: walletName,
|
||||||
|
derivation: addressToScan[scannedWallet],
|
||||||
|
imageDefaultPath: '${scanedWalletNumber % 4}.png',
|
||||||
|
isOwned: true);
|
||||||
|
await walletBox.put(myWallet.address, myWallet);
|
||||||
|
scanedWalletNumber++;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
log.d(scanedWalletNumber);
|
|
||||||
scanedWalletNumber = -1;
|
scanStatus = ScanDerivationsStatus.none;
|
||||||
scanedValidWalletNumber = -1;
|
scanedWalletNumber = scanedValidWalletNumber = -1;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return isAlive;
|
return isAlive;
|
||||||
}
|
}
|
||||||
|
@ -445,21 +369,20 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
onTimeout: () => {},
|
onTimeout: () => {},
|
||||||
);
|
);
|
||||||
|
|
||||||
log.d(
|
|
||||||
"${addressData.address!}: ${balance['transferableBalance']} $currencyName");
|
|
||||||
if (balance['transferableBalance'] != 0) {
|
if (balance['transferableBalance'] != 0) {
|
||||||
String walletName = 'myRootWallet'.tr();
|
String walletName = 'myRootWallet'.tr();
|
||||||
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);
|
||||||
|
scanedWalletNumber++;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
// import 'package:audioplayers/audio_cache.dart';
|
|
||||||
// import 'package:audioplayers/audioplayers.dart';
|
|
||||||
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;
|
||||||
|
@ -29,10 +18,11 @@ import 'package:provider/provider.dart';
|
||||||
class HomeProvider with ChangeNotifier {
|
class HomeProvider with ChangeNotifier {
|
||||||
bool? isSearching;
|
bool? isSearching;
|
||||||
Icon searchIcon = const Icon(Icons.search);
|
Icon searchIcon = const Icon(Icons.search);
|
||||||
final TextEditingController searchQuery = TextEditingController();
|
final searchQuery = TextEditingController();
|
||||||
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;
|
||||||
|
@ -58,18 +48,21 @@ class HomeProvider with ChangeNotifier {
|
||||||
|
|
||||||
// Init app folders
|
// Init app folders
|
||||||
final documentDir = await getApplicationDocumentsDirectory();
|
final documentDir = await getApplicationDocumentsDirectory();
|
||||||
imageDirectory = Directory('${documentDir.path}/images');
|
avatarsDirectory = Directory('${documentDir.path}/avatars');
|
||||||
|
avatarsCacheDirectory = Directory('${documentDir.path}/avatarsCache');
|
||||||
|
|
||||||
if (!await imageDirectory.exists()) {
|
if (!await avatarsDirectory.exists()) {
|
||||||
await imageDirectory.create();
|
await avatarsDirectory.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -112,7 +105,6 @@ class HomeProvider with ChangeNotifier {
|
||||||
configBox.put('endpoint', listEndpoints);
|
configBox.put('endpoint', listEndpoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.i('ENDPOINT: $listEndpoints');
|
|
||||||
return listEndpoints;
|
return listEndpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,114 +114,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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
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 '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/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/screens/myWallets/unlocking_wallet.dart';
|
||||||
|
import 'package:gecko/widgets/commons/common_elements.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MyWalletsProvider with ChangeNotifier {
|
class MyWalletsProvider with ChangeNotifier {
|
||||||
|
@ -13,8 +17,10 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
late String mnemonic;
|
late String mnemonic;
|
||||||
int? pinLenght;
|
int? pinLenght;
|
||||||
bool isNewDerivationLoading = false;
|
bool isNewDerivationLoading = false;
|
||||||
String lastFlyBy = '';
|
WalletData? lastFlyBy;
|
||||||
String dragAddress = '';
|
WalletData? dragAddress;
|
||||||
|
bool isPinValid = false;
|
||||||
|
bool isPinLoading = true;
|
||||||
|
|
||||||
int getCurrentChest() {
|
int getCurrentChest() {
|
||||||
if (configBox.get('currentChest') == null) {
|
if (configBox.get('currentChest') == null) {
|
||||||
|
@ -24,29 +30,39 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
return configBox.get('currentChest');
|
return configBox.get('currentChest');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkIfWalletExist() {
|
bool isWalletsExists() => chestBox.isNotEmpty;
|
||||||
if (chestBox.isEmpty) {
|
|
||||||
log.i('No wallets detected');
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<WalletData> readAllWallets([int? chest]) {
|
Future<List<WalletData>> readAllWallets([int? chest]) async {
|
||||||
chest = chest ?? configBox.get('currentChest') ?? 0;
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
chest = chest ?? getCurrentChest();
|
||||||
listWallets.clear();
|
listWallets.clear();
|
||||||
walletBox.toMap().forEach((key, value) {
|
final wallets = walletBox.toMap().values.toList();
|
||||||
if (value.chest == chest) {
|
Map<String, WalletData> walletsToScan = {};
|
||||||
listWallets.add(value);
|
for (var walletFromBox in wallets) {
|
||||||
|
if (walletFromBox.chest != chest) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
});
|
if (walletFromBox.identityStatus == IdtyStatus.unknown) {
|
||||||
|
walletsToScan.putIfAbsent(walletFromBox.address, (() => walletFromBox));
|
||||||
|
} else {
|
||||||
|
listWallets.add(walletFromBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update all idty status in lists
|
||||||
|
int n = 0;
|
||||||
|
final idtyStatusList = await sub.idtyStatus(walletsToScan.keys.toList());
|
||||||
|
for (final wallet in walletsToScan.values) {
|
||||||
|
wallet.identityStatus = idtyStatusList[n];
|
||||||
|
walletBox.put(wallet.address, wallet);
|
||||||
|
listWallets.add(wallet);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
return listWallets;
|
return listWallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -61,6 +77,20 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
return targetedWallet;
|
return targetedWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> askPinCode() async {
|
||||||
|
final defaultWallet = getDefaultWallet();
|
||||||
|
|
||||||
|
if (pinCode.isEmpty) {
|
||||||
|
await Navigator.push(
|
||||||
|
homeContext,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (homeContext) => UnlockingWallet(wallet: defaultWallet),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return pinCode.isNotEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
WalletData? getWalletDataByAddress(String address) {
|
WalletData? getWalletDataByAddress(String address) {
|
||||||
WalletData? targetedWallet;
|
WalletData? targetedWallet;
|
||||||
|
|
||||||
|
@ -76,18 +106,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 ?');
|
||||||
|
@ -100,12 +130,17 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
await configBox.delete('defaultWallet');
|
await configBox.delete('defaultWallet');
|
||||||
await sub.deleteAllAccounts();
|
await sub.deleteAllAccounts();
|
||||||
|
|
||||||
|
final directory = await getApplicationDocumentsDirectory();
|
||||||
|
final avatarFolder = Directory('${directory.path}/avatars/');
|
||||||
|
if (await avatarFolder.exists()) {
|
||||||
|
await avatarFolder.delete(recursive: true);
|
||||||
|
await avatarFolder.create();
|
||||||
|
}
|
||||||
|
|
||||||
myWalletProvider.pinCode = '';
|
myWalletProvider.pinCode = '';
|
||||||
|
|
||||||
await Navigator.of(context).pushNamedAndRemoveUntil(
|
await Navigator.of(context)
|
||||||
'/',
|
.pushNamedAndRemoveUntil('/', (Route<dynamic> route) => false);
|
||||||
ModalRoute.withName('/'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -118,36 +153,37 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
isNewDerivationLoading = true;
|
isNewDerivationLoading = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final List idList = getNextWalletNumberAndDerivation();
|
final List idList = await getNextWalletNumberAndDerivation();
|
||||||
int newWalletNbr = idList[0];
|
int newWalletNbr = idList[0];
|
||||||
int newDerivationNbr = number ?? idList[1];
|
int newDerivationNbr = number ?? idList[1];
|
||||||
|
|
||||||
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);
|
||||||
|
await readAllWallets();
|
||||||
|
|
||||||
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;
|
||||||
|
@ -155,48 +191,54 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
int newWalletNbr;
|
int newWalletNbr;
|
||||||
int? chest = getCurrentChest();
|
int? chest = getCurrentChest();
|
||||||
|
|
||||||
List<WalletData> walletConfig = readAllWallets(chest);
|
List<WalletData> walletConfig = await 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);
|
||||||
|
await readAllWallets();
|
||||||
|
|
||||||
isNewDerivationLoading = false;
|
isNewDerivationLoading = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int> getNextWalletNumberAndDerivation(
|
Future<List<int>> getNextWalletNumberAndDerivation(
|
||||||
{int? chestNumber, bool isOneshoot = false}) {
|
{int? chestNumber, bool isOneshoot = false}) async {
|
||||||
int newDerivationNbr = 0;
|
int newDerivationNbr = 0;
|
||||||
int newWalletNbr = 0;
|
int newWalletNbr = 0;
|
||||||
|
|
||||||
chestNumber ??= getCurrentChest();
|
chestNumber ??= getCurrentChest();
|
||||||
|
|
||||||
List<WalletData> walletConfig = readAllWallets(chestNumber);
|
listWallets.sort((p1, p2) {
|
||||||
|
return Comparable.compare(p1.number!, p2.number!);
|
||||||
|
});
|
||||||
|
|
||||||
if (walletConfig.isEmpty) {
|
if (listWallets.isEmpty) {
|
||||||
newDerivationNbr = 2;
|
newDerivationNbr = 2;
|
||||||
} else {
|
} else {
|
||||||
WalletData lastWallet = walletConfig.reduce(
|
final lastWallet = listWallets.reduce(
|
||||||
(curr, next) => curr.derivation! > next.derivation! ? curr : next);
|
(curr, next) => curr.derivation! > next.derivation! ? curr : next);
|
||||||
|
|
||||||
if (lastWallet.derivation == -1) {
|
if (lastWallet.derivation == -1) {
|
||||||
|
@ -205,14 +247,14 @@ class MyWalletsProvider with ChangeNotifier {
|
||||||
newDerivationNbr = lastWallet.derivation! + (isOneshoot ? 1 : 2);
|
newDerivationNbr = lastWallet.derivation! + (isOneshoot ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
newWalletNbr = walletConfig.last.number! + 1;
|
newWalletNbr = listWallets.last.number! + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [newWalletNbr, newDerivationNbr];
|
return [newWalletNbr, newDerivationNbr];
|
||||||
}
|
}
|
||||||
|
|
||||||
int lockPin = 0;
|
int lockPin = 0;
|
||||||
Future resetPinCode([int minutes = 15]) async {
|
Future debounceResetPinCode([int minutes = 15]) async {
|
||||||
lockPin++;
|
lockPin++;
|
||||||
final actualLock = lockPin;
|
final actualLock = lockPin;
|
||||||
await Future.delayed(
|
await Future.delayed(
|
||||||
|
|
|
@ -3,75 +3,16 @@ import 'package:gecko/models/g1_wallets_list.dart';
|
||||||
import 'package:gecko/providers/wallets_profiles.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
|
|
||||||
class SearchProvider with ChangeNotifier {
|
class SearchProvider with ChangeNotifier {
|
||||||
TextEditingController searchController = TextEditingController();
|
final searchController = TextEditingController();
|
||||||
List searchResult = [];
|
List searchResult = [];
|
||||||
final cacheDuring = 20 * 60 * 1000; //First number is minutes
|
int resultLenght = 0;
|
||||||
int cacheTime = 0;
|
|
||||||
|
|
||||||
void reload() {
|
void reload() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<List> searchBlockchain() async {
|
|
||||||
// searchResult.clear();
|
|
||||||
// int searchTime = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
// WalletsProfilesProvider _walletProfiles = WalletsProfilesProvider('pubkey');
|
|
||||||
|
|
||||||
// if (cacheTime + cacheDuring <= searchTime) {
|
|
||||||
// g1WalletsBox.clear();
|
|
||||||
// // final url = Uri.parse('https://g1-stats.axiom-team.fr/data/forbes.json');
|
|
||||||
// // final response = await http.get(url);
|
|
||||||
|
|
||||||
// var dio = Dio();
|
|
||||||
// late Response response;
|
|
||||||
// try {
|
|
||||||
// response = await dio.get(
|
|
||||||
// 'https://g1-stats.axiom-team.fr/data/forbes.json',
|
|
||||||
// options: Options(
|
|
||||||
// sendTimeout: 5000,
|
|
||||||
// receiveTimeout: 10000,
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// // response = await http.post((Uri.parse(queryOptions[0])),
|
|
||||||
// // body: queryOptions[1], headers: queryOptions[2]);
|
|
||||||
// } catch (e) {
|
|
||||||
// log.e(e);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// List<G1WalletsList> _listWallets = _parseG1Wallets(response.data)!;
|
|
||||||
// Map<String?, G1WalletsList> _mapWallets = {
|
|
||||||
// for (var e in _listWallets) e.pubkey: e
|
|
||||||
// };
|
|
||||||
|
|
||||||
// await g1WalletsBox.putAll(_mapWallets);
|
|
||||||
// cacheTime = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// g1WalletsBox.toMap().forEach((key, value) {
|
|
||||||
// if ((value.id != null &&
|
|
||||||
// value.id!.username != null &&
|
|
||||||
// value.id!.username!
|
|
||||||
// .toLowerCase()
|
|
||||||
// .contains(searchController.text)) ||
|
|
||||||
// value.pubkey!.contains(searchController.text)) {
|
|
||||||
// searchResult.add(value);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (searchResult.isEmpty &&
|
|
||||||
// _walletProfiles.isPubkey(searchController.text)) {
|
|
||||||
// searchResult = [G1WalletsList(pubkey: searchController.text)];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return searchResult;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Future<List<G1WalletsList>> searchAddress() async {
|
Future<List<G1WalletsList>> searchAddress() async {
|
||||||
final WalletsProfilesProvider walletProfiles =
|
if (await isAddress(searchController.text)) {
|
||||||
WalletsProfilesProvider('pubkey');
|
|
||||||
|
|
||||||
if (walletProfiles.isAddress(searchController.text)) {
|
|
||||||
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
G1WalletsList wallet = G1WalletsList(address: searchController.text);
|
||||||
return [wallet];
|
return [wallet];
|
||||||
} else {
|
} else {
|
||||||
|
@ -79,11 +20,3 @@ class SearchProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List<G1WalletsList>? _parseG1Wallets(var responseBody) {
|
|
||||||
// final parsed = responseBody.cast<Map<String, dynamic>>();
|
|
||||||
|
|
||||||
// return parsed
|
|
||||||
// .map<G1WalletsList>((json) => G1WalletsList.fromJson(json))
|
|
||||||
// .toList();
|
|
||||||
// }
|
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:gecko/models/queries_datapod.dart';
|
||||||
|
import 'package:gecko/models/scale_functions.dart';
|
||||||
|
import 'package:gecko/providers/my_wallets.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:graphql_flutter/graphql_flutter.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
class V2sDatapodProvider with ChangeNotifier {
|
||||||
|
late GraphQLClient datapodClient;
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> _setSignedVariables(
|
||||||
|
String address, Map<String, dynamic> messageToSign) async {
|
||||||
|
final myWalletProvider =
|
||||||
|
Provider.of<MyWalletsProvider>(homeContext, listen: false);
|
||||||
|
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
final hashDocBytes = utf8.encode(jsonEncode(messageToSign));
|
||||||
|
final hashDoc = sha256.convert(hashDocBytes).toString().toUpperCase();
|
||||||
|
if (!await myWalletProvider.askPinCode()) return {};
|
||||||
|
final signature = await sub.signDatapod(hashDoc, address);
|
||||||
|
|
||||||
|
return <String, dynamic>{
|
||||||
|
...messageToSign,
|
||||||
|
'hash': hashDoc,
|
||||||
|
'signature': signature
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<QueryResult?> _execQuery(
|
||||||
|
String query, Map<String, dynamic> variables) async {
|
||||||
|
//TODO: Switch to IPFS Datapod
|
||||||
|
return null;
|
||||||
|
// final QueryOptions options =
|
||||||
|
// QueryOptions(document: gql(query), variables: variables);
|
||||||
|
// return await datapodClient.query(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> updateProfile(
|
||||||
|
{required String address,
|
||||||
|
String? title,
|
||||||
|
String? description,
|
||||||
|
String? avatar,
|
||||||
|
String? city,
|
||||||
|
List<Map<String, String>>? socials,
|
||||||
|
Map<String, double>? geoloc}) async {
|
||||||
|
final messageToSign = {
|
||||||
|
'address': address,
|
||||||
|
'description': description,
|
||||||
|
'avatarBase64': avatar,
|
||||||
|
'geoloc': geoloc,
|
||||||
|
'title': title,
|
||||||
|
'city': city,
|
||||||
|
'socials': socials
|
||||||
|
};
|
||||||
|
final variables = await _setSignedVariables(address, messageToSign);
|
||||||
|
if (variables.isEmpty) return false;
|
||||||
|
|
||||||
|
final result = await _execQuery(updateProfileQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
log.e(result?.exception.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.d(result!.data!['updateProfile']['message']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> deleteProfile({required String address}) async {
|
||||||
|
final messageToSign = {'address': address};
|
||||||
|
final variables = await _setSignedVariables(address, messageToSign);
|
||||||
|
if (variables.isEmpty) return false;
|
||||||
|
|
||||||
|
final result = await _execQuery(deleteProfileQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
log.e(result?.exception.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.d(result!.data!['deleteProfile']['message']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> migrateProfile(
|
||||||
|
{required String addressOld, required String addressNew}) async {
|
||||||
|
final messageToSign = {'addressOld': addressOld, 'addressNew': addressNew};
|
||||||
|
final variables = await _setSignedVariables(addressOld, messageToSign);
|
||||||
|
if (variables.isEmpty) return false;
|
||||||
|
|
||||||
|
final result = await _execQuery(migrateProfileQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
log.e(result?.exception.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.d(result!.data!['migrateProfile']['message']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> addTransactionComment({
|
||||||
|
required String id,
|
||||||
|
required String issuer,
|
||||||
|
required String comment,
|
||||||
|
}) async {
|
||||||
|
final messageToSign = {
|
||||||
|
'id': id,
|
||||||
|
'address': issuer,
|
||||||
|
'comment': comment,
|
||||||
|
};
|
||||||
|
final variables = await _setSignedVariables(issuer, messageToSign);
|
||||||
|
if (variables.isEmpty) return false;
|
||||||
|
|
||||||
|
final result = await _execQuery(addTransactionCommentQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
log.e(result?.exception.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.d(result!.data!['addTransaction']['message']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> setAvatar(String address, String avatarPath) async {
|
||||||
|
final avatarBytes = await File(avatarPath).readAsBytes();
|
||||||
|
final avatarString = base64Encode(avatarBytes);
|
||||||
|
return await updateProfile(address: address, avatar: avatarString);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<DateTime?> profileEditedAt(String address) async {
|
||||||
|
final variables = <String, dynamic>{
|
||||||
|
'address': address,
|
||||||
|
};
|
||||||
|
final result = await _execQuery(profileEditedAtQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
// log.e(result?.exception.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String? profileDateData =
|
||||||
|
result!.data!['profiles_by_pk']?['updated_at'];
|
||||||
|
final profileDate =
|
||||||
|
profileDateData == null ? null : DateTime.tryParse(profileDateData);
|
||||||
|
return profileDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Image> getRemoteAvatar(String address,
|
||||||
|
{double size = 20, String? uuid}) async {
|
||||||
|
final variables = <String, dynamic>{
|
||||||
|
'address': address,
|
||||||
|
};
|
||||||
|
final result = await _execQuery(getAvatarQ, variables);
|
||||||
|
if (result?.hasException ?? true) {
|
||||||
|
log.e(result?.exception.toString());
|
||||||
|
return defaultAvatar(size);
|
||||||
|
}
|
||||||
|
final String? avatar64 = result!.data!['profiles_by_pk']?['avatar64'];
|
||||||
|
|
||||||
|
if (avatar64 == null) {
|
||||||
|
return defaultAvatar(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
final sanitizedAvatar64 =
|
||||||
|
avatar64.replaceAll('\n', '').replaceAll('\r', '').replaceAll(' ', '');
|
||||||
|
|
||||||
|
log.d('We save avatar for $address');
|
||||||
|
await saveAvatar(address, sanitizedAvatar64, uuid);
|
||||||
|
|
||||||
|
return Image.memory(
|
||||||
|
base64.decode(sanitizedAvatar64),
|
||||||
|
height: size,
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<File> saveAvatar(String address, String data, String? uuid) async {
|
||||||
|
uuid = uuid ?? const Uuid().v4();
|
||||||
|
final file = File('${avatarsDirectory.path}/$address-$uuid');
|
||||||
|
return await file.writeAsBytes(base64.decode(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<File> cacheAvatar(String address, String data) async {
|
||||||
|
final uuid = const Uuid().v4();
|
||||||
|
final tempFile = File('${avatarsCacheDirectory.path}/$uuid$address');
|
||||||
|
final targetFile = File('${avatarsCacheDirectory.path}/$address');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Write to a temporary file first to prevent data race
|
||||||
|
await tempFile.writeAsBytes(base64.decode(data));
|
||||||
|
log.d('Caching avatar of $address');
|
||||||
|
return await tempFile.rename(targetFile.path);
|
||||||
|
} catch (e) {
|
||||||
|
log.e("An error occurred while caching avatar: $e");
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image getAvatarLocal(String address) {
|
||||||
|
final avatarFile = File('${avatarsCacheDirectory.path}/$address');
|
||||||
|
return Image.file(
|
||||||
|
avatarFile,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Image defaultAvatar(double size) =>
|
||||||
|
Image.asset(('assets/icon_user.png'), height: scaleSize(size));
|
||||||
|
|
||||||
|
Future deleteAvatarsCacheDirectory() async {
|
||||||
|
if (await avatarsCacheDirectory.exists()) {
|
||||||
|
await avatarsCacheDirectory.delete(recursive: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future deleteAvatarsDirectory() async {
|
||||||
|
if (await avatarsDirectory.exists()) {
|
||||||
|
await avatarsDirectory.delete(recursive: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,29 +11,26 @@ 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/providers/v2s_datapod.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/widgets/commons/common_elements.dart';
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
|
||||||
import 'package:gecko/screens/transaction_in_progress.dart';
|
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';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class WalletOptionsProvider with ChangeNotifier {
|
class WalletOptionsProvider with ChangeNotifier {
|
||||||
TextEditingController address = TextEditingController();
|
final address = TextEditingController();
|
||||||
final TextEditingController _newWalletName = TextEditingController();
|
final _newWalletName = TextEditingController();
|
||||||
bool isWalletUnlock = false;
|
bool isWalletUnlock = false;
|
||||||
bool ischangedPin = false;
|
bool ischangedPin = false;
|
||||||
TextEditingController newPin = TextEditingController();
|
final newPin = TextEditingController();
|
||||||
bool isEditing = false;
|
bool isEditing = false;
|
||||||
bool isBalanceBlur = false;
|
bool isBalanceBlur = false;
|
||||||
FocusNode walletNameFocus = FocusNode();
|
final nameController = TextEditingController();
|
||||||
TextEditingController nameController = TextEditingController();
|
|
||||||
late bool isDefaultWallet;
|
late bool isDefaultWallet;
|
||||||
bool canValidateNameBool = false;
|
bool canValidateNameBool = false;
|
||||||
Map<String, String> idtyStatusCache = {};
|
Map<String, double> balanceCache = {};
|
||||||
Future<NewWallet>? get badWallet => null;
|
|
||||||
|
|
||||||
int getPinLenght(walletNbr) {
|
int getPinLenght(walletNbr) {
|
||||||
return pinLength;
|
return pinLength;
|
||||||
|
@ -51,27 +48,34 @@ 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 datapod = Provider.of<V2sDatapodProvider>(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!);
|
if (balanceCache[wallet.address] != 0) {
|
||||||
if (balance != {}) {
|
final myWalletProvider =
|
||||||
MyWalletsProvider 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);
|
|
||||||
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.address);
|
||||||
await sub.deleteAccounts([wallet.address!]);
|
if (wallet.imageCustomPath != null) {
|
||||||
|
final avatarFile = File(wallet.imageCustomPath!);
|
||||||
|
if (await avatarFile.exists()) {
|
||||||
|
await avatarFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datapod.deleteProfile(address: wallet.address);
|
||||||
|
await sub.deleteAccounts([wallet.address]);
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
@ -84,14 +88,15 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> changeAvatar() async {
|
Future<String> changeAvatar() async {
|
||||||
// File _image;
|
final datapod = Provider.of<V2sDatapodProvider>(homeContext, listen: false);
|
||||||
|
|
||||||
final picker = ImagePicker();
|
final picker = ImagePicker();
|
||||||
|
|
||||||
XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
|
XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
|
||||||
|
|
||||||
if (pickedFile != null) {
|
if (pickedFile != null) {
|
||||||
File imageFile = File(pickedFile.path);
|
File imageFile = File(pickedFile.path);
|
||||||
if (!await imageDirectory.exists()) {
|
if (!await avatarsDirectory.exists()) {
|
||||||
log.e("Image folder doesn't exist");
|
log.e("Image folder doesn't exist");
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -114,17 +119,31 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
final newPath = "${imageDirectory.path}/${pickedFile.name}";
|
final avatarUuid = const Uuid().v4();
|
||||||
|
final newPath = "${avatarsDirectory.path}/${address.text}-$avatarUuid";
|
||||||
|
|
||||||
if (croppedFile != null) {
|
if (croppedFile == null) {
|
||||||
await File(croppedFile.path).rename(newPath);
|
|
||||||
} else {
|
|
||||||
log.w('No image selected.');
|
log.w('No image selected.');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
// await imageFile.copy(newPath);
|
|
||||||
|
|
||||||
log.i(newPath);
|
await File(croppedFile.path).rename(newPath);
|
||||||
|
|
||||||
|
final walletData =
|
||||||
|
MyWalletsProvider().getWalletDataByAddress(address.text);
|
||||||
|
|
||||||
|
if (walletData!.imageCustomPath != null) {
|
||||||
|
final avatarFile = File(walletData.imageCustomPath!);
|
||||||
|
await avatarFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
walletData.profileUpdatedTime = DateTime.now();
|
||||||
|
walletData.imageCustomPath = newPath;
|
||||||
|
|
||||||
|
await walletBox.put(address.text, walletData);
|
||||||
|
notifyListeners();
|
||||||
|
datapod.setAvatar(address.text, newPath);
|
||||||
|
|
||||||
return newPath;
|
return newPath;
|
||||||
} else {
|
} else {
|
||||||
log.w('No image selected.');
|
log.w('No image selected.');
|
||||||
|
@ -132,107 +151,27 @@ 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();
|
final 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);
|
||||||
|
final duniterIndexer = Provider.of<DuniterIndexer>(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,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text(
|
title: Text(
|
||||||
'confirmYourIdentity'.tr(),
|
'confirmYourIdentity'.tr(),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
|
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
height: 100,
|
height: 100,
|
||||||
|
@ -240,7 +179,15 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
TextField(
|
TextField(
|
||||||
key: keyEnterIdentityUsername,
|
key: keyEnterIdentityUsername,
|
||||||
onChanged: (_) => notifyListeners(),
|
onChanged: (_) async {
|
||||||
|
idtyExist = await duniterIndexer.isIdtyExist(idtyName.text);
|
||||||
|
canValidate = !idtyExist &&
|
||||||
|
!await duniterIndexer.isIdtyExist(idtyName.text) &&
|
||||||
|
idtyName.text.length >= 2 &&
|
||||||
|
idtyName.text.length <= 32;
|
||||||
|
|
||||||
|
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'^ ')),
|
||||||
|
@ -249,8 +196,13 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
controller: idtyName,
|
controller: idtyName,
|
||||||
style: const TextStyle(fontSize: 19),
|
style: const TextStyle(fontSize: 17),
|
||||||
)
|
),
|
||||||
|
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 +213,53 @@ 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) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
|
|
||||||
|
final wallet = myWalletProvider
|
||||||
|
.getWalletDataByAddress(address.text);
|
||||||
|
await sub.setCurrentWallet(wallet!);
|
||||||
|
final transactionId = await sub.confirmIdentity(
|
||||||
|
walletOptions.address.text,
|
||||||
|
idtyName.text,
|
||||||
|
myWalletProvider.pinCode);
|
||||||
|
Navigator.pop(context);
|
||||||
|
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) {
|
||||||
|
return TransactionInProgress(
|
||||||
|
transactionId: transactionId,
|
||||||
|
transType: 'comfirmIdty',
|
||||||
|
fromAddress: getShortPubkey(wallet.address),
|
||||||
|
toAddress: getShortPubkey(wallet.address),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: null,
|
||||||
child: Text(
|
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)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -323,7 +267,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> editWalletName(BuildContext context, List<int?> wID) async {
|
Future<String?> editWalletName(BuildContext context, List<int?> wID) async {
|
||||||
TextEditingController walletName = TextEditingController();
|
final walletName = TextEditingController();
|
||||||
canValidateNameBool = false;
|
canValidateNameBool = false;
|
||||||
|
|
||||||
return showDialog<String>(
|
return showDialog<String>(
|
||||||
|
@ -371,7 +315,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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -404,8 +348,8 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canValidateName(BuildContext context, TextEditingController walletName) {
|
bool canValidateName(BuildContext context, final 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 &&
|
||||||
|
@ -436,204 +380,4 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
await configBox.put('isCacheChecked', !isCacheChecked);
|
await configBox.put('isCacheChecked', !isCacheChecked);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getAddress(int chest, int derivation) {
|
|
||||||
String? addressGet;
|
|
||||||
walletBox.toMap().forEach((key, value) {
|
|
||||||
if (value.chest == chest && value.derivation == derivation) {
|
|
||||||
addressGet = value.address!;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
address.text = 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));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
|
// 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/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/models/scale_functions.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/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:barcode_scan2/barcode_scan2.dart';
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -25,8 +22,8 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
bool isHistoryScreen = false;
|
bool isHistoryScreen = false;
|
||||||
String historySwitchButtun = "Voir l'historique";
|
String historySwitchButtun = "Voir l'historique";
|
||||||
String? rawSvg;
|
String? rawSvg;
|
||||||
TextEditingController payAmount = TextEditingController();
|
final payAmount = TextEditingController();
|
||||||
TextEditingController payComment = TextEditingController();
|
final payComment = TextEditingController();
|
||||||
num? _balance;
|
num? _balance;
|
||||||
|
|
||||||
Future<String> scan(context) async {
|
Future<String> scan(context) async {
|
||||||
|
@ -37,14 +34,22 @@ 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 (await isAddress(barcode.rawContent)) {
|
||||||
|
address = barcode.rawContent;
|
||||||
|
Navigator.popUntil(
|
||||||
|
context,
|
||||||
|
ModalRoute.withName('/'),
|
||||||
|
);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
return WalletViewScreen(address: barcode!.rawContent);
|
return WalletViewScreen(
|
||||||
|
address: barcode!.rawContent,
|
||||||
|
username: null,
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,51 +58,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
return barcode.rawContent;
|
return barcode.rawContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<String> pay(BuildContext context, {int? derivation}) async {
|
|
||||||
// MyWalletsProvider _myWalletProvider =
|
|
||||||
// Provider.of<MyWalletsProvider>(context, listen: false);
|
|
||||||
// int? currentChest = configBox.get('currentChest');
|
|
||||||
// String result;
|
|
||||||
|
|
||||||
// derivation ??=
|
|
||||||
// _myWalletProvider.getDefaultWallet(currentChest)!.derivation!;
|
|
||||||
// result = await Gva(node: endPointGVA).pay(
|
|
||||||
// recipient: pubkey!,
|
|
||||||
// amount: double.parse(payAmount.text),
|
|
||||||
// mnemonic: _myWalletProvider.mnemonic,
|
|
||||||
// comment: payComment.text,
|
|
||||||
// derivation: derivation,
|
|
||||||
// lang: appLang);
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool isAddress(address) {
|
|
||||||
final RegExp regExp = RegExp(
|
|
||||||
r'^[a-zA-Z0-9]+$',
|
|
||||||
caseSensitive: false,
|
|
||||||
multiLine: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (regExp.hasMatch(address) == true &&
|
|
||||||
address.length > 45 &&
|
|
||||||
address.length < 52) {
|
|
||||||
log.d("C'est une adresse !");
|
|
||||||
|
|
||||||
this.address = address;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// poka: Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P
|
|
||||||
// Pi: D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU // For debug
|
|
||||||
// Boris: JE6mkuzSpT3ePciCPRTpuMT9fqPUVVLJz2618d33p7tn
|
|
||||||
// Matograine portefeuille: 9p5nHsES6xujFR7pw2yGy4PLKKHgWsMvsDHaHF64Uj25.
|
|
||||||
// Lion simone: 78jhpprYkMNF6i5kQPXfkAVBpd2aqcpieNsXTSW4c21f
|
|
||||||
|
|
||||||
void resetdHistory() {
|
void resetdHistory() {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -106,21 +66,6 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
return Jdenticon.toSvg(pubkey);
|
return Jdenticon.toSvg(pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<num> getBalance(String _pubkey) async {
|
|
||||||
// final url = Uri.parse(
|
|
||||||
// '$endPointGVA?query={%20balance(script:%20%22$_pubkey%22)%20{%20amount%20base%20}%20}');
|
|
||||||
// final response = await http.get(url);
|
|
||||||
// final result = json.decode(response.body);
|
|
||||||
|
|
||||||
// if (result['data']['balance'] == null) {
|
|
||||||
// balance = 0.0;
|
|
||||||
// } else {
|
|
||||||
// balance = removeDecimalZero(result['data']['balance']['amount'] / 100);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return balance;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Future<num?> getBalance(String? pubkey) async {
|
Future<num?> getBalance(String? pubkey) async {
|
||||||
while (_balance == null) {
|
while (_balance == null) {
|
||||||
await Future.delayed(const Duration(milliseconds: 50));
|
await Future.delayed(const Duration(milliseconds: 50));
|
||||||
|
@ -129,112 +74,18 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future addContact(G1WalletsList profile) async {
|
Future addContact(G1WalletsList profile) async {
|
||||||
// log.d(profile.username);
|
|
||||||
if (isContact(profile.address)) {
|
if (isContact(profile.address)) {
|
||||||
await contactsBox.delete(profile.address);
|
await contactsBox.delete(profile.address);
|
||||||
|
snackMessage(homeContext,
|
||||||
|
message: 'removedFromcontacts'.tr(), duration: 4);
|
||||||
} else {
|
} else {
|
||||||
await contactsBox.put(profile.address, profile);
|
await contactsBox.put(profile.address, profile);
|
||||||
|
snackMessage(homeContext, message: 'addedToContacts'.tr(), duration: 4);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -244,11 +95,57 @@ class WalletsProfilesProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bool isAddress(address) {
|
||||||
|
// final RegExp regExp = RegExp(
|
||||||
|
// r'^[a-zA-Z0-9]+$',
|
||||||
|
// caseSensitive: false,
|
||||||
|
// multiLine: false,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// if (regExp.hasMatch(address) == true &&
|
||||||
|
// address.length > 45 &&
|
||||||
|
// address.length < 52) {
|
||||||
|
// return true;
|
||||||
|
// } else {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<bool> isAddress(String address) async {
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
return await sub.sdk.api.account
|
||||||
|
.checkAddressFormat(address, sub.initSs58)
|
||||||
|
.timeout(const Duration(milliseconds: 300))
|
||||||
|
.onError((_, __) => false) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
snackMessage(context,
|
||||||
|
{required String message, int duration = 2, double fontSize = 14}) {
|
||||||
|
final snackBar = SnackBar(
|
||||||
|
backgroundColor: Colors.grey[900],
|
||||||
|
padding: EdgeInsets.all(scaleSize(19)),
|
||||||
|
content: Text(message, style: scaledTextStyle(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),
|
backgroundColor: Colors.grey[900],
|
||||||
|
padding: EdgeInsets.all(scaleSize(19)),
|
||||||
content: Text("thisAddressHasBeenCopiedToClipboard".tr(),
|
content: Text("thisAddressHasBeenCopiedToClipboard".tr(),
|
||||||
style: const TextStyle(fontSize: 16)),
|
style: scaledTextStyle(fontSize: 14)),
|
||||||
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(
|
||||||
|
backgroundColor: Colors.grey[900],
|
||||||
|
padding: EdgeInsets.all(scaleSize(19)),
|
||||||
|
content: Text("thisMnemonicHasBeenCopiedToClipboard".tr(),
|
||||||
|
style: scaledTextStyle(fontSize: 14)),
|
||||||
|
duration: const Duration(seconds: 4));
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
|
}
|
||||||
|
|
|
@ -1,365 +1,57 @@
|
||||||
// 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/scale_functions.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/providers/duniter_indexer.dart';
|
||||||
import 'package:graphql_flutter/graphql_flutter.dart';
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:gecko/widgets/bottom_app_bar.dart';
|
||||||
|
import 'package:gecko/widgets/header_profile.dart';
|
||||||
|
import 'package:gecko/widgets/history_query.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ActivityScreen extends StatelessWidget with ChangeNotifier {
|
class ActivityScreen extends StatefulWidget {
|
||||||
ActivityScreen({required this.address, required this.avatar, this.username})
|
const ActivityScreen({required this.address, 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;
|
|
||||||
|
|
||||||
FetchMore? fetchMore;
|
@override
|
||||||
FetchMoreOptions? opts;
|
State<ActivityScreen> createState() => _ActivityScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
class _ActivityScreenState extends State<ActivityScreen> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
final sub = Provider.of<SubstrateSdk>(homeContext, listen: false);
|
||||||
|
sub.getOldOwnerKey(widget.address);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: true);
|
||||||
WalletsProfilesProvider walletProfile =
|
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: false);
|
|
||||||
HomeProvider homeProvider =
|
|
||||||
Provider.of<HomeProvider>(context, listen: false);
|
|
||||||
|
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
key: _scaffoldKey,
|
onPopInvoked: (_) {
|
||||||
appBar: AppBar(
|
duniterIndexer.refetch = duniterIndexer.transBC = null;
|
||||||
elevation: 0,
|
},
|
||||||
toolbarHeight: 60 * ratio,
|
child: Scaffold(
|
||||||
title: SizedBox(
|
appBar: AppBar(
|
||||||
height: 22,
|
elevation: 0,
|
||||||
child: Text('accountActivity'.tr()),
|
toolbarHeight: scaleSize(57),
|
||||||
),
|
title: Text(
|
||||||
),
|
'accountActivity'.tr(),
|
||||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
style: scaledTextStyle(fontSize: 18),
|
||||||
body: Column(children: <Widget>[
|
|
||||||
walletProfile.headerProfileView(context, address, username),
|
|
||||||
historyQuery(context),
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|
||||||
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(
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
padding: const EdgeInsets.only(right: 0),
|
body: Column(children: <Widget>[
|
||||||
child:
|
HeaderProfile(address: widget.address, username: widget.username),
|
||||||
// Row(children: [Column(children: [],)],)
|
HistoryQuery(address: widget.address),
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
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/models/scale_functions.dart';
|
||||||
|
import 'package:gecko/widgets/certs_list.dart';
|
||||||
|
import 'package:gecko/widgets/certs_counter.dart';
|
||||||
|
import 'package:accordion/accordion.dart';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.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: GeckoAppBar('certificationsOf'.tr(args: [username])),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Accordion(
|
||||||
|
paddingListTop: 7,
|
||||||
|
paddingListBottom: 10,
|
||||||
|
maxOpenSections: 1,
|
||||||
|
headerBackgroundColorOpened: orangeC,
|
||||||
|
scaleWhenAnimating: true,
|
||||||
|
openAndCloseAnimation: true,
|
||||||
|
headerPadding: EdgeInsets.symmetric(
|
||||||
|
vertical: scaleSize(6), horizontal: scaleSize(14)),
|
||||||
|
sectionOpeningHapticFeedback: SectionHapticFeedback.heavy,
|
||||||
|
sectionClosingHapticFeedback: SectionHapticFeedback.light,
|
||||||
|
children: [
|
||||||
|
AccordionSection(
|
||||||
|
isOpen: true,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.insights_rounded,
|
||||||
|
color: Colors.black,
|
||||||
|
size: scaleSize(20),
|
||||||
|
),
|
||||||
|
headerBackgroundColor: yellowC,
|
||||||
|
headerBackgroundColorOpened: orangeC,
|
||||||
|
header: Row(children: [
|
||||||
|
Text(
|
||||||
|
'received'.tr(),
|
||||||
|
style: scaledTextStyle(fontSize: 17),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(width: 5),
|
||||||
|
CertsCounter(address: address)
|
||||||
|
]),
|
||||||
|
content: CertsList(
|
||||||
|
address: address, direction: CertDirection.received),
|
||||||
|
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(),
|
||||||
|
style: scaledTextStyle(fontSize: 17),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(width: 5),
|
||||||
|
CertsCounter(address: address, isSent: true)
|
||||||
|
]),
|
||||||
|
content: CertsList(
|
||||||
|
address: address,
|
||||||
|
direction: CertDirection.sent,
|
||||||
|
),
|
||||||
|
contentHorizontalPadding: 0,
|
||||||
|
contentBorderWidth: 1,
|
||||||
|
// onOpenSection: () => print('onOpenSection ...'),
|
||||||
|
// onCloseSection: () => print('onCloseSection ...'),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
// }),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:gecko/globals.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gecko/models/scale_functions.dart';
|
||||||
|
import 'package:gecko/providers/substrate_sdk.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class DebugScreen extends StatelessWidget {
|
||||||
|
const DebugScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final sub = Provider.of<SubstrateSdk>(context);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
appBar: AppBar(
|
||||||
|
toolbarHeight: scaleSize(57), title: const Text('Debug screen')),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
Center(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'node: ${sub.getConnectedEndpoint()}',
|
||||||
|
style: TextStyle(fontSize: 15, color: Colors.grey[700]),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Text(
|
||||||
|
'blockN'.tr(args: [
|
||||||
|
sub.blocNumber.toString()
|
||||||
|
]), //'bloc N°${sub.blocNumber}',
|
||||||
|
style: TextStyle(fontSize: 15, color: Colors.grey[700]),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
SizedBox(
|
||||||
|
height: 50,
|
||||||
|
width: 210,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
|
),
|
||||||
|
onPressed: () async => await sub.spawnBlock(),
|
||||||
|
child: const Text(
|
||||||
|
'Spawn a bloc',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 17, fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,194 +1,155 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
|
||||||
|
|
||||||
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: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/scale_functions.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';
|
||||||
import 'package:gecko/providers/home.dart';
|
import 'package:gecko/providers/home.dart';
|
||||||
import 'package:gecko/providers/substrate_sdk.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/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/providers/v2s_datapod.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/widgets/bubble_speak.dart';
|
||||||
|
import 'package:gecko/widgets/commons/animated_text.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/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/widgets/drawer.dart';
|
||||||
import 'package:gecko/screens/settings.dart';
|
import 'package:gecko/widgets/buttons/home_buttons.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:graphql_flutter/graphql_flutter.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';
|
|
||||||
|
|
||||||
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 homeProvider = 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 datapod = Provider.of<V2sDatapodProvider>(context, listen: false);
|
||||||
|
|
||||||
|
final bool isWalletsExists = myWalletProvider.isWalletsExists();
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
await datapod.deleteAvatarsDirectory();
|
||||||
|
await avatarsDirectory.create();
|
||||||
|
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');
|
||||||
|
await datapod.deleteAvatarsCacheDirectory();
|
||||||
|
await avatarsCacheDirectory.create();
|
||||||
|
g1WalletsBox = await Hive.openBox<G1WalletsList>("g1WalletsBox");
|
||||||
|
contactsBox = await Hive.openBox<G1WalletsList>("contactsBox");
|
||||||
|
|
||||||
|
homeProvider.isWalletBoxInit = true;
|
||||||
|
myWalletProvider.reload();
|
||||||
|
|
||||||
|
duniterIndexer.getValidIndexerEndpoint().then((validIndexerEndpoint) {
|
||||||
|
final wsLinkIndexer = WebSocketLink(
|
||||||
|
'wss://$validIndexerEndpoint/v1beta1/relay',
|
||||||
|
);
|
||||||
|
|
||||||
|
// const headerWebsocket =
|
||||||
|
// datapodEndpoint == '10.0.2.2:8080' ? 'ws' : 'wss';
|
||||||
|
// final wsLinkDatapod = WebSocketLink(
|
||||||
|
// '$headerWebsocket://$datapodEndpoint/v1/graphql',
|
||||||
|
// );
|
||||||
|
|
||||||
|
duniterIndexer.indexerClient = GraphQLClient(
|
||||||
|
cache: GraphQLCache(),
|
||||||
|
link: wsLinkIndexer,
|
||||||
|
);
|
||||||
|
|
||||||
|
// datapod.datapodClient = GraphQLClient(
|
||||||
|
// cache: GraphQLCache(),
|
||||||
|
// link: wsLinkDatapod,
|
||||||
|
// );
|
||||||
|
});
|
||||||
|
|
||||||
|
await homeProvider.getValidEndpoints();
|
||||||
|
if (configBox.get('isCacheChecked') == null) {
|
||||||
|
configBox.put('isCacheChecked', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connectivity()
|
||||||
|
.onConnectivityChanged
|
||||||
|
.listen((ConnectivityResult result) async {
|
||||||
|
log.i('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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
homeContext = context;
|
homeContext = context;
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
|
||||||
MyWalletsProvider myWalletProvider =
|
final myWalletProvider = Provider.of<MyWalletsProvider>(context);
|
||||||
Provider.of<MyWalletsProvider>(context);
|
|
||||||
Provider.of<ChestProvider>(context);
|
Provider.of<ChestProvider>(context);
|
||||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
final isWalletsExists = myWalletProvider.isWalletsExists();
|
||||||
|
|
||||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
isTall = (MediaQuery.of(context).size.height /
|
||||||
|
MediaQuery.of(context).size.width) >
|
||||||
|
1.75;
|
||||||
|
|
||||||
isTall = false;
|
|
||||||
ratio = 1;
|
|
||||||
if (MediaQuery.of(context).size.height >= 930) {
|
|
||||||
isTall = true;
|
|
||||||
ratio = 1.125;
|
|
||||||
}
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
drawer: Drawer(
|
drawer: MainDrawer(isWalletsExists: isWalletsExists),
|
||||||
child: Column(
|
backgroundColor: yellowC,
|
||||||
children: <Widget>[
|
body: isWalletsExists ? geckHome(context) : welcomeHome(context));
|
||||||
Expanded(
|
|
||||||
child: ListView(padding: EdgeInsets.zero, children: <Widget>[
|
|
||||||
DrawerHeader(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
color: orangeC,
|
|
||||||
),
|
|
||||||
child: Column(children: const <Widget>[
|
|
||||||
SizedBox(height: 0),
|
|
||||||
Image(
|
|
||||||
image: AssetImage('assets/icon/gecko_final.png'),
|
|
||||||
height: 130),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
key: keyParameters,
|
|
||||||
title: Text('parameters'.tr()),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return SettingsScreen();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
key: keyContacts,
|
|
||||||
title: Text('contactsManagement'.tr()),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const ContactsScreen();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
])),
|
|
||||||
Align(
|
|
||||||
alignment: FractionalOffset.bottomCenter,
|
|
||||||
child: Text('Ğecko v$appVersion')),
|
|
||||||
const SizedBox(height: 20)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// bottomNavigationBar: _homeProvider.bottomBar(context, 1),
|
|
||||||
backgroundColor: const Color(0xffF9F9F1),
|
|
||||||
body: Builder(
|
|
||||||
builder: (ctx) => StatefulWrapper(
|
|
||||||
onInit: () {
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
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);
|
|
||||||
Provider.of<ChestProvider>(context);
|
Provider.of<ChestProvider>(context);
|
||||||
|
|
||||||
WalletsProfilesProvider historyProvider =
|
final statusBarHeight = MediaQuery.of(context).padding.top;
|
||||||
Provider.of<WalletsProfilesProvider>(context);
|
|
||||||
final double statusBarHeight = MediaQuery.of(context).padding.top;
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
|
@ -200,42 +161,43 @@ Widget geckHome(context) {
|
||||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
|
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
|
||||||
Stack(children: <Widget>[
|
Stack(children: <Widget>[
|
||||||
Positioned(
|
Positioned(
|
||||||
top: statusBarHeight + 10,
|
top: statusBarHeight + scaleSize(10),
|
||||||
left: 15,
|
left: scaleSize(15),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) => IconButton(
|
builder: (context) => IconButton(
|
||||||
key: keyDrawerMenu,
|
key: keyDrawerMenu,
|
||||||
icon: const Icon(
|
icon: Icon(
|
||||||
Icons.menu,
|
Icons.menu,
|
||||||
color: Colors.white,
|
color: Colors.black,
|
||||||
size: 35,
|
size: scaleSize(35),
|
||||||
),
|
),
|
||||||
onPressed: () => Scaffold.of(context).openDrawer(),
|
onPressed: () => Scaffold.of(context).openDrawer(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Align(
|
Align(
|
||||||
child:
|
child: Image(
|
||||||
Image(image: AssetImage('assets/home/header.png'), height: 210),
|
image: const AssetImage('assets/home/header.png'),
|
||||||
|
height: scaleSize(165)),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 15 * ratio),
|
padding: const EdgeInsets.only(top: 15),
|
||||||
child:
|
child:
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
||||||
DefaultTextStyle(
|
DefaultTextStyle(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 24,
|
fontSize: 19,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
shadows: <Shadow>[
|
shadows: <Shadow>[
|
||||||
Shadow(
|
const Shadow(
|
||||||
offset: Offset(0, 0),
|
offset: Offset(0, 0),
|
||||||
blurRadius: 20,
|
blurRadius: 20,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
Shadow(
|
const Shadow(
|
||||||
offset: Offset(0, 0),
|
offset: Offset(0, 0),
|
||||||
blurRadius: 20,
|
blurRadius: 20,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
@ -252,7 +214,7 @@ Widget geckHome(context) {
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
ScaledSizedBox(height: 15),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -266,167 +228,7 @@ Widget geckHome(context) {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Column(children: <Widget>[
|
child: const HomeButtons(),
|
||||||
const Spacer(),
|
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
|
||||||
Column(children: <Widget>[
|
|
||||||
Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Colors.black,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: Offset(1, 1.5),
|
|
||||||
spreadRadius: 0.5)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: ClipOval(
|
|
||||||
child: Material(
|
|
||||||
color: orangeC, // button color
|
|
||||||
child: InkWell(
|
|
||||||
key: keyOpenSearch,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(18),
|
|
||||||
child: Image(
|
|
||||||
image:
|
|
||||||
const AssetImage('assets/home/loupe.png'),
|
|
||||||
height: 62 * ratio),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const SearchScreen();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Text(
|
|
||||||
"searchWallet".tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 15 * ratio,
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
const SizedBox(width: 120),
|
|
||||||
Column(children: <Widget>[
|
|
||||||
Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Colors.black,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: Offset(1, 1.5),
|
|
||||||
spreadRadius: 0.5)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: ClipOval(
|
|
||||||
key: keyOpenWalletsHomme,
|
|
||||||
child: Material(
|
|
||||||
color: orangeC, // button color
|
|
||||||
child: InkWell(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(18),
|
|
||||||
child: Image(
|
|
||||||
image: const AssetImage(
|
|
||||||
'assets/home/wallet.png'),
|
|
||||||
height: 68 * ratio)),
|
|
||||||
onTap: () async {
|
|
||||||
WalletData? defaultWallet =
|
|
||||||
myWalletProvider.getDefaultWallet();
|
|
||||||
String? pin;
|
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(
|
|
||||||
wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const WalletsHome();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// log.d(_myWalletProvider.pinCode);
|
|
||||||
|
|
||||||
// Navigator.pushNamed(
|
|
||||||
// context, '/mywallets')));
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Text(
|
|
||||||
"manageWallets".tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 15 * ratio,
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
)
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(top: 35 * ratio),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Column(children: <Widget>[
|
|
||||||
Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Colors.black,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
blurRadius: 2,
|
|
||||||
offset: Offset(1, 1.5),
|
|
||||||
spreadRadius: 0.5)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: ClipOval(
|
|
||||||
child: Material(
|
|
||||||
color: orangeC, // button color
|
|
||||||
child: InkWell(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(18),
|
|
||||||
child: Image(
|
|
||||||
image: const AssetImage(
|
|
||||||
'assets/home/qrcode.png'),
|
|
||||||
height: 68 * ratio)),
|
|
||||||
onTap: () async {
|
|
||||||
await historyProvider.scan(context);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
Text(
|
|
||||||
"scanQRCode".tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 15 * ratio,
|
|
||||||
fontWeight: FontWeight.w500),
|
|
||||||
)
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
SizedBox(height: isTall ? 80 : 40)
|
|
||||||
]),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
|
@ -434,7 +236,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(
|
||||||
|
@ -447,37 +249,38 @@ Widget welcomeHome(context) {
|
||||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
|
Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
|
||||||
Stack(children: <Widget>[
|
Stack(children: <Widget>[
|
||||||
Positioned(
|
Positioned(
|
||||||
top: statusBarHeight + 10,
|
top: statusBarHeight + scaleSize(10),
|
||||||
left: 15,
|
left: scaleSize(15),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) => IconButton(
|
builder: (context) => IconButton(
|
||||||
key: keyDrawerMenu,
|
key: keyDrawerMenu,
|
||||||
icon: const Icon(
|
icon: Icon(
|
||||||
Icons.menu,
|
Icons.menu,
|
||||||
color: Colors.white,
|
color: Colors.black,
|
||||||
size: 35,
|
size: scaleSize(35),
|
||||||
),
|
),
|
||||||
onPressed: () => Scaffold.of(context).openDrawer(),
|
onPressed: () => Scaffold.of(context).openDrawer(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Align(
|
Align(
|
||||||
child:
|
child: Image(
|
||||||
Image(image: AssetImage('assets/home/header.png'), height: 210),
|
image: const AssetImage('assets/home/header.png'),
|
||||||
|
height: scaleSize(165)),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 1 * ratio),
|
padding: const EdgeInsets.only(top: 1),
|
||||||
child:
|
child:
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
"fastAppDescription".tr(args: [currencyName]),
|
"fastAppDescription".tr(args: [currencyName]),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 24,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
shadows: <Shadow>[
|
shadows: const <Shadow>[
|
||||||
Shadow(
|
Shadow(
|
||||||
offset: Offset(0, 0),
|
offset: Offset(0, 0),
|
||||||
blurRadius: 20,
|
blurRadius: 20,
|
||||||
|
@ -510,39 +313,35 @@ Widget welcomeHome(context) {
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 480),
|
constraints: const BoxConstraints(maxWidth: 480),
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
const Spacer(),
|
const Spacer(flex: 4),
|
||||||
Row(children: <Widget>[
|
Row(children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Stack(children: <Widget>[
|
child: Stack(children: <Widget>[
|
||||||
const Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 55),
|
padding: EdgeInsets.only(top: scaleSize(55)),
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage('assets/home/gecko-bienvenue.png'),
|
image: const AssetImage(
|
||||||
height: 220,
|
'assets/home/gecko-bienvenue.png'),
|
||||||
|
height: scaleSize(180),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 180,
|
left: scaleSize(160),
|
||||||
child: bubbleSpeak("noLizard".tr()),
|
top: 10,
|
||||||
),
|
child: BubbleSpeakWithTail(text: "noLizard".tr()),
|
||||||
const Positioned(
|
|
||||||
left: 200,
|
|
||||||
top: 60,
|
|
||||||
child: Image(
|
|
||||||
image: AssetImage('assets/home/bout_de_bulle.png'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 410,
|
width: 330,
|
||||||
height: 70,
|
height: 60,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyOnboardingNewChest,
|
key: keyOnboardingNewChest,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
@ -556,19 +355,21 @@ Widget welcomeHome(context) {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'createWallet'.tr(),
|
'createWallet'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 24, fontWeight: FontWeight.w600),
|
fontSize: 21,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 25 * ratio),
|
ScaledSizedBox(height: scaleSize(25)),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 410,
|
width: 330,
|
||||||
height: 70,
|
height: 60,
|
||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
key: keyRestoreChest,
|
key: keyRestoreChest,
|
||||||
style: OutlinedButton.styleFrom(
|
style: OutlinedButton.styleFrom(
|
||||||
side: const BorderSide(width: 4, color: orangeC)),
|
side: BorderSide(width: scaleSize(4), color: orangeC)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
|
@ -581,14 +382,14 @@ Widget welcomeHome(context) {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
"restoreWallet".tr(),
|
"restoreWallet".tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 24,
|
fontSize: 21,
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: isTall ? 100 : 50)
|
const Spacer(flex: 3),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -597,19 +398,3 @@ Widget welcomeHome(context) {
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget bubbleSpeak(String text, {double? long, Key? textKey}) {
|
|
||||||
return Bubble(
|
|
||||||
padding: long == null
|
|
||||||
? const BubbleEdges.all(20)
|
|
||||||
: BubbleEdges.symmetric(horizontal: long, vertical: 30),
|
|
||||||
elevation: 5,
|
|
||||||
color: backgroundColor,
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
key: textKey,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Colors.black, fontSize: 21, fontWeight: FontWeight.w400),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,17 +3,13 @@
|
||||||
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/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/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/widgets/commons/top_appbar.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,45 +18,35 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
||||||
final String? walletName;
|
final String? walletName;
|
||||||
final MyWalletsProvider walletProvider;
|
final MyWalletsProvider walletProvider;
|
||||||
|
|
||||||
final TextEditingController newPin = TextEditingController();
|
@override
|
||||||
|
State<ChangePinScreen> createState() => _ChangePinScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ChangePinScreenState extends State<ChangePinScreen> {
|
||||||
|
final 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 PopScope(
|
||||||
onWillPop: () {
|
onPopInvoked: (_) {
|
||||||
newPin.text = '';
|
newPin.text = '';
|
||||||
return Future<bool>.value(true);
|
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar(widget.walletName!),
|
||||||
elevation: 1,
|
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
|
||||||
onPressed: () {
|
|
||||||
newPin.text = '';
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}),
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(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(),
|
||||||
|
@ -99,31 +85,20 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier {
|
||||||
height: 50,
|
height: 50,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.black, elevation: 12,
|
foregroundColor: Colors.black,
|
||||||
backgroundColor: Colors.green[400], // foreground
|
elevation: 12,
|
||||||
|
backgroundColor: Colors.green[400],
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
WalletData defaultWallet =
|
final defaultWallet = myWalletProvider.getDefaultWallet();
|
||||||
myWalletProvider.getDefaultWallet();
|
|
||||||
|
|
||||||
String? pin;
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
await sub.changePassword(context, defaultWallet.address,
|
||||||
context,
|
widget.walletProvider.pinCode, newPin.text);
|
||||||
MaterialPageRoute(
|
widget.walletProvider.pinCode = newPin.text;
|
||||||
builder: (homeContext) {
|
newPin.text = '';
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
Navigator.pop(context);
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
|
||||||
await sub.changePassword(context, defaultWallet.address!,
|
|
||||||
walletProvider.pinCode, newPin.text);
|
|
||||||
walletProvider.pinCode = newPin.text;
|
|
||||||
newPin.text = '';
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'confirm'.tr(),
|
'confirm'.tr(),
|
||||||
|
|
|
@ -4,18 +4,16 @@ 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/scale_functions.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/widgets/bottom_app_bar.dart';
|
||||||
|
import 'package:gecko/widgets/commons/offline_info.dart';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ChestOptions extends StatelessWidget {
|
class ChestOptions extends StatelessWidget {
|
||||||
|
@ -25,132 +23,105 @@ 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'))!;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar(currentChest.name!),
|
||||||
elevation: 1,
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
// leading: IconButton(
|
|
||||||
// icon: const Icon(Icons.arrow_back, color: Colors.black),
|
|
||||||
// onPressed: () {
|
|
||||||
// // Navigator.popUntil(
|
|
||||||
// // context,
|
|
||||||
// // ModalRoute.withName('/mywallets'),
|
|
||||||
// // );
|
|
||||||
// Navigator.pop(context);
|
|
||||||
// }),
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(currentChest.name!),
|
|
||||||
)),
|
|
||||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
|
||||||
body: Stack(children: [
|
body: Stack(children: [
|
||||||
Builder(
|
Builder(
|
||||||
builder: (ctx) => SafeArea(
|
builder: (ctx) => SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 30 * ratio),
|
ScaledSizedBox(height: 20),
|
||||||
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 =
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
myWalletProvider.getDefaultWallet();
|
|
||||||
String? pin;
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pin != null) {
|
Navigator.push(
|
||||||
Navigator.push(
|
context,
|
||||||
context,
|
MaterialPageRoute(builder: (context) {
|
||||||
MaterialPageRoute(builder: (context) {
|
return ShowSeed(
|
||||||
return ShowSeed(
|
walletName: currentChest.name,
|
||||||
walletName: currentChest.name,
|
walletProvider: walletProvider,
|
||||||
walletProvider: walletProvider,
|
);
|
||||||
);
|
}),
|
||||||
}),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 60,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 20),
|
ScaledSizedBox(width: 20),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/onBoarding/phrase_de_restauration_flou.png',
|
'assets/onBoarding/phrase_de_restauration_flou.png',
|
||||||
width: 60,
|
width: scaleSize(60),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 15),
|
ScaledSizedBox(width: 13),
|
||||||
Text(
|
ScaledSizedBox(
|
||||||
'displayMnemonic'.tr(),
|
width: 270,
|
||||||
style: const TextStyle(
|
child: Text(
|
||||||
fontSize: 20,
|
'displayMnemonic'.tr(),
|
||||||
color: orangeC,
|
style: scaledTextStyle(
|
||||||
|
fontSize: 17,
|
||||||
|
color: orangeC,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 10 * ratio),
|
ScaledSizedBox(height: 2),
|
||||||
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: ScaledSizedBox(
|
||||||
height: 50,
|
height: 60,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 26),
|
ScaledSizedBox(width: 30),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/chests/secret_code.png',
|
'assets/chests/secret_code.png',
|
||||||
height: 25,
|
height: scaleSize(22),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 18),
|
ScaledSizedBox(width: 18),
|
||||||
Text(
|
Text(
|
||||||
'changePassword'.tr(),
|
'changePassword'.tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20,
|
fontSize: 17,
|
||||||
color: sub.nodeConnected
|
color: sub.nodeConnected
|
||||||
? Colors.black
|
? Colors.grey[500]
|
||||||
: Colors.grey[500]),
|
: Colors.grey[500]),
|
||||||
),
|
),
|
||||||
])),
|
])),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10 * ratio),
|
ScaledSizedBox(height: 2),
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
key: keycreateRootDerivation,
|
key: keycreateRootDerivation,
|
||||||
|
@ -166,19 +137,19 @@ class ChestOptions extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 60,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 35),
|
ScaledSizedBox(width: 37),
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.manage_accounts,
|
Icons.manage_accounts,
|
||||||
size: 33,
|
size: scaleSize(31),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 25),
|
ScaledSizedBox(width: 23),
|
||||||
Text(
|
Text(
|
||||||
'createDerivation'.tr(),
|
'createDerivation'.tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20,
|
fontSize: 17,
|
||||||
color: sub.nodeConnected
|
color: sub.nodeConnected
|
||||||
? Colors.black
|
? Colors.black
|
||||||
: Colors.grey[500]),
|
: Colors.grey[500]),
|
||||||
|
@ -187,26 +158,26 @@ class ChestOptions extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10 * ratio),
|
ScaledSizedBox(height: 2),
|
||||||
InkWell(
|
InkWell(
|
||||||
key: keyDeleteChest,
|
key: keyDeleteChest,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await chestProvider.deleteChest(context, currentChest);
|
await chestProvider.deleteChest(context, currentChest);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 60,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 28),
|
ScaledSizedBox(width: 32),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/walletOptions/trash.png',
|
'assets/walletOptions/trash.png',
|
||||||
height: 45,
|
height: scaleSize(38),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
ScaledSizedBox(width: 22),
|
||||||
Text(
|
Text(
|
||||||
'deleteChest'.tr(),
|
'deleteChest'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20,
|
fontSize: 17,
|
||||||
color: Color(0xffD80000),
|
color: const Color(0xffD80000),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -215,7 +186,7 @@ class ChestOptions extends StatelessWidget {
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CommonElements().offlineInfo(context),
|
const OfflineInfo(),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
// 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/scale_functions.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/models/wallet_data.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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:carousel_slider/carousel_slider.dart';
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
import 'package:gecko/screens/myWallets/wallets_home.dart';
|
|
||||||
import 'package:gecko/screens/onBoarding/5.dart';
|
import 'package:gecko/screens/onBoarding/5.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -24,27 +21,21 @@ class ChooseChest extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChooseChestState extends State<ChooseChest> {
|
class _ChooseChestState extends State<ChooseChest> {
|
||||||
TextEditingController tplController = TextEditingController();
|
final tplController = TextEditingController();
|
||||||
CarouselController buttonCarouselController = CarouselController();
|
CarouselController buttonCarouselController = CarouselController();
|
||||||
int? currentChest = configBox.get('currentChest');
|
int? currentChest = configBox.get('currentChest');
|
||||||
|
|
||||||
@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,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
toolbarHeight: 60 * ratio,
|
toolbarHeight: scaleSize(57), title: Text('selectMyChest'.tr())),
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('selectMyChest'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
SizedBox(height: 160 * ratio),
|
const SizedBox(height: 160),
|
||||||
CarouselSlider(
|
CarouselSlider(
|
||||||
carouselController: buttonCarouselController,
|
carouselController: buttonCarouselController,
|
||||||
options: CarouselOptions(
|
options: CarouselOptions(
|
||||||
|
@ -105,42 +96,25 @@ class _ChooseChestState extends State<ChooseChest> {
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
SizedBox(height: 80 * ratio),
|
const SizedBox(height: 80),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 70,
|
height: 70,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
backgroundColor: orangeC, // foreground
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await configBox.put('currentChest', currentChest);
|
await configBox.put('currentChest', currentChest);
|
||||||
myWalletProvider.pinCode = '';
|
myWalletProvider.pinCode = '';
|
||||||
WalletData? defaultWallet =
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
myWalletProvider.getDefaultWallet();
|
|
||||||
myWalletProvider.reload();
|
|
||||||
|
|
||||||
await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
Navigator.popUntil(
|
Navigator.popUntil(
|
||||||
context,
|
context,
|
||||||
ModalRoute.withName('/'),
|
ModalRoute.withName('/'),
|
||||||
);
|
);
|
||||||
if (myWalletProvider.pinCode != '') {
|
Navigator.pushNamed(context, '/mywallets');
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const WalletsHome();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'openThisChest'.tr(),
|
'openThisChest'.tr(),
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
// ignore_for_file: use_build_context_synchronously, must_be_immutable
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:gecko/globals.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
|
||||||
import 'package:gecko/models/widgets_keys.dart';
|
|
||||||
import 'package:gecko/providers/my_wallets.dart';
|
|
||||||
import 'package:gecko/providers/substrate_sdk.dart';
|
|
||||||
import 'package:gecko/providers/wallet_options.dart';
|
|
||||||
import 'package:gecko/screens/myWallets/wallets_home.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
// import 'package:gecko/models/home.dart';
|
|
||||||
// import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class ChooseWalletScreen extends StatelessWidget {
|
|
||||||
ChooseWalletScreen({Key? key, required this.pin}) : super(key: key);
|
|
||||||
final String pin;
|
|
||||||
WalletData? selectedWallet;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
|
||||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
|
||||||
final int chest = configBox.get('currentChest');
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
appBar: AppBar(
|
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('choiceOfSourceWallet'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Stack(children: [
|
|
||||||
myWalletsTiles(context, chest),
|
|
||||||
Positioned.fill(
|
|
||||||
bottom: 60,
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
child: SizedBox(
|
|
||||||
width: 470,
|
|
||||||
height: 70,
|
|
||||||
child: ElevatedButton(
|
|
||||||
key: keyConfirm,
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
|
||||||
backgroundColor: orangeC, // foreground
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
await sub.setCurrentWallet(selectedWallet!);
|
|
||||||
sub.reload();
|
|
||||||
|
|
||||||
// Navigator.pop(context);
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'chooseThisWallet'.tr(),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24, fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget myWalletsTiles(BuildContext context, int currentChest) {
|
|
||||||
MyWalletsProvider myWalletProvider =
|
|
||||||
Provider.of<MyWalletsProvider>(context);
|
|
||||||
// SubstrateSdk _sub = Provider.of<SubstrateSdk>(context, listen: false);
|
|
||||||
|
|
||||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
|
||||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
|
||||||
|
|
||||||
selectedWallet ??= defaultWallet;
|
|
||||||
myWalletProvider.readAllWallets(currentChest);
|
|
||||||
|
|
||||||
if (!isWalletsExists) {
|
|
||||||
return const Text('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myWalletProvider.listWallets.isEmpty) {
|
|
||||||
return Column(children: const <Widget>[
|
|
||||||
Center(
|
|
||||||
child: Text(
|
|
||||||
'Veuillez générer votre premier portefeuille',
|
|
||||||
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
|
|
||||||
)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
List listWallets = myWalletProvider.listWallets;
|
|
||||||
final double screenWidth = MediaQuery.of(context).size.width;
|
|
||||||
int nTule = 2;
|
|
||||||
|
|
||||||
if (screenWidth >= 900) {
|
|
||||||
nTule = 4;
|
|
||||||
} else if (screenWidth >= 650) {
|
|
||||||
nTule = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CustomScrollView(slivers: <Widget>[
|
|
||||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
|
||||||
SliverGrid.count(
|
|
||||||
key: keyListWallets,
|
|
||||||
crossAxisCount: nTule,
|
|
||||||
childAspectRatio: 1,
|
|
||||||
crossAxisSpacing: 0,
|
|
||||||
mainAxisSpacing: 0,
|
|
||||||
children: <Widget>[
|
|
||||||
for (WalletData repository in listWallets as Iterable<WalletData>)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
child: GestureDetector(
|
|
||||||
key: keySelectThisWallet(repository.address!),
|
|
||||||
onTap: () {
|
|
||||||
selectedWallet = repository;
|
|
||||||
myWalletProvider.reload();
|
|
||||||
},
|
|
||||||
child: ClipOvalShadow(
|
|
||||||
shadow: const Shadow(
|
|
||||||
color: Colors.transparent,
|
|
||||||
offset: Offset(0, 0),
|
|
||||||
blurRadius: 5,
|
|
||||||
),
|
|
||||||
clipper: CustomClipperOval(),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius:
|
|
||||||
const BorderRadius.all(Radius.circular(12)),
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: RadialGradient(
|
|
||||||
radius: 0.6,
|
|
||||||
colors: [
|
|
||||||
Colors.green[400]!,
|
|
||||||
const Color(0xFFE7E7A6),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
child: repository.imageCustomPath == null
|
|
||||||
? Image.asset(
|
|
||||||
'assets/avatars/${repository.imageDefaultPath}',
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
scale: 0.5,
|
|
||||||
)
|
|
||||||
: Container(
|
|
||||||
width: 120,
|
|
||||||
height: 120,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Colors.transparent,
|
|
||||||
image: DecorationImage(
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
image: FileImage(
|
|
||||||
File(repository.imageCustomPath!),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
balanceBuilder(context, repository.address!,
|
|
||||||
selectedWallet!.address == repository.address!),
|
|
||||||
ListTile(
|
|
||||||
shape: const RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.vertical(
|
|
||||||
bottom: Radius.circular(12),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
tileColor:
|
|
||||||
repository.address == selectedWallet!.address
|
|
||||||
? orangeC
|
|
||||||
: const Color(0xffFFD58D),
|
|
||||||
title: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding:
|
|
||||||
const EdgeInsets.symmetric(horizontal: 5),
|
|
||||||
child: Text(
|
|
||||||
repository.name!,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 17.0,
|
|
||||||
color: repository.address ==
|
|
||||||
selectedWallet!.address
|
|
||||||
? const Color(0xffF9F9F1)
|
|
||||||
: Colors.black,
|
|
||||||
fontStyle: FontStyle.italic),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onTap: () async {
|
|
||||||
selectedWallet = repository;
|
|
||||||
myWalletProvider.reload();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget balanceBuilder(context, String address, bool isDefault) {
|
|
||||||
return Container(
|
|
||||||
width: double.infinity,
|
|
||||||
color: isDefault ? orangeC : yellowC,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 30,
|
|
||||||
child: Column(children: [
|
|
||||||
const Spacer(),
|
|
||||||
// Text(
|
|
||||||
// '0.0 gd',
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
// style: TextStyle(color: isDefault ? Colors.white : Colors.black),
|
|
||||||
// ),
|
|
||||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
|
||||||
balance(
|
|
||||||
context, address, 16, isDefault ? Colors.white : Colors.black),
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,12 @@
|
||||||
// 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/scale_functions.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/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/widgets/commons/top_appbar.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class CustomDerivation extends StatefulWidget {
|
class CustomDerivation extends StatefulWidget {
|
||||||
|
@ -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>[
|
||||||
|
@ -36,9 +35,7 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
||||||
for (var i = 0; i < 51; i += 1) i.toString()
|
for (var i = 0; i < 51; i += 1) i.toString()
|
||||||
];
|
];
|
||||||
|
|
||||||
final listWallets = myWalletProvider.readAllWallets();
|
for (WalletData wallet in myWalletProvider.listWallets) {
|
||||||
|
|
||||||
for (WalletData wallet in listWallets) {
|
|
||||||
derivationList.remove(wallet.derivation.toString());
|
derivationList.remove(wallet.derivation.toString());
|
||||||
if (wallet.derivation == -1) {
|
if (wallet.derivation == -1) {
|
||||||
derivationList.remove('root');
|
derivationList.remove('root');
|
||||||
|
@ -51,28 +48,27 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('createCustomDerivation'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('createCustomDerivation'.tr()),
|
|
||||||
)),
|
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Text(
|
Text(
|
||||||
'chooseDerivation'.tr(),
|
'chooseDerivation'.tr(),
|
||||||
|
style: scaledTextStyle(fontSize: 17),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 100,
|
width: 100,
|
||||||
child: DropdownButton<String>(
|
child: DropdownButton<String>(
|
||||||
value: dropdownValue,
|
value: dropdownValue,
|
||||||
menuMaxHeight: 300,
|
menuMaxHeight: 300,
|
||||||
icon: const Icon(Icons.arrow_downward),
|
icon: Icon(
|
||||||
|
Icons.arrow_downward,
|
||||||
|
size: scaleSize(20),
|
||||||
|
),
|
||||||
elevation: 16,
|
elevation: 16,
|
||||||
style: const TextStyle(color: orangeC),
|
style: scaledTextStyle(color: orangeC),
|
||||||
underline: Container(
|
underline: Container(
|
||||||
height: 2,
|
height: 2,
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
|
@ -86,14 +82,14 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
||||||
.map<DropdownMenuItem<String>>((String value) {
|
.map<DropdownMenuItem<String>>((String value) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: value,
|
value: value,
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
width: 75,
|
width: 75,
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Text(
|
Text(
|
||||||
value,
|
value,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20, color: Colors.black),
|
fontSize: 17, color: Colors.black),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
]),
|
]),
|
||||||
|
@ -102,56 +98,38 @@ class _CustomDerivationState extends State<CustomDerivation> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(flex: 1),
|
const Spacer(flex: 1),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 410,
|
width: 240,
|
||||||
height: 70,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
WalletData? defaultWallet =
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
myWalletProvider.getDefaultWallet();
|
String newDerivationName =
|
||||||
String? pin;
|
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
|
||||||
if (myWalletProvider.pinCode == '') {
|
if (dropdownValue == 'root') {
|
||||||
pin = await Navigator.push(
|
await myWalletProvider.generateRootWallet(
|
||||||
|
context, 'rootWallet'.tr());
|
||||||
|
} else {
|
||||||
|
await myWalletProvider.generateNewDerivation(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
newDerivationName,
|
||||||
builder: (homeContext) {
|
int.parse(dropdownValue!),
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Navigator.popUntil(
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
context, ModalRoute.withName('/mywallets'));
|
||||||
String newDerivationName =
|
|
||||||
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
|
|
||||||
if (dropdownValue == 'root') {
|
|
||||||
await myWalletProvider.generateRootWallet(
|
|
||||||
context, 'Portefeuille racine');
|
|
||||||
} else {
|
|
||||||
await myWalletProvider.generateNewDerivation(
|
|
||||||
context,
|
|
||||||
newDerivationName,
|
|
||||||
int.parse(dropdownValue!),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.pop(context);
|
|
||||||
// Navigator.push(
|
|
||||||
// context,
|
|
||||||
// MaterialPageRoute(builder: (context) {
|
|
||||||
// return const WalletsHome();
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'validate'.tr(),
|
'validate'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 24, fontWeight: FontWeight.w600),
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,76 +1,60 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:async';
|
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/migrate_wallet_checks.dart';
|
||||||
|
import 'package:gecko/models/scale_functions.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/commons/top_appbar.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 {
|
||||||
const ImportG1v1({Key? key}) : super(key: key);
|
const ImportG1v1({Key? key}) : super(key: key);
|
||||||
|
static const int debouneTime = 600;
|
||||||
|
|
||||||
@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;
|
||||||
const int debouneTime = 300;
|
|
||||||
WalletData selectedWallet = myWalletProvider.getDefaultWallet();
|
WalletData selectedWallet = myWalletProvider.getDefaultWallet();
|
||||||
bool canValidate = false;
|
|
||||||
String validationStatus = '';
|
|
||||||
|
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () {
|
onPopInvoked: (_) {
|
||||||
resetScreen(context);
|
resetScreen(context);
|
||||||
return Future<bool>.value(true);
|
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('importOldAccount'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
|
||||||
onPressed: () {
|
|
||||||
resetScreen(context);
|
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}),
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('importOldAccount'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
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,
|
||||||
// log.d(_certs.data);
|
AsyncSnapshot<MigrateWalletChecks> status) {
|
||||||
|
|
||||||
if (status.data == null) {
|
if (status.data == null) {
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
const SizedBox(height: 80),
|
ScaledSizedBox(height: 80),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: const [
|
children: [
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
width: 35,
|
width: 35,
|
||||||
child: CircularProgressIndicator(
|
child: const CircularProgressIndicator(
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
strokeWidth: 4,
|
strokeWidth: 4,
|
||||||
),
|
),
|
||||||
|
@ -79,58 +63,38 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map balance = status.data?[0] ?? {};
|
final statusData = status.data!;
|
||||||
final String idtyStatus = status.data?[1];
|
|
||||||
final String myIdtyStatus = status.data?[2];
|
|
||||||
final bool hasConsumer = status.data?[3] ?? false;
|
|
||||||
|
|
||||||
// log.d('hasconsumer: $hasConsumer');
|
|
||||||
|
|
||||||
if (balance['transferableBalance'] != 0 && !hasConsumer) {
|
|
||||||
canValidate = true;
|
|
||||||
validationStatus = '';
|
|
||||||
} else {
|
|
||||||
canValidate = false;
|
|
||||||
validationStatus = hasConsumer
|
|
||||||
? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X'])
|
|
||||||
: 'thisAccountIsEmpty'.tr();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
|
|
||||||
canValidate = false;
|
|
||||||
validationStatus =
|
|
||||||
'youCannotMigrateIdentityToExistingIdentity'.tr();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sub.g1V1NewAddress == '') {
|
|
||||||
validationStatus = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
||||||
|
|
||||||
return Column(children: <Widget>[
|
return Column(children: <Widget>[
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 10),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
key: keyCesiumId,
|
key: keyCesiumId,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
|
autocorrect: false,
|
||||||
onChanged: (text) {
|
onChanged: (text) {
|
||||||
if (debounce?.isActive ?? false) {
|
if (debounce?.isActive ?? false) {
|
||||||
debounce!.cancel();
|
debounce!.cancel();
|
||||||
}
|
}
|
||||||
debounce = Timer(
|
debounce = Timer(
|
||||||
const Duration(milliseconds: debouneTime), () {
|
const Duration(milliseconds: debouneTime), () {
|
||||||
sub.reload();
|
if (sub.csSalt.text != '' &&
|
||||||
sub.csToV2Address(
|
sub.csPassword.text != '') {
|
||||||
sub.csSalt.text, sub.csPassword.text);
|
sub.reload();
|
||||||
|
sub.csToV2Address(
|
||||||
|
sub.csSalt.text, sub.csPassword.text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
controller: sub.csSalt,
|
controller: sub.csSalt,
|
||||||
obscureText: !sub
|
obscureText: !sub.isCesiumIDVisible,
|
||||||
.isCesiumIDVisible, //This will obscure text dynamically
|
style: scaledTextStyle(fontSize: 14),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'enterCesiumId'.tr(),
|
hintText: 'enterCesiumId'.tr(),
|
||||||
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
key: keyCesiumIdVisible,
|
key: keyCesiumIdVisible,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
@ -138,6 +102,7 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
? Icons.visibility_off
|
? Icons.visibility_off
|
||||||
: Icons.visibility,
|
: Icons.visibility,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
size: scaleSize(22),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
sub.cesiumIDisVisible();
|
sub.cesiumIDisVisible();
|
||||||
|
@ -145,10 +110,11 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 7),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
key: keyCesiumPassword,
|
key: keyCesiumPassword,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
|
autocorrect: false,
|
||||||
onChanged: (text) {
|
onChanged: (text) {
|
||||||
if (debounce?.isActive ?? false) {
|
if (debounce?.isActive ?? false) {
|
||||||
debounce!.cancel();
|
debounce!.cancel();
|
||||||
|
@ -156,23 +122,28 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
debounce = Timer(
|
debounce = Timer(
|
||||||
const Duration(milliseconds: debouneTime), () {
|
const Duration(milliseconds: debouneTime), () {
|
||||||
sub.g1V1NewAddress = '';
|
sub.g1V1NewAddress = '';
|
||||||
sub.reload();
|
if (sub.csSalt.text != '' &&
|
||||||
sub.csToV2Address(
|
sub.csPassword.text != '') {
|
||||||
sub.csSalt.text, sub.csPassword.text);
|
sub.reload();
|
||||||
|
sub.csToV2Address(
|
||||||
|
sub.csSalt.text, sub.csPassword.text);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
controller: sub.csPassword,
|
controller: sub.csPassword,
|
||||||
obscureText: !sub
|
obscureText: !sub.isCesiumIDVisible,
|
||||||
.isCesiumIDVisible, //This will obscure text dynamically
|
style: scaledTextStyle(fontSize: 14),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'enterCesiumPassword'.tr(),
|
hintText: 'enterCesiumPassword'.tr(),
|
||||||
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
sub.isCesiumIDVisible
|
sub.isCesiumIDVisible
|
||||||
? Icons.visibility_off
|
? Icons.visibility_off
|
||||||
: Icons.visibility,
|
: Icons.visibility,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
size: scaleSize(22),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
sub.cesiumIDisVisible();
|
sub.cesiumIDisVisible();
|
||||||
|
@ -180,52 +151,84 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
GestureDetector(
|
Visibility(
|
||||||
key: keyCopyAddress,
|
visible: sub.g1V1OldPubkey != '',
|
||||||
onTap: () {
|
child: Row(
|
||||||
Clipboard.setData(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
ClipboardData(text: sub.g1V1NewAddress));
|
children: [
|
||||||
snackCopyKey(context);
|
Column(
|
||||||
},
|
children: [
|
||||||
child: Text(
|
GestureDetector(
|
||||||
getShortPubkey(sub.g1V1NewAddress),
|
key: keyCopyPubkey,
|
||||||
style: const TextStyle(
|
onTap: () {
|
||||||
fontSize: 20,
|
Clipboard.setData(
|
||||||
fontWeight: FontWeight.w600,
|
ClipboardData(text: sub.g1V1OldPubkey));
|
||||||
),
|
snackCopyKey(context);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'v1: ${getShortPubkey(sub.g1V1OldPubkey)}',
|
||||||
|
style: scaledTextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontFamily: 'Monospace'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(height: 5),
|
||||||
|
GestureDetector(
|
||||||
|
key: keyCopyAddress,
|
||||||
|
onTap: () {
|
||||||
|
Clipboard.setData(
|
||||||
|
ClipboardData(text: sub.g1V1OldPubkey));
|
||||||
|
snackCopyKey(context);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'v2: ${getShortPubkey(sub.g1V1NewAddress)}',
|
||||||
|
style: scaledTextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontFamily: 'Monospace'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ScaledSizedBox(width: 30),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${statusData.balance['transferableBalance']} $unit',
|
||||||
|
style: scaledTextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
IdentityStatus(
|
||||||
|
address: sub.g1V1NewAddress,
|
||||||
|
isOwner: false,
|
||||||
|
color: Colors.black),
|
||||||
|
ScaledSizedBox(width: 10),
|
||||||
|
Certifications(
|
||||||
|
address: sub.g1V1NewAddress, size: 14)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
'${balance['transferableBalance']} $unit',
|
'migrateToThisWallet'.tr(),
|
||||||
style: const TextStyle(fontSize: 17),
|
style: scaledTextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
Row(
|
ScaledSizedBox(height: 5),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
walletOptions.idtyStatus(context, sub.g1V1NewAddress,
|
|
||||||
isOwner: false, color: Colors.black),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
getCerts(context, sub.g1V1NewAddress, 14)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
Text('selectDestWallet'.tr()),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
DropdownButtonHideUnderline(
|
DropdownButtonHideUnderline(
|
||||||
key: keySelectWallet,
|
key: keySelectWallet,
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
// alignment: AlignmentDirectional.topStart,
|
|
||||||
value: selectedWallet,
|
value: selectedWallet,
|
||||||
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!,
|
||||||
style: const TextStyle(fontSize: 18),
|
style: scaledTextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
@ -235,17 +238,18 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
ScaledSizedBox(height: 10),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 380 * ratio,
|
width: 320,
|
||||||
height: 60 * ratio,
|
height: 50,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyConfirm,
|
key: keyConfirm,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: canValidate
|
onPressed: statusData.canValidate
|
||||||
? () async {
|
? () async {
|
||||||
WalletData? defaultWallet =
|
WalletData? defaultWallet =
|
||||||
myWalletProvider.getDefaultWallet();
|
myWalletProvider.getDefaultWallet();
|
||||||
|
@ -263,23 +267,25 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub.migrateCsToV2(
|
final transactionId = await sub.migrateCsToV2(
|
||||||
sub.csSalt.text,
|
sub.csSalt.text,
|
||||||
sub.csPassword.text,
|
sub.csPassword.text,
|
||||||
selectedWallet.address!,
|
selectedWallet.address,
|
||||||
destPassword:
|
destPassword:
|
||||||
pin ?? myWalletProvider.pinCode,
|
pin ?? myWalletProvider.pinCode,
|
||||||
balance: balance,
|
balance: statusData.balance,
|
||||||
idtyStatus: idtyStatus);
|
idtyStatus: statusData.idtyStatus);
|
||||||
Navigator.push(
|
Navigator.pop(context);
|
||||||
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
return TransactionInProgress(
|
return TransactionInProgress(
|
||||||
|
transactionId: transactionId,
|
||||||
transType: 'identityMigration',
|
transType: 'identityMigration',
|
||||||
fromAddress:
|
fromAddress:
|
||||||
getShortPubkey(sub.g1V1NewAddress),
|
getShortPubkey(sub.g1V1NewAddress),
|
||||||
toAddress: getShortPubkey(
|
toAddress: getShortPubkey(
|
||||||
selectedWallet.address!));
|
selectedWallet.address));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
resetScreen(context);
|
resetScreen(context);
|
||||||
|
@ -287,17 +293,17 @@ class ImportG1v1 extends StatelessWidget {
|
||||||
: null,
|
: null,
|
||||||
child: Text(
|
child: Text(
|
||||||
'migrateAccount'.tr(),
|
'migrateAccount'.tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 23 * ratio,
|
fontSize: 19, fontWeight: FontWeight.w600),
|
||||||
fontWeight: FontWeight.w600),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
ScaledSizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
validationStatus,
|
statusData.validationStatus,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 15, color: Colors.grey[600]),
|
style: scaledTextStyle(
|
||||||
|
fontSize: 12, color: Colors.grey[600]),
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -308,10 +314,11 @@ 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 = '';
|
||||||
sub.g1V1NewAddress = '';
|
sub.g1V1NewAddress = '';
|
||||||
|
sub.g1V1OldPubkey = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
// 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/scale_functions.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/transaction_in_progress.dart';
|
import 'package:gecko/screens/transaction_in_progress.dart';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.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';
|
||||||
|
@ -27,49 +26,43 @@ 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(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('manageMembership'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: const Text('manageMembership').tr(),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
migrateIdentity(context),
|
migrateIdentity(context),
|
||||||
const SizedBox(height: 10),
|
ScaledSizedBox(height: 10),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: sub.isSmithGet(address),
|
future: sub.isSmith(address),
|
||||||
builder: (BuildContext context, AsyncSnapshot<bool> isSmith) {
|
builder: (BuildContext context, AsyncSnapshot<bool> isSmith) {
|
||||||
if (isSmith.data ?? false) {
|
if (isSmith.data ?? false) {
|
||||||
return SizedBox(
|
return ScaledSizedBox(
|
||||||
height: 70,
|
height: 75,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const SizedBox(width: 20),
|
ScaledSizedBox(width: 17),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/skull_Icon.png',
|
'assets/skull_Icon.png',
|
||||||
color: Colors.grey[500],
|
color: Colors.grey[500],
|
||||||
height: 30,
|
height: scaleSize(28),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
ScaledSizedBox(width: 12),
|
||||||
Column(
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('revokeMyIdentity'.tr(),
|
Text('revokeMyIdentity'.tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20,
|
fontSize: 18,
|
||||||
color: Colors.grey[500])),
|
color: Colors.grey[500])),
|
||||||
const SizedBox(height: 5),
|
ScaledSizedBox(height: 2),
|
||||||
Text("youCannotRevokeThisIdentity".tr(),
|
Text("youCannotRevokeThisIdentity".tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 14,
|
fontSize: 13,
|
||||||
color: Colors.grey[500])),
|
color: Colors.grey[500])),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
|
@ -78,7 +71,6 @@ class ManageMembership extends StatelessWidget {
|
||||||
return revokeMyIdentity(context);
|
return revokeMyIdentity(context);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// const SizedBox(height: 20),
|
|
||||||
]),
|
]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -94,13 +86,13 @@ class ManageMembership extends StatelessWidget {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 60,
|
height: 55,
|
||||||
child: Row(children: const <Widget>[
|
child: Row(children: <Widget>[
|
||||||
SizedBox(width: 16),
|
ScaledSizedBox(width: 16),
|
||||||
Icon(Icons.change_circle_outlined, size: 35),
|
Icon(Icons.change_circle_outlined, size: scaleSize(32)),
|
||||||
SizedBox(width: 11.5),
|
ScaledSizedBox(width: 11.5),
|
||||||
Text('Migrer mon identité', style: TextStyle(fontSize: 20)),
|
Text('Migrer mon identité', style: scaledTextStyle(fontSize: 18)),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -110,58 +102,43 @@ class ManageMembership extends StatelessWidget {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
key: keyRevokeIdty,
|
key: keyRevokeIdty,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options
|
|
||||||
final answer = await confirmPopup(context,
|
final answer = await confirmPopup(context,
|
||||||
'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
|
'Êtes-vous certains de vouloir révoquer définitivement cette identité ?') ??
|
||||||
false;
|
false;
|
||||||
|
|
||||||
if (answer) {
|
if (!answer) return;
|
||||||
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();
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
// final wallet = mw.getWalletDataByAddress(address);
|
|
||||||
// await sub.setCurrentWallet(wallet!);
|
|
||||||
|
|
||||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
final transactionId =
|
||||||
String? pin;
|
await sub.revokeIdentity(address, myWalletProvider.pinCode);
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (pin != null || myWalletProvider.pinCode != '') {
|
|
||||||
sub.revokeIdentity(address, myWalletProvider.pinCode);
|
|
||||||
}
|
|
||||||
Navigator.pop(context);
|
|
||||||
|
|
||||||
Navigator.push(
|
Navigator.pop(context);
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
Navigator.push(
|
||||||
return TransactionInProgress(
|
context,
|
||||||
transType: 'revokeIdty',
|
MaterialPageRoute(builder: (context) {
|
||||||
fromAddress: getShortPubkey(address),
|
return TransactionInProgress(
|
||||||
toAddress: getShortPubkey(address));
|
transactionId: transactionId,
|
||||||
}),
|
transType: 'revokeIdty',
|
||||||
);
|
fromAddress: getShortPubkey(address),
|
||||||
}
|
toAddress: getShortPubkey(address));
|
||||||
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 60,
|
height: 55,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 20),
|
ScaledSizedBox(width: 20),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/skull_Icon.png',
|
'assets/skull_Icon.png',
|
||||||
height: 30,
|
height: scaleSize(28),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
ScaledSizedBox(width: 16),
|
||||||
const Text('Révoquer mon adhésion', style: TextStyle(fontSize: 20)),
|
Text('Révoquer mon adhésion', style: scaledTextStyle(fontSize: 18)),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
// 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';
|
||||||
import 'package:gecko/models/wallet_data.dart';
|
import 'package:gecko/models/migrate_wallet_checks.dart';
|
||||||
|
import 'package:gecko/models/scale_functions.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/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/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/providers/wallets_profiles.dart';
|
||||||
import 'package:gecko/screens/transaction_in_progress.dart';
|
import 'package:gecko/screens/transaction_in_progress.dart';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.dart';
|
||||||
|
import 'package:polkawallet_sdk/api/apiKeyring.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MigrateIdentityScreen extends StatelessWidget {
|
class MigrateIdentityScreen extends StatelessWidget {
|
||||||
|
@ -20,240 +23,237 @@ class MigrateIdentityScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
final walletOptions =
|
||||||
// HomeProvider _homeProvider = Provider.of<HomeProvider>(context);
|
|
||||||
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 generatedWalletsProvider =
|
||||||
Provider.of<DuniterIndexer>(context, listen: false);
|
Provider.of<GenerateWalletsProvider>(context, listen: false);
|
||||||
|
final duniterIndexer = Provider.of<DuniterIndexer>(context, listen: false);
|
||||||
|
final sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
|
|
||||||
final fromAddress = walletOptions.address.text;
|
final fromAddress = walletOptions.address.text;
|
||||||
final defaultWallet = myWalletProvider.getDefaultWallet();
|
final newMnemonicSentence = TextEditingController();
|
||||||
final walletsList = myWalletProvider.listWallets.toList();
|
final newWalletAddress = TextEditingController();
|
||||||
late WalletData selectedWallet;
|
|
||||||
|
|
||||||
if (fromAddress == defaultWallet.address) {
|
|
||||||
selectedWallet =
|
|
||||||
walletsList[fromAddress == walletsList[0].address ? 1 : 0];
|
|
||||||
} else {
|
|
||||||
selectedWallet = defaultWallet;
|
|
||||||
}
|
|
||||||
bool canValidate = false;
|
|
||||||
String validationStatus = '';
|
|
||||||
|
|
||||||
final mdStyle = MarkdownStyleSheet(
|
final mdStyle = MarkdownStyleSheet(
|
||||||
p: const TextStyle(fontSize: 18, color: Colors.black, letterSpacing: 0.3),
|
p: scaledTextStyle(fontSize: 16, color: Colors.black, letterSpacing: 0.3),
|
||||||
textAlign: WrapAlignment.center,
|
textAlign: WrapAlignment.center,
|
||||||
);
|
);
|
||||||
|
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
||||||
|
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
||||||
|
|
||||||
if (walletsList.length < 2) {
|
var statusData = const MigrateWalletChecks.defaultValues();
|
||||||
return Column(
|
var mnemonicIsValid = false;
|
||||||
children: [
|
int? matchDerivationNbr;
|
||||||
const SizedBox(height: 80),
|
String matchInfo = '';
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
Future scanDerivations() async {
|
||||||
children: const [
|
if (!await isAddress(newWalletAddress.text) ||
|
||||||
Text(
|
!await sub.isMnemonicValid(newMnemonicSentence.text) ||
|
||||||
'Vous devez avoir au moins 2 portefeuilles\npour effecter cette opération',
|
!statusData.canValidate) {
|
||||||
style: TextStyle(fontSize: 20),
|
mnemonicIsValid = false;
|
||||||
)
|
matchInfo = '';
|
||||||
],
|
walletOptions.reload();
|
||||||
)
|
return;
|
||||||
],
|
}
|
||||||
|
log.d('Scan derivations to find a match');
|
||||||
|
|
||||||
|
//Scan root wallet
|
||||||
|
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
||||||
|
sub.currencyParameters['ss58']!,
|
||||||
|
cryptoType: CryptoType.sr25519,
|
||||||
|
mnemonic: newMnemonicSentence.text,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (addressData.address == newWalletAddress.text) {
|
||||||
|
matchDerivationNbr = -1;
|
||||||
|
mnemonicIsValid = true;
|
||||||
|
walletOptions.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scan derivations
|
||||||
|
for (int derivationNbr in [
|
||||||
|
for (var i = 0; i < generatedWalletsProvider.numberScan; i += 1) i
|
||||||
|
]) {
|
||||||
|
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
||||||
|
sub.currencyParameters['ss58']!,
|
||||||
|
cryptoType: CryptoType.sr25519,
|
||||||
|
mnemonic: newMnemonicSentence.text,
|
||||||
|
derivePath: '//$derivationNbr');
|
||||||
|
|
||||||
|
if (addressData.address == newWalletAddress.text) {
|
||||||
|
matchDerivationNbr = derivationNbr;
|
||||||
|
mnemonicIsValid = true;
|
||||||
|
matchInfo = "youCanMigrateThisIdentity".tr();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
mnemonicIsValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mnemonicIsValid) {
|
||||||
|
matchInfo = "addressNotBelongToMnemonic".tr();
|
||||||
|
}
|
||||||
|
walletOptions.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('migrateIdentity'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('importOldAccount'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
child: Column(children: <Widget>[
|
||||||
return FutureBuilder(
|
const Row(children: []),
|
||||||
future: sub.getBalanceAndIdtyStatus(
|
ScaledSizedBox(height: 18),
|
||||||
fromAddress, selectedWallet.address!),
|
ScaledSizedBox(
|
||||||
builder: (BuildContext context, AsyncSnapshot<List> status) {
|
width: 320,
|
||||||
if (status.data == null) {
|
child: MarkdownBody(
|
||||||
return Column(children: [
|
data: 'areYouSureMigrateIdentity'.tr(args: [
|
||||||
const SizedBox(height: 80),
|
duniterIndexer.walletNameIndexer[fromAddress] ?? '???',
|
||||||
Row(
|
'${walletOptions.balanceCache[fromAddress]} $unit'
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
]),
|
||||||
children: const [
|
styleSheet: mdStyle),
|
||||||
SizedBox(
|
),
|
||||||
height: 35,
|
ScaledSizedBox(height: 55),
|
||||||
width: 35,
|
Text('migrateToThisWallet'.tr(),
|
||||||
child: CircularProgressIndicator(
|
style: scaledTextStyle(fontSize: 16)),
|
||||||
color: orangeC,
|
ScaledSizedBox(height: 5),
|
||||||
strokeWidth: 4,
|
ScaledSizedBox(
|
||||||
),
|
width: 320,
|
||||||
),
|
child: TextField(
|
||||||
]),
|
controller: newMnemonicSentence,
|
||||||
]);
|
autofocus: true,
|
||||||
}
|
minLines: 2,
|
||||||
|
maxLines: 2,
|
||||||
// log.d('statusData: ${status.data}');
|
style: scaledTextStyle(fontSize: 14),
|
||||||
|
decoration: InputDecoration(
|
||||||
final Map balance = status.data?[0] ?? {};
|
icon: Image.asset(
|
||||||
final String idtyStatus = status.data?[1];
|
'assets/onBoarding/phrase_de_restauration_flou.png',
|
||||||
final String myIdtyStatus = status.data?[2];
|
width: scaleSize(30),
|
||||||
final bool hasConsumer = status.data?[3] ?? false;
|
),
|
||||||
|
hintText: 'enterYourNewMnemonic'.tr(),
|
||||||
// log.d('hasconsumer: $hasConsumer');
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
|
focusedBorder: const UnderlineInputBorder(
|
||||||
if (balance['transferableBalance'] != 0 && !hasConsumer) {
|
borderSide: BorderSide(color: orangeC),
|
||||||
canValidate = true;
|
),
|
||||||
validationStatus = '';
|
),
|
||||||
|
onChanged: (newMnemonic) async {
|
||||||
|
await scanDerivations();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(height: 5),
|
||||||
|
ScaledSizedBox(
|
||||||
|
width: 320,
|
||||||
|
child: TextField(
|
||||||
|
controller: newWalletAddress,
|
||||||
|
style: scaledTextStyle(fontSize: 14),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
icon: Image.asset(
|
||||||
|
'assets/walletOptions/key.png',
|
||||||
|
height: scaleSize(30),
|
||||||
|
),
|
||||||
|
hintText: 'enterYourNewAddress'.tr(args: [currencyName]),
|
||||||
|
hintStyle: scaledTextStyle(fontSize: 14),
|
||||||
|
focusedBorder: const UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: orangeC),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: (newAddress) async {
|
||||||
|
if (await isAddress(newAddress)) {
|
||||||
|
statusData = await sub.getBalanceAndIdtyStatus(
|
||||||
|
fromAddress, newAddress);
|
||||||
|
await scanDerivations();
|
||||||
} else {
|
} else {
|
||||||
canValidate = false;
|
statusData = const MigrateWalletChecks.defaultValues();
|
||||||
validationStatus = hasConsumer
|
matchInfo = '';
|
||||||
? 'youMustWaitBeforeCashoutThisAccount'.tr(args: ['X'])
|
walletOptions.reload();
|
||||||
: 'thisAccountIsEmpty'.tr();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(flex: 2),
|
||||||
|
Consumer<WalletOptionsProvider>(builder: (context, _, __) {
|
||||||
|
return ScaledSizedBox(
|
||||||
|
width: 320,
|
||||||
|
height: 55,
|
||||||
|
child: ElevatedButton(
|
||||||
|
key: keyConfirm,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
|
),
|
||||||
|
onPressed: statusData.canValidate && mnemonicIsValid
|
||||||
|
? () async {
|
||||||
|
if (!await myWalletProvider.askPinCode()) return;
|
||||||
|
|
||||||
if (idtyStatus != 'noid' && myIdtyStatus != 'noid') {
|
await sub.importAccount(
|
||||||
canValidate = false;
|
mnemonic: newMnemonicSentence.text,
|
||||||
validationStatus =
|
derivePath: matchDerivationNbr == -1
|
||||||
'youCannotMigrateIdentityToExistingIdentity'.tr();
|
? ''
|
||||||
}
|
: "//$matchDerivationNbr",
|
||||||
|
password: 'password');
|
||||||
|
|
||||||
log.d(
|
final transactionId = await sub.migrateIdentity(
|
||||||
'tatatata: ${sub.g1V1NewAddress}, ${selectedWallet.address!}, $balance, $idtyStatus, $myIdtyStatus');
|
fromAddress: fromAddress,
|
||||||
|
destAddress: newWalletAddress.text,
|
||||||
|
fromPassword: myWalletProvider.pinCode,
|
||||||
|
destPassword: 'password',
|
||||||
|
withBalance: true,
|
||||||
|
fromBalance: statusData.balance);
|
||||||
|
|
||||||
final walletsList = myWalletProvider.listWallets.toList();
|
sub.deleteAccounts([newWalletAddress.text]);
|
||||||
|
Navigator.pop(context);
|
||||||
walletsList
|
Navigator.push(
|
||||||
.removeWhere((element) => element.address == fromAddress);
|
context,
|
||||||
// walletsList.add(WalletData(address: 'custom', name: 'custom'));
|
MaterialPageRoute(builder: (context) {
|
||||||
|
return TransactionInProgress(
|
||||||
final bool isUdUnit = configBox.get('isUdUnit') ?? false;
|
transactionId: transactionId,
|
||||||
final unit = isUdUnit ? 'ud'.tr(args: ['']) : currencyName;
|
transType: 'identityMigration',
|
||||||
|
fromAddress: getShortPubkey(fromAddress),
|
||||||
return Column(children: <Widget>[
|
toAddress:
|
||||||
Row(children: const []),
|
getShortPubkey(newWalletAddress.text));
|
||||||
const SizedBox(height: 20),
|
}),
|
||||||
|
|
||||||
SizedBox(
|
|
||||||
width: 350,
|
|
||||||
child: MarkdownBody(
|
|
||||||
data: 'areYouSureMigrateIdentity'.tr(args: [
|
|
||||||
duniterIndexer.walletNameIndexer[fromAddress] ??
|
|
||||||
'???',
|
|
||||||
'${balance['transferableBalance']} $unit'
|
|
||||||
]),
|
|
||||||
styleSheet: mdStyle),
|
|
||||||
),
|
|
||||||
// Text(
|
|
||||||
// 'areYouSureMigrateIdentity'.tr(args: [
|
|
||||||
// duniterIndexer
|
|
||||||
// .walletNameIndexer[fromAddress]!,
|
|
||||||
// '$balance $currencyName'
|
|
||||||
// ]),
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
// ),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Text(
|
|
||||||
sub.g1V1NewAddress,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14.0,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontFamily: 'Monospace'),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
Text('selectDestWallet'.tr()),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
DropdownButtonHideUnderline(
|
|
||||||
key: keySelectWallet,
|
|
||||||
child: DropdownButton(
|
|
||||||
// alignment: AlignmentDirectional.topStart,
|
|
||||||
value: selectedWallet,
|
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
|
||||||
items: walletsList.map((wallet) {
|
|
||||||
return DropdownMenuItem(
|
|
||||||
key: keySelectThisWallet(wallet.address!),
|
|
||||||
value: wallet,
|
|
||||||
child: Text(
|
|
||||||
wallet.name!,
|
|
||||||
style: const TextStyle(fontSize: 18),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}).toList(),
|
}
|
||||||
onChanged: (WalletData? newSelectedWallet) {
|
: null,
|
||||||
selectedWallet = newSelectedWallet!;
|
child: Text(
|
||||||
sub.reload();
|
'migrateIdentity'.tr(),
|
||||||
},
|
style: scaledTextStyle(
|
||||||
),
|
fontSize: 19,
|
||||||
),
|
fontWeight: FontWeight.w600,
|
||||||
const SizedBox(height: 30),
|
color: Colors.white),
|
||||||
SizedBox(
|
),
|
||||||
width: 380 * ratio,
|
),
|
||||||
height: 60 * ratio,
|
);
|
||||||
child: ElevatedButton(
|
}),
|
||||||
key: keyConfirm,
|
Consumer<WalletOptionsProvider>(builder: (context, _, __) {
|
||||||
style: ElevatedButton.styleFrom(
|
return ScaledSizedBox(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
width: 320,
|
||||||
backgroundColor: orangeC, // foreground
|
child: Column(
|
||||||
),
|
children: [
|
||||||
onPressed: canValidate
|
ScaledSizedBox(height: 10),
|
||||||
? () async {
|
|
||||||
log.d('GOOO');
|
|
||||||
WalletData? defaultWallet =
|
|
||||||
myWalletProvider.getDefaultWallet();
|
|
||||||
|
|
||||||
String? pin;
|
|
||||||
if (myWalletProvider.pinCode == '') {
|
|
||||||
pin = await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (homeContext) {
|
|
||||||
return UnlockingWallet(
|
|
||||||
wallet: defaultWallet);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub.migrateIdentity(
|
|
||||||
fromAddress: fromAddress,
|
|
||||||
destAddress: selectedWallet.address!,
|
|
||||||
fromPassword: pin ?? myWalletProvider.pinCode,
|
|
||||||
destPassword: pin ?? myWalletProvider.pinCode,
|
|
||||||
withBalance: true,
|
|
||||||
fromBalance: balance);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return TransactionInProgress(
|
|
||||||
transType: 'identityMigration',
|
|
||||||
fromAddress: getShortPubkey(fromAddress),
|
|
||||||
toAddress: getShortPubkey(
|
|
||||||
selectedWallet.address!));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
child: Text(
|
|
||||||
'migrateIdentity'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 23 * ratio, fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Text(
|
Text(
|
||||||
validationStatus,
|
statusData.validationStatus,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 15, color: Colors.grey[600]),
|
style:
|
||||||
)
|
scaledTextStyle(fontSize: 12, color: Colors.grey[600]),
|
||||||
]);
|
),
|
||||||
});
|
ScaledSizedBox(height: 5),
|
||||||
}),
|
Text(
|
||||||
|
matchInfo,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style:
|
||||||
|
scaledTextStyle(fontSize: 12, color: Colors.grey[600]),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
const Spacer(),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
|
// 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/scale_functions.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:gecko/widgets/commons/top_appbar.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,42 +23,27 @@ 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;
|
|
||||||
if (genW.isSentenceComplete(context)) {
|
if (genW.isSentenceComplete(context)) {
|
||||||
genW.generatedMnemonic =
|
genW.generatedMnemonic =
|
||||||
'${genW.cellController0.text} ${genW.cellController1.text} ${genW.cellController2.text} ${genW.cellController3.text} ${genW.cellController4.text} ${genW.cellController5.text} ${genW.cellController6.text} ${genW.cellController7.text} ${genW.cellController8.text} ${genW.cellController9.text} ${genW.cellController10.text} ${genW.cellController11.text}';
|
'${genW.cellController0.text} ${genW.cellController1.text} ${genW.cellController2.text} ${genW.cellController3.text} ${genW.cellController4.text} ${genW.cellController5.text} ${genW.cellController6.text} ${genW.cellController7.text} ${genW.cellController8.text} ${genW.cellController9.text} ${genW.cellController10.text} ${genW.cellController11.text}';
|
||||||
}
|
}
|
||||||
|
|
||||||
return WillPopScope(
|
return PopScope(
|
||||||
onWillPop: () {
|
onPopInvoked: (_) {
|
||||||
genW.resetImportView();
|
genW.resetImportView();
|
||||||
return Future<bool>.value(true);
|
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('restoreAChest'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
|
||||||
onPressed: () {
|
|
||||||
genW.resetImportView();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}),
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('restoreAChest'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
Column(children: <Widget>[
|
Column(children: <Widget>[
|
||||||
SizedBox(height: isTall ? 30 : 15),
|
ScaledSizedBox(height: isTall ? 20 : 3),
|
||||||
bubbleSpeak('toRestoreEnterMnemonic'.tr()),
|
bubbleSpeak('toRestoreEnterMnemonic'.tr()),
|
||||||
SizedBox(height: isTall ? 30 : 15),
|
ScaledSizedBox(height: isTall ? 20 : 5),
|
||||||
Column(children: <Widget>[
|
Column(children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
@ -64,7 +53,7 @@ class RestoreChest extends StatelessWidget {
|
||||||
arrayCell(context, genW.cellController2),
|
arrayCell(context, genW.cellController2),
|
||||||
arrayCell(context, genW.cellController3),
|
arrayCell(context, genW.cellController3),
|
||||||
]),
|
]),
|
||||||
const SizedBox(height: 15),
|
ScaledSizedBox(height: isTall ? 10 : 3),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -73,7 +62,7 @@ class RestoreChest extends StatelessWidget {
|
||||||
arrayCell(context, genW.cellController6),
|
arrayCell(context, genW.cellController6),
|
||||||
arrayCell(context, genW.cellController7),
|
arrayCell(context, genW.cellController7),
|
||||||
]),
|
]),
|
||||||
const SizedBox(height: 15),
|
ScaledSizedBox(height: isTall ? 10 : 3),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -88,14 +77,15 @@ class RestoreChest extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
width: 410,
|
width: 340,
|
||||||
height: 70,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyGoNext,
|
key: keyGoNext,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (await sub
|
if (await sub
|
||||||
|
@ -117,8 +107,10 @@ class RestoreChest extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'restoreThisChest'.tr(),
|
'restoreThisChest'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 24, fontWeight: FontWeight.w600),
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -126,38 +118,39 @@ class RestoreChest extends StatelessWidget {
|
||||||
))
|
))
|
||||||
else
|
else
|
||||||
Column(children: [
|
Column(children: [
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 190,
|
width: 210,
|
||||||
height: 60,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyPastMnemonic,
|
key: keyPastMnemonic,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.black, elevation: 4,
|
foregroundColor: Colors.black,
|
||||||
backgroundColor: yellowC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: yellowC,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
genW.pasteMnemonic(context);
|
genW.pasteMnemonic(context);
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.content_paste_go,
|
Icons.content_paste_go,
|
||||||
size: 25,
|
size: scaleSize(28),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
|
||||||
Text(
|
Text(
|
||||||
'pasteFromClipboard'.tr(),
|
'pasteFromClipboard'.tr(),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 17, fontWeight: FontWeight.w400),
|
fontSize: 16, fontWeight: FontWeight.w400),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
CommonElements().offlineInfo(context),
|
const OfflineInfo(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -167,7 +160,7 @@ class RestoreChest extends StatelessWidget {
|
||||||
Widget bubbleSpeak(String text) {
|
Widget bubbleSpeak(String text) {
|
||||||
return Bubble(
|
return Bubble(
|
||||||
margin: const BubbleEdges.symmetric(horizontal: 20),
|
margin: const BubbleEdges.symmetric(horizontal: 20),
|
||||||
padding: BubbleEdges.all(isTall ? 25 : 15),
|
padding: BubbleEdges.all(scaleSize(15)),
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: Colors.black,
|
borderColor: Colors.black,
|
||||||
radius: Radius.zero,
|
radius: Radius.zero,
|
||||||
|
@ -176,19 +169,19 @@ class RestoreChest extends StatelessWidget {
|
||||||
text,
|
text,
|
||||||
key: keyBubbleSpeak,
|
key: keyBubbleSpeak,
|
||||||
textAlign: TextAlign.justify,
|
textAlign: TextAlign.justify,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400),
|
color: Colors.black, fontSize: 17, fontWeight: FontWeight.w400),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget arrayCell(BuildContext context, TextEditingController cellCtl) {
|
Widget arrayCell(BuildContext context, final cellCtl) {
|
||||||
GenerateWalletsProvider generateWalletProvider =
|
final generateWalletProvider =
|
||||||
Provider.of<GenerateWalletsProvider>(context);
|
Provider.of<GenerateWalletsProvider>(context);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 102,
|
width: scaleSize(87),
|
||||||
height: 40 * ratio,
|
height: scaleSize(37),
|
||||||
// ),
|
// ),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: Colors.grey),
|
border: Border.all(color: Colors.grey),
|
||||||
|
@ -219,7 +212,7 @@ class RestoreChest extends StatelessWidget {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(fontSize: 20),
|
style: scaledTextStyle(fontSize: 17),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +220,7 @@ class RestoreChest extends StatelessWidget {
|
||||||
Future<bool?> badMnemonicPopup(BuildContext context) async {
|
Future<bool?> badMnemonicPopup(BuildContext context) async {
|
||||||
return showDialog<bool>(
|
return showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: true, // user must tap button!
|
barrierDismissible: true,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('Phrase incorrecte'),
|
title: const Text('Phrase incorrecte'),
|
||||||
|
|
|
@ -2,11 +2,14 @@ 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/scale_functions.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:gecko/widgets/commons/top_appbar.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,36 +26,28 @@ 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();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar('myMnemonic'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text('myMnemonic'.tr()),
|
|
||||||
)),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
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) {
|
||||||
return const SizedBox(
|
return ScaledSizedBox(
|
||||||
height: 15,
|
height: 15,
|
||||||
width: 15,
|
width: 15,
|
||||||
child: CircularProgressIndicator(
|
child: const CircularProgressIndicator(
|
||||||
color: orangeC,
|
color: orangeC,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
),
|
),
|
||||||
|
@ -65,74 +60,82 @@ class ShowSeed extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Column(children: [
|
Column(children: [
|
||||||
common.buildText('keepYourMnemonicSecret'.tr()),
|
BuildText(
|
||||||
SizedBox(height: 35 * ratio),
|
text: 'keepYourMnemonicSecret'.tr(), size: 16),
|
||||||
|
ScaledSizedBox(height: 35),
|
||||||
sentanceArray(context, seed.data!.split(' ')),
|
sentanceArray(context, seed.data!.split(' ')),
|
||||||
const SizedBox(height: 20),
|
ScaledSizedBox(height: 20),
|
||||||
SizedBox(
|
Row(
|
||||||
height: 40,
|
children: [
|
||||||
child: ElevatedButton(
|
ScaledSizedBox(
|
||||||
style: ElevatedButton.styleFrom(
|
height: 39,
|
||||||
foregroundColor: Colors.black,
|
child: ElevatedButton(
|
||||||
shape: RoundedRectangleBorder(
|
style: ElevatedButton.styleFrom(
|
||||||
borderRadius: BorderRadius.circular(8),
|
foregroundColor: Colors.black,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
backgroundColor: orangeC,
|
||||||
|
elevation: 1,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Clipboard.setData(
|
||||||
|
ClipboardData(text: seed.data!));
|
||||||
|
snackCopySeed(context);
|
||||||
|
},
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
Image.asset(
|
||||||
|
'assets/walletOptions/copy-white.png',
|
||||||
|
height: scaleSize(24),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(width: 7),
|
||||||
|
Text(
|
||||||
|
'copy'.tr(),
|
||||||
|
style: scaledTextStyle(
|
||||||
|
fontSize: 14, color: Colors.grey[50]),
|
||||||
|
)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
backgroundColor: orangeC,
|
|
||||||
elevation: 1, // foreground
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
ScaledSizedBox(width: 50),
|
||||||
Clipboard.setData(
|
GestureDetector(
|
||||||
ClipboardData(text: seed.data));
|
onTap: () {
|
||||||
snackCopyKey(context);
|
Navigator.push(
|
||||||
},
|
context,
|
||||||
child: Row(children: <Widget>[
|
MaterialPageRoute(builder: (context) {
|
||||||
Image.asset(
|
return PrintWallet(seed.data);
|
||||||
'assets/walletOptions/copy-white.png',
|
}),
|
||||||
height: 25,
|
);
|
||||||
|
},
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/printer.png',
|
||||||
|
height: scaleSize(38),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 7),
|
),
|
||||||
Text(
|
],
|
||||||
'copy'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15, color: Colors.grey[50]),
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return PrintWallet(seed.data);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/printer.png',
|
|
||||||
height: 42 * ratio,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
const Spacer(flex: 2),
|
const Spacer(flex: 3),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 380 * ratio,
|
width: 240,
|
||||||
height: 60 * ratio,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'close'.tr(),
|
'close'.tr(),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 23 * ratio, fontWeight: FontWeight.w600),
|
fontSize: 19,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -141,72 +144,56 @@ 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 Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 3),
|
constraints: BoxConstraints(maxWidth: scaleSize(360)),
|
||||||
child: Container(
|
decoration: BoxDecoration(
|
||||||
constraints: const BoxConstraints(maxWidth: 450),
|
border: Border.all(color: Colors.black),
|
||||||
decoration: BoxDecoration(
|
color: const Color(0xffeeeedd),
|
||||||
border: Border.all(color: Colors.black),
|
borderRadius: const BorderRadius.all(
|
||||||
color: const Color(0xffeeeedd),
|
Radius.circular(10),
|
||||||
borderRadius: const BorderRadius.all(
|
)),
|
||||||
Radius.circular(10),
|
padding: EdgeInsets.all(scaleSize(14)),
|
||||||
)),
|
child: Column(
|
||||||
padding: const EdgeInsets.all(20),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: Column(
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.max,
|
children: <Widget>[
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
Row(children: <Widget>[
|
||||||
children: <Widget>[
|
arrayCell(mnemonic[0], 1),
|
||||||
Row(children: <Widget>[
|
arrayCell(mnemonic[1], 2),
|
||||||
arrayCell(mnemonic[0], 1),
|
arrayCell(mnemonic[2], 3),
|
||||||
arrayCell(mnemonic[1], 2),
|
arrayCell(mnemonic[3], 4),
|
||||||
arrayCell(mnemonic[2], 3),
|
]),
|
||||||
arrayCell(mnemonic[3], 4),
|
ScaledSizedBox(height: 15),
|
||||||
]),
|
Row(children: <Widget>[
|
||||||
const SizedBox(height: 15),
|
arrayCell(mnemonic[4], 5),
|
||||||
Row(children: <Widget>[
|
arrayCell(mnemonic[5], 6),
|
||||||
arrayCell(mnemonic[4], 5),
|
arrayCell(mnemonic[6], 7),
|
||||||
arrayCell(mnemonic[5], 6),
|
arrayCell(mnemonic[7], 8),
|
||||||
arrayCell(mnemonic[6], 7),
|
]),
|
||||||
arrayCell(mnemonic[7], 8),
|
ScaledSizedBox(height: 15),
|
||||||
]),
|
Row(children: <Widget>[
|
||||||
const SizedBox(height: 15),
|
arrayCell(mnemonic[8], 9),
|
||||||
Row(children: <Widget>[
|
arrayCell(mnemonic[9], 10),
|
||||||
arrayCell(mnemonic[8], 9),
|
arrayCell(mnemonic[10], 11),
|
||||||
arrayCell(mnemonic[9], 10),
|
arrayCell(mnemonic[11], 12),
|
||||||
arrayCell(mnemonic[10], 11),
|
]),
|
||||||
arrayCell(mnemonic[11], 12),
|
]));
|
||||||
]),
|
|
||||||
])),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget arrayCell(dataWord, int nbr) {
|
Widget arrayCell(dataWord, int nbr) {
|
||||||
log.d(nbr);
|
return ScaledSizedBox(
|
||||||
|
width: 82,
|
||||||
return SizedBox(
|
|
||||||
width: 100,
|
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
nbr.toString(),
|
nbr.toString(),
|
||||||
style:
|
style: scaledTextStyle(fontSize: 11, color: const Color(0xff6b6b52)),
|
||||||
TextStyle(fontSize: 13 * ratio, color: const Color(0xff6b6b52)),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
dataWord,
|
dataWord,
|
||||||
key: keyMnemonicWord(dataWord),
|
key: keyMnemonicWord(dataWord),
|
||||||
style: TextStyle(fontSize: 17 * ratio, color: Colors.black),
|
style: scaledTextStyle(fontSize: 16, color: Colors.black),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
@ -230,13 +217,10 @@ class PrintWallet extends StatelessWidget {
|
||||||
}),
|
}),
|
||||||
backgroundColor: yellowC,
|
backgroundColor: yellowC,
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
toolbarHeight: 60 * ratio,
|
toolbarHeight: scaleSize(57),
|
||||||
title: SizedBox(
|
title: Text(
|
||||||
height: 22,
|
'printMyMnemonic'.tr(),
|
||||||
child: Text(
|
style: scaledTextStyle(fontWeight: FontWeight.w600),
|
||||||
'printMyMnemonic'.tr(),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: PdfPreview(
|
body: PdfPreview(
|
||||||
|
@ -253,21 +237,19 @@ class PrintWallet extends StatelessWidget {
|
||||||
await rootBundle.load("assets/OpenSans-Regular.ttf");
|
await rootBundle.load("assets/OpenSans-Regular.ttf");
|
||||||
final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData());
|
final pw.Font ttf = pw.Font.ttf(fontData.buffer.asByteData());
|
||||||
final pdf = pw.Document();
|
final pdf = pw.Document();
|
||||||
int nbr = 1;
|
|
||||||
|
|
||||||
final seedList = seed.split(' ');
|
final seedList = seed.split(' ');
|
||||||
|
|
||||||
// const imageProvider = AssetImage('assets/icon/gecko_final.png');
|
const imageProvider = AssetImage('assets/icon/gecko_final.png');
|
||||||
// final geckoLogo = await flutterImageProvider(imageProvider);
|
final geckoLogo = await flutterImageProvider(imageProvider);
|
||||||
|
|
||||||
pw.Widget arrayCell(String dataWord, int nbr) {
|
|
||||||
nbr++;
|
|
||||||
|
|
||||||
|
pw.Widget arrayCell(int number, String dataWord) {
|
||||||
return pw.SizedBox(
|
return pw.SizedBox(
|
||||||
width: 120,
|
width: 120,
|
||||||
|
height: 70,
|
||||||
child: pw.Column(children: <pw.Widget>[
|
child: pw.Column(children: <pw.Widget>[
|
||||||
pw.Text(
|
pw.Text(
|
||||||
nbr.toString(),
|
number.toString(),
|
||||||
style: pw.TextStyle(
|
style: pw.TextStyle(
|
||||||
fontSize: 15, color: const PdfColor(0.5, 0, 0), font: ttf),
|
fontSize: 15, color: const PdfColor(0.5, 0, 0), font: ttf),
|
||||||
),
|
),
|
||||||
|
@ -285,38 +267,44 @@ class PrintWallet extends StatelessWidget {
|
||||||
pw.Page(
|
pw.Page(
|
||||||
pageFormat: PdfPageFormat.a4,
|
pageFormat: PdfPageFormat.a4,
|
||||||
build: (context) {
|
build: (context) {
|
||||||
return pw.Column(
|
return pw.Stack(children: <pw.Widget>[
|
||||||
// mainAxisAlignment: pw.MainAxisAlignment.center,
|
pw.Positioned(top: 217, child: pw.Text('-'.padRight(130, '-'))),
|
||||||
// mainAxisSize: pw.MainAxisSize.max,
|
pw.Positioned(bottom: 217, child: pw.Text('-'.padRight(130, '-'))),
|
||||||
// crossAxisAlignment: pw.CrossAxisAlignment.center,
|
pw.Column(
|
||||||
children: <pw.Widget>[
|
// mainAxisAlignment: pw.MainAxisAlignment.center,
|
||||||
pw.Row(children: <pw.Widget>[
|
// mainAxisSize: pw.MainAxisSize.max,
|
||||||
arrayCell(seedList[0], nbr),
|
// crossAxisAlignment: pw.CrossAxisAlignment.center,
|
||||||
arrayCell(seedList[1], nbr),
|
children: <pw.Widget>[
|
||||||
arrayCell(seedList[2], nbr),
|
pw.SizedBox(height: 10),
|
||||||
arrayCell(seedList[3], nbr),
|
pw.Row(children: <pw.Widget>[
|
||||||
]),
|
arrayCell(1, seedList[0]),
|
||||||
pw.Row(children: <pw.Widget>[
|
arrayCell(2, seedList[1]),
|
||||||
arrayCell(seedList[4], nbr),
|
arrayCell(3, seedList[2]),
|
||||||
arrayCell(seedList[5], nbr),
|
arrayCell(4, seedList[3]),
|
||||||
arrayCell(seedList[6], nbr),
|
]),
|
||||||
arrayCell(seedList[7], nbr),
|
pw.Row(children: <pw.Widget>[
|
||||||
]),
|
arrayCell(5, seedList[4]),
|
||||||
pw.Row(children: <pw.Widget>[
|
arrayCell(6, seedList[5]),
|
||||||
arrayCell(seedList[8], nbr),
|
arrayCell(7, seedList[6]),
|
||||||
arrayCell(seedList[9], nbr),
|
arrayCell(8, seedList[7]),
|
||||||
arrayCell(seedList[10], nbr),
|
]),
|
||||||
arrayCell(seedList[11], nbr)
|
pw.Row(children: <pw.Widget>[
|
||||||
]),
|
arrayCell(9, seedList[8]),
|
||||||
pw.Expanded(
|
arrayCell(10, seedList[9]),
|
||||||
child: pw.Align(
|
arrayCell(11, seedList[10]),
|
||||||
alignment: pw.Alignment.bottomCenter,
|
arrayCell(12, seedList[11])
|
||||||
child: pw.Text(
|
]),
|
||||||
"Gardez cette feuille préciseusement, à l’abri des lézards indiscrets.",
|
pw.SizedBox(height: 105),
|
||||||
style: pw.TextStyle(fontSize: 15, font: ttf),
|
pw.Image(geckoLogo, height: 80),
|
||||||
)))
|
pw.SizedBox(height: 205),
|
||||||
],
|
pw.Text(
|
||||||
);
|
"keepThisPaperSafe".tr(),
|
||||||
|
textAlign: pw.TextAlign.center,
|
||||||
|
style: pw.TextStyle(fontSize: 15, font: ttf),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
]);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
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/scale_functions.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';
|
||||||
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/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;
|
||||||
|
final 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,165 +43,185 @@ 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 PopScope(
|
||||||
child: Column(
|
onPopInvoked: (_) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
myWalletProvider.isPinValid = false;
|
||||||
children: <Widget>[
|
myWalletProvider.isPinLoading = true;
|
||||||
Stack(children: <Widget>[
|
},
|
||||||
Positioned(
|
child: Scaffold(
|
||||||
top: 10, //statusBarHeight + 10,
|
backgroundColor: backgroundColor,
|
||||||
left: 15,
|
body: SafeArea(
|
||||||
child: Builder(
|
child: Column(
|
||||||
builder: (context) => IconButton(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
key: keyPopButton,
|
children: <Widget>[
|
||||||
icon: const Icon(
|
Stack(children: <Widget>[
|
||||||
Icons.arrow_back,
|
Positioned(
|
||||||
color: Colors.black,
|
top: 10,
|
||||||
size: 30,
|
left: 15,
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) => IconButton(
|
||||||
|
key: keyPopButton,
|
||||||
|
icon: Icon(
|
||||||
|
Icons.arrow_back,
|
||||||
|
color: Colors.black,
|
||||||
|
size: scaleSize(28),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
myWalletProvider.isPinValid = false;
|
||||||
|
myWalletProvider.isPinLoading = true;
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Column(children: <Widget>[
|
||||||
Column(children: <Widget>[
|
ScaledSizedBox(height: isTall ? 80 : 65),
|
||||||
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: scaleSize(95),
|
||||||
width: isTall ? 130 : 100,
|
)
|
||||||
)
|
: Image.file(
|
||||||
: Image.file(
|
currentChest.imageFile!,
|
||||||
currentChest.imageFile!,
|
width: scaleSize(127),
|
||||||
width: isTall ? 130 : 100,
|
),
|
||||||
),
|
ScaledSizedBox(width: 5),
|
||||||
const SizedBox(width: 5),
|
ScaledSizedBox(
|
||||||
SizedBox(
|
width: 250,
|
||||||
width: 250,
|
child: Text(
|
||||||
child: Text(
|
currentChest.name!,
|
||||||
currentChest.name!,
|
textAlign: TextAlign.center,
|
||||||
textAlign: TextAlign.center,
|
style: scaledTextStyle(
|
||||||
style: const TextStyle(
|
fontSize: 22,
|
||||||
fontSize: 25,
|
color: Colors.black,
|
||||||
color: Colors.black,
|
fontWeight: FontWeight.w700),
|
||||||
fontWeight: FontWeight.w700),
|
)),
|
||||||
)),
|
]),
|
||||||
]),
|
ScaledSizedBox(height: isTall ? 30 : 15),
|
||||||
SizedBox(height: 30 * ratio),
|
ScaledSizedBox(
|
||||||
SizedBox(
|
width: 350,
|
||||||
width: 400,
|
child: Text(
|
||||||
child: Text(
|
'toUnlockEnterPassword'.tr(),
|
||||||
'toUnlockEnterPassword'.tr(),
|
textAlign: TextAlign.center,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 19,
|
fontSize: 16,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontWeight.w400),
|
fontWeight: FontWeight.w400),
|
||||||
)),
|
)),
|
||||||
SizedBox(height: 40 * ratio),
|
ScaledSizedBox(height: isTall ? 30 : 15),
|
||||||
pinForm(context, pinLenght),
|
if (!myWalletProvider.isPinValid &&
|
||||||
SizedBox(height: 3 * ratio),
|
!myWalletProvider.isPinLoading)
|
||||||
if (canUnlock)
|
Text(
|
||||||
InkWell(
|
"thisIsNotAGoodCode".tr(),
|
||||||
key: keyCachePassword,
|
style: scaledTextStyle(
|
||||||
onTap: () {
|
color: Colors.red,
|
||||||
walletOptions.changePinCacheChoice();
|
fontWeight: FontWeight.w500,
|
||||||
},
|
fontSize: 16),
|
||||||
child: Row(children: [
|
),
|
||||||
const SizedBox(height: 30),
|
ScaledSizedBox(height: isTall ? 8 : 0),
|
||||||
const Spacer(),
|
pinForm(context, pinLenght),
|
||||||
Icon(
|
ScaledSizedBox(height: 8),
|
||||||
configBox.get('isCacheChecked')
|
if (canUnlock)
|
||||||
? Icons.check_box
|
Consumer<WalletOptionsProvider>(
|
||||||
: Icons.check_box_outline_blank,
|
builder: (context, sub, _) {
|
||||||
color: orangeC,
|
return InkWell(
|
||||||
),
|
key: keyCachePassword,
|
||||||
const SizedBox(width: 8),
|
onTap: () {
|
||||||
Text(
|
walletOptions.changePinCacheChoice();
|
||||||
'rememberPassword'.tr(),
|
},
|
||||||
style: TextStyle(
|
child: Row(children: [
|
||||||
fontSize: 16, color: Colors.grey[700]),
|
ScaledSizedBox(height: 30),
|
||||||
),
|
const Spacer(),
|
||||||
const Spacer()
|
Icon(
|
||||||
]),
|
configBox.get('isCacheChecked')
|
||||||
),
|
? Icons.check_box
|
||||||
const SizedBox(height: 10),
|
: Icons.check_box_outline_blank,
|
||||||
// if (canUnlock)
|
color: orangeC,
|
||||||
InkWell(
|
size: scaleSize(22),
|
||||||
key: keyChangeChest,
|
),
|
||||||
onTap: () {
|
ScaledSizedBox(width: 8),
|
||||||
Navigator.push(
|
Text(
|
||||||
context,
|
'rememberPassword'.tr(),
|
||||||
MaterialPageRoute(builder: (context) {
|
style: scaledTextStyle(
|
||||||
return const ChooseChest();
|
fontSize: 15, color: Colors.grey[700]),
|
||||||
}),
|
),
|
||||||
|
const Spacer()
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
},
|
}),
|
||||||
child: SizedBox(
|
// const ScaledSizedBox(height: 10),
|
||||||
width: 400,
|
// if (canUnlock)
|
||||||
height: 50,
|
// InkWell(
|
||||||
child: Center(
|
// key: keyChangeChest,
|
||||||
child: Text(
|
// onTap: () {
|
||||||
'changeChest'.tr(),
|
// // Navigator.push(
|
||||||
style: const TextStyle(
|
// // context,
|
||||||
fontSize: 22,
|
// // MaterialPageRoute(builder: (context) {
|
||||||
color: orangeC,
|
// // return const ChooseChest();
|
||||||
fontWeight: FontWeight.w600),
|
// // }),
|
||||||
),
|
// // );
|
||||||
),
|
// },
|
||||||
)),
|
// child: ScaledSizedBox(
|
||||||
|
// width: 400,
|
||||||
|
// height: 50,
|
||||||
|
// child: Center(
|
||||||
|
// child: Text(
|
||||||
|
// 'changeChest'.tr(),
|
||||||
|
// style: const scaledTextStyle(
|
||||||
|
// 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 scaledTextStyle(
|
||||||
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: scaleSize(3), horizontal: scaleSize(isTall ? 30 : 15)),
|
||||||
child: PinCodeTextField(
|
child: PinCodeTextField(
|
||||||
key: keyPinForm,
|
key: keyPinForm,
|
||||||
|
textCapitalization: TextCapitalization.characters,
|
||||||
focusNode: pinFocus,
|
focusNode: pinFocus,
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
appContext: context,
|
appContext: context,
|
||||||
pastedTextStyle: TextStyle(
|
pastedTextStyle: scaledTextStyle(
|
||||||
color: Colors.green.shade600,
|
color: Colors.green.shade600,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
length: pinLenght,
|
length: pinLenght,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
obscuringCharacter: '*',
|
obscuringCharacter: '*',
|
||||||
animationType: AnimationType.fade,
|
animationType: AnimationType.slide,
|
||||||
|
animationDuration: const Duration(milliseconds: 40),
|
||||||
|
useHapticFeedback: true,
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
if (v!.length < pinLenght) {
|
if (v!.length < pinLenght) {
|
||||||
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
|
return "yourPasswordLengthIsX".tr(args: [pinLenght.toString()]);
|
||||||
|
@ -212,17 +234,15 @@ class UnlockingWallet extends StatelessWidget {
|
||||||
borderWidth: 4,
|
borderWidth: 4,
|
||||||
shape: PinCodeFieldShape.box,
|
shape: PinCodeFieldShape.box,
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
fieldHeight: 50 * ratio,
|
fieldHeight: scaleSize(47),
|
||||||
fieldWidth: 50,
|
fieldWidth: scaleSize(47),
|
||||||
activeFillColor: Colors.black,
|
activeFillColor: Colors.black,
|
||||||
),
|
),
|
||||||
showCursor: kDebugMode ? false : true,
|
showCursor: !kDebugMode,
|
||||||
cursorColor: Colors.black,
|
cursorColor: Colors.black,
|
||||||
animationDuration: const Duration(milliseconds: 300),
|
textStyle: scaledTextStyle(fontSize: 25, 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 +253,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.debounceResetPinCode();
|
||||||
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();
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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/scale_functions.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/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/buttons/manage_membership_button.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,59 +33,62 @@ 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);
|
|
||||||
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(0, 20);
|
|
||||||
|
|
||||||
log.d(walletOptions.address.text);
|
walletOptions.address.text = wallet.address;
|
||||||
|
|
||||||
final int currentChest = myWalletProvider.getCurrentChest();
|
final currentChest = myWalletProvider.getCurrentChest();
|
||||||
|
final isWalletNameIndexed =
|
||||||
|
duniterIndexer.walletNameIndexer[walletOptions.address.text] != null;
|
||||||
|
|
||||||
// final currentWallet = _myWalletProvider.getDefaultWallet();
|
// StreamSubscription<QueryResult>? subscription;
|
||||||
// log.d(_walletOptions.getAddress(_currentChest, 3));
|
// final stream = duniterIndexer.subscribeHistoryIssued(wallet.address);
|
||||||
log.d("Wallet options: $currentChest:${wallet.derivation}");
|
|
||||||
|
|
||||||
return WillPopScope(
|
// subscription = stream.listen((result) {
|
||||||
onWillPop: () {
|
// if (result.hasException) {
|
||||||
|
// log.e(result.exception);
|
||||||
|
// } else {
|
||||||
|
// final Map transData =
|
||||||
|
// result.data?['account_by_pk']['transactions_issued'].first;
|
||||||
|
// final String receiver = transData['receiver_pubkey'];
|
||||||
|
// final double amount = transData['amount'] / 100;
|
||||||
|
// final createdAt = DateTime.parse(transData['created_at']);
|
||||||
|
// log.d('$receiver --- $amount --- $createdAt');
|
||||||
|
|
||||||
|
// subscription?.cancel();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
return PopScope(
|
||||||
|
onPopInvoked: (_) {
|
||||||
walletOptions.isEditing = false;
|
walletOptions.isEditing = false;
|
||||||
walletOptions.isBalanceBlur = false;
|
walletOptions.isBalanceBlur = false;
|
||||||
myWalletProvider.reload();
|
myWalletProvider.reload();
|
||||||
Navigator.pop(context);
|
|
||||||
return Future<bool>.value(true);
|
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
toolbarHeight: 60 * ratio,
|
toolbarHeight: scaleSize(57),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
title: Consumer<WalletOptionsProvider>(
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
builder: (context, walletProvider, _) {
|
||||||
onPressed: () {
|
return Text(
|
||||||
walletOptions.isEditing = false;
|
isWalletNameIndexed
|
||||||
walletOptions.isBalanceBlur = false;
|
? duniterIndexer
|
||||||
myWalletProvider.reload();
|
.walletNameIndexer[walletOptions.address.text]!
|
||||||
Navigator.pop(context);
|
: wallet.name!,
|
||||||
}),
|
style: scaledTextStyle(fontSize: 19),
|
||||||
title: SizedBox(
|
);
|
||||||
height: 22,
|
}),
|
||||||
child: Consumer<WalletOptionsProvider>(
|
|
||||||
builder: (context, walletProvider, _) {
|
|
||||||
return Text(wallet.name!);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -91,21 +101,21 @@ class WalletOptions extends StatelessWidget {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: QrImageWidget(
|
child: QrImageView(
|
||||||
data: walletOptions.address.text,
|
data: walletOptions.address.text,
|
||||||
version: QrVersions.auto,
|
version: QrVersions.auto,
|
||||||
size: 80,
|
size: scaleSize(70),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
body: Stack(children: [
|
body: Stack(children: [
|
||||||
Builder(
|
Builder(
|
||||||
builder: (ctx) => SafeArea(
|
builder: (ctx) => SafeArea(
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: isTall ? 5 : 0,
|
height: 5,
|
||||||
color: yellowC,
|
color: yellowC,
|
||||||
),
|
),
|
||||||
Consumer<WalletOptionsProvider>(
|
Consumer<WalletOptionsProvider>(
|
||||||
|
@ -120,44 +130,100 @@ class WalletOptions extends StatelessWidget {
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
child: Row(
|
child: Row(children: <Widget>[
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
const Spacer(flex: 1),
|
||||||
children: <Widget>[
|
ScaledSizedBox(width: 15),
|
||||||
const Spacer(flex: 1),
|
avatar(walletProvider),
|
||||||
avatar(walletProvider),
|
const Spacer(flex: 1),
|
||||||
const Spacer(flex: 1),
|
Column(
|
||||||
Column(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Stack(children: [
|
||||||
duniterIndexer.getNameByAddress(
|
ScaledSizedBox(
|
||||||
context,
|
width: 230,
|
||||||
walletProvider.address.text,
|
child: Row(
|
||||||
wallet,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
27,
|
children: [
|
||||||
false,
|
Consumer<WalletOptionsProvider>(
|
||||||
Colors.black,
|
builder: (context, walletProvider, _) {
|
||||||
FontWeight.w400,
|
return NameByAddress(
|
||||||
FontStyle.normal),
|
wallet: wallet,
|
||||||
// SizedBox(height: isTall ? 5 : 0),
|
size: 24,
|
||||||
|
color: Colors.black,
|
||||||
SizedBox(height: isTall ? 5 : 0),
|
fontWeight: wallet.identityStatus ==
|
||||||
balance(
|
IdtyStatus.member
|
||||||
context, walletProvider.address.text, 21),
|
? FontWeight.w500
|
||||||
const SizedBox(width: 30),
|
: FontWeight.w400,
|
||||||
Column(
|
fontStyle: FontStyle.normal);
|
||||||
crossAxisAlignment:
|
})
|
||||||
CrossAxisAlignment.center,
|
],
|
||||||
children: [
|
),
|
||||||
walletOptions.idtyStatus(
|
),
|
||||||
context, walletOptions.address.text,
|
ScaledSizedBox(width: 10),
|
||||||
isOwner: true, color: orangeC),
|
if (duniterIndexer
|
||||||
getCerts(context,
|
.walletNameIndexer[wallet.address] ==
|
||||||
walletProvider.address.text, 15),
|
null)
|
||||||
]),
|
Positioned(
|
||||||
SizedBox(height: 10 * ratio),
|
right: 0,
|
||||||
]),
|
child: InkWell(
|
||||||
const Spacer(flex: 2),
|
key: keyRenameWallet,
|
||||||
]),
|
onTap: () async {
|
||||||
|
await walletOptions.editWalletName(
|
||||||
|
context, wallet.id());
|
||||||
|
await Future.delayed(
|
||||||
|
const Duration(milliseconds: 30));
|
||||||
|
},
|
||||||
|
child: ClipRRect(
|
||||||
|
child: Image.asset(
|
||||||
|
walletOptions.isEditing
|
||||||
|
? 'assets/walletOptions/android-checkmark.png'
|
||||||
|
: 'assets/walletOptions/edit.png',
|
||||||
|
width: scaleSize(23),
|
||||||
|
height: scaleSize(23)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
ScaledSizedBox(height: 5),
|
||||||
|
Balance(
|
||||||
|
address: walletProvider.address.text, size: 20),
|
||||||
|
ScaledSizedBox(width: 30),
|
||||||
|
InkWell(
|
||||||
|
onTap: () => sub.certsCounterCache[
|
||||||
|
walletProvider.address.text] !=
|
||||||
|
null
|
||||||
|
? {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
PageNoTransit(builder: (context) {
|
||||||
|
return CertificationsScreen(
|
||||||
|
address:
|
||||||
|
walletProvider.address.text,
|
||||||
|
username: duniterIndexer
|
||||||
|
.walletNameIndexer[
|
||||||
|
walletProvider
|
||||||
|
.address.text] ??
|
||||||
|
'');
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
IdentityStatus(
|
||||||
|
address: walletOptions.address.text,
|
||||||
|
isOwner: true,
|
||||||
|
color: orangeC),
|
||||||
|
Certifications(
|
||||||
|
address: walletProvider.address.text,
|
||||||
|
size: 17)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
ScaledSizedBox(height: 10),
|
||||||
|
]),
|
||||||
|
const Spacer(flex: 2),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -165,62 +231,36 @@ class WalletOptions extends StatelessWidget {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
// InkWell(
|
ScaledSizedBox(height: 25),
|
||||||
// onTap: () {
|
|
||||||
// Navigator.push(
|
|
||||||
// context,
|
|
||||||
// MaterialPageRoute(builder: (context) {
|
|
||||||
// return QrCodeFullscreen(
|
|
||||||
// _walletOptions.address.text,
|
|
||||||
// );
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// child: QrImageWidget(
|
|
||||||
// data: _walletOptions.address.text,
|
|
||||||
// version: QrVersions.auto,
|
|
||||||
// size: isTall ? 150 : 80,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
SizedBox(height: 30 * ratio),
|
|
||||||
Consumer<WalletOptionsProvider>(
|
Consumer<WalletOptionsProvider>(
|
||||||
builder: (context, walletProvider, _) {
|
builder: (context, walletProvider, _) {
|
||||||
|
final defaultWallet =
|
||||||
|
myWalletProvider.getDefaultWallet();
|
||||||
|
walletProvider.isDefaultWallet =
|
||||||
|
walletOptions.address.text ==
|
||||||
|
defaultWallet.address;
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
confirmIdentityButton(walletProvider),
|
confirmIdentityButton(walletProvider),
|
||||||
pubkeyWidget(walletProvider, ctx),
|
pubkeyWidget(walletProvider, ctx),
|
||||||
SizedBox(height: 10 * ratio),
|
ScaledSizedBox(height: 11),
|
||||||
activityWidget(
|
activityWidget(
|
||||||
context, historyProvider, walletProvider),
|
context, historyProvider, walletProvider),
|
||||||
SizedBox(height: 12 * ratio),
|
ScaledSizedBox(height: 11),
|
||||||
setDefaultWalletWidget(
|
setDefaultWalletWidget(
|
||||||
context,
|
context,
|
||||||
walletProvider,
|
walletProvider,
|
||||||
myWalletProvider,
|
myWalletProvider,
|
||||||
walletOptions,
|
walletOptions,
|
||||||
currentChest),
|
currentChest),
|
||||||
SizedBox(height: 17 * ratio),
|
ScaledSizedBox(height: 11),
|
||||||
// walletProvider.isMember(context, _walletOptions.address.text)
|
Column(children: [
|
||||||
FutureBuilder(
|
if (!walletProvider.isDefaultWallet &&
|
||||||
future: walletProvider.isMember(
|
!wallet.isMembre())
|
||||||
context, walletOptions.address.text),
|
deleteWallet(
|
||||||
builder: (BuildContext context,
|
context, walletProvider, currentChest),
|
||||||
AsyncSnapshot<bool> isMember) {
|
if (wallet.isMembre())
|
||||||
if (isMember.connectionState !=
|
const ManageMembershipButton()
|
||||||
ConnectionState.done ||
|
])
|
||||||
isMember.hasError) {
|
|
||||||
return const Text('');
|
|
||||||
}
|
|
||||||
return Column(children: [
|
|
||||||
if (!walletProvider.isDefaultWallet &&
|
|
||||||
!isMember.data!)
|
|
||||||
deleteWallet(context, walletProvider,
|
|
||||||
currentChest)
|
|
||||||
else
|
|
||||||
const SizedBox(),
|
|
||||||
if (isMember.data!)
|
|
||||||
manageMembership(context)
|
|
||||||
]);
|
|
||||||
}),
|
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
@ -229,7 +269,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CommonElements().offlineInfo(context),
|
const OfflineInfo(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -240,21 +280,16 @@ class WalletOptions extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final newPath = await (walletProvider.changeAvatar());
|
await (walletProvider.changeAvatar());
|
||||||
if (newPath != '') {
|
|
||||||
wallet.imageCustomPath = newPath;
|
|
||||||
walletBox.put(wallet.key, wallet);
|
|
||||||
}
|
|
||||||
walletProvider.reload();
|
|
||||||
},
|
},
|
||||||
child: wallet.imageCustomPath == null || wallet.imageCustomPath == ''
|
child: wallet.imageCustomPath == null || wallet.imageCustomPath == ''
|
||||||
? Image.asset(
|
? Image.asset(
|
||||||
'assets/avatars/${wallet.imageDefaultPath}',
|
'assets/avatars/${wallet.imageDefaultPath}',
|
||||||
width: 110,
|
width: scaleSize(122),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
width: 150,
|
width: scaleSize(122),
|
||||||
height: 150,
|
height: scaleSize(122),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
@ -277,7 +312,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/walletOptions/camera.png',
|
'assets/walletOptions/camera.png',
|
||||||
height: 40,
|
height: scaleSize(38),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -288,80 +323,79 @@ class WalletOptions extends StatelessWidget {
|
||||||
Widget confirmIdentityButton(WalletOptionsProvider walletProvider) {
|
Widget confirmIdentityButton(WalletOptionsProvider walletProvider) {
|
||||||
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
return Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: sub.idtyStatus(walletProvider.address.text),
|
future: sub.idtyStatus([walletProvider.address.text]),
|
||||||
initialData: '',
|
initialData: const [IdtyStatus.unknown],
|
||||||
builder: (context, snapshot) {
|
builder:
|
||||||
if (snapshot.data == 'Created') {
|
(BuildContext context, AsyncSnapshot<List<IdtyStatus>> snapshot) {
|
||||||
|
if (!snapshot.hasData || snapshot.hasError) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
if (snapshot.data!.first == IdtyStatus.unconfirmed) {
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
width: 320,
|
width: 310,
|
||||||
height: 60,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyConfirmIdentity,
|
key: keyConfirmIdentity,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
|
backgroundColor: orangeC,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
walletProvider.confirmIdentityPopup(context);
|
walletProvider.confirmIdentityPopup(context);
|
||||||
// Navigator.push(
|
|
||||||
// context,
|
|
||||||
// MaterialPageRoute(builder: (context) {
|
|
||||||
// return const SearchResultScreen();
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'confirmMyIdentity'.tr(),
|
'confirmMyIdentity'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 21, fontWeight: FontWeight.w600),
|
fontSize: 21, fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 7),
|
ScaledSizedBox(height: 7),
|
||||||
Text(
|
Text(
|
||||||
"someoneCreatedYourIdentity".tr(args: [currencyName]),
|
"someoneCreatedYourIdentity".tr(args: [currencyName]),
|
||||||
style: TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Colors.grey[600],
|
color: Colors.grey[600],
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 40),
|
ScaledSizedBox(height: 40),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox();
|
return ScaledSizedBox();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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: () {
|
||||||
Clipboard.setData(ClipboardData(text: walletProvider.address.text));
|
Clipboard.setData(ClipboardData(text: walletProvider.address.text));
|
||||||
snackCopyKey(ctx);
|
snackCopyKey(ctx);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 30),
|
ScaledSizedBox(width: 26),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/walletOptions/key.png',
|
'assets/walletOptions/key.png',
|
||||||
height: 45,
|
height: scaleSize(42),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
ScaledSizedBox(width: 19),
|
||||||
Text(shortPubkey,
|
Text(shortPubkey,
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 22,
|
fontSize: 19,
|
||||||
fontWeight: FontWeight.w800,
|
fontWeight: FontWeight.w800,
|
||||||
fontFamily: 'Monospace',
|
fontFamily: 'Monospace',
|
||||||
color: Colors.black)),
|
color: Colors.black)),
|
||||||
const SizedBox(width: 15),
|
const Spacer(),
|
||||||
SizedBox(
|
ScaledSizedBox(
|
||||||
height: 40,
|
height: 35,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.black,
|
foregroundColor: Colors.black,
|
||||||
|
@ -369,7 +403,7 @@ class WalletOptions extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
backgroundColor: orangeC,
|
backgroundColor: orangeC,
|
||||||
elevation: 1, // foreground
|
elevation: 1,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(
|
Clipboard.setData(
|
||||||
|
@ -379,16 +413,12 @@ class WalletOptions extends StatelessWidget {
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/walletOptions/copy-white.png',
|
'assets/walletOptions/copy-white.png',
|
||||||
height: 25,
|
height: scaleSize(23),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 7),
|
|
||||||
Text(
|
|
||||||
'copy'.tr(),
|
|
||||||
style: TextStyle(fontSize: 15, color: Colors.grey[50]),
|
|
||||||
)
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Spacer(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -401,66 +431,23 @@ class WalletOptions extends StatelessWidget {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
key: keyOpenActivity,
|
key: keyOpenActivity,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// _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
|
|
||||||
? Image.asset(
|
|
||||||
'assets/avatars/${wallet.imageDefaultPath}',
|
|
||||||
width: 110,
|
|
||||||
)
|
|
||||||
: Image.asset(
|
|
||||||
wallet.imageCustomPath!,
|
|
||||||
width: 110,
|
|
||||||
));
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 50,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 30),
|
ScaledSizedBox(width: 26),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/walletOptions/clock.png',
|
'assets/walletOptions/clock.png',
|
||||||
height: 45,
|
height: scaleSize(42),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 22),
|
ScaledSizedBox(width: 20),
|
||||||
Text("displayActivity".tr(),
|
Text("displayActivity".tr(), style: scaledTextStyle(fontSize: 18)),
|
||||||
style:
|
|
||||||
const TextStyle(fontSize: 20, fontWeight: FontWeight.w500)),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget manageMembership(BuildContext context) {
|
|
||||||
WalletOptionsProvider walletOptions =
|
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
|
||||||
return InkWell(
|
|
||||||
key: keyManageMembership,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return ManageMembership(
|
|
||||||
address: walletOptions.address.text,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
height: 40,
|
|
||||||
child: Row(children: <Widget>[
|
|
||||||
const SizedBox(width: 32),
|
|
||||||
Image.asset(
|
|
||||||
'assets/medal.png',
|
|
||||||
height: 45,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 22),
|
|
||||||
Text('manageMembership'.tr(), style: const TextStyle(fontSize: 20)),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -469,8 +456,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();
|
||||||
|
@ -482,28 +469,34 @@ class WalletOptions extends StatelessWidget {
|
||||||
await setDefaultWallet(context, currentChest);
|
await setDefaultWallet(context, currentChest);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: SizedBox(
|
child: ScaledSizedBox(
|
||||||
height: 50,
|
height: 60,
|
||||||
child: Row(children: <Widget>[
|
child: Row(children: <Widget>[
|
||||||
const SizedBox(width: 31),
|
ScaledSizedBox(width: isTall ? 28 : 23),
|
||||||
CircleAvatar(
|
ScaledSizedBox(
|
||||||
backgroundColor:
|
height: 42,
|
||||||
Colors.grey[walletProvider.isDefaultWallet ? 300 : 500],
|
child: CircleAvatar(
|
||||||
child: Image.asset(
|
backgroundColor:
|
||||||
'assets/walletOptions/android-checkmark.png',
|
Colors.grey[walletProvider.isDefaultWallet ? 300 : 500],
|
||||||
height: 25,
|
child: Image.asset(
|
||||||
|
'assets/walletOptions/android-checkmark.png',
|
||||||
|
height: scaleSize(23),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 22),
|
ScaledSizedBox(width: isTall ? 21 : 18),
|
||||||
Text(
|
ScaledSizedBox(
|
||||||
walletProvider.isDefaultWallet
|
width: 250,
|
||||||
? 'thisWalletIsDefault'.tr()
|
child: Text(
|
||||||
: 'defineWalletAsDefault'.tr(),
|
walletProvider.isDefaultWallet
|
||||||
style: TextStyle(
|
? 'thisWalletIsDefault'.tr()
|
||||||
fontSize: 20,
|
: 'defineWalletAsDefault'.tr(),
|
||||||
color: walletProvider.isDefaultWallet
|
style: scaledTextStyle(
|
||||||
? Colors.grey[500]
|
fontSize: 18,
|
||||||
: Colors.black)),
|
color: walletProvider.isDefaultWallet
|
||||||
|
? Colors.grey[500]
|
||||||
|
: Colors.black)),
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -511,68 +504,66 @@ 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()!;
|
|
||||||
// defaultWallet = wallet;
|
|
||||||
await sub.setCurrentWallet(wallet);
|
await sub.setCurrentWallet(wallet);
|
||||||
myWalletProvider.readAllWallets(currentChest);
|
await myWalletProvider.readAllWallets(currentChest);
|
||||||
myWalletProvider.reload();
|
myWalletProvider.reload();
|
||||||
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>(
|
|
||||||
// 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 ||
|
||||||
|
!hasConsumers.hasData) {
|
||||||
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) &&
|
||||||
|
!wallet.hasIdentity();
|
||||||
return InkWell(
|
return InkWell(
|
||||||
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((_) async {
|
||||||
myWalletProvider.listWallets =
|
myWalletProvider.listWallets =
|
||||||
myWalletProvider.readAllWallets(currentChest);
|
await myWalletProvider.readAllWallets(currentChest);
|
||||||
myWalletProvider.reload();
|
myWalletProvider.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: canDelete
|
child: canDelete
|
||||||
? Row(children: <Widget>[
|
? Row(children: <Widget>[
|
||||||
const SizedBox(width: 30),
|
ScaledSizedBox(width: 27),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/walletOptions/trash.png',
|
'assets/walletOptions/trash.png',
|
||||||
height: 45,
|
height: scaleSize(42),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 19),
|
ScaledSizedBox(width: 19),
|
||||||
Text('deleteThisWallet'.tr(),
|
Text('deleteThisWallet'.tr(),
|
||||||
style: const TextStyle(
|
style: scaledTextStyle(
|
||||||
fontSize: 20, color: Color(0xffD80000))),
|
fontSize: 18, color: const Color(0xffD80000))),
|
||||||
])
|
])
|
||||||
: const SizedBox(width: 30),
|
: ScaledSizedBox(width: 30),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,200 +1,108 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
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: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/scale_functions.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/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/widgets/bottom_app_bar.dart';
|
||||||
import 'package:gecko/screens/common_elements.dart';
|
import 'package:gecko/widgets/buttons/add_new_derivation_button.dart';
|
||||||
import 'package:gecko/screens/myWallets/chest_options.dart';
|
import 'package:gecko/widgets/buttons/chest_options_buttons.dart';
|
||||||
import 'package:gecko/screens/myWallets/choose_chest.dart';
|
import 'package:gecko/widgets/commons/offline_info.dart';
|
||||||
import 'package:gecko/screens/myWallets/import_g1_v1.dart';
|
import 'package:gecko/widgets/drag_tule_action.dart';
|
||||||
import 'package:gecko/screens/myWallets/unlocking_wallet.dart';
|
import 'package:gecko/widgets/drag_wallets_info.dart';
|
||||||
import 'package:gecko/screens/myWallets/wallet_options.dart';
|
import 'package:gecko/widgets/wallet_tile.dart';
|
||||||
import 'package:gecko/screens/wallet_view.dart';
|
import 'package:gecko/widgets/wallet_tile_membre.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.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 ChestData currentChest = chestBox.get(currentChestNumber)!;
|
@override
|
||||||
myWalletProvider.listWallets =
|
void initState() {
|
||||||
myWalletProvider.readAllWallets(currentChestNumber);
|
super.initState();
|
||||||
|
|
||||||
return WillPopScope(
|
|
||||||
onWillPop: () {
|
|
||||||
Navigator.popUntil(
|
|
||||||
context,
|
|
||||||
ModalRoute.withName('/'),
|
|
||||||
);
|
|
||||||
return Future<bool>.value(true);
|
|
||||||
},
|
|
||||||
child: Scaffold(
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
appBar: AppBar(
|
|
||||||
elevation: 1,
|
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.black),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.popUntil(
|
|
||||||
context,
|
|
||||||
ModalRoute.withName('/'),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
title: Text(currentChest.name!,
|
|
||||||
style: TextStyle(color: Colors.grey[850])),
|
|
||||||
backgroundColor: const Color(0xffFFD58D),
|
|
||||||
),
|
|
||||||
bottomNavigationBar: myWalletProvider.lastFlyBy == ''
|
|
||||||
? homeProvider.bottomAppBar(context)
|
|
||||||
: dragInfo(context),
|
|
||||||
body: SafeArea(
|
|
||||||
child: Stack(children: [
|
|
||||||
myWalletsTiles(context, currentChestNumber),
|
|
||||||
CommonElements().offlineInfo(context),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget dragInfo(BuildContext context) {
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
final myWalletProvider =
|
final myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
|
|
||||||
final walletDataFrom =
|
final currentChestNumber = myWalletProvider.getCurrentChest();
|
||||||
myWalletProvider.getWalletDataByAddress(myWalletProvider.dragAddress);
|
final ChestData currentChest = chestBox.get(currentChestNumber)!;
|
||||||
final walletDataTo =
|
|
||||||
myWalletProvider.getWalletDataByAddress(myWalletProvider.lastFlyBy);
|
|
||||||
|
|
||||||
final bool isSameAddress =
|
return Scaffold(
|
||||||
myWalletProvider.dragAddress == myWalletProvider.lastFlyBy;
|
backgroundColor: backgroundColor,
|
||||||
|
appBar: AppBar(
|
||||||
final double screenWidth = MediaQuery.of(homeContext).size.width;
|
backgroundColor: yellowC,
|
||||||
return Container(
|
toolbarHeight: scaleSize(57),
|
||||||
color: yellowC,
|
title: Row(
|
||||||
width: screenWidth,
|
children: [
|
||||||
height: 80,
|
Image.asset(
|
||||||
child: Center(
|
'assets/chests/${currentChest.imageName}',
|
||||||
child: Column(
|
height: 32,
|
||||||
children: [
|
),
|
||||||
const SizedBox(height: 5),
|
ScaledSizedBox(width: 17),
|
||||||
Text('${'executeATransfer'.tr()}:'),
|
Text(
|
||||||
MarkdownBody(data: '${'from'.tr()} **${walletDataFrom!.name}**'),
|
currentChest.name!,
|
||||||
if (isSameAddress) Text('chooseATargetWallet'.tr()),
|
style: scaledTextStyle(
|
||||||
if (!isSameAddress)
|
color: Colors.grey[850],
|
||||||
MarkdownBody(data: 'Vers: **${walletDataTo!.name}**'),
|
fontSize: 17,
|
||||||
],
|
fontWeight: FontWeight.w500),
|
||||||
)),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bottomNavigationBar:
|
||||||
|
Consumer<MyWalletsProvider>(builder: (context, _, __) {
|
||||||
|
return myWalletProvider.lastFlyBy == null
|
||||||
|
? const GeckoBottomAppBar(
|
||||||
|
actualRoute: 'safeHome',
|
||||||
|
)
|
||||||
|
: DragWalletsInfo(
|
||||||
|
lastFlyBy: myWalletProvider.lastFlyBy!,
|
||||||
|
dragAddress: myWalletProvider.dragAddress!,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: myWalletProvider.readAllWallets(currentChestNumber),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState != ConnectionState.done ||
|
||||||
|
snapshot.hasError) {
|
||||||
|
return Center(
|
||||||
|
child: ScaledSizedBox(
|
||||||
|
height: 50,
|
||||||
|
width: 50,
|
||||||
|
child: const CircularProgressIndicator(
|
||||||
|
color: orangeC,
|
||||||
|
strokeWidth: 3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return SafeArea(
|
||||||
|
child: Stack(children: [
|
||||||
|
myWalletsTiles(context, currentChestNumber),
|
||||||
|
const OfflineInfo(),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget chestOptions(
|
|
||||||
BuildContext context, MyWalletsProvider myWalletProvider) {
|
|
||||||
return Column(children: [
|
|
||||||
const SizedBox(height: 50),
|
|
||||||
SizedBox(
|
|
||||||
height: 80,
|
|
||||||
width: 420,
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
icon: Image.asset(
|
|
||||||
'assets/chests/config.png',
|
|
||||||
height: 60,
|
|
||||||
),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
foregroundColor: Colors.black, elevation: 2,
|
|
||||||
backgroundColor: floattingYellow, // foreground
|
|
||||||
),
|
|
||||||
onPressed: () => Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return ChestOptions(walletProvider: myWalletProvider);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
label: Text(
|
|
||||||
" ${"manageChest".tr()}",
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 22,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
color: Color(0xff8a3c0f),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
InkWell(
|
|
||||||
key: keyImportG1v1,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const ImportG1v1();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
width: 400,
|
|
||||||
height: 60,
|
|
||||||
child: Center(
|
|
||||||
child: Text('importG1v1'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 22,
|
|
||||||
color: Colors.blue[900],
|
|
||||||
fontWeight: FontWeight.w500))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
InkWell(
|
|
||||||
key: keyChangeChest,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) {
|
|
||||||
return const ChooseChest();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
width: 400,
|
|
||||||
height: 60,
|
|
||||||
child: Center(
|
|
||||||
child: Text('changeChest'.tr(),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 22,
|
|
||||||
color: orangeC,
|
|
||||||
fontWeight: FontWeight.w500))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 bool isWalletsExists = myWalletProvider.isWalletsExists();
|
||||||
WalletOptionsProvider walletOptions =
|
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
|
||||||
final bool isWalletsExists = myWalletProvider.checkIfWalletExist();
|
|
||||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
|
||||||
|
|
||||||
if (!isWalletsExists) {
|
if (!isWalletsExists) {
|
||||||
return const Text('');
|
return const Text('');
|
||||||
|
@ -202,354 +110,112 @@ class WalletsHome extends StatelessWidget {
|
||||||
|
|
||||||
if (myWalletProvider.listWallets.isEmpty) {
|
if (myWalletProvider.listWallets.isEmpty) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Column(children: const <Widget>[
|
child: Column(children: <Widget>[
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Veuillez générer votre premier portefeuille',
|
'Veuillez générer votre premier portefeuille',
|
||||||
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
|
style: scaledTextStyle(fontSize: 17, fontWeight: FontWeight.w500),
|
||||||
)),
|
)),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
List listWallets = myWalletProvider.listWallets;
|
// Get wallet list and sort by derivation number
|
||||||
WalletData? defaultWallet = myWalletProvider.getDefaultWallet();
|
List<WalletData> listWallets = myWalletProvider.listWallets;
|
||||||
final double screenWidth = MediaQuery.of(context).size.width;
|
listWallets.sort((p1, p2) {
|
||||||
int nTule = 2;
|
return Comparable.compare(p1.number!, p2.number!);
|
||||||
|
});
|
||||||
|
|
||||||
if (screenWidth >= 900) {
|
// Get first wallet with identity
|
||||||
nTule = 4;
|
final idtyWallet = listWallets.firstWhere(
|
||||||
} else if (screenWidth >= 650) {
|
(w) => w.hasIdentity(),
|
||||||
nTule = 3;
|
orElse: () => WalletData(address: ''),
|
||||||
}
|
|
||||||
// Offset followDragAnchorStrategy(
|
|
||||||
// Draggable<Object> d, BuildContext context, Offset point) {
|
|
||||||
// return Offset(d.feedbackOffset.dx - 30, d.feedbackOffset.dy - 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return CustomScrollView(slivers: <Widget>[
|
|
||||||
const SliverToBoxAdapter(child: SizedBox(height: 20)),
|
|
||||||
SliverGrid.count(
|
|
||||||
key: keyListWallets,
|
|
||||||
crossAxisCount: nTule,
|
|
||||||
childAspectRatio: 1,
|
|
||||||
crossAxisSpacing: 0,
|
|
||||||
mainAxisSpacing: 0,
|
|
||||||
children: <Widget>[
|
|
||||||
for (WalletData repository in listWallets as Iterable<WalletData>)
|
|
||||||
LongPressDraggable<String>(
|
|
||||||
delay: const Duration(milliseconds: 200),
|
|
||||||
data: repository.address!,
|
|
||||||
dragAnchorStrategy:
|
|
||||||
(Draggable<Object> _, BuildContext __, Offset ___) =>
|
|
||||||
const Offset(0, 0),
|
|
||||||
// feedbackOffset: const Offset(-500, -500),
|
|
||||||
// dragAnchorStrategy: childDragAnchorStrategy,
|
|
||||||
onDragStarted: () =>
|
|
||||||
myWalletProvider.dragAddress = repository.address!,
|
|
||||||
onDragEnd: (_) {
|
|
||||||
myWalletProvider.lastFlyBy = '';
|
|
||||||
myWalletProvider.dragAddress = '';
|
|
||||||
myWalletProvider.reload();
|
|
||||||
},
|
|
||||||
feedback: ElevatedButton(
|
|
||||||
onPressed: () {},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: orangeC,
|
|
||||||
shape: const CircleBorder(),
|
|
||||||
padding: const EdgeInsets.all(15),
|
|
||||||
),
|
|
||||||
child: const SizedBox(
|
|
||||||
height: 35,
|
|
||||||
child: Image(image: AssetImage('assets/vector_white.png')),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: DragTarget<String>(
|
|
||||||
onAccept: (senderAddress) async {
|
|
||||||
log.d(
|
|
||||||
'INTERPAY: sender: $senderAddress --- receiver: ${repository.address!}');
|
|
||||||
final walletData = myWalletProvider
|
|
||||||
.getWalletDataByAddress(senderAddress);
|
|
||||||
await sub.setCurrentWallet(walletData!);
|
|
||||||
sub.reload();
|
|
||||||
paymentPopup(context, repository.address!);
|
|
||||||
},
|
|
||||||
onMove: (details) {
|
|
||||||
if (repository.address! != myWalletProvider.lastFlyBy) {
|
|
||||||
myWalletProvider.lastFlyBy = repository.address!;
|
|
||||||
myWalletProvider.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onWillAccept: (senderAddress) =>
|
|
||||||
senderAddress != repository.address!,
|
|
||||||
builder: (
|
|
||||||
BuildContext context,
|
|
||||||
List<dynamic> accepted,
|
|
||||||
List<dynamic> rejected,
|
|
||||||
) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
child: GestureDetector(
|
|
||||||
key: keyOpenWallet(repository.address!),
|
|
||||||
onTap: () {
|
|
||||||
walletOptions.getAddress(
|
|
||||||
currentChestNumber, repository.derivation!);
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
SmoothTransition(
|
|
||||||
page: WalletOptions(
|
|
||||||
wallet: repository,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: ClipOvalShadow(
|
|
||||||
shadow: const Shadow(
|
|
||||||
color: Colors.transparent,
|
|
||||||
offset: Offset(0, 0),
|
|
||||||
blurRadius: 5,
|
|
||||||
),
|
|
||||||
clipper: CustomClipperOval(),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius:
|
|
||||||
const BorderRadius.all(Radius.circular(12)),
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: RadialGradient(
|
|
||||||
radius: 0.6,
|
|
||||||
colors: [
|
|
||||||
Colors.green[400]!,
|
|
||||||
const Color(0xFFE7E7A6),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
child:
|
|
||||||
// SvgPicture.asset('assets/chopp-gecko2.png',
|
|
||||||
// semanticsLabel: 'Gecko', height: 48),
|
|
||||||
repository.imageCustomPath == null ||
|
|
||||||
repository.imageCustomPath == ''
|
|
||||||
? Image.asset(
|
|
||||||
'assets/avatars/${repository.imageDefaultPath}',
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
scale: 0.5,
|
|
||||||
)
|
|
||||||
: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
color: Colors.transparent,
|
|
||||||
image: DecorationImage(
|
|
||||||
fit: BoxFit.fitHeight,
|
|
||||||
image: FileImage(
|
|
||||||
File(repository
|
|
||||||
.imageCustomPath!),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
Stack(children: <Widget>[
|
|
||||||
balanceBuilder(
|
|
||||||
context,
|
|
||||||
repository.address!,
|
|
||||||
repository.address ==
|
|
||||||
defaultWallet.address),
|
|
||||||
nameBuilder(context, repository,
|
|
||||||
defaultWallet, currentChestNumber),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
|
||||||
return sub.nodeConnected
|
|
||||||
? addNewDerivation(context)
|
|
||||||
: const Text('');
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
SliverToBoxAdapter(child: chestOptions(context, myWalletProvider)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
List<WalletData> listWalletsWithoutIdty = listWallets.toList();
|
||||||
WalletData defaultWallet, int currentChestNumber) {
|
listWalletsWithoutIdty.removeWhere((w) => w.address == idtyWallet.address);
|
||||||
WalletOptionsProvider walletOptions =
|
|
||||||
Provider.of<WalletOptionsProvider>(context, listen: false);
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
DuniterIndexer duniterIndexer =
|
int nTule;
|
||||||
Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
return ListTile(
|
if (screenWidth >= 700) {
|
||||||
shape: const RoundedRectangleBorder(
|
nTule = 4;
|
||||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))),
|
} else if (screenWidth >= 450) {
|
||||||
tileColor: repository.address == defaultWallet.address
|
nTule = 3;
|
||||||
? orangeC
|
} else {
|
||||||
: const Color(0xffFFD58D),
|
nTule = 2;
|
||||||
title: Center(
|
}
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 5, right: 5, bottom: 35, top: 5),
|
final tutorialCoachMark = TutorialCoachMark(
|
||||||
child: duniterIndexer.getNameByAddress(
|
targets: [
|
||||||
context,
|
TargetFocus(
|
||||||
repository.address!,
|
identify: "drag_and_drop",
|
||||||
repository,
|
keyTarget: keyDragAndDrop,
|
||||||
20,
|
contents: [
|
||||||
true,
|
TargetContent(
|
||||||
repository.id()[1] == defaultWallet.id()[1]
|
child: Column(
|
||||||
? const Color(0xffF9F9F1)
|
children: [
|
||||||
: Colors.black),
|
Image.asset('assets/drag-and-drop.png', height: scaleSize(115)),
|
||||||
|
ScaledSizedBox(height: 15),
|
||||||
|
Text(
|
||||||
|
'explainDraggableWallet'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: scaledTextStyle(
|
||||||
|
fontSize: 17, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
|
alignSkip: Alignment.bottomRight,
|
||||||
|
enableOverlayTab: true,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
onTap: () {
|
colorShadow: orangeC,
|
||||||
walletOptions.getAddress(currentChestNumber, repository.derivation!);
|
textSkip: "skip".tr(),
|
||||||
Navigator.push(
|
paddingFocus: 10,
|
||||||
context,
|
opacityShadow: 0.8,
|
||||||
SmoothTransition(
|
);
|
||||||
page: WalletOptions(
|
|
||||||
wallet: repository,
|
// configBox.delete('showDraggableTutorial');
|
||||||
|
final bool showDraggableTutorial =
|
||||||
|
configBox.get('showDraggableTutorial') ?? true;
|
||||||
|
|
||||||
|
if (listWallets.length > 1 && showDraggableTutorial) {
|
||||||
|
tutorialCoachMark.show(context: context);
|
||||||
|
configBox.put('showDraggableTutorial', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||||
|
child: CustomScrollView(slivers: <Widget>[
|
||||||
|
SliverToBoxAdapter(child: ScaledSizedBox(height: 12)),
|
||||||
|
if (idtyWallet.address != '')
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: DragTuleAction(
|
||||||
|
wallet: idtyWallet,
|
||||||
|
child: WalletTileMembre(repository: idtyWallet),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
SliverGrid.count(
|
||||||
},
|
key: keyListWallets,
|
||||||
);
|
crossAxisCount: nTule,
|
||||||
}
|
childAspectRatio: 1,
|
||||||
|
crossAxisSpacing: 0,
|
||||||
Widget addNewDerivation(context) {
|
mainAxisSpacing: 0,
|
||||||
MyWalletsProvider myWalletProvider =
|
children: <Widget>[
|
||||||
Provider.of<MyWalletsProvider>(context);
|
for (WalletData repository in listWalletsWithoutIdty)
|
||||||
|
DragTuleAction(
|
||||||
String newDerivationName =
|
wallet: repository,
|
||||||
'${'wallet'.tr()} ${myWalletProvider.listWallets.last.number! + 2}';
|
child: WalletTile(repository: repository),
|
||||||
return Padding(
|
),
|
||||||
padding: const EdgeInsets.all(16),
|
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
child: ClipRRect(
|
return sub.nodeConnected &&
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
myWalletProvider.listWallets.length < maxWalletsInSafe
|
||||||
child: Column(children: <Widget>[
|
? const AddNewDerivationButton()
|
||||||
Expanded(
|
: const Text('');
|
||||||
child: InkWell(
|
}),
|
||||||
key: keyAddDerivation,
|
]),
|
||||||
onTap: () async {
|
const SliverToBoxAdapter(child: ChestOptionsButtons()),
|
||||||
if (!myWalletProvider.isNewDerivationLoading) {
|
]),
|
||||||
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 != '') {
|
|
||||||
await myWalletProvider.generateNewDerivation(
|
|
||||||
context, newDerivationName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: double.infinity,
|
|
||||||
decoration: const BoxDecoration(color: floattingYellow),
|
|
||||||
child: Center(
|
|
||||||
child: myWalletProvider.isNewDerivationLoading
|
|
||||||
? const SizedBox(
|
|
||||||
height: 60,
|
|
||||||
width: 60,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: orangeC,
|
|
||||||
strokeWidth: 7,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: const Text(
|
|
||||||
'+',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 150,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
color: Color(0xFFFCB437)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomClipperOval extends CustomClipper<Rect> {
|
|
||||||
@override
|
|
||||||
Rect getClip(Size size) {
|
|
||||||
return Rect.fromCircle(
|
|
||||||
center: Offset(size.width / 2, size.width / 2),
|
|
||||||
radius: size.width / 2 + 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldReclip(CustomClipper<Rect> oldClipper) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClipOvalShadow extends StatelessWidget {
|
|
||||||
final Shadow shadow;
|
|
||||||
final CustomClipper<Rect> clipper;
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const ClipOvalShadow({
|
|
||||||
Key? key,
|
|
||||||
required this.shadow,
|
|
||||||
required this.clipper,
|
|
||||||
required this.child,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return CustomPaint(
|
|
||||||
painter: _ClipOvalShadowPainter(
|
|
||||||
clipper: clipper,
|
|
||||||
shadow: shadow,
|
|
||||||
),
|
|
||||||
child: ClipRect(clipper: clipper, child: child),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ClipOvalShadowPainter extends CustomPainter {
|
|
||||||
final Shadow shadow;
|
|
||||||
final CustomClipper<Rect> clipper;
|
|
||||||
|
|
||||||
_ClipOvalShadowPainter({required this.shadow, required this.clipper});
|
|
||||||
|
|
||||||
@override
|
|
||||||
void paint(Canvas canvas, Size size) {
|
|
||||||
var paint = shadow.toPaint();
|
|
||||||
var clipRect = clipper.getClip(size).shift(const Offset(0, 0));
|
|
||||||
canvas.drawOval(clipRect, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
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/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/commons/top_appbar.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 +13,10 @@ class ContactsScreen extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
Provider.of<WalletsProfilesProvider>(context, listen: true);
|
||||||
CesiumPlusProvider cesiumPlusProvider =
|
|
||||||
Provider.of<CesiumPlusProvider>(context, listen: false);
|
|
||||||
WalletsProfilesProvider walletsProfilesClass =
|
|
||||||
Provider.of<WalletsProfilesProvider>(context, listen: true);
|
|
||||||
HomeProvider homeProvider =
|
|
||||||
Provider.of<HomeProvider>(context, listen: false);
|
|
||||||
DuniterIndexer duniterIndexer =
|
|
||||||
Provider.of<DuniterIndexer>(context, listen: false);
|
|
||||||
|
|
||||||
double avatarSize = 55;
|
|
||||||
|
|
||||||
final myContacts = contactsBox.toMap().values.toList();
|
final myContacts = contactsBox.toMap().values.toList();
|
||||||
|
|
||||||
// for (var element in myContacts) {
|
// Order contacts by username
|
||||||
// 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');
|
||||||
|
@ -44,96 +24,13 @@ class ContactsScreen extends StatelessWidget {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: GeckoAppBar(
|
||||||
elevation: 1,
|
'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])),
|
||||||
toolbarHeight: 60 * ratio,
|
bottomNavigationBar: const GeckoBottomAppBar(),
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(
|
|
||||||
'contactsManagementWithNbr'.tr(args: ['${myContacts.length}'])),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
bottomNavigationBar: homeProvider.bottomAppBar(context),
|
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
Padding(
|
ContactsList(myContacts: myContacts),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
const OfflineInfo(),
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
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),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,43 +1,31 @@
|
||||||
// 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';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.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: GeckoAppBar('newWallet'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(
|
|
||||||
'newWallet'.tr(),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
// ignore_for_file: file_names
|
// ignore_for_file: file_names
|
||||||
// ignore_for_file: must_be_immutable
|
// ignore_for_file: must_be_immutable
|
||||||
|
|
||||||
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/scale_functions.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/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/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:gecko/widgets/commons/top_appbar.dart';
|
||||||
|
import 'package:gecko/widgets/scan_derivations_info.dart';
|
||||||
import 'package:pin_code_fields/pin_code_fields.dart';
|
import 'package:pin_code_fields/pin_code_fields.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -26,126 +30,110 @@ 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;
|
||||||
|
final 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 PopScope(
|
||||||
backgroundColor: backgroundColor,
|
onPopInvoked: (_) {
|
||||||
appBar: AppBar(
|
myWalletProvider.isPinValid = false;
|
||||||
toolbarHeight: 60 * ratio,
|
myWalletProvider.isPinLoading = true;
|
||||||
title: SizedBox(
|
},
|
||||||
height: 22,
|
child: Scaffold(
|
||||||
child: Text(
|
backgroundColor: backgroundColor,
|
||||||
'myPassword'.tr(),
|
appBar: GeckoAppBar('myPassword'.tr()),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
body: SafeArea(
|
||||||
),
|
child: Stack(children: [
|
||||||
),
|
Column(children: <Widget>[
|
||||||
),
|
ScaledSizedBox(height: isTall ? 25 : 5),
|
||||||
extendBodyBehindAppBar: true,
|
const BuildProgressBar(pagePosition: 9),
|
||||||
body: SafeArea(
|
ScaledSizedBox(height: isTall ? 25 : 5),
|
||||||
child: Stack(children: [
|
BuildText(text: "geckoWillCheckPassword".tr()),
|
||||||
Column(children: <Widget>[
|
ScaledSizedBox(height: isTall ? 25 : 0),
|
||||||
SizedBox(height: isTall ? 40 : 20),
|
const ScanDerivationsInfo(),
|
||||||
common.buildProgressBar(9),
|
Consumer<MyWalletsProvider>(builder: (context, mw, _) {
|
||||||
SizedBox(height: isTall ? 40 : 20),
|
return Visibility(
|
||||||
common.buildText("geckoWillCheckPassword".tr()),
|
visible: !myWalletProvider.isPinValid &&
|
||||||
SizedBox(height: isTall ? 80 : 20),
|
!myWalletProvider.isPinLoading,
|
||||||
Visibility(
|
child: Text(
|
||||||
visible: generateWalletProvider.scanedValidWalletNumber != -1,
|
"thisIsNotAGoodCode".tr(),
|
||||||
child: Padding(
|
style: scaledTextStyle(
|
||||||
padding: const EdgeInsets.only(bottom: 15),
|
fontSize: 16,
|
||||||
child: Row(
|
color: Colors.red,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
fontWeight: FontWeight.w500),
|
||||||
children: [
|
),
|
||||||
Text("derivationsScanProgress".tr(args: [
|
);
|
||||||
'${generateWalletProvider.scanedWalletNumber}',
|
}),
|
||||||
'${generateWalletProvider.numberScan + 1}'
|
ScaledSizedBox(height: isTall ? 20 : 0),
|
||||||
])),
|
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
||||||
const SizedBox(width: 10),
|
return sub.nodeConnected
|
||||||
const SizedBox(
|
? pinForm(context, walletOptions, pinLenght, 1, 2)
|
||||||
height: 22,
|
: Row(
|
||||||
width: 22,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: CircularProgressIndicator(
|
children: [
|
||||||
color: orangeC,
|
Text(
|
||||||
strokeWidth: 3,
|
"youHaveToBeConnectedToValidateChest".tr(),
|
||||||
),
|
style: scaledTextStyle(
|
||||||
),
|
fontSize: 17,
|
||||||
],
|
color: Colors.redAccent,
|
||||||
),
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
textAlign: TextAlign.center,
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
|
||||||
return sub.nodeConnected
|
|
||||||
? pinForm(context, walletOptions, pinLenght, 1, 2)
|
|
||||||
: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: const [
|
|
||||||
Text(
|
|
||||||
'Vous devez vous connecter à internet\npour valider votre coffre',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
color: Colors.redAccent,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
]);
|
||||||
|
}),
|
||||||
|
Consumer<WalletOptionsProvider>(
|
||||||
|
builder: (context, walletOptions, _) {
|
||||||
|
return sub.nodeConnected
|
||||||
|
? InkWell(
|
||||||
|
key: keyCachePassword,
|
||||||
|
onTap: () {
|
||||||
|
walletOptions.changePinCacheChoice();
|
||||||
|
},
|
||||||
|
child: Row(children: [
|
||||||
|
ScaledSizedBox(height: isTall ? 30 : 0),
|
||||||
|
const Spacer(),
|
||||||
|
Icon(
|
||||||
|
configBox.get('isCacheChecked') ?? false
|
||||||
|
? Icons.check_box
|
||||||
|
: Icons.check_box_outline_blank,
|
||||||
|
color: orangeC,
|
||||||
|
size: scaleSize(22),
|
||||||
),
|
),
|
||||||
]);
|
ScaledSizedBox(width: 8),
|
||||||
}),
|
Text(
|
||||||
Consumer<SubstrateSdk>(builder: (context, sub, _) {
|
'rememberPassword'.tr(),
|
||||||
return sub.nodeConnected
|
style: scaledTextStyle(
|
||||||
? InkWell(
|
fontSize: 15, color: Colors.grey[700]),
|
||||||
key: keyCachePassword,
|
),
|
||||||
onTap: () {
|
const Spacer()
|
||||||
walletOptions.changePinCacheChoice();
|
]))
|
||||||
},
|
: const Text('');
|
||||||
child: Row(children: [
|
}),
|
||||||
const SizedBox(height: 30),
|
]),
|
||||||
const Spacer(),
|
const OfflineInfo(),
|
||||||
Icon(
|
|
||||||
configBox.get('isCacheChecked') ?? false
|
|
||||||
? Icons.check_box
|
|
||||||
: Icons.check_box_outline_blank,
|
|
||||||
color: orangeC,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
Text(
|
|
||||||
'rememberPassword'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16, color: Colors.grey[700]),
|
|
||||||
),
|
|
||||||
const Spacer()
|
|
||||||
]))
|
|
||||||
: const Text('');
|
|
||||||
}),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
]),
|
]),
|
||||||
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 +141,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 +153,9 @@ class OnboardingStepTen extends StatelessWidget {
|
||||||
length: pinLenght,
|
length: pinLenght,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
obscuringCharacter: '*',
|
obscuringCharacter: '*',
|
||||||
animationType: AnimationType.fade,
|
useHapticFeedback: true,
|
||||||
|
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 +168,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: scaleSize(47),
|
||||||
fieldWidth: 50,
|
fieldWidth: scaleSize(47),
|
||||||
activeFillColor: hasError ? Colors.blueAccent : Colors.black,
|
activeFillColor: Colors.black,
|
||||||
),
|
),
|
||||||
showCursor: kDebugMode ? false : true,
|
showCursor: !kDebugMode,
|
||||||
cursorColor: Colors.black,
|
cursorColor: Colors.black,
|
||||||
animationDuration: const Duration(milliseconds: 300),
|
textStyle: const TextStyle(fontSize: 25, 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 [
|
||||||
|
@ -198,9 +189,10 @@ class OnboardingStepTen extends StatelessWidget {
|
||||||
onCompleted: (pin) async {
|
onCompleted: (pin) async {
|
||||||
myWalletProvider.pinCode = pin.toUpperCase();
|
myWalletProvider.pinCode = pin.toUpperCase();
|
||||||
myWalletProvider.pinLenght = pinLenght;
|
myWalletProvider.pinLenght = pinLenght;
|
||||||
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,38 +206,40 @@ 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);
|
await myWalletProvider.readAllWallets(currentChest);
|
||||||
myWalletProvider.reload();
|
myWalletProvider.reload();
|
||||||
|
|
||||||
generateWalletProvider.generatedMnemonic = '';
|
generateWalletProvider.generatedMnemonic = '';
|
||||||
myWalletProvider.resetPinCode();
|
myWalletProvider.debounceResetPinCode();
|
||||||
// sleep(const Duration(milliseconds: 500));
|
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
FaderTransition(
|
FaderTransition(
|
||||||
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 = '';
|
||||||
|
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();
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,83 +1,98 @@
|
||||||
// ignore_for_file: file_names
|
// ignore_for_file: file_names
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
import 'package:confetti/confetti.dart';
|
||||||
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/scale_functions.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';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.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]);
|
final conffetiController =
|
||||||
CommonElements common = CommonElements();
|
ConfettiController(duration: const Duration(milliseconds: 500));
|
||||||
|
conffetiController.play();
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
backgroundColor: backgroundColor,
|
canPop: false,
|
||||||
appBar: AppBar(
|
child: Scaffold(
|
||||||
toolbarHeight: 60 * ratio,
|
backgroundColor: backgroundColor,
|
||||||
title: SizedBox(
|
appBar: GeckoAppBar('allGood'.tr()),
|
||||||
height: 22,
|
body: SafeArea(
|
||||||
child: Text(
|
child: Stack(children: [
|
||||||
'allGood'.tr(),
|
Column(children: <Widget>[
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
ScaledSizedBox(height: isTall ? 25 : 5),
|
||||||
),
|
BuildText(
|
||||||
),
|
text: "yourChestAndWalletWereCreatedSuccessfully".tr()),
|
||||||
),
|
ScaledSizedBox(height: isTall ? 15 : 5),
|
||||||
extendBodyBehindAppBar: true,
|
Image.asset(
|
||||||
body: SafeArea(
|
'assets/onBoarding/gecko-clin.gif',
|
||||||
child: Column(children: <Widget>[
|
height: scaleSize(isTall ? 330 : 280),
|
||||||
const SizedBox(height: 40),
|
),
|
||||||
common.buildText("yourChestAndWalletWereCreatedSuccessfully".tr()),
|
Expanded(
|
||||||
SizedBox(height: isTall ? 20 : 10),
|
child: Align(
|
||||||
Image.asset(
|
alignment: Alignment.bottomCenter,
|
||||||
'assets/onBoarding/gecko-clin.gif',
|
child: finishButton(context)),
|
||||||
height: isTall ? 400 : 300,
|
),
|
||||||
),
|
ScaledSizedBox(height: isTall ? 40 : 5),
|
||||||
Expanded(
|
]),
|
||||||
child: Align(
|
Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.topLeft,
|
||||||
child: finishButton(context)),
|
child: ConfettiWidget(
|
||||||
),
|
confettiController: conffetiController,
|
||||||
const SizedBox(height: 40),
|
blastDirection: pi * 0.1,
|
||||||
]),
|
maxBlastForce: 10,
|
||||||
));
|
minBlastForce: 1,
|
||||||
|
emissionFrequency: 0.01,
|
||||||
|
numberOfParticles: 7,
|
||||||
|
shouldLoop: false,
|
||||||
|
gravity: 0.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
child: ConfettiWidget(
|
||||||
|
confettiController: conffetiController,
|
||||||
|
blastDirection: pi * 0.9,
|
||||||
|
maxBlastForce: 10,
|
||||||
|
minBlastForce: 1,
|
||||||
|
emissionFrequency: 0.01,
|
||||||
|
numberOfParticles: 7,
|
||||||
|
shouldLoop: false,
|
||||||
|
gravity: 0.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget finishButton(BuildContext context) {
|
Widget finishButton(BuildContext context) {
|
||||||
return SizedBox(
|
return ScaledSizedBox(
|
||||||
width: 380 * ratio,
|
width: 340,
|
||||||
height: 60 * ratio,
|
height: 55,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
key: keyGoWalletsHome,
|
key: keyGoWalletsHome,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
foregroundColor: Colors.white, elevation: 4,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: orangeC, // foreground
|
elevation: 4,
|
||||||
),
|
backgroundColor: orangeC,
|
||||||
onPressed: () {
|
),
|
||||||
//TODO: fix bad widget ancestor when pupUntil (multi_chest test failed)
|
onPressed: () {
|
||||||
|
Navigator.pushNamedAndRemoveUntil(
|
||||||
// Navigator.popUntil(homeContext, ModalRoute.withName('/'));
|
context, '/mywallets', ModalRoute.withName('/'));
|
||||||
// Navigator.of(homeContext, rootNavigator: true)
|
},
|
||||||
// .popUntil(ModalRoute.withName('/'));
|
child: Text(
|
||||||
// while (Navigator.of(homeContext).canPop()) {
|
"accessMyChest".tr(),
|
||||||
// Navigator.of(homeContext).pop();
|
style: scaledTextStyle(
|
||||||
// }
|
fontSize: 21, fontWeight: FontWeight.w600, color: Colors.white),
|
||||||
|
),
|
||||||
// Navigator.pushNamed(homeContext, '/mywallets');
|
),
|
||||||
|
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
|
||||||
context, '/mywallets', (route) => route.isFirst);
|
|
||||||
|
|
||||||
// Navigator.pushNamedAndRemoveUntil(
|
|
||||||
// homeContext, '/mywallets', ModalRoute.withName('/'));
|
|
||||||
},
|
|
||||||
child: Text("accessMyChest".tr(),
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 22 * ratio, fontWeight: FontWeight.w600))),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,31 @@
|
||||||
// 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';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.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: GeckoAppBar('yourMnemonic'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(
|
|
||||||
'yourMnemonic'.tr(),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,38 +1,32 @@
|
||||||
// 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';
|
||||||
|
import 'package:gecko/widgets/commons/top_appbar.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: GeckoAppBar('yourMnemonic'.tr()),
|
||||||
toolbarHeight: 60 * ratio,
|
|
||||||
title: SizedBox(
|
|
||||||
height: 22,
|
|
||||||
child: Text(
|
|
||||||
'yourMnemonic'.tr(),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
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,
|
||||||
|
boxHeight: 316,
|
||||||
|
),
|
||||||
|
const OfflineInfo(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|