Compare commits

...
Author SHA1 Message Date
jo-mut 31d0c14247 code refactor 2024-05-27 00:58:53 +02:00
Ajay Sivan 539b7bbff4 fix: white panel when the bottom sheet is launched 2024-05-27 00:55:59 +02:00
Jamie Caprani 777b2bb8da chore(wallet): smooth collectible list loading transition 2024-05-24 13:44:16 -07:00
Parvesh Monu f17484f61b fix missing pinned messages label (#20174) 2024-05-25 00:00:46 +05:30
Ulises Manuel 49a41f4787 [#19232] - Fix derivation path generation and keypair creation (#19531)
* Add more default dependencies to slide button

* Fix wallet account creation: derivation paths and keypairs
2024-05-24 10:03:02 -06:00
Siddarth Kumar f65c10502b pick between JSC & Hermes for Android (#20171)
We implement both `JSC` and `Hermes` in build phase of `Android` which increases our `APK` size by ~ `2 MB`.
This was fine before but currently we have to get below the `100 MB` limit.

This commit implements the preferred engine after inferring `hermesEnabled`  property from gradle.properties
This property is modified at build time for release here
https://github.com/status-im/status-mobile/blob/178d62bd276afffef5fe7a3f773e390d83336d9c/nix/mobile/android/build.nix#L17
and set for debug here
https://github.com/status-im/status-mobile/blob/178d62bd276afffef5fe7a3f773e390d83336d9c/Makefile#L280

Which should further reduce the `APK` size by `2 MB`.
2024-05-24 21:02:32 +05:30
flexsurfer e30ca97372 Remove not implemented Notification settings from community longtap m… (#20169) 2024-05-24 16:51:25 +02:00
Andrea Maria Piana 178d62bd27 Update eth-archival pokt url 2024-05-24 14:56:52 +01:00
Ajay Sivan 4262d0e8ab Avatars/dApp Avatar Component (#20145) 2024-05-24 05:48:43 -07:00
Ajay Sivan 6f3aa19a04 Avatars/Community Avatar Component (#20147) 2024-05-24 05:33:52 -07:00
Ajay Sivan c398c85b0f Avatars/Token Avatar Component (#20141) 2024-05-24 05:04:20 -07:00
Jamie Caprani 3a728fb112 chore(wallet): reset input on send flow when swapping accounts (#20099) 2024-05-24 13:31:34 +02:00
Omar Basem d2fb6c7ee0 fix: balances in network preferences after removing account (#20139)
fix: balances in network preferences after removing account (#20139)
2024-05-23 17:52:14 +04:00
BalogunofAfricaandBrian Sztamfater 2ffdeb1fa2 fix(wallets): no routes render on input amount (#20112)
* fix: no routes found error when disabling chains and current amount exceeds new max amount

* fix: disable button on routes loading

* add no-routes-found component

---------

Co-authored-by: Brian Sztamfater <brian@status.im>
2024-05-23 12:33:33 +01:00
flexsurfer a0d9134f7b Incorrect Button Label Color in Disabled State #20056 (#20156) 2024-05-23 12:38:03 +02:00
flexsurfer 81977475c5 support ios "15.3" (#20127) 2024-05-23 10:59:43 +02:00
flexsurfer 813e4ee730 Syncing/Sync failed screens are missing illustrations #20068 (#20142) 2024-05-23 10:54:38 +02:00
flexsurfer 5eba373c3c Feature/hide browser behind feature flag #20022 (#20082) 2024-05-23 10:12:39 +02:00
yqrashawn c19f170239 fix(dev exp): auto disable fast refresh on iOS (#20120) 2024-05-23 15:17:01 +08:00
Sean Hagstrom 60ef4fab4b Implement display of missing key pairs in wallet settings (#20094)
* fix: ensure the keypairs use blur for their theme

* fix: allow for container-style to be passed to standard-title component

* chore: add translations for for missing-keypair labels

* tweak: add support for missing-keypair type for drawer-top component

* tweak: add initial implementation of missing-keypair list-item component

* tweak: add initial implementation of missing-keypairs list component

* feature: add initial implementation of displaying missing key-pairs

* tweak: update missing-keypair list-item to support blur, light, and dark mode

* chore: add missing-keypair list-item preview

* chore: add missing-keypairs preview

* chore: decode :operable key in account to be keyword

* tweak: remove unneeded keyword decoding

* tweak: update drawer-top component to use keypair and stored field

* tidy: revert change for checking for not default-keypair in actions menu
2024-05-22 18:30:32 +01:00
flexsurfer 47b4ab923b Pinning contact request message leads to a crash #20131 (#20132) 2024-05-22 16:43:18 +02:00
Ajay Sivan 05a09d1fa1 Buttons/Swap-Order-Button Component (#20119) 2024-05-22 05:03:13 -07:00
John Ngei 8bd1c8de95 refactored some styles and fixed text alignment fix ens name verication 2024-05-22 11:11:36 +02:00
Ajay Sivan e5ab94f1b2 Wallet/Approval Label Component (#20117) 2024-05-22 00:59:46 -07:00
Omar Basem ff82d9c39e fix: update confirm button copy on input amount screen(#20122)
* fix: update confirm button copy on input amount screen(#20122)
2024-05-22 09:34:55 +04:00
Ulises Manuel e1210e90c0 [#19544] Show preselected networks in QR code (#20070)
* Add subscription to get preferred networks given an address
* Fix preselected networks in receive screen
* Improve subscription
* Fix preselected networks in share screen
* Update test to include oeth
2024-05-21 10:08:14 -06:00
Jamie Caprani ed88170c5d chore(wallet): hide share button on scanner pages except universal scanner 2024-05-21 08:11:04 -07:00
Brian Sztamfater 32123d2f69 fix: max value is incorrect for some tokens (#20096)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-05-21 11:59:19 -03:00
Yevheniia Berdnyk a480df4ef5 e2e: fixes 21.05 2024-05-21 16:50:58 +03:00
Anton Iakimov b3361b7d89 chore: drop wakuv2 fleets, use waku fleets
See https://github.com/status-im/infra-nim-waku/issues/91 for details

Mostly done automatically. Some parts manually.
https://github.com/status-im/status-go/compare/3103c298...92ef58d4

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-05-21 14:02:30 +02:00
Ajay Sivan f7163c748b Use data from API to populate the buy assets sheet (#20078)
Remove unused code & resources
2024-05-21 04:45:07 -07:00
Omar Basem 34cf65bfc9 fix: overlapping send details (#20102)
* fix: overlapping send details (#20102)
2024-05-21 11:19:22 +04:00
122 changed files with 2752 additions and 1252 deletions
-1
View File
@@ -36,5 +36,4 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
ENABLE_ALERT_BANNER=1
+8 -6
View File
@@ -83,7 +83,6 @@ def jscFlavor = 'org.webkit:android-jsc:+'
*/
def enableHermes = hermesEnabled.toBoolean();
def getCommitHash = { ->
if (project.hasProperty("commitHash")) {
return project.commitHash
@@ -278,11 +277,14 @@ dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation("androidx.core:core-splashscreen:1.0.0")
// we don't use hermes for debug but we need its pom file for release builds
// https://github.com/status-im/status-mobile/pull/18675
implementation("com.facebook.react:hermes-android")
// FIXME: implementing both hermes & JSC increases bundle size by ~ 2MB
implementation(jscFlavor)
if (enableHermes) {
implementation("com.facebook.react:hermes-android")
} else {
// https://github.com/status-im/status-mobile/issues/18493
// we don't use hermes for debug builds because it crashes too often
implementation(jscFlavor)
}
// react-native-screens
implementation("androidx.appcompat:appcompat:1.1.0-rc01")
+2 -1
View File
@@ -55,7 +55,8 @@ com.android.tools.build:gradle:8.1.1
com.google.errorprone:error_prone_annotations:2.7.1
com.android.tools.lint:lint-gradle:31.1.1
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
com.android.tools.build:gradle:3.5.4' \
com.android.tools.build:gradle:3.5.4
com.facebook.react:hermes-android:0.73.5' \
>> "${DEPS_LIST}"
}
+1 -1
View File
@@ -57,7 +57,7 @@ in {
yarn = super.yarn.override { nodejs = super.nodejs-18_x; };
openjdk = super.openjdk11_headless;
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
versions = ["15.1" "15.2"];
versions = ["15.1" "15.2" "15.3"];
};
go = super.go_1_20;
clang = super.clang_15;
+20 -37
View File
@@ -1,7 +1,7 @@
{
"meta": {
"hostname": "node-01.do-ams3.sites.misc",
"timestamp": "2024-02-02T14:48:22.521541",
"timestamp": "2024-03-15T00:00:36.865154",
"warning": "DO NOT EDIT! Auto generated from Consul. Should only be used at build time."
},
"fleets": {
@@ -82,38 +82,21 @@
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu"
}
},
"wakuv2.prod": {
"waku.sandbox": {
"tcp/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD"
"node-01.do-ams3.waku.sandbox": "/dns4/node-01.do-ams3.waku.sandbox.status.im/tcp/30303/p2p/16Uiu2HAmQSMNExfUYUqfuXWkD5DaNZnMYnigRxFKbk3tcEFQeQeE",
"node-01.gc-us-central1-a.waku.sandbox": "/dns4/node-01.gc-us-central1-a.waku.sandbox.status.im/tcp/30303/p2p/16Uiu2HAm6fyqE1jB5MonzvoMdU8v76bWV8ZeNpncDamY1MQXfjdB",
"node-01.ac-cn-hongkong-c.waku.sandbox": "/dns4/node-01.ac-cn-hongkong-c.waku.sandbox.status.im/tcp/30303/p2p/16Uiu2HAmSJvSJphxRdbnigUV5bjRRZFBhTtWFTSyiKaQByCjwmpV"
},
"enr/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "enr:-P-4QJI8tS1WTdIQxq_yIrD05oIIW1Xg-tm_qfP0CHfJGnp9dfr6ttQJmHwTNxGEl4Le8Q7YHcmi-kXTtphxFysS11oBgmlkgnY0gmlwhLymh5GKbXVsdGlhZGRyc7hgAC02KG5vZGUtMDEuZG8tYW1zMy53YWt1djIucHJvZC5zdGF0dXNpbS5uZXQGdl8ALzYobm9kZS0wMS5kby1hbXMzLndha3V2Mi5wcm9kLnN0YXR1c2ltLm5ldAYfQN4DiXNlY3AyNTZrMaEDbl1X_zJIw3EAJGtmHMVn4Z2xhpSoUaP5ElsHKCv7hlWDdGNwgnZfg3VkcIIjKIV3YWt1Mg8",
"node-01.gc-us-central1-a.wakuv2.prod": "enr:-QERuEC0EGWTjg_gYdnuPypJ9LAbB3lml6M8GiRajGegL2iWEj1MJzUMV9X6jXw7mMAQQLozLCTLFT-zv-ELQLPwWdACAYJpZIJ2NIJpcIQieWRsim11bHRpYWRkcnO4cgA2NjFub2RlLTAxLmdjLXVzLWNlbnRyYWwxLWEud2FrdXYyLnByb2Quc3RhdHVzaW0ubmV0BnZfADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS53YWt1djIucHJvZC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhA_30kHgQqfXZRioa4J_u5asgXTJ5iw_8w3lEICH4TFu_g3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "enr:-QERuEDABor1lVmSa5ek8of5eBc8jZoxxdleJVLLdMl8UeZHNwhsVp64SFiCT4BRIIfcs7uxTPUCjmWxK_OA1s-FfIW7AYJpZIJ2NIJpcIQI0t7nim11bHRpYWRkcnO4cgA2NjFub2RlLTAxLmFjLWNuLWhvbmdrb25nLWMud2FrdXYyLnByb2Quc3RhdHVzaW0ubmV0BnZfADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy53YWt1djIucHJvZC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhAo0C-VvfgHiXrxZi3umDiooXMGY9FvYj5_d1Q4EeS7eyg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP"
"node-01.do-ams3.waku.sandbox": "enr:-QESuEB4Dchgjn7gfAvwB00CxTA-nGiyk-aALI-H4dYSZD3rUk7bZHmP8d2U6xDiQ2vZffpo45Jp7zKNdnwDUx6g4o6XAYJpZIJ2NIJpcIRA4VDAim11bHRpYWRkcnO4XAArNiZub2RlLTAxLmRvLWFtczMud2FrdS5zYW5kYm94LnN0YXR1cy5pbQZ2XwAtNiZub2RlLTAxLmRvLWFtczMud2FrdS5zYW5kYm94LnN0YXR1cy5pbQYfQN4DgnJzkwABCAAAAAEAAgADAAQABQAGAAeJc2VjcDI1NmsxoQOvD3S3jUNICsrOILlmhENiWAMmMVlAl6-Q8wRB7hidY4N0Y3CCdl-DdWRwgiMohXdha3UyDw",
"node-01.gc-us-central1-a.waku.sandbox": "enr:-QEkuEBIkb8q8_mrorHndoXH9t5N6ZfD-jehQCrYeoJDPHqT0l0wyaONa2-piRQsi3oVKAzDShDVeoQhy0uwN1xbZfPZAYJpZIJ2NIJpcIQiQlleim11bHRpYWRkcnO4bgA0Ni9ub2RlLTAxLmdjLXVzLWNlbnRyYWwxLWEud2FrdS5zYW5kYm94LnN0YXR1cy5pbQZ2XwA2Ni9ub2RlLTAxLmdjLXVzLWNlbnRyYWwxLWEud2FrdS5zYW5kYm94LnN0YXR1cy5pbQYfQN4DgnJzkwABCAAAAAEAAgADAAQABQAGAAeJc2VjcDI1NmsxoQKnGt-GSgqPSf3IAPM7bFgTlpczpMZZLF3geeoNNsxzSoN0Y3CCdl-DdWRwgiMohXdha3UyDw",
"node-01.ac-cn-hongkong-c.waku.sandbox": "enr:-QEkuEB3WHNS-xA3RDpfu9A2Qycr3bN3u7VoArMEiDIFZJ66F1EB3d4wxZN1hcdcOX-RfuXB-MQauhJGQbpz3qUofOtLAYJpZIJ2NIJpcIQI2SVcim11bHRpYWRkcnO4bgA0Ni9ub2RlLTAxLmFjLWNuLWhvbmdrb25nLWMud2FrdS5zYW5kYm94LnN0YXR1cy5pbQZ2XwA2Ni9ub2RlLTAxLmFjLWNuLWhvbmdrb25nLWMud2FrdS5zYW5kYm94LnN0YXR1cy5pbQYfQN4DgnJzkwABCAAAAAEAAgADAAQABQAGAAeJc2VjcDI1NmsxoQPK35Nnz0cWUtSAhBp7zvHEhyU_AqeQUlqzLiLxfP2L4oN0Y3CCdl-DdWRwgiMohXdha3UyDw"
},
"wss/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD"
}
},
"wakuv2.test": {
"tcp/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
},
"enr/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "enr:-P-4QPLMQ1zIYRAs4-F0mYmMxMihSySRtEIuGHJ_Qd_GL8XqUE78hpVUE97rgwlXnxPkzMJHkWyiNq7DT1fdZSy3QcgBgmlkgnY0gmlwhIbRi9KKbXVsdGlhZGRyc7hgAC02KG5vZGUtMDEuZG8tYW1zMy53YWt1djIudGVzdC5zdGF0dXNpbS5uZXQGdl8ALzYobm9kZS0wMS5kby1hbXMzLndha3V2Mi50ZXN0LnN0YXR1c2ltLm5ldAYfQN4DiXNlY3AyNTZrMaEDnr03Tuo77930a7sYLikftxnuG3BbC3gCFhA4632ooDaDdGNwgnZfg3VkcIIjKIV3YWt1Mg8",
"node-01.gc-us-central1-a.wakuv2.test": "enr:-QERuEDZcXS5tjppj4TIlOm-TLanjmqx3-uk2kGFvvAQR1NVrklUhiN1JCb5dWucEQ_oDADOb6nG_1mJ5goF5CHneZ-VAYJpZIJ2NIJpcIRomu-Aim11bHRpYWRkcnO4cgA2NjFub2RlLTAxLmdjLXVzLWNlbnRyYWwxLWEud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS53YWt1djIudGVzdC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhA1giYsmWV9r2yJZYAiMGHJfjLlLeqAuTAokUGPN__pkxg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.ac-cn-hongkong-c.wakuv2.test": "enr:-QERuEC2LyiXKURIKxNHa7Mj7frsM-lZiAGJ-2mopR3w8LMn2UhKmahZ9RHKV5ehBN1fXbRYqAeiXuOxD9t2igF4PIizAYJpZIJ2NIJpcIQv8tJJim11bHRpYWRkcnO4cgA2NjFub2RlLTAxLmFjLWNuLWhvbmdrb25nLWMud2FrdXYyLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy53YWt1djIudGVzdC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhAhAm-P4q6mWONKcGnbLPU8WXZJ4Qs3AxIbrycvc7PVKsg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP"
},
"wss/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
"node-01.do-ams3.waku.sandbox": "/dns4/node-01.do-ams3.waku.sandbox.status.im/tcp/8000/wss/p2p/16Uiu2HAmQSMNExfUYUqfuXWkD5DaNZnMYnigRxFKbk3tcEFQeQeE",
"node-01.gc-us-central1-a.waku.sandbox": "/dns4/node-01.gc-us-central1-a.waku.sandbox.status.im/tcp/8000/wss/p2p/16Uiu2HAm6fyqE1jB5MonzvoMdU8v76bWV8ZeNpncDamY1MQXfjdB",
"node-01.ac-cn-hongkong-c.waku.sandbox": "/dns4/node-01.ac-cn-hongkong-c.waku.sandbox.status.im/tcp/8000/wss/p2p/16Uiu2HAmSJvSJphxRdbnigUV5bjRRZFBhTtWFTSyiKaQByCjwmpV"
}
},
"waku.test": {
@@ -183,9 +166,9 @@
"boot-01.ac-cn-hongkong-c.shards.test": "/dns4/boot-01.ac-cn-hongkong-c.shards.test.statusim.net/tcp/30303/p2p/16Uiu2HAmGwcE8v7gmJNEWFtZtojYpPMTHy2jBLL6xRk33qgDxFWX"
},
"enr/p2p/waku/boot": {
"boot-01.do-ams3.shards.test": "enr:-QEOuEAuAK49evunDoidpHqcmeVqZz73wt4jwHnHJlmCVBFj6EdIbZ9uH5BnCYKOEPJTns2QJKUR2XLtWyzIspPAfJF9AYJpZIJ2NIJpcISnYxMvim11bHRpYWRkcnO4YAAtNihib290LTAxLmRvLWFtczMuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfAC82KGJvb3QtMDEuZG8tYW1zMy5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc4sAEAQAIABAAIABAIlzZWNwMjU2azGhAt60bRUEoHNuLlnsM12sU2PIQwBwfLIJ8a_ZPEY2-Rnkg3RjcIJ2X4N1ZHCCIyiFd2FrdTIN",
"boot-01.gc-us-central1-a.shards.test": "enr:-QEguEC3wjzOk7U5rIqiX32CCD-0_J1cYYGK_YwKSah5di2NTxJUaKQ9B7NMiEQ_-YGm-Eus4SzHtxN_fXEuVaNHql9aAYJpZIJ2NIJpcIQihw1Xim11bHRpYWRkcnO4cgA2NjFib290LTAxLmdjLXVzLWNlbnRyYWwxLWEuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MWJvb3QtMDEuZ2MtdXMtY2VudHJhbDEtYS5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc4sAEAQAIABAAIABAIlzZWNwMjU2azGhAsY6oA0NFskUjopWFN9gwOZP1zZQ4rN5tVXV5CvcTOpDg3RjcIJ2X4N1ZHCCIyiFd2FrdTIN",
"boot-01.ac-cn-hongkong-c.shards.test": "enr:-QEguEBb4rlxsdYCIZ8NcAlcjnb2zp4C9JbDsz-01Ix2sKNdWzI79KRFnhlakX-4F8gRYcviDvQL5eEZDOxHTupUW7VXAYJpZIJ2NIJpcIQI2hdMim11bHRpYWRkcnO4cgA2NjFib290LTAxLmFjLWNuLWhvbmdrb25nLWMuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MWJvb3QtMDEuYWMtY24taG9uZ2tvbmctYy5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc4sAEAQAIABAAIABAIlzZWNwMjU2azGhAz-wm0ZPmCicDhRTOGfZ3stBj3O1jyWgsBpKTUcpWu5gg3RjcIJ2X4N1ZHCCIyiFd2FrdTIN"
"boot-01.do-ams3.shards.test": "enr:-QEQuEAdkU8UWa5vvRr-uoULGoyWflIOozVUWj-9iUXw7nEo_yWKmDKrYJ_t4rSwbRLobDy8M0mO8HQyDFVfdQxDZQRVAYJpZIJ2NIJpcISnYxMvim11bHRpYWRkcnO4YAAtNihib290LTAxLmRvLWFtczMuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfAC82KGJvb3QtMDEuZG8tYW1zMy5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc40AEAUAAQAgAEAAgAEAiXNlY3AyNTZrMaEC3rRtFQSgc24uWewzXaxTY8hDAHB8sgnxr9k8Rjb5GeSDdGNwgnZfg3VkcIIjKIV3YWt1Mg0",
"boot-01.gc-us-central1-a.shards.test": "enr:-QEiuECIDOWRVQAUq2xpm3EUhuLRH1e_WCiLa6-5zmLoyVB-QSkSealvjt5Zb7cEqhU0pIeRaqnX6b8s98BahmG2XaSIAYJpZIJ2NIJpcIQihw1Xim11bHRpYWRkcnO4cgA2NjFib290LTAxLmdjLXVzLWNlbnRyYWwxLWEuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MWJvb3QtMDEuZ2MtdXMtY2VudHJhbDEtYS5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc40AEAUAAQAgAEAAgAEAiXNlY3AyNTZrMaECxjqgDQ0WyRSOilYU32DA5k_XNlDis3m1VdXkK9xM6kODdGNwgnZfg3VkcIIjKIV3YWt1Mg0",
"boot-01.ac-cn-hongkong-c.shards.test": "enr:-QEiuEDvfBDIqKRhdBHfGkRLvbYdD8Cja_m8tqWqUG40zXDUSTWejzvi2TL7z4H9gMhy2asTJ0vBTMjpQPj6Te-e2uAFAYJpZIJ2NIJpcIQI2hdMim11bHRpYWRkcnO4cgA2NjFib290LTAxLmFjLWNuLWhvbmdrb25nLWMuc2hhcmRzLnRlc3Quc3RhdHVzaW0ubmV0BnZfADg2MWJvb3QtMDEuYWMtY24taG9uZ2tvbmctYy5zaGFyZHMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4Jyc40AEAUAAQAgAEAAgAEAiXNlY3AyNTZrMaEDP7CbRk-YKJwOFFM4Z9ney0GPc7WPJaCwGkpNRyla7mCDdGNwgnZfg3VkcIIjKIV3YWt1Mg0"
},
"wss/p2p/waku/boot": {
"boot-01.do-ams3.shards.test": "/dns4/boot-01.do-ams3.shards.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmAR24Mbb6VuzoyUiGx42UenDkshENVDj4qnmmbabLvo31",
@@ -201,12 +184,12 @@
"store-02.ac-cn-hongkong-c.shards.test": "/dns4/store-02.ac-cn-hongkong-c.shards.test.statusim.net/tcp/30303/p2p/16Uiu2HAm9CQhsuwPR54q27kNj9iaQVfyRzTGKrhFmr94oD8ujU6P"
},
"enr/p2p/waku/store": {
"store-01.do-ams3.shards.test": "enr:-QEQuEDom7vBcLEP3ZCvRGPyBVTUJUO5YIyXvxcibag_iq6s5Ux6Zd1_nnqEXqynppYMNOTaTzSetRhmV9IH83j72umYAYJpZIJ2NIJpcISf3_Jeim11bHRpYWRkcnO4YgAuNilzdG9yZS0wMS5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwAwNilzdG9yZS0wMS5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaEC36GkB96EmFufcsRAX3gGW5bZlJwuAc2JB6nq9lUDE8qDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"store-02.do-ams3.shards.test": "enr:-QEQuEAmPituRLmZuwA6z0AT_Vl-KWbb7kpyX7qcWwbjygv_Oxrdu_0kmpShNtauWxhRmaOMOYddv9IwiIS8HujxHvpbAYJpZIJ2NIJpcISf3_Kaim11bHRpYWRkcnO4YgAuNilzdG9yZS0wMi5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwAwNilzdG9yZS0wMi5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaEC0jOth5qhqWd_NmDOAsiPjAiJZMTD-2WzsKsET75PcLCDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"store-01.gc-us-central1-a.shards.test": "enr:-QEiuEBW0x-NQAwfFIgwrwtMRbPpWYRbWzsQ6nMDQK5K8vT8uAph5mlAw-TaeIxw9K2Vc0QuEYzf8-MnOESVyQ-C6ywcAYJpZIJ2NIJpcIQiqsAnim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMS5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMS5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaEDf2gcTbDga3Hgy8gu-bwRUbs7_7Vn2hxudCXPQ0M7cJCDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"store-02.gc-us-central1-a.shards.test": "enr:-QEiuEDjbS1EbRmNA7Gl1F3z_NsTHloyfZp4h0tm5cQmTvo5SlFGIBPPpmB6oycGnVGCHFPmqV_XbJJRO5pObWa5dOHgAYJpZIJ2NIJpcIQiqpoCim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMi5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMi5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaEDWxINW5DCQgYg-U43t2f9dUfpHfZrp2RdL-IomGWtY4KDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"store-01.ac-cn-hongkong-c.shards.test": "enr:-QEiuEDkMIJT5pVMmtzHD5RATLyU0kAG0tKcC3AE3BQe0O6S9R6OsA7PEVaaUg52fA4_I2pwjoW2GroE6uR9a-7Vdfy-AYJpZIJ2NIJpcIQI2kpJim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMS5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMS5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaECZtdI3Wq88fYXHYUShn7AMktB3OaVo98ock70-RSMChiDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"store-02.ac-cn-hongkong-c.shards.test": "enr:-QEiuEBzOdkswwOBobEe-nUvdtALMP8sjV9b_v9rQS4E0QOv2TVdrXRKKrBzOgk8TIXFtdry3RrowN5pTH7vBWl8TPKUAYJpZIJ2NIJpcIQI2nnoim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMi5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMi5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJziwAQBAAgAEAAgAEAiXNlY3AyNTZrMaECzJ3LruqSdw0Ec2FKpAdT22kcWVyBiYvMGim2wRWzkjSDdGNwgnZfg3VkcIIjKIV3YWt1MgM"
"store-01.do-ams3.shards.test": "enr:-QESuEBxlk35-NNVnppRQaNSB3fR4M7J7xK3NUYer3z-L9j0uTpg9MatcSEHLUFkf4lt5qxacyBxD6G1w5elhdSgeKo4AYJpZIJ2NIJpcISf3_Jeim11bHRpYWRkcnO4YgAuNilzdG9yZS0wMS5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwAwNilzdG9yZS0wMS5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQLfoaQH3oSYW59yxEBfeAZbltmUnC4BzYkHqer2VQMTyoN0Y3CCdl-DdWRwgiMohXdha3UyAw",
"store-02.do-ams3.shards.test": "enr:-QESuEC_CCKHt-bfmNcpFhY4_RyzEPfb9qXDzc7-2mo0oTanx2pMNLVkGYQuAWzgS14nGqecJ4qNGnJf0iW6xmk7bvgSAYJpZIJ2NIJpcISf3_Kaim11bHRpYWRkcnO4YgAuNilzdG9yZS0wMi5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwAwNilzdG9yZS0wMi5kby1hbXMzLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQLSM62HmqGpZ382YM4CyI-MCIlkxMP7ZbOwqwRPvk9wsIN0Y3CCdl-DdWRwgiMohXdha3UyAw",
"store-01.gc-us-central1-a.shards.test": "enr:-QEkuEDdeEvvLl4imez1cjafogCr4Y9TC739Io6U7J78VG6ong2UtkKNADtupsHKArUcc13jCZI_O4z6XnLz6zYLpDn-AYJpZIJ2NIJpcIQiqsAnim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMS5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMS5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQN_aBxNsOBrceDLyC75vBFRuzv_tWfaHG50Jc9DQztwkIN0Y3CCdl-DdWRwgiMohXdha3UyAw",
"store-02.gc-us-central1-a.shards.test": "enr:-QEkuEA98rxs-uF2s5E1qVW-yg7p7y6JZ5sFCDmeQOvaeQekLwbEO_O68XfOFCmuJsWwmA00HtnnbkAfFaYy0ZhsHWbKAYJpZIJ2NIJpcIQiqpoCim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMi5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMi5nYy11cy1jZW50cmFsMS1hLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQNbEg1bkMJCBiD5Tje3Z_11R-kd9munZF0v4iiYZa1jgoN0Y3CCdl-DdWRwgiMohXdha3UyAw",
"store-01.ac-cn-hongkong-c.shards.test": "enr:-QEkuEAIYrY2284THz1f4FkFEr7PIHw5GrBLEd_4UZWMh1aCGUzePYMf-YIaw_-bEqfqRK_1p7RJVgLupl8EaENIUXG3AYJpZIJ2NIJpcIQI2kpJim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMS5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMS5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQJm10jdarzx9hcdhRKGfsAyS0Hc5pWj3yhyTvT5FIwKGIN0Y3CCdl-DdWRwgiMohXdha3UyAw",
"store-02.ac-cn-hongkong-c.shards.test": "enr:-QEkuECDx1C82BBcVM4UAFnTNTRe8zwX6vIy3iYU3qOyJJZGuDhceqbwVwW_Nc5j6tAUgnotg_jiZiNXoj_tJrFildM4AYJpZIJ2NIJpcIQI2nnoim11bHRpYWRkcnO4dAA3NjJzdG9yZS0wMi5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAZ2XwA5NjJzdG9yZS0wMi5hYy1jbi1ob25na29uZy1jLnNoYXJkcy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DgnJzjQAQBQABACAAQACAAQCJc2VjcDI1NmsxoQLMncuu6pJ3DQRzYUqkB1PbaRxZXIGJi8waKbbBFbOSNIN0Y3CCdl-DdWRwgiMohXdha3UyAw"
},
"wss/p2p/waku/store": {
"store-01.do-ams3.shards.test": "/dns4/store-01.do-ams3.shards.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmAUdrQ3uwzuE4Gy4D56hX6uLKEeerJAnhKEHZ3DxF1EfT",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

+14 -10
View File
@@ -11,9 +11,11 @@
[legacy.status-im.utils.random :as random]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[react-native.core :as react]
[react-native.platform :as platform]
[status-im.common.json-rpc.events :as json-rpc]
[status-im.common.universal-links :as links]
[status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.chat.events :as chat.events]
[status-im.navigation.events :as navigation]
@@ -302,16 +304,18 @@
:history [normalized-url]}]
(if (links/universal-link? normalized-url)
{:dispatch [:universal-links/handle-url normalized-url]}
(rf/merge cofx
{:db (assoc db
:browser/options
{:browser-id (:browser-id browser)}
:browser/screen-id :browser)}
(navigation/pop-to-root :shell-stack)
(chat.events/close-chat)
(navigation/change-tab :browser-stack)
(update-browser browser)
(resolve-url nil)))))
(if config/show-not-implemented-features?
(rf/merge cofx
{:db (assoc db
:browser/options
{:browser-id (:browser-id browser)}
:browser/screen-id :browser)}
(navigation/pop-to-root :shell-stack)
(chat.events/close-chat)
(navigation/change-tab :browser-stack)
(update-browser browser)
(resolve-url nil))
(.openURL ^js react/linking (url/normalize-url url))))))
(rf/defn open-existing-browser
"Opens an existing browser with it's history"
+89 -90
View File
@@ -1,8 +1,5 @@
(ns legacy.status-im.browser.core-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.browser.core :as browser]
[utils.i18n :as i18n]
[utils.url :as url]))
(defn has-wrong-properties?
@@ -21,101 +18,103 @@
(some #(when (= (url/normalize-and-decode-url dapp-url) (first (:history %))) (:browser-id %))
(vals (get-in result [:db :browser/browsers]))))
(deftest browser-test
(let [dapp1-url "cryptokitties.co"
dapp2-url "http://test2.com"]
#_(deftest browser-test
(let [dapp1-url "cryptokitties.co"
dapp2-url "http://test2.com"]
(testing "user opens a dapp"
(let [result-open (browser/open-url {:db {} :now 1} dapp1-url)
dapp1-id (get-dapp-id result-open dapp1-url)]
(is (= dapp1-id (get-in result-open [:db :browser/options :browser-id]))
"browser-id should be dapp1-url")
(is (not (has-wrong-properties? result-open
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "user opens a dapp"
(let [result-open (browser/open-url {:db {} :now 1} dapp1-url)
dapp1-id (get-dapp-id result-open dapp1-url)]
(is (= dapp1-id (get-in result-open [:db :browser/options :browser-id]))
"browser-id should be dapp1-url")
(is (not (has-wrong-properties? result-open
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then a second dapp"
(let [result-open-2 (browser/open-url {:db (:db result-open)
:now 2}
dapp2-url)
dapp2-id (get-dapp-id result-open-2 dapp2-url)]
(is (= dapp2-id (get-in result-open-2 [:db :browser/options :browser-id]))
"browser-id should be dapp2 host")
(is (not (has-wrong-properties? result-open-2
dapp2-id
{:browser-id dapp2-id
:history-index 0
:history ["http://test2.com"]
:dapp? false}))
"some properties of the browser are not correct")
(testing "then a second dapp"
(let [result-open-2 (browser/open-url {:db (:db result-open)
:now 2}
dapp2-url)
dapp2-id (get-dapp-id result-open-2 dapp2-url)]
(is (= dapp2-id (get-in result-open-2 [:db :browser/options :browser-id]))
"browser-id should be dapp2 host")
(is (not (has-wrong-properties? result-open-2
dapp2-id
{:browser-id dapp2-id
:history-index 0
:history ["http://test2.com"]
:dapp? false}))
"some properties of the browser are not correct")
(testing "then removes the second dapp"
(let [result-remove-2 (browser/remove-browser {:db (:db result-open-2)} dapp2-id)]
(is (= #{dapp1-id}
(set (keys (get-in result-remove-2 [:db :browser/browsers]))))
"the second dapp shouldn't be in the browser list anymore")))))
(testing "then removes the second dapp"
(let [result-remove-2 (browser/remove-browser {:db (:db result-open-2)} dapp2-id)]
(is (= #{dapp1-id}
(set (keys (get-in result-remove-2 [:db :browser/browsers]))))
"the second dapp shouldn't be in the browser list anymore")))))
(testing "then opens the dapp again"
(let [result-open-existing (browser/open-existing-browser {:db (:db result-open)
:now 2}
dapp1-id)
dapp1-url2 (str "https://" dapp1-url "/nav2")]
(is (not (has-wrong-properties? result-open-existing
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(is (nil? (browser/navigate-to-next-page result-open-existing))
"nothing should happen if user tries to navigate to next page")
(is (nil? (browser/navigate-to-previous-page result-open-existing))
"nothing should happen if user tries to navigate to previous page")
(testing "then opens the dapp again"
(let [result-open-existing (browser/open-existing-browser {:db (:db result-open)
:now 2}
dapp1-id)
dapp1-url2 (str "https://" dapp1-url "/nav2")]
(is (not (has-wrong-properties? result-open-existing
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(is (nil? (browser/navigate-to-next-page result-open-existing))
"nothing should happen if user tries to navigate to next page")
(is (nil? (browser/navigate-to-previous-page result-open-existing))
"nothing should happen if user tries to navigate to previous page")
(testing "then navigates to a new url in the dapp"
(let [result-navigate (browser/navigation-state-changed
{:db (:db result-open-existing)
:now 4}
(clj->js {"url" dapp1-url2
"loading" false})
false)]
(is (not (has-wrong-properties? result-navigate
dapp1-id
{:browser-id dapp1-id
:history-index 1
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then navigates to previous page"
(let [result-previous (browser/navigate-to-previous-page {:db (:db result-navigate)
:now 5})]
(is
(not (has-wrong-properties? result-previous
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then navigates to next page")
(let [result-next (browser/navigate-to-next-page {:db (:db result-previous)
:now 6})]
(is (not
(has-wrong-properties? result-next
(testing "then navigates to a new url in the dapp"
(let [result-navigate (browser/navigation-state-changed
{:db (:db result-open-existing)
:now 4}
(clj->js {"url" dapp1-url2
"loading" false})
false)]
(is (not (has-wrong-properties? result-navigate
dapp1-id
{:browser-id dapp1-id
:history-index 1
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct"))))))))))))
"some properties of the browser are not correct")
(testing "then navigates to previous page"
(let [result-previous (browser/navigate-to-previous-page {:db (:db result-navigate)
:now 5})]
(is
(not (has-wrong-properties? result-previous
dapp1-id
{:browser-id dapp1-id
:history-index 0
:history ["https://cryptokitties.co"
dapp1-url2]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then navigates to next page")
(let [result-next (browser/navigate-to-next-page {:db (:db result-previous)
:now 6})]
(is (not
(has-wrong-properties? result-next
dapp1-id
{:browser-id dapp1-id
:history-index 1
:history ["https://cryptokitties.co"
dapp1-url2]
:dapp? false
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct"))))))))))))
@@ -1,96 +1,90 @@
(ns legacy.status-im.browser.permissions-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.browser.core :as browser]
[legacy.status-im.browser.core-test :as core.tests]
[legacy.status-im.browser.permissions :as permissions]
[legacy.status-im.utils.deprecated-types :as types]))
(ns legacy.status-im.browser.permissions-test)
(deftest permissions-test
(let [dapp-name "test.com"
dapp-name2 "test2.org"
cofx {:db (assoc-in (:db (browser/open-url {:db {}} dapp-name))
[:profile/profile :public-key]
"public-key")}
dapp-id (core.tests/get-dapp-id cofx dapp-name)]
(testing "dapps permissions are initialized"
(is (zero? (count (get-in cofx [:db :dapps/permissions]))))
(is (= dapp-id (get-in cofx [:db :browser/options :browser-id]))))
#_(deftest permissions-test
(let [dapp-name "test.com"
dapp-name2 "test2.org"
cofx {:db (assoc-in (:db (browser/open-url {:db {}} dapp-name))
[:profile/profile :public-key]
"public-key")}
dapp-id (core.tests/get-dapp-id cofx dapp-name)]
(testing "dapps permissions are initialized"
(is (zero? (count (get-in cofx [:db :dapps/permissions]))))
(is (= dapp-id (get-in cofx [:db :browser/options :browser-id]))))
(testing "receiving an unsupported permission"
(let [result-ask (browser/process-bridge-message cofx
(types/clj->json
{:type "api-request"
:host dapp-name
:messageId 0
:permission "FAKE_PERMISSION"}))]
(is (not (get-in result-ask [:browser/send-to-bridge :isAllowed])))))
(testing "receiving an unsupported permission"
(let [result-ask (browser/process-bridge-message cofx
(types/clj->json
{:type "api-request"
:host dapp-name
:messageId 0
:permission "FAKE_PERMISSION"}))]
(is (not (get-in result-ask [:browser/send-to-bridge :isAllowed])))))
(testing "receiving a supported permission"
(let [result-ask (browser/process-bridge-message cofx
(types/clj->json {:type "api-request"
(testing "receiving a supported permission"
(let [result-ask (browser/process-bridge-message cofx
(types/clj->json {:type "api-request"
:host dapp-name
:messageId 1
:permission "contact-code"}))]
(is (= (get-in result-ask [:db :browser/options :show-permission])
{:requested-permission "contact-code"
:dapp-name "test.com"
:message-id 1
:yield-control? nil}))
(is (zero? (count (get-in result-ask [:db :dapps/permissions]))))
(testing "then user accepts the supported permission"
(let [accept-result (permissions/allow-permission {:db (:db result-ask)})]
(is (= (get accept-result :browser/send-to-bridge)
{:type "api-response"
:messageId 1
:isAllowed true
:data "public-key"
:permission "contact-code"})
"the data should have been sent to the bridge")
(is (= (get-in accept-result [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}})
"the dapp should now have CONTACT_CODE permission")
(testing "then dapp asks for permission again"
(let [result-ask-again (browser/process-bridge-message {:db (:db accept-result)}
(types/clj->json
{:type "api-request"
:host dapp-name
:messageId 1
:messageId 2
:permission "contact-code"}))]
(is (= (get-in result-ask [:db :browser/options :show-permission])
{:requested-permission "contact-code"
:dapp-name "test.com"
:message-id 1
:yield-control? nil}))
(is (zero? (count (get-in result-ask [:db :dapps/permissions]))))
(is (= (get result-ask-again :browser/send-to-bridge)
{:type "api-response"
:isAllowed true
:messageId 2
:data "public-key"
:permission "contact-code"})
"the response should be immediatly sent to the bridge")))
(testing "then user accepts the supported permission"
(let [accept-result (permissions/allow-permission {:db (:db result-ask)})]
(is (= (get accept-result :browser/send-to-bridge)
{:type "api-response"
:messageId 1
:isAllowed true
:data "public-key"
:permission "contact-code"})
"the data should have been sent to the bridge")
(is (= (get-in accept-result [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}})
"the dapp should now have CONTACT_CODE permission")
(testing "then user switch to another dapp that asks for permissions"
(let [new-dapp (browser/open-url {:db (:db accept-result)} dapp-name2)
result-ask2 (browser/process-bridge-message {:db (:db new-dapp)}
(types/clj->json
{:type "api-request"
:host dapp-name2
:messageId 3
:permission "contact-code"}))]
(is (= (get-in result-ask2 [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}})
"there should only be permissions for dapp-name at that point")
(is (nil? (get result-ask2 :browser/send-to-bridge))
"no message should be sent to the bridge")
(testing "then dapp asks for permission again"
(let [result-ask-again (browser/process-bridge-message {:db (:db accept-result)}
(types/clj->json
{:type "api-request"
:host dapp-name
:messageId 2
:permission "contact-code"}))]
(is (= (get result-ask-again :browser/send-to-bridge)
{:type "api-response"
:isAllowed true
:messageId 2
:data "public-key"
:permission "contact-code"})
"the response should be immediatly sent to the bridge")))
(testing "then user switch to another dapp that asks for permissions"
(let [new-dapp (browser/open-url {:db (:db accept-result)} dapp-name2)
result-ask2 (browser/process-bridge-message {:db (:db new-dapp)}
(types/clj->json
{:type "api-request"
:host dapp-name2
:messageId 3
:permission "contact-code"}))]
(is (= (get-in result-ask2 [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}})
"there should only be permissions for dapp-name at that point")
(is (nil? (get result-ask2 :browser/send-to-bridge))
"no message should be sent to the bridge")
(testing "then user accepts permission for dapp-name2"
(let [accept-result2 (permissions/allow-permission {:db (:db result-ask2)})]
(is (= (get-in accept-result2 [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}
"test2.org" {:dapp "test2.org" :permissions ["contact-code"]}})
"there should be permissions for both dapps now")
(is (= (get accept-result2 :browser/send-to-bridge)
{:type "api-response"
:isAllowed true
:messageId 3
:data "public-key"
:permission "contact-code"})
"the response should be sent to the bridge")))))))))))
(testing "then user accepts permission for dapp-name2"
(let [accept-result2 (permissions/allow-permission {:db (:db result-ask2)})]
(is (= (get-in accept-result2 [:db :dapps/permissions])
{"test.com" {:dapp "test.com" :permissions ["contact-code"]}
"test2.org" {:dapp "test2.org" :permissions ["contact-code"]}})
"there should be permissions for both dapps now")
(is (= (get accept-result2 :browser/send-to-bridge)
{:type "api-response"
:isAllowed true
:messageId 3
:data "public-key"
:permission "contact-code"})
"the response should be sent to the bridge")))))))))))
+1 -2
View File
@@ -9,8 +9,7 @@
(testing "it returns the default fleets"
(is (=
#{:eth.prod
:eth.staging
:eth.test}
:eth.staging}
(into #{}
(keys (node/fleets {})))))))
(testing "passing a custom fleet"
@@ -5,6 +5,7 @@
[legacy.status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[status-im.config :as config]
[utils.i18n :as i18n]
[utils.url :as url]))
@@ -27,10 +28,13 @@
(defn browse
[link]
(show {:title (i18n/label :t/browsing-title)
:options [{:label (i18n/label :t/browsing-open-in-status)
:action #(re-frame/dispatch [:browser.ui/open-url link])}
{:label (i18n/label (platform-web-browser))
:action #(.openURL ^js react/linking (url/normalize-url link))}]
:options (if config/show-not-implemented-features?
[{:label (i18n/label :t/browsing-open-in-status)
:action #(re-frame/dispatch [:browser.ui/open-url link])}
{:label (i18n/label (platform-web-browser))
:action #(.openURL ^js react/linking (url/normalize-url link))}]
[{:label (i18n/label (platform-web-browser))
:action #(.openURL ^js react/linking (url/normalize-url link))}])
:cancel-text (i18n/label :t/browsing-cancel)}))
(defn browse-in-web-browser
@@ -10,12 +10,13 @@
:image - collection image
:theme - keyword -> :light/:dark"
[{:keys [image size on-load-end on-error] :or {size :size-24}}]
[{:keys [image size on-load-start on-load-end on-error] :or {size :size-24}}]
(let [theme (quo.theme/use-theme)]
[rn/view {:style (style/collection-avatar-container theme size)}
[fast-image/fast-image
{:accessibility-label :collection-avatar
:source image
:on-load-start on-load-start
:on-load-end on-load-end
:on-error on-error
:style (style/collection-avatar size)}]]))
@@ -0,0 +1,9 @@
(ns quo.components.avatars.community-avatar.component-spec
(:require [quo.components.avatars.community-avatar.view :as community-avatar]
[test-helpers.component :as h]))
(h/describe "Avatars: Community Avatar"
(h/test "should render correctly"
(h/render-with-theme-provider
[community-avatar/view {:image "mock-image"}])
(h/is-truthy (h/get-by-label-text :community-avatar))))
@@ -0,0 +1,12 @@
(ns quo.components.avatars.community-avatar.style)
(def ^:private sizes
{:size-32 32
:size-24 24})
(defn image
[size]
(let [size-val (sizes size)]
{:border-radius (/ size-val 2)
:width size-val
:height size-val}))
@@ -0,0 +1,23 @@
(ns quo.components.avatars.community-avatar.view
(:require [quo.components.avatars.community-avatar.style :as style]
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:size {:optional true} [:maybe [:enum :size-32 :size-24]]]
[:image :schema.common/image-source]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [size image container-style]}]
[rn/image
{:source image
:accessibility-label :community-avatar
:style (merge (style/image size) container-style)}])
(def view (schema/instrument #'view-internal ?schema))
@@ -0,0 +1,14 @@
(ns quo.components.avatars.dapp-avatar.component-spec
(:require [quo.components.avatars.dapp-avatar.view :as dapp-avatar]
[test-helpers.component :as h]))
(h/describe "Avatars: dApp Avatar"
(h/test "should render correctly without context"
(h/render-with-theme-provider
[dapp-avatar/view {:image "mock-image"}])
(h/is-truthy (h/get-by-label-text :dapp-avatar)))
(h/test "should render correctly with context"
(h/render-with-theme-provider
[dapp-avatar/view {:image "mock-image" :network-image "mock-image" :context? true}])
(h/is-truthy (h/get-by-label-text :dapp-avatar))))
@@ -0,0 +1,23 @@
(ns quo.components.avatars.dapp-avatar.style)
(def ^:const size 32)
(def container
{:height size
:width size})
(def hole-view
{:width size
:height size})
(def context
{:width 16
:height 16
:border-radius 8
:position :absolute
:right -4
:bottom -4})
(def image
{:width size
:height size})
@@ -0,0 +1,42 @@
(ns quo.components.avatars.dapp-avatar.view
(:require [quo.components.avatars.dapp-avatar.style :as style]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[react-native.platform :as platform]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:context? {:optional true} [:maybe :boolean]]
[:image :schema.common/image-source]
[:network-image {:optional true} [:maybe :schema.common/image-source]]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [context? image network-image container-style]}]
[rn/view
{:style (merge style/container container-style)
:accessibility-label :dapp-avatar}
[hole-view/hole-view
(cond-> {:holes (if context?
[{:x 19
:y 19
:width 18
:height 18
:borderRadius 9}]
[])
:style style/hole-view}
platform/android? (assoc :key context?))
[rn/image
{:source image
:style style/image}]]
(when context?
[rn/image
{:source network-image
:style style/context}])])
(def view (schema/instrument #'view-internal ?schema))
@@ -0,0 +1,14 @@
(ns quo.components.avatars.token-avatar.component-spec
(:require [quo.components.avatars.token-avatar.view :as token-avatar]
[test-helpers.component :as h]))
(h/describe "Avatars: Token Avatar"
(h/test "should render correctly without context"
(h/render-with-theme-provider
[token-avatar/view {:image "mock-image"}])
(h/is-truthy (h/get-by-label-text :token-avatar)))
(h/test "should render correctly with context"
(h/render-with-theme-provider
[token-avatar/view {:image "mock-image" :network-image "mock-image" :context? true}])
(h/is-truthy (h/get-by-label-text :token-avatar))))
@@ -0,0 +1,25 @@
(ns quo.components.avatars.token-avatar.style)
(def ^:const size 32)
(def container
{:height size
:width size})
(def hole-view
{:width size
:height size})
(def context
{:width 16
:height 16
:border-radius 8
:position :absolute
:right -4
:bottom -4})
(defn image
[type]
{:width size
:border-radius (if (= type :collectible) 8 0)
:height size})
@@ -0,0 +1,43 @@
(ns quo.components.avatars.token-avatar.view
(:require [quo.components.avatars.token-avatar.style :as style]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[react-native.platform :as platform]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type {:optional true} [:enum :asset :collectible]]
[:context? {:optional true} [:maybe :boolean]]
[:image :schema.common/image-source]
[:network-image {:optional true} [:maybe :schema.common/image-source]]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [type context? image network-image container-style]}]
[rn/view
{:style (merge style/container container-style)
:accessibility-label :token-avatar}
[hole-view/hole-view
(cond-> {:holes (if context?
[{:x 19
:y 19
:width 18
:height 18
:borderRadius 9}]
[])
:style style/hole-view}
platform/android? (assoc :key context?))
[rn/image
{:source image
:style (style/image type)}]]
(when context?
[rn/image
{:source network-image
:style style/context}])])
(def view (schema/instrument #'view-internal ?schema))
+1 -2
View File
@@ -117,8 +117,7 @@
{:size (when (#{56 24} size) :paragraph-2)
:weight :medium
:number-of-lines 1
:style {:color label-color
:opacity (when disabled? 0.3)}}
:style {:color label-color}}
children]
(vector? children)
@@ -0,0 +1,23 @@
(ns quo.components.buttons.swap-order-button.component-spec
(:require [quo.components.buttons.swap-order-button.view :as swap-order-button]
[test-helpers.component :as h]))
(h/describe "Buttons: Swap Order Button"
(h/test "should render correctly"
(h/render-with-theme-provider
[swap-order-button/view {:on-press identity}])
(h/is-truthy (h/get-by-label-text :swap-order-button)))
(h/test "should call on-press handler when pressed"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider
[swap-order-button/view {:on-press on-press}])
(h/fire-event :press (h/get-by-label-text :swap-order-button))
(h/was-called on-press)))
(h/test "should not call on-press handler when button is disabled"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider
[swap-order-button/view {:on-press on-press :disabled? true}])
(h/fire-event :press (h/get-by-label-text :swap-order-button))
(h/was-not-called on-press))))
@@ -0,0 +1,11 @@
(ns quo.components.buttons.swap-order-button.schema)
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:disabled? {:optional true} [:maybe :boolean]]
[:on-press fn?]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
@@ -0,0 +1,18 @@
(ns quo.components.buttons.swap-order-button.style
(:require [quo.foundations.colors :as colors]))
(defn container
[pressed? disabled? theme]
{:width 32
:height 32
:border-radius 10
:border-width 1
:opacity (if disabled? 0.3 1)
:align-items :center
:justify-content :center
:border-color (if pressed?
(colors/theme-colors colors/neutral-20 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
:background-color (if pressed?
(colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
(colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme))})
@@ -0,0 +1,28 @@
(ns quo.components.buttons.swap-order-button.view
(:require [quo.components.buttons.swap-order-button.schema :as swap-order-button.schema]
[quo.components.buttons.swap-order-button.style :as style]
[quo.components.icon :as icon]
[quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]
[schema.core :as schema]))
(defn- view-internal
[{:keys [disabled? on-press container-style]}]
(let [theme (quo.theme/use-theme)
[pressed? set-pressed] (rn/use-state false)
on-press-in (rn/use-callback #(set-pressed true) [])
on-press-out (rn/use-callback #(set-pressed false) [])]
[rn/pressable
{:style (merge (style/container pressed? disabled? theme)
container-style)
:accessibility-label :swap-order-button
:disabled disabled?
:on-press on-press
:on-press-in on-press-in
:on-press-out on-press-out}
[icon/icon :i/arrow-down
{:size 20
:color (colors/theme-colors colors/neutral-100 colors/white theme)}]]))
(def view (schema/instrument #'view-internal swap-order-button.schema/?schema))
@@ -80,10 +80,10 @@
(h/is-truthy (h/get-by-text "0x62b...0a5"))
(h/is-truthy (h/get-by-label-text :account-avatar)))
(h/test "component renders in keypair type when keycard? is false"
(h/test "component renders keypair type with default label"
(h/render-with-theme-provider [quo/drawer-top
{:title "Title"
:keycard? false
:stored nil
:icon-avatar :i/placeholder
:type :keypair}]
theme)
@@ -91,10 +91,21 @@
(-> (h/expect (h/get-by-translation-text :t/on-device))
(.toBeTruthy)))
(h/test "component renders in keypair type when keycard? is true"
(h/test "component renders keypair type when stored on device"
(h/render-with-theme-provider [quo/drawer-top
{:title "Title"
:keycard? true
:stored :on-device
:icon-avatar :i/placeholder
:type :keypair}]
theme)
(h/is-truthy (h/get-by-text "Title"))
(-> (h/expect (h/get-by-translation-text :t/on-device))
(.toBeTruthy)))
(h/test "component renders keypair type when stored on keycard"
(h/render-with-theme-provider [quo/drawer-top
{:title "Title"
:stored :on-keycard
:icon-avatar :i/placeholder
:type :keypair}]
theme)
@@ -102,6 +113,17 @@
(-> (h/expect (h/get-by-translation-text :t/on-keycard))
(.toBeTruthy)))
(h/test "component renders keypair type when considered missing"
(h/render-with-theme-provider [quo/drawer-top
{:title "Title"
:stored :missing
:icon-avatar :i/placeholder
:type :keypair}]
theme)
(h/is-truthy (h/get-by-text "Title"))
(-> (h/expect (h/get-by-translation-text :t/import-to-use-derived-accounts))
(.toBeTruthy)))
(h/test "component renders in default-keypair type"
(h/render-with-theme-provider [quo/drawer-top
{:title "Title"
+12 -10
View File
@@ -37,16 +37,18 @@
nil))
(defn- keypair-subtitle
[{:keys [theme blur? keycard?]}]
[{:keys [theme blur? stored]}]
[rn/view {:style style/row}
[text/text
{:size :paragraph-2
:weight :regular
:style (style/description theme blur?)}
(if keycard?
(i18n/label :t/on-keycard)
(case stored
:on-device (i18n/label :t/on-device)
:on-keycard (i18n/label :t/on-keycard)
:missing (i18n/label :t/import-to-use-derived-accounts)
(i18n/label :t/on-device))]
(when keycard?
(when (= stored :on-keycard)
[icons/icon
:i/keycard-card
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
@@ -103,14 +105,14 @@
description])
(defn- subtitle
[{:keys [type theme blur? keycard? networks description community-name community-logo
[{:keys [type theme blur? stored networks description community-name community-logo
context-tag-type account-name emoji customization-color full-name profile-picture]}]
(cond
(= :keypair type)
[keypair-subtitle
{:theme theme
:blur? blur?
:keycard? keycard?}]
{:theme theme
:blur? blur?
:stored stored}]
(= :account type)
[account-subtitle
@@ -195,7 +197,7 @@
(defn view
[{:keys [title title-icon type description blur? community-name community-logo button-icon
account-name emoji context-tag-type button-type container-style
on-button-press on-button-long-press profile-picture keycard? networks label full-name
on-button-press on-button-long-press profile-picture stored networks label full-name
button-disabled? account-avatar-emoji account-avatar-type customization-color icon-avatar]}]
(let [theme (quo.theme/use-theme)]
[rn/view {:style (merge style/container container-style)}
@@ -220,7 +222,7 @@
{:type type
:theme theme
:blur? blur?
:keycard? keycard?
:stored stored
:networks networks
:description description
:community-name community-name
@@ -0,0 +1,30 @@
(ns quo.components.list-items.missing-keypair.component-spec
(:require
[quo.components.list-items.missing-keypair.view :as missing-keypair]
[test-helpers.component :as h]))
(def keypair-data
{:accounts []
:name "Key Pair Name"})
(def props
{:keypair keypair-data
:blur? true
:on-options-press (fn [])})
(h/describe "List items: missing keypair item"
(h/test "Test item container renders"
(h/render-with-theme-provider [missing-keypair/view props])
(h/is-truthy (h/get-by-label-text :missing-keypair-item)))
(h/test "Test keypair icon renders"
(h/render-with-theme-provider [missing-keypair/view props])
(h/is-truthy (h/get-by-label-text :icon)))
(h/test "Test name renders"
(h/render-with-theme-provider [missing-keypair/view props])
(h/is-truthy (h/get-by-label-text :name)))
(h/test "Test preview-list renders"
(h/render-with-theme-provider [missing-keypair/view props])
(h/is-truthy (h/get-by-label-text :preview-list)))
(h/test "Test options button renders"
(h/render-with-theme-provider [missing-keypair/view props])
(h/is-truthy (h/get-by-label-text :options-button))))
@@ -0,0 +1,25 @@
(ns quo.components.list-items.missing-keypair.schema)
(def ^:private ?base
[:map
[:blur? {:optional true} [:maybe :boolean]]
[:keypair
[:map
[:key-uid :string]
[:name :string]
[:accounts
[:sequential
[:map {:closed true}
[:type [:enum :default]]
[:emoji :string]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]]]]])
(def ^:private ?on-option-press
[:map
[:on-options-press {:optional true} [:maybe fn?]]])
(def ?schema
[:=>
[:cat
[:merge ?base ?on-option-press]]
:any])
@@ -0,0 +1,46 @@
(ns quo.components.list-items.missing-keypair.style
(:require
[quo.foundations.colors :as colors]))
(defn container
[{:keys [blur? theme]}]
{:flex-direction :row
:align-items :center
:flex 1
:padding-right 12
:padding-left 8
:padding-vertical 8
:border-radius 12
:border-width (if blur? 0 1)
:border-color (colors/theme-colors colors/neutral-10
colors/neutral-80
theme)
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-2_5
colors/neutral-80-opa-40
theme))})
(defn icon-container
[{:keys [blur? theme]}]
{:border-radius 32
:border-width 1
:border-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-20
colors/neutral-80
theme))})
(def name-container
{:flex 1
:padding-right 16
:padding-left 8})
(def preview-list-container
{:padding-right 16})
(defn options-icon-color
[{:keys [theme blur?]}]
(if blur?
colors/white-opa-70
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
@@ -0,0 +1,56 @@
(ns quo.components.list-items.missing-keypair.view
(:require
[quo.components.avatars.icon-avatar :as icon-avatar]
[quo.components.icon :as icon]
[quo.components.list-items.missing-keypair.schema :as component-schema]
[quo.components.list-items.missing-keypair.style :as style]
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.markdown.text :as text]
[quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(defn- internal-view
[{{:keys [accounts name]} :keypair
:keys [keypair blur? on-options-press]}]
(let [theme (quo.theme/use-theme)
on-keypair-options-press (rn/use-callback
(fn [event]
(on-options-press event keypair))
[keypair on-options-press])]
[rn/view
{:style (style/container {:theme theme
:blur? blur?})
:accessibility-label :missing-keypair-item}
[rn/view
{:style (style/icon-container {:theme theme
:blur? blur?})
:accessibility-label :icon}
[icon-avatar/icon-avatar
{:size :size-32
:icon :i/seed
:color :neutral
:border? false}]]
[rn/view
{:style style/name-container
:accessibility-label :name}
[text/text
{:weight :semi-bold}
name]]
[rn/view
{:accessibility-label :preview-list}
[preview-list/view
{:blur? blur?
:type :accounts
:size :size-24
:number (count accounts)
:container-style style/preview-list-container}
accounts]]
[rn/pressable {:on-press on-keypair-options-press}
[icon/icon :i/options
{:color (style/options-icon-color
{:theme theme
:blur? blur?})
:accessibility-label :options-button}]]]))
(def view (schema/instrument #'internal-view component-schema/?schema))
@@ -8,8 +8,7 @@
(h/render-with-theme-provider component :light))
(def props
{:theme :light
:state :default
{:state :default
:label "Mainnet"
:network-image 873
:customization-color :blue
@@ -40,7 +40,6 @@
[:catn
[:props
[:map {:closed true}
[:theme :schema.common/theme]
[:network-image :int]
[:label :string]
[:fiat-value :string]
@@ -5,18 +5,22 @@
(def container-border-radius 12)
(def card-image-padding-vertical 3)
(def card-image-padding-horizontal 3)
(def default-opacity-for-loader 1)
(def default-opacity-for-image 0)
(defn fallback
[{:keys [theme]}]
{:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
:border-style :dashed
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:border-width 1
:border-radius container-border-radius
:width "100%"
:aspect-ratio 1
:align-items :center
:justify-content :center})
[{:keys [theme opacity]}]
[{:opacity opacity}
{:opacity default-opacity-for-image
:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
:border-style :dashed
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:border-width 1
:border-radius container-border-radius
:width "100%"
:aspect-ratio 1
:align-items :center
:justify-content :center}])
(def collectible-counter
{:position :absolute
@@ -59,6 +63,15 @@
(def card-detail-text
{:flex 1})
(defn card-loader
[opacity]
[{:opacity opacity}
{:position :absolute
:opacity default-opacity-for-loader
:left 8
:align-items :center
:flex-direction :row}])
(def image-view-container
{:aspect-ratio 1
:border-radius container-border-radius})
@@ -83,6 +96,7 @@
(defn loading-image
[theme]
{:position :absolute
:opacity default-opacity-for-loader
:top 0
:bottom 0
:left 0
@@ -91,8 +105,20 @@
:background-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)
:z-index 2})
(defn loading-image-with-opacity
[theme opacity]
[{:opacity opacity}
(loading-image theme)])
(defn avatar-container
[loaded?]
{:flex 1
:flex-direction :row
:opacity (when-not loaded? 0)})
[opacity]
[{:opacity opacity}
{:flex 1
:flex-direction :row
:opacity default-opacity-for-image}])
(defn supported-file
[opacity]
[{:opacity opacity}
{:aspect-ratio 1
:opacity default-opacity-for-image}])
@@ -10,13 +10,54 @@
[quo.foundations.gradients :as gradients]
[quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[schema.core :as schema]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))
(def timing-options-out 650)
(def timing-options-in 1000)
(def first-load-time 500)
(def cached-load-time 200)
(def error-wait-time 800)
(defn on-load-end
[{:keys [load-time set-state loader-opacity image-opacity]}]
(reanimated/animate loader-opacity 0 timing-options-out)
(reanimated/animate image-opacity 1 timing-options-in)
(if (> load-time cached-load-time)
(js/setTimeout
(fn []
(set-state (fn [prev-state]
(assoc prev-state :image-loaded? true))))
first-load-time)
(set-state (fn [prev-state]
(assoc prev-state :image-loaded? true)))))
(defn on-load-error
[set-state]
(js/setTimeout (fn []
(set-state (fn [prev-state] (assoc prev-state :image-error? true))))
error-wait-time))
(defn on-load-avatar
[{:keys [load-time set-state loader-opacity avatar-opacity]}]
(reanimated/animate loader-opacity 0 timing-options-out)
(reanimated/animate avatar-opacity 1 timing-options-in)
(if (> load-time cached-load-time)
(js/setTimeout
(fn []
(set-state (fn [prev-state]
(assoc prev-state :avatar-loaded? true))))
first-load-time)
(set-state (fn [prev-state]
(assoc prev-state :avatar-loaded? true)))))
(defn- fallback-view
[{:keys [label theme]}]
[rn/view
{:style (style/fallback {:theme theme})}
[{:keys [label theme image-opacity]}]
[reanimated/view
{:style (style/fallback {:opacity image-opacity
:theme theme})}
[rn/view
[icon/icon :i/sad {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
[rn/view {:style {:height 4}}]
@@ -34,77 +75,85 @@
[rn/view {:style (style/loading-message theme)}])
(defn- loading-image
[{:keys [theme gradient-color-index]}]
[gradients/view
{:theme theme
:container-style (style/loading-image theme)
:color-index gradient-color-index}])
[{:keys [theme gradient-color-index loader-opacity]}]
[reanimated/view
{:style (style/loading-image-with-opacity theme loader-opacity)}
[gradients/view
{:theme theme
:container-style (style/loading-image theme)
:color-index gradient-color-index}]])
(defn- card-details
[{:keys [community? avatar-image-src collectible-name theme state set-state]}]
[rn/view {:style style/card-details-container}
(cond (not (:avatar-loaded? state))
[rn/view {:style {:flex-direction :row}}
[loading-square theme]
[loading-message theme]]
community?
[:<>
[preview-list/view
{:type :communities
:size :size-20}
[avatar-image-src]]
[rn/view {:style {:width 8}}]
[text/text
{:size :paragraph-1
:weight :semi-bold
:style style/card-detail-text}
collectible-name]])
[rn/view
{:style (style/avatar-container (:avatar-loaded? state))}
[:<>
[collection-avatar/view
{:size :size-20
:on-load-end #(set-state (fn [prev-state] (assoc prev-state :avatar-loaded? true)))
:image avatar-image-src}]
[rn/view {:style {:width 8}}]]
[text/text
{:size :paragraph-1
:weight :semi-bold
:ellipsize-mode :tail
:number-of-lines 1
:style style/card-detail-text}
collectible-name]]])
(let [loader-opacity (reanimated/use-shared-value 1)
avatar-opacity (reanimated/use-shared-value 0)
[load-time set-load-time] (rn/use-state (datetime/now))]
[rn/view {:style style/card-details-container}
[reanimated/view {:style (style/avatar-container avatar-opacity)}
(if community?
[preview-list/view
{:type :communities
:size :size-20}
[avatar-image-src]]
[collection-avatar/view
{:size :size-20
:on-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
:on-load-end #(on-load-avatar {:set-state set-state
:load-time load-time
:loader-opacity loader-opacity
:avatar-opacity avatar-opacity})
:image avatar-image-src}])
[rn/view {:style {:width 8}}]
[text/text
{:size :paragraph-1
:weight :semi-bold
:ellipsize-mode :tail
:number-of-lines 1
:style style/card-detail-text}
collectible-name]]
(when (not (:avatar-loaded? state))
[reanimated/view {:style (style/card-loader loader-opacity)}
[loading-square theme]
[loading-message theme]])]))
(defn- card-view
[{:keys [avatar-image-src collectible-name community? counter state set-state
gradient-color-index image-src supported-file?]}]
(let [theme (quo.theme/use-theme)]
(let [theme (quo.theme/use-theme)
loader-opacity (reanimated/use-shared-value (if supported-file? 1 0))
image-opacity (reanimated/use-shared-value (if supported-file? 0 1))
[load-time set-load-time] (rn/use-state (datetime/now))]
[rn/view {:style (style/card-view-container theme)}
[rn/view {:style {:aspect-ratio 1}}
(cond
(:image-error? state)
[fallback-view
{:theme theme
:label (i18n/label :t/cant-fetch-info)}]
{:image-opacity image-opacity
:theme theme
:label (i18n/label :t/cant-fetch-info)}]
(not supported-file?)
[fallback-view
{:theme theme
:label (i18n/label :t/unsupported-file)}]
{:image-opacity image-opacity
:theme theme
:label (i18n/label :t/unsupported-file)}]
(not (:image-loaded? state))
[loading-image
{:theme theme
{:loader-opacity loader-opacity
:theme theme
:gradient-color-index gradient-color-index}])
(when supported-file?
[rn/view {:style {:aspect-ratio 1}}
[reanimated/view {:style (style/supported-file image-opacity)}
[rn/image
{:style style/image
:on-load-end #(set-state (fn [prev-state] (assoc prev-state :image-loaded? true)))
:on-error #(set-state (fn [prev-state] (assoc prev-state :image-error? true)))
:source image-src}]])]
{:style style/image
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
:on-load-end #(on-load-end {:load-time load-time
:set-state set-state
:loader-opacity loader-opacity
:image-opacity image-opacity})
:on-error #(on-load-error set-state)
:source image-src}]])]
(when (and (:image-loaded? state) (not (:image-error? state)) counter)
[collectible-counter/view
{:container-style style/collectible-counter
@@ -121,30 +170,40 @@
(defn- image-view
[{:keys [avatar-image-src community? counter state set-state
gradient-color-index image-src supported-file?]}]
(let [theme (quo.theme/use-theme)]
(let [theme (quo.theme/use-theme)
loader-opacity (reanimated/use-shared-value (if supported-file? 1 0))
image-opacity (reanimated/use-shared-value (if supported-file? 0 1))
[load-time set-load-time] (rn/use-state (datetime/now))]
[rn/view {:style style/image-view-container}
(cond
(:image-error? state)
[fallback-view
{:theme theme
:label (i18n/label :t/cant-fetch-info)}]
{:image-opacity image-opacity
:theme theme
:label (i18n/label :t/cant-fetch-info)}]
(not supported-file?)
[fallback-view
{:theme theme
:label (i18n/label :t/unsupported-file)}]
{:image-opacity image-opacity
:theme theme
:label (i18n/label :t/unsupported-file)}]
(not (:image-loaded? state))
[loading-image
{:theme theme
{:loader-opacity loader-opacity
:theme theme
:gradient-color-index gradient-color-index}])
(when supported-file?
[rn/view {:style {:aspect-ratio 1}}
[reanimated/view {:style (style/supported-file image-opacity)}
[rn/image
{:style style/image
:on-load-end #(set-state (fn [prev-state] (assoc prev-state :image-loaded? true)))
:on-error #(set-state (fn [prev-state] (assoc prev-state :image-error? true)))
:source image-src}]])
{:style style/image
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
:on-load-end #(on-load-end {:load-time load-time
:set-state set-state
:loader-opacity loader-opacity
:image-opacity image-opacity})
:on-error #(on-load-error set-state)
:source image-src}]])
(when (and (:image-loaded? state) (not (:image-error? state)) counter)
[collectible-counter/view
{:container-style style/collectible-counter
@@ -3,7 +3,6 @@
(def container
{:flex-direction :row
:flex 1
:justify-content :space-between})
(def right-counter
@@ -55,8 +55,8 @@
:icon-color (style/right-tag-icon-color blur? theme)}]))
(defn view
[{:keys [title right accessibility-label] :as props}]
[rn/view {:style style/container}
[{:keys [title right accessibility-label container-style] :as props}]
[rn/view {:style (merge style/container container-style)}
[text/text
{:size :heading-1
:weight :semi-bold
@@ -0,0 +1,43 @@
(ns quo.components.wallet.approval-label.component-spec
(:require [quo.components.wallet.approval-label.view :as approval-label]
[test-helpers.component :as h]))
(h/describe "Wallet: Approval Label"
(h/test "with :approve status"
(h/render-with-theme-provider
[approval-label/view
{:status :approve
:customization-color :blue
:token-value "100"
:token-symbol "SNT"}])
(h/is-truthy (h/get-by-translation-text :t/approve-amount-symbol {:amount "100" :symbol "SNT"})))
(h/test "with :approving status"
(h/render-with-theme-provider
[approval-label/view
{:status :approving
:customization-color :blue
:token-value "50"
:token-symbol "DAI"}])
(h/is-truthy (h/get-by-translation-text :t/approving-amount-symbol {:amount "50" :symbol "DAI"})))
(h/test "with :approved status"
(h/render-with-theme-provider
[approval-label/view
{:status :approved
:customization-color :blue
:token-value "5"
:token-symbol "ETH"}])
(h/is-truthy (h/get-by-translation-text :t/approved-amount-symbol {:amount "5" :symbol "ETH"})))
(h/test "on-press event is called when button is pressed"
(let [mock-fn (h/mock-fn)]
(h/render-with-theme-provider
[approval-label/view
{:status :approve
:customization-color :blue
:token-value "11"
:token-symbol "DAI"
:button-props {:on-press mock-fn}}])
(h/fire-event :press (h/get-by-translation-text :t/approve))
(h/was-called mock-fn))))
@@ -0,0 +1,14 @@
(ns quo.components.wallet.approval-label.schema)
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:status [:enum :approve :approving :approved]]
[:token-value :string]
[:token-symbol :string]
[:container-style {:optional true} [:maybe :map]]
[:button-props {:optional true} [:maybe :map]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]]
:any])
@@ -0,0 +1,28 @@
(ns quo.components.wallet.approval-label.style
(:require [quo.foundations.colors :as colors]))
(def ^:const top-hole-view-height 24)
(defn container
[customization-color theme]
{:background-color (colors/resolve-color customization-color theme 5)
:align-items :center
:padding-horizontal 12
:padding-vertical 8
:padding-top (+ 8 top-hole-view-height)
:gap 8
:border-bottom-left-radius 16
:border-bottom-right-radius 16
:flex-direction :row})
(def content
{:flex-direction :row
:align-items :center
:flex 1
:padding-vertical 4
:gap 4})
(defn message
[theme]
{:flex 1
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
@@ -0,0 +1,70 @@
(ns quo.components.wallet.approval-label.view
(:require [oops.core :as oops]
[quo.components.buttons.button.view :as button]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.wallet.approval-label.schema :as approval-label.schema]
[quo.components.wallet.approval-label.style :as style]
[quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[schema.core :as schema]
[utils.i18n :as i18n]))
(def ^:private status-icons
{:approve :i/alert
:approving :i/pending-state
:approved :i/check})
(def ^:private status-message
{:approve :t/approve-amount-symbol
:approving :t/approving-amount-symbol
:approved :t/approved-amount-symbol})
(defn- view-internal
[{:keys [status token-value token-symbol
container-style button-props]
:as props}]
(let [theme (quo.theme/use-theme)
customization-color (or (:customization-color props) :blue)
[container-width set-container-width] (rn/use-state 0)
on-layout (rn/use-callback
#(set-container-width
(oops/oget % :nativeEvent :layout :width)))]
[hole-view/hole-view
{:holes [{:x 0
:y 0
:height style/top-hole-view-height
:width container-width
:borderBottomStartRadius 16
:borderBottomEndRadius 16}]
:style {:margin-top (- style/top-hole-view-height)}
:on-layout on-layout}
[rn/view
{:style (merge (style/container customization-color theme)
container-style)
:accessibility-label :approval-label}
[rn/view {:style style/content}
[icon/icon
(status-icons status)
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:size 16}]
[text/text
{:size :paragraph-2
:style (style/message theme)}
(i18n/label (status-message status)
{:amount token-value
:symbol token-symbol})]]
(when button-props
[button/button
(merge {:type (if (= status :approve) :primary :grey)
:background (when-not (= status :approve) :blur)
:customization-color customization-color
:size 24}
button-props)
(i18n/label (if (= status :approve)
:t/approve
:t/view))])]]))
(def view (schema/instrument #'view-internal approval-label.schema/?schema))
@@ -0,0 +1,24 @@
(ns quo.components.wallet.missing-keypairs.component-spec
(:require
[quo.components.wallet.missing-keypairs.view :as missing-keypairs]
[test-helpers.component :as h]))
(def ^:private theme :dark)
(def props
{:blur? true
:container-style {}
:on-options-press (fn [])
:keypairs [{:type :seed
:name name
:key-uid "123"
:accounts [{:customization-color :turquoise
:emoji "\uD83C\uDFB2"
:type :default}]}]})
(h/describe "Wallet: Missing key pairs"
(h/test "Missing key pair title renders"
(h/render-with-theme-provider [missing-keypairs/view props]
theme)
(h/is-truthy (h/get-by-label-text :title))
(h/is-truthy (h/get-by-label-text :t/import-to-use-derived-accounts))))
@@ -0,0 +1,28 @@
(ns quo.components.wallet.missing-keypairs.style
(:require
[quo.foundations.colors :as colors]))
(def container
{:border-width 1
:border-radius 16
:padding 8
:border-color colors/warning-50-opa-20
:background-color colors/warning-50-opa-5})
(def title-icon-container
{:top 1})
(def title-info-container
{:padding-left 8})
(def title-container
{:align-items :flex-start
:flex-direction :row
:padding-left 4
:padding-bottom 12})
(defn subtitle
[blur? theme]
{:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
@@ -0,0 +1,53 @@
(ns quo.components.wallet.missing-keypairs.view
(:require
[quo.components.icon :as icon]
[quo.components.list-items.missing-keypair.view :as missing-keypair]
[quo.components.markdown.text :as text]
[quo.components.wallet.missing-keypairs.style :as style]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]))
(defn title-view
[{:keys [keypairs blur?]}]
(let [theme (quo.theme/use-theme)]
[rn/view
{:accessibility-label :title
:style style/title-container}
[rn/view
{:style style/title-icon-container}
[icon/icon :i/info
{:size 20
:color colors/warning-60}]]
[rn/view
{:style style/title-info-container}
[text/text
{:weight :medium
:style {:color colors/warning-60}}
(i18n/label :t/amount-missing-keypairs
{:amount (str (count keypairs))})]
[text/text
{:size :paragraph-2
:style (style/subtitle blur? theme)}
(i18n/label :t/import-to-use-derived-accounts)]]]))
(defn- missing-keypair-item
[keypair _index _separators
{:keys [blur? on-options-press]}]
[missing-keypair/view
{:keypair keypair
:blur? blur?
:on-options-press on-options-press}])
(defn view
[{:keys [blur? keypairs container-style on-options-press] :as props}]
[rn/view
{:style (merge style/container container-style)}
[title-view props]
[rn/flat-list
{:data keypairs
:render-fn missing-keypair-item
:render-data {:blur? blur?
:on-options-press on-options-press}
:separator [rn/view {:style {:height 8}}]}]])
+14
View File
@@ -5,8 +5,11 @@
quo.components.avatars.account-avatar.view
quo.components.avatars.channel-avatar.view
quo.components.avatars.collection-avatar.view
quo.components.avatars.community-avatar.view
quo.components.avatars.dapp-avatar.view
quo.components.avatars.group-avatar.view
quo.components.avatars.icon-avatar
quo.components.avatars.token-avatar.view
quo.components.avatars.user-avatar.view
quo.components.avatars.wallet-user-avatar.view
quo.components.banners.banner.view
@@ -17,6 +20,7 @@
quo.components.buttons.logout-button.view
quo.components.buttons.predictive-keyboard.view
quo.components.buttons.slide-button.view
quo.components.buttons.swap-order-button.view
quo.components.buttons.wallet-button.view
quo.components.buttons.wallet-ctas.view
quo.components.calendar.calendar-day.view
@@ -84,6 +88,7 @@
quo.components.list-items.community.view
quo.components.list-items.dapp.view
quo.components.list-items.menu-item
quo.components.list-items.missing-keypair.view
quo.components.list-items.network-list.view
quo.components.list-items.preview-list.view
quo.components.list-items.quiz-item.view
@@ -165,8 +170,10 @@
quo.components.wallet.account-permissions.view
quo.components.wallet.address-text.view
quo.components.wallet.amount-input.view
quo.components.wallet.approval-label.view
quo.components.wallet.confirmation-progress.view
quo.components.wallet.keypair.view
quo.components.wallet.missing-keypairs.view
quo.components.wallet.network-amount.view
quo.components.wallet.network-bridge.view
quo.components.wallet.network-link.view
@@ -186,8 +193,11 @@
(def account-avatar quo.components.avatars.account-avatar.view/view)
(def channel-avatar quo.components.avatars.channel-avatar.view/view)
(def collection-avatar quo.components.avatars.collection-avatar.view/view)
(def community-avatar quo.components.avatars.community-avatar.view/view)
(def dapp-avatar quo.components.avatars.dapp-avatar.view/view)
(def group-avatar quo.components.avatars.group-avatar.view/view)
(def icon-avatar quo.components.avatars.icon-avatar/icon-avatar)
(def token-avatar quo.components.avatars.token-avatar.view/view)
(def user-avatar quo.components.avatars.user-avatar.view/user-avatar)
(def wallet-user-avatar quo.components.avatars.wallet-user-avatar.view/wallet-user-avatar)
@@ -201,6 +211,7 @@
(def logout-button quo.components.buttons.logout-button.view/view)
(def predictive-keyboard quo.components.buttons.predictive-keyboard.view/view)
(def slide-button quo.components.buttons.slide-button.view/view)
(def swap-order-button quo.components.buttons.swap-order-button.view/view)
(def wallet-button quo.components.buttons.wallet-button.view/view)
(def wallet-ctas quo.components.buttons.wallet-ctas.view/view)
@@ -317,6 +328,7 @@
(def community-list quo.components.list-items.community.view/view)
(def dapp quo.components.list-items.dapp.view/view)
(def menu-item quo.components.list-items.menu-item/menu-item)
(def missing-keypair quo.components.list-items.missing-keypair.view/view)
(def network-list quo.components.list-items.network-list.view/view)
(def preview-list quo.components.list-items.preview-list.view/view)
(def quiz-item quo.components.list-items.quiz-item.view/view)
@@ -434,8 +446,10 @@
(def account-permissions quo.components.wallet.account-permissions.view/view)
(def address-text quo.components.wallet.address-text.view/view)
(def amount-input quo.components.wallet.amount-input.view/view)
(def approval-label quo.components.wallet.approval-label.view/view)
(def confirmation-progress quo.components.wallet.confirmation-progress.view/view)
(def keypair quo.components.wallet.keypair.view/view)
(def missing-keypairs quo.components.wallet.missing-keypairs.view/view)
(def network-amount quo.components.wallet.network-amount.view/view)
(def network-bridge quo.components.wallet.network-bridge.view/view)
(def network-routing quo.components.wallet.network-routing.view/view)
+5
View File
@@ -1,6 +1,9 @@
(ns quo.core-spec
(:require
quo.components.avatars.account-avatar.component-spec
quo.components.avatars.community-avatar.component-spec
quo.components.avatars.dapp-avatar.component-spec
quo.components.avatars.token-avatar.component-spec
quo.components.avatars.user-avatar.component-spec
quo.components.banners.banner.component-spec
quo.components.browser.browser-input.component-spec
@@ -9,6 +12,7 @@
quo.components.buttons.logout-button.component-spec
quo.components.buttons.predictive-keyboard.component-spec
quo.components.buttons.slide-button.component-spec
quo.components.buttons.swap-order-button.component-spec
quo.components.buttons.wallet-button.component-spec
quo.components.buttons.wallet-ctas.component-spec
quo.components.calendar.calendar-day.component-spec
@@ -95,6 +99,7 @@
quo.components.wallet.account-overview.component-spec
quo.components.wallet.account-permissions.component-spec
quo.components.wallet.amount-input.component-spec
quo.components.wallet.approval-label.component-spec
quo.components.wallet.confirmation-progress.component-spec
quo.components.wallet.keypair.component-spec
quo.components.wallet.network-amount.component-spec
-9
View File
@@ -128,15 +128,6 @@
:user-picture-male4 (js/require "../resources/images/mock2/user_picture_male4.png")
:user-picture-male5 (js/require "../resources/images/mock2/user_picture_male5.png")})
(def services
{:latamex (js/require "../resources/images/services/Latamex.png")
:moonpay (js/require "../resources/images/services/Moonpay.png")
:ramp (js/require "../resources/images/services/Ramp.png")})
(defn get-service-image
[k]
(get services k))
(defn get-mock-image
[k]
(get mock-images k))
+16 -14
View File
@@ -20,7 +20,7 @@
(defonce camera-permission-granted? (reagent/atom false))
(defn- header
[{:keys [title subtitle]}]
[{:keys [title subtitle share-button?]}]
[:<>
[rn/view {:style style/header-container}
[quo/button
@@ -31,16 +31,17 @@
:accessibility-label :close-scan-qr-code
:on-press #(rf/dispatch [:navigate-back])}
:i/close]
[quo/button
{:icon-only? true
:type :grey
:background :blur
:size 32
:accessibility-label :show-qr-button
:on-press (fn []
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/share-shell]))}
:i/qr-code]]
(when share-button?
[quo/button
{:icon-only? true
:type :grey
:background :blur
:size 32
:accessibility-label :show-qr-button
:on-press (fn []
(rf/dispatch [:navigate-back])
(rf/dispatch [:open-modal :screen/share-shell]))}
:i/qr-code])]
[quo/text
{:size :heading-1
:weight :semi-bold
@@ -195,7 +196,7 @@
true)
(defn view
[{:keys [title subtitle validate-fn on-success-scan error-message]}]
[{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}]
(let [insets (safe-area/get-insets)
qr-code-succeed? (reagent/atom false)
qr-view-finder (reagent/atom {})
@@ -237,8 +238,9 @@
:set-rescan-timeout set-rescan-timeout}])
[rn/view {:style (style/root-container (:top insets))}
[header
{:title title
:subtitle subtitle}]
{:title title
:subtitle subtitle
:share-button? share-button?}]
(when (empty? @qr-view-finder)
[:<>
[rn/view {:style style/scan-qr-code-container}]
@@ -24,7 +24,7 @@
:on-auth-success on-auth-success
:on-auth-fail on-auth-fail
:auth-button-label auth-button-label}]))
(into [] (concat [theme] dependencies)))]
(vec (conj dependencies on-auth-success on-auth-fail)))]
[quo/slide-button
{:container-style container-style
:size size
+5 -22
View File
@@ -26,7 +26,7 @@
(goog-define ALCHEMY_OPTIMISM_SEPOLIA_TOKEN "")
(goog-define WALLET_CONNECT_PROJECT_ID "")
(def mainnet-rpc-url (str "https://eth-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
(def mainnet-rpc-url (str "https://eth-archival.rpc.grove.city/v1/" POKT_TOKEN))
(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
(def mainnet-chain-explorer-link "https://etherscan.io/address/")
(def optimism-mainnet-chain-explorer-link "https://optimistic.etherscan.io/address/")
@@ -105,32 +105,15 @@
(def fast-create-community-enabled?
(enabled? (get-config :FAST_CREATE_COMMUNITY_ENABLED "0")))
(def default-multiaccount
{:preview-privacy? blank-preview?
:wallet-legacy/visible-tokens {:mainnet #{:SNT}}
:currency :usd
:appearance 0
:profile-pictures-show-to 2
:profile-pictures-visibility 2
:log-level log-level
:webview-allow-permission-requests? false
:opensea-enabled? false
:link-previews-enabled-sites #{}
:link-preview-request-enabled true})
(defn default-visible-tokens
[chain]
(get-in default-multiaccount [:wallet-legacy/visible-tokens chain]))
(def waku-nodes-config
{:status.prod
["enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"]
:status.test
["enrtree://AIO6LUM3IVWCU2KCPBBI6FEH2W42IGK3ASCZHZGG5TIXUR56OGQUO@test.status.nodes.status.im"]
:wakuv2.prod
["enrtree://ANEDLO25QVUGJOUTQFRYKWX6P4Z4GKVESBMHML7DZ6YK4LGS5FC5O@prod.wakuv2.nodes.status.im"]
:wakuv2.test
["enrtree://AO47IDOLBKH72HIZZOXQP6NMRESAN7CHYWIBNXDXWRJRZWLODKII6@test.wakuv2.nodes.status.im"]})
:waku.sandbox
["enrtree://AIRVQ5DDA4FFWLRBCHJWUWOO6X6S4ZTZ5B667LQ6AJU6PEYDLRD5O@sandbox.waku.nodes.status.im"]
:waku.test
["enrtree://AOGYWMBYOUIMOENHXCHILPKY3ZRFEULMFI4DOM442QSZ73TT2A7VI@test.waku.nodes.status.im"]})
(def default-kdf-iterations 3200)
@@ -5,32 +5,25 @@
[theme]
{:flex 1
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:justify-content :space-between
:align-items :center
:margin-top 2
:padding-horizontal 20})
(def container-invalid
{:style {:flex-direction :row
:align-items :center
:margin-top 8}})
{:flex-direction :row
:margin-top 8})
(defn text-description
[theme]
{:size :paragraph-2
:weight :medium
:style {:margin-bottom 6
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}})
{:margin-bottom 6
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def icon-invalid
{:size 16
:color colors/danger-50})
(def text-invalid
{:size :paragraph-2
:align :left
:style {:margin-left 4
:color colors/danger-50}})
{:margin-left 4
:color colors/danger-50})
(def input-and-scan-container
{:flex-direction :row
@@ -18,7 +18,10 @@
theme (quo.theme/use-theme)]
(when primary-name
[rn/view style/found-user
[quo/text (style/text-description theme)
[quo/text
{:size :paragraph-2
:weight :medium
:style (style/text-description theme)}
(i18n/label :t/user-found)]
[rn/view (style/found-user-container theme)
[quo/user-avatar
@@ -105,7 +108,9 @@
[message]
[rn/view style/container-invalid
[quo/icon :i/alert style/icon-invalid]
[quo/text style/text-invalid
[quo/text
{:size :paragraph-2
:style style/text-invalid}
(i18n/label (or message :t/invalid-ens-or-key))]])
(defn navigate-back [] (rf/dispatch [:navigate-back]))
@@ -187,29 +187,29 @@
muted? (and muted (some? muted-till))
mute-chat-label (if community-channel? :t/mute-channel :t/mute-chat)
unmute-chat-label (if community-channel? :t/unmute-channel :t/unmute-chat)]
[quo/channel-actions
{:actions [{:accessibility-label :action-button-pinned
:big? true
:label (or latest-pin-text (i18n/label :t/no-pinned-messages))
:customization-color cover-bg-color
:icon :i/pin
:counter-value pins-count
:on-press (fn []
(rf/dispatch [:pin-message/show-pins-bottom-sheet
chat-id]))}
{:accessibility-label :action-button-mute
:label (i18n/label (if muted
unmute-chat-label
mute-chat-label))
:customization-color cover-bg-color
:icon (if muted? :i/activity-center :i/muted)
:on-press (fn []
(if muted?
(home.actions/unmute-chat-action chat-id)
(home.actions/mute-chat-action chat-id
chat-type
muted?)))}]}]))
{:actions
[{:accessibility-label :action-button-pinned
:big? true
:label (if (pos? pins-count) latest-pin-text (i18n/label :t/no-pinned-messages))
:customization-color cover-bg-color
:icon :i/pin
:counter-value pins-count
:on-press (fn []
(rf/dispatch [:pin-message/show-pins-bottom-sheet
chat-id]))}
{:accessibility-label :action-button-mute
:label (i18n/label (if muted
unmute-chat-label
mute-chat-label))
:customization-color cover-bg-color
:icon (if muted? :i/activity-center :i/muted)
:on-press (fn []
(if muted?
(home.actions/unmute-chat-action chat-id)
(home.actions/mute-chat-action chat-id
chat-type
muted?)))}]}]))
(defn bio-and-actions
[{:keys [distance-from-list-top bio chat-id customization-color empty-chat? description]}]
@@ -14,7 +14,7 @@
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
;(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
@@ -30,7 +30,7 @@
(h/is-truthy (h/get-by-translation-text :t/view-token-gating))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
;(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
@@ -44,7 +44,7 @@
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
;(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
@@ -58,7 +58,7 @@
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
;(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
@@ -3,6 +3,7 @@
[quo.core :as quo]
[status-im.common.mute-drawer.view :as mute-options]
[status-im.common.muting.helpers :refer [format-mute-till]]
[status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.communities.actions.leave.view :as leave-menu]
[status-im.contexts.communities.actions.permissions-sheet.view :as permissions-sheet]
@@ -83,11 +84,12 @@
(defn community-notification-settings
[id]
{:icon :i/notifications
:accessibility-label :community-notification-settings
:label (i18n/label :t/notification-settings)
:on-press #(js/alert (str "implement action" id))
:right-icon :i/chevron-right})
(when config/show-not-implemented-features?
{:icon :i/notifications
:accessibility-label :community-notification-settings
:label (i18n/label :t/notification-settings)
:on-press #(js/alert (str "implement action" id))
:right-icon :i/chevron-right}))
(defn invite-contacts
[id]
@@ -2,6 +2,7 @@
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.config :as config]
[status-im.contexts.onboarding.common.background.view :as background]
[status-im.contexts.onboarding.syncing.progress.style :as style]
[utils.debounce :as debounce]
@@ -54,11 +55,13 @@
(when-not in-onboarding? [background/view true])
[quo/page-nav {:type :no-title :background :blur}]
[page-title (pairing-progress pairing-status)]
(if (pairing-progress pairing-status)
[rn/view {:style style/page-illustration}
[quo/text "[Success here]"]]
[rn/view {:style style/page-illustration}
[quo/text "[Error here]"]])
(if config/show-not-implemented-features?
(if (pairing-progress pairing-status)
[rn/view {:style style/page-illustration}
[quo/text "[Success here]"]]
[rn/view {:style style/page-illustration}
[quo/text "[Error here]"]])
[rn/view {:flex 1}])
(when-not (pairing-progress pairing-status)
[try-again-button profile-color in-onboarding? logged-in?])]))
@@ -0,0 +1,24 @@
(ns status-im.contexts.preview.quo.avatars.community-avatar
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.common.resources :as resources]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :select
:key :size
:options [{:key :size-32}
{:key :size-24}]}])
(defn view
[]
(let [[state set-state] (rn/use-state {:size :size-32})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[quo/community-avatar
(assoc state
:image
(resources/get-mock-image :community-logo))]]))
@@ -0,0 +1,22 @@
(ns status-im.contexts.preview.quo.avatars.dapp-avatar
(:require
[quo.core :as quo]
[quo.foundations.resources :as resources]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :boolean
:key :context?}])
(defn view
[]
(let [[state set-state] (rn/use-state {:context? false})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[quo/dapp-avatar
(assoc state
:network-image (resources/get-network :ethereum)
:image (resources/get-dapp :coingecko))]]))
@@ -0,0 +1,29 @@
(ns status-im.contexts.preview.quo.avatars.token-avatar
(:require
[quo.core :as quo]
[quo.foundations.resources :as foundations.resources]
[react-native.core :as rn]
[status-im.common.resources :as resources]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :select
:key :type
:options [{:key :asset}
{:key :collectible}]}
{:type :boolean
:key :context?}])
(defn view
[]
(let [[state set-state] (rn/use-state {:type :asset
:context? false})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[quo/token-avatar
(assoc state
:network-image (foundations.resources/get-network :optimism)
:image (resources/get-mock-image
(if (= (state :type) :asset) :status-logo :collectible1)))]]))
@@ -0,0 +1,21 @@
(ns status-im.contexts.preview.quo.buttons.swap-order-button
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :boolean
:key :disabled?}])
(defn view
[]
(let [[state set-state] (rn/use-state {:disabled? false})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[quo/swap-order-button
(assoc state
:on-press
#(js/alert "Pressed"))]]))
@@ -25,8 +25,11 @@
:value "null"}]}
{:key :blur?
:type :boolean}
{:key :keycard?
:type :boolean}
{:key :stored
:type :select
:options [{:key :on-device}
{:key :on-keycard}
{:key :missing}]}
{:key :title
:type :text}
{:key :description
@@ -44,7 +47,7 @@
:title "Title"
:type :default
:label "Drawer label"
:keycard? true
:stored :on-device
:networks [{:network-name :ethereum :short-name "eth"}]
:description "0x62b...0a5"
:button-icon :i/placeholder
@@ -0,0 +1,32 @@
(ns status-im.contexts.preview.quo.list-items.missing-keypair
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :blur?
:type :boolean}])
(def component-props
{:blur? false
:keypair {:type :seed
:key-uid "0x01"
:name "Trip to Vegas"
:accounts [{:type :default
:emoji "🍑"
:customization-color :purple}]}})
(defn view
[]
(let [state (reagent/atom component-props)]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true
:blur-dark-only? true}
[rn/view {:style {:align-items :flex-start}}
[quo/missing-keypair @state]]])))
+22 -1
View File
@@ -10,8 +10,11 @@
[status-im.contexts.preview.quo.avatars.account-avatar :as account-avatar]
[status-im.contexts.preview.quo.avatars.channel-avatar :as channel-avatar]
[status-im.contexts.preview.quo.avatars.collection-avatar :as collection-avatar]
[status-im.contexts.preview.quo.avatars.community-avatar :as community-avatar]
[status-im.contexts.preview.quo.avatars.dapp-avatar :as dapp-avatar]
[status-im.contexts.preview.quo.avatars.group-avatar :as group-avatar]
[status-im.contexts.preview.quo.avatars.icon-avatar :as icon-avatar]
[status-im.contexts.preview.quo.avatars.token-avatar :as token-avatar]
[status-im.contexts.preview.quo.avatars.user-avatar :as user-avatar]
[status-im.contexts.preview.quo.avatars.wallet-user-avatar :as
wallet-user-avatar]
@@ -24,6 +27,7 @@
[status-im.contexts.preview.quo.buttons.predictive-keyboard :as
predictive-keyboard]
[status-im.contexts.preview.quo.buttons.slide-button :as slide-button]
[status-im.contexts.preview.quo.buttons.swap-order-button :as swap-order-button]
[status-im.contexts.preview.quo.buttons.wallet-button :as wallet-button]
[status-im.contexts.preview.quo.buttons.wallet-ctas :as wallet-ctas]
[status-im.contexts.preview.quo.calendar.calendar :as calendar]
@@ -102,6 +106,7 @@
[status-im.contexts.preview.quo.list-items.address :as address]
[status-im.contexts.preview.quo.list-items.channel :as channel]
[status-im.contexts.preview.quo.list-items.dapp :as dapp]
[status-im.contexts.preview.quo.list-items.missing-keypair :as missing-keypair]
[status-im.contexts.preview.quo.list-items.network-list :as network-list]
[status-im.contexts.preview.quo.list-items.preview-lists :as preview-lists]
[status-im.contexts.preview.quo.list-items.quiz-item :as quiz-item]
@@ -191,9 +196,11 @@
account-overview]
[status-im.contexts.preview.quo.wallet.account-permissions :as account-permissions]
[status-im.contexts.preview.quo.wallet.amount-input :as amount-input]
[status-im.contexts.preview.quo.wallet.approval-label :as approval-label]
[status-im.contexts.preview.quo.wallet.confirmation-progress :as
confirmation-progress]
[status-im.contexts.preview.quo.wallet.keypair :as keypair]
[status-im.contexts.preview.quo.wallet.missing-keypairs :as missing-keypairs]
[status-im.contexts.preview.quo.wallet.network-amount :as network-amount]
[status-im.contexts.preview.quo.wallet.network-bridge :as network-bridge]
[status-im.contexts.preview.quo.wallet.network-link :as network-link]
@@ -216,10 +223,16 @@
:component shadows/view}]
:animated-list [{:name :animated-header-list
:component animated-header-list/mock-screen}]
:avatar [{:name :group-avatar
:avatar [{:name :community-avatar
:component community-avatar/view}
{:name :dapp-avatar
:component dapp-avatar/view}
{:name :group-avatar
:component group-avatar/view}
{:name :icon-avatar
:component icon-avatar/view}
{:name :token-avatar
:component token-avatar/view}
{:name :user-avatar
:component user-avatar/view}
{:name :wallet-user-avatar
@@ -240,6 +253,8 @@
:component dynamic-button/view}
{:name :slide-button
:component slide-button/view}
{:name :swap-order-button
:component swap-order-button/view}
{:name :predictive-keyboard
:component predictive-keyboard/view}
{:name :wallet-button
@@ -376,6 +391,8 @@
:component community-list-item/view}
{:name :dapp
:component dapp/preview}
{:name :missing-keypair
:component missing-keypair/view}
{:name :network-list
:component network-list/view}
{:name :preview-lists
@@ -526,9 +543,13 @@
:component account-permissions/view}
{:name :amount-input
:component amount-input/view}
{:name :approval-label
:component approval-label/view}
{:name :confirmation-progress
:component confirmation-progress/view}
{:name :keypair :component keypair/view}
{:name :missing-keypairs
:component missing-keypairs/view}
{:name :network-amount :component network-amount/view}
{:name :network-bridge :component network-bridge/view}
{:name :network-link :component network-link/view}
@@ -0,0 +1,37 @@
(ns status-im.contexts.preview.quo.wallet.approval-label
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :select
:key :status
:options [{:key :approve}
{:key :approving}
{:key :approved}]}
{:type :text
:key :token-value}
{:type :select
:key :token-symbol
:options [{:key "SNT"}
{:key "DAI"}
{:key "ETH"}]}
(preview/customization-color-option)])
(defn view
[]
(let [[state set-state] (rn/use-state {:status :approve
:customization-color :blue
:token-value "100"
:token-symbol "SNT"})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor
:component-container-style {:padding-top 50}}
[quo/approval-label
(assoc state
:button-props
{:on-press
#(js/alert "Pressed")})]]))
@@ -0,0 +1,57 @@
(ns status-im.contexts.preview.quo.wallet.missing-keypairs
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def keypair
{:key-uid "0x01"
:type "seed"
:name "My Key Pair"
:blur? false})
(def accounts
[{:customization-color :turquoise
:emoji "\uD83C\uDFB2"
:type :default}
{:customization-color :purple
:emoji "\uD83C\uDF7F"
:type :default}
{:customization-color :army
:emoji "\uD83D\uDCC8"
:type :default}
{:customization-color :orange
:emoji "\uD83C\uDFF0"
:type :default}
{:customization-color :yellow
:emoji "\uD83C\uDFDD"
:type :default}])
(def descriptor
[{:key :blur? :type :boolean}])
(def component-props
{:blur? false
:keypairs [{:name (:name keypair)
:key-uid (:key-uid keypair)
:type (keyword (:type keypair))
:accounts accounts}]})
(defn view
[]
(let [state (reagent/atom {:blur? false})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true
:blur-dark-only? true
:blur-height 400
:component-container-style {:padding-vertical 30
:flex-direction :row
:justify-content :center}}
[rn/view {:style {:flex 1}}
[quo/missing-keypairs
(merge component-props @state)]]])))
@@ -16,3 +16,10 @@
(def keypair-container-style
{:margin-horizontal 20
:margin-vertical 8})
(def missing-keypairs-container-style
{:margin-horizontal 20
:margin-vertical 8})
(def settings-keypairs-container
{:flex 1})
@@ -20,6 +20,21 @@
{:content (fn [] [actions/view props keypair])
:theme theme}]))
(defn options-drawer-props
[{{:keys [name]} :keypair
:keys [type stored theme shortened-key customization-color profile-picture]}]
(cond-> {:theme theme
:type type
:blur? true
:title name
:stored stored}
(= type :default-keypair)
(assoc :description shortened-key
:customization-color customization-color
:profile-picture profile-picture)
(= type :keypair)
(assoc :icon-avatar :i/seed)))
(defn- keypair
[{keypair-type :type
:keys [accounts name]
@@ -33,22 +48,19 @@
on-press (rn/use-callback
(fn []
(on-options-press
(cond-> {:theme theme
:blur? true
:title name}
default-keypair?
(assoc :type :default-keypair
:description shortened-key
:customization-color customization-color
:profile-picture profile-picture)
(not default-keypair?)
(assoc :type :keypair
:icon-avatar :i/seed))
(options-drawer-props
{:theme theme
:keypair item
:type (if default-keypair? :default-keypair :keypair)
:stored :on-device
:shortened-key shortened-key
:customization-color customization-color
:profile-picture profile-picture})
item))
[customization-color default-keypair? name
[customization-color default-keypair? item
profile-picture shortened-key theme])]
[quo/keypair
{:blur? false
{:blur? true
:status-indicator false
:stored :on-device
:action :options
@@ -61,13 +73,27 @@
:details {:full-name name
:address shortened-key}}]))
(defn on-missing-keypair-options-press
[_event keypair-data]
(rf/dispatch [:show-bottom-sheet
{:theme :dark
:content (fn [] [actions/view
(options-drawer-props
{:theme :dark
:type :keypair
:stored :missing
:blur? true
:keypair keypair-data})
keypair-data])}]))
(defn view
[]
(let [insets (safe-area/get-insets)
compressed-key (rf/sub [:profile/compressed-key])
profile-picture (rf/sub [:profile/image])
customization-color (rf/sub [:profile/customization-color])
quo-keypairs-accounts (rf/sub [:wallet/settings-keypairs-accounts])]
(let [insets (safe-area/get-insets)
compressed-key (rf/sub [:profile/compressed-key])
profile-picture (rf/sub [:profile/image])
customization-color (rf/sub [:profile/customization-color])
{missing-keypairs :missing
operable-keypairs :operable} (rf/sub [:wallet/settings-keypairs-accounts])]
[quo/overlay
{:type :shell
:container-style (style/page-wrapper (:top insets))}
@@ -81,9 +107,15 @@
{:title (i18n/label :t/keypairs-and-accounts)
:accessibility-label :keypairs-and-accounts-header
:customization-color customization-color}]]
[rn/view {:style {:flex 1}}
[rn/view {:style style/settings-keypairs-container}
(when (seq missing-keypairs)
[quo/missing-keypairs
{:blur? true
:keypairs missing-keypairs
:container-style style/missing-keypairs-container-style
:on-options-press on-missing-keypair-options-press}])
[rn/flat-list
{:data quo-keypairs-accounts
{:data operable-keypairs
:render-fn keypair
:render-data {:profile-picture profile-picture
:compressed-key compressed-key
@@ -6,6 +6,7 @@
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.config :as config]
[status-im.contexts.shell.jump-to.animation :as animation]
[status-im.contexts.shell.jump-to.components.bottom-tabs.style :as style]
[status-im.contexts.shell.jump-to.constants :as shell.constants]
@@ -70,4 +71,5 @@
[gesture/gesture-detector {:gesture messages-double-tap-gesture}
[bottom-tab :i/messages :chats-stack shared-values notifications-data]]
[bottom-tab :i/wallet :wallet-stack shared-values notifications-data]
[bottom-tab :i/browser :browser-stack shared-values notifications-data]]]]))
(when config/show-not-implemented-features?
[bottom-tab :i/browser :browser-stack shared-values notifications-data])]]]))
@@ -118,6 +118,7 @@
(rn/dismiss-keyboard!))
[scan-qr-code/view
{:title (i18n/label :t/scan-qr)
:share-button? true
:on-success-scan on-qr-code-scanned}]]))
(defn view
@@ -19,11 +19,12 @@
(h/before-each
(fn []
(h/setup-subs {:dimensions/window-width 500
:mediaserver/port 200
:wallet/accounts [{:address "0x707f635951193ddafbb40971a0fcaab8a6415160"
:name "Wallet One"
:emoji "😆"
:color :blue}]})))
:mediaserver/port 200
:wallet/accounts [{:address "0x707f635951193ddafbb40971a0fcaab8a6415160"
:name "Wallet One"
:emoji "😆"
:color :blue}]
:wallet/preferred-chain-names-for-address #{:eth :oeth :arb1}})))
(h/test "should display the wallet tab"
(render-wallet-view)
@@ -5,7 +5,6 @@
[react-native.core :as rn]
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.contexts.shell.share.style :as style]
[status-im.contexts.shell.share.wallet.style :as wallet-style]
[status-im.contexts.wallet.common.utils :as utils]
@@ -51,9 +50,9 @@
chain-ids)))}])}]))
(defn- wallet-qr-code-item
[{:keys [account index]}]
[{:keys [account index preferred-chains]}]
(let [{window-width :width} (rn/get-window)
selected-networks (reagent/atom constants/default-network-names)
selected-networks (reagent/atom preferred-chains)
wallet-type (reagent/atom :multichain)
on-settings-press #(open-preferences selected-networks account)
on-legacy-press #(reset! wallet-type :legacy)
@@ -97,10 +96,11 @@
^{:key i} [indicator (= current-index i)])])
(defn render-item
[item]
[{:keys [address] :as account}]
[wallet-qr-code-item
{:account item
:index (:position item)}])
{:account account
:index (:position account)
:preferred-chains (rf/sub [:wallet/preferred-chain-names-for-address address])}])
(defn- qr-code-visualized-index
[offset qr-code-size num-qr-codes]
@@ -47,13 +47,10 @@
:shell? true
:content sheet-content}])))
(defn view
[]
(let [padding-top (:top (safe-area/get-insets))
wallet-type (reagent/atom :legacy)
;; Design team is yet to confirm the default selected networks here. Should be the current
;; selected for the account or all the networks always
selected-networks (reagent/atom constants/default-network-names)
on-settings-press #(open-preferences selected-networks)
on-legacy-press #(reset! wallet-type :legacy)
@@ -61,11 +58,11 @@
(fn []
(let [{:keys [address color emoji watch-only?]
:as account} (rf/sub [:wallet/current-viewing-account])
preferred-networks (rf/sub [:wallet/preferred-chain-names-for-address address])
share-title (str (:name account) " " (i18n/label :t/address))
qr-url (utils/get-wallet-qr {:wallet-type @wallet-type
:selected-networks
@selected-networks
:address address})
qr-url (utils/get-wallet-qr {:wallet-type @wallet-type
:selected-networks @selected-networks
:address address})
qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
{:url qr-url
:port (rf/sub [:mediaserver/port])
@@ -76,6 +73,9 @@
:share (i18n/label :t/share-address)
:receive (i18n/label :t/receive)
nil)]
(rn/use-mount #(reset! selected-networks preferred-networks))
[quo/overlay {:type :shell}
[rn/view
{:flex 1
@@ -11,6 +11,22 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- on-collectible-press
[{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))
(defn- on-collectible-long-press
[{:keys [preview-url collectible-details]}]
(rf/dispatch [:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:name (:name collectible-details)
:image (:uri preview-url)}])}]))
(defn- on-end-reached
[]
(rf/dispatch [:wallet/request-collectibles-for-current-viewing-account]))
(defn view
[{:keys [selected-tab]}]
(let [collectible-list (rf/sub
@@ -20,19 +36,11 @@
(case selected-tab
:assets [assets/view]
:collectibles [collectibles/view
{:collectibles collectible-list
:current-account-address current-account-address
:on-end-reached #(rf/dispatch
[:wallet/request-collectibles-for-current-viewing-account])
:on-collectible-press (fn [{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))
:on-collectible-long-press (fn [{:keys [preview-url collectible-details]}]
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:name (:name collectible-details)
:image (:uri preview-url)}])}]))}]
{:collectibles collectible-list
:current-account-address current-account-address
:on-end-reached on-end-reached
:on-collectible-press on-collectible-press
:on-collectible-long-press on-collectible-long-press}]
:activity [activity/view]
:permissions [empty-tab/view
{:title (i18n/label :t/no-permissions)
@@ -28,6 +28,7 @@
(let [{:keys [name color formatted-balance
watch-only?]} (rf/sub [:wallet/current-viewing-account])
customization-color (rf/sub [:profile/customization-color])]
(rn/use-unmount #(rf/dispatch [:wallet/close-account-page]))
[rn/view {:style {:flex 1}}
[account-switcher/view
{:type :wallet-networks
@@ -38,8 +38,7 @@
:disabled? (string/blank? @account-name)
:accessibility-label :confirm-button-label
:on-press #(rf/dispatch [:wallet/add-account
{:sha3-pwd nil
:type :watch
{:type :watch
:account-name @account-name
:emoji @account-emoji
:color @account-color}
@@ -1,6 +1,10 @@
(ns status-im.contexts.wallet.add-account.create-account.events
(:require [camel-snake-kebab.extras :as cske]
[clojure.string :as string]
[status-im.constants :as constants]
[status-im.contexts.wallet.add-account.create-account.utils :as create-account.utils]
[status-im.contexts.wallet.data-store :as data-store]
[taoensso.timbre :as log]
[utils.re-frame :as rf]
[utils.security.core :as security]
[utils.transforms :as transforms]))
@@ -22,14 +26,18 @@
(rf/reg-event-fx :wallet/confirm-account-origin confirm-account-origin)
(defn store-seed-phrase
(defn store-new-seed-phrase
[{:keys [db]} [{:keys [seed-phrase random-phrase]}]]
{:db (-> db
(assoc-in [:wallet :ui :create-account :seed-phrase] seed-phrase)
(assoc-in [:wallet :ui :create-account :random-phrase] random-phrase))
:fx [[:dispatch-later [{:ms 20 :dispatch [:navigate-to :screen/wallet.confirm-backup]}]]]})
{:db (update-in db
[:wallet :ui :create-account :new-keypair]
assoc
:seed-phrase seed-phrase
:random-phrase random-phrase)
:fx [[:dispatch-later
[{:ms 20
:dispatch [:navigate-to :screen/wallet.confirm-backup]}]]]})
(rf/reg-event-fx :wallet/store-seed-phrase store-seed-phrase)
(rf/reg-event-fx :wallet/store-new-seed-phrase store-new-seed-phrase)
(defn seed-phrase-validated
[{:keys [db]} [seed-phrase]]
@@ -43,33 +51,45 @@
{:fx [[:multiaccount/validate-mnemonic
[seed-phrase
(fn [mnemonic key-uid]
(rf/dispatch [:wallet/seed-phrase-validated
mnemonic key-uid]))
(rf/dispatch [:wallet/seed-phrase-validated mnemonic key-uid]))
on-error]]]})
(rf/reg-event-fx :wallet/seed-phrase-entered seed-phrase-entered)
(defn new-keypair-created
[{:keys [db]} [{:keys [new-keypair]}]]
{:db (assoc-in db [:wallet :ui :create-account :new-keypair] new-keypair)
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]})
(defn store-account-generated
[{:keys [db]} [{:keys [new-account-data keypair-name]}]]
(let [new-account (update new-account-data :mnemonic security/mask-data)]
{:db (-> db
(update-in [:wallet :ui :create-account :new-keypair]
assoc
:new-account-data new-account
:keypair-name keypair-name)
(update-in [:wallet :ui :create-account :new-keypair]
dissoc
:seed-phrase
:random-phrase))
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]}))
(rf/reg-event-fx :wallet/new-keypair-created new-keypair-created)
(rf/reg-event-fx :wallet/store-account-generated store-account-generated)
(defn new-keypair-continue
(defn generate-account-for-keypair
[{:keys [db]} [{:keys [keypair-name]}]]
(let [seed-phrase (get-in db [:wallet :ui :create-account :seed-phrase])]
(let [seed-phrase (-> db :wallet :ui :create-account :new-keypair :seed-phrase)]
{:fx [[:effects.wallet/create-account-from-mnemonic
{:seed-phrase (security/safe-unmask-data seed-phrase)
:keypair-name keypair-name}]]}))
{:mnemonic-phrase (security/safe-unmask-data seed-phrase)
:paths [constants/path-default-wallet]
:on-success (fn [new-account-data]
(rf/dispatch [:wallet/store-account-generated
{:new-account-data new-account-data
:keypair-name keypair-name}]))}]]}))
(rf/reg-event-fx :wallet/new-keypair-continue new-keypair-continue)
(rf/reg-event-fx :wallet/generate-account-for-keypair generate-account-for-keypair)
(defn clear-new-keypair
(defn clear-create-account-data
[{:keys [db]}]
{:db (update-in db [:wallet :ui :create-account] dissoc :new-keypair)})
(rf/reg-event-fx :wallet/clear-new-keypair clear-new-keypair)
(rf/reg-event-fx :wallet/clear-create-account clear-create-account-data)
(defn get-derived-addresses
[{:keys [db]} [{:keys [password derived-from paths]}]]
@@ -80,6 +100,21 @@
(rf/reg-event-fx :wallet/get-derived-addresses get-derived-addresses)
(rf/reg-event-fx
:wallet/next-derivation-path
(fn [_ [{:keys [on-success keypair-uid]}]]
{:fx [[:json-rpc/call
[{:method "accounts_resolveSuggestedPathForKeypair"
:params [keypair-uid]
:on-success on-success
:on-error (fn [error]
(log/error
"Failed to resolve next path derivation path"
{:event :wallet/next-derivation-path
:method "accounts_resolveSuggestedPathForKeypair"
:error error
:params keypair-uid}))}]]]}))
(defn get-derived-addresses-success
[{:keys [db]} [response]]
(let [derived-address (first response)]
@@ -105,3 +140,53 @@
:wallet/clear-private-key-data
(fn [{:keys [db]} _]
{:db (update-in db [:wallet :ui :create-account] dissoc :private-key :public-address)}))
(rf/reg-event-fx
:wallet/create-keypair-with-account
(fn [{db :db} [password account-preferences]]
(let [{:keys [keypair-name
new-account-data]} (-> db :wallet :ui :create-account :new-keypair)
keypair-with-account (create-account.utils/prepare-new-account
{:keypair-name keypair-name
:account-data new-account-data
:account-preferences account-preferences})
new-address (some-> new-account-data
(create-account.utils/first-derived-account)
(:address)
(string/lower-case))
unmasked-password (security/safe-unmask-data password)]
{:fx [[:json-rpc/call
[{:method "accounts_addKeypair"
:params [unmasked-password keypair-with-account]
:on-success [:wallet/add-account-success new-address]
:on-error #(log/error "Failed to add Keypair and create account" %)}]]]})))
(defn import-and-create-keypair-with-account
[{db :db} [{:keys [password account-preferences]}]]
(let [account-data (-> db :wallet :ui :create-account :new-keypair :new-account-data)
unmasked-mnemonic (security/safe-unmask-data (:mnemonic account-data))
unmasked-password (security/safe-unmask-data password)]
{:fx [[:json-rpc/call
[{:method "accounts_importMnemonic"
:params [unmasked-mnemonic unmasked-password]
:on-success #(rf/dispatch
[:wallet/create-keypair-with-account password account-preferences])}]]]}))
(rf/reg-event-fx :wallet/import-and-create-keypair-with-account import-and-create-keypair-with-account)
(rf/reg-event-fx
:wallet/derive-address-and-add-account
(fn [_ [{:keys [password derived-from-address derivation-path account-preferences]}]]
{:fx [[:json-rpc/call
[{:method "wallet_getDerivedAddresses"
:params [(security/safe-unmask-data password)
derived-from-address
[derivation-path]]
:on-success (fn [[derived-account]]
(rf/dispatch [:wallet/add-account
(assoc account-preferences :password password)
derived-account]))
:on-error #(log/info "Failed to get derived addresses"
derived-from-address
%)}]]]}))
@@ -1,8 +1,10 @@
(ns status-im.contexts.wallet.add-account.create-account.events-test
(:require
[cljs.test :refer-macros [deftest is]]
matcher-combinators.test
[status-im.contexts.wallet.add-account.create-account.events :as events]))
[matcher-combinators.test]
[status-im.constants :as constants]
[status-im.contexts.wallet.add-account.create-account.events :as events]
[utils.security.core :as security]))
(deftest confirm-account-origin
(let [db {:wallet {:ui {:create-account {}}}}
@@ -15,32 +17,60 @@
(deftest store-seed-phrase
(let [db {}
props [{:seed-phrase "test-secret" :random-phrase "random-test"}]
expected-db {:wallet {:ui {:create-account {:seed-phrase "test-secret"
:random-phrase "random-test"}}}}
effects (events/store-seed-phrase {:db db} props)
expected-db {:wallet {:ui {:create-account {:new-keypair {:seed-phrase "test-secret"
:random-phrase "random-test"}}}}}
effects (events/store-new-seed-phrase {:db db} props)
result-db (:db effects)]
(is (match? result-db expected-db))))
(deftest new-keypair-created
(let [db {}
props [{:new-keypair "test-keypair"}]
expected-db {:wallet {:ui {:create-account {:new-keypair "test-keypair"}}}}
effects (events/new-keypair-created {:db db} props)
result-db (:db effects)]
(is (match? result-db expected-db))))
(deftest store-account-generated
(let [db {:wallet {:ui {:create-account
{:new-keypair {:seed-phrase "test-secret"
:random-phrase "random-test"}}}}}
mnemonic "my mnemonic"
masked-mnemonic (security/mask-data mnemonic)
props [{:new-account-data {"test" "data"
:mnemonic mnemonic}
:keypair-name "new-keypair-name"}]
expected-db {:wallet {:ui {:create-account
{:new-keypair
{:new-account-data {"test" "data"
:mnemonic masked-mnemonic}
:keypair-name "new-keypair-name"}}}}}
effects (events/store-account-generated {:db db} props)
result-db (:db effects)
remove-mnemonic #(update-in %
[:wallet :ui :create-account :new-keypair :new-account-data]
dissoc
:mnemonic)
unmask-mnemonic #(-> %
:wallet
:ui
:create-account
:new-keypair
:new-account-data
:mnemonic
security/safe-unmask-data)]
(is (= (remove-mnemonic result-db) (remove-mnemonic expected-db)))
(is (= (unmask-mnemonic result-db) (unmask-mnemonic expected-db)))))
(deftest new-keypair-continue
(let [db {:wallet {:ui {:create-account {:seed-phrase "test-secret"}}}}
(deftest generate-account-for-keypair
(let [db {:wallet {:ui {:create-account {:new-keypair {:seed-phrase "test-secret"}}}}}
props [{:keypair-name "test-keypair"}]
expected-effects [[:effects.wallet/create-account-from-mnemonic
{:seed-phrase "test-secret" :keypair-name "test-keypair"}]]
effects (events/new-keypair-continue {:db db} props)]
(is (match? effects {:fx expected-effects}))))
{:mnemonic-phrase "test-secret"
:paths [constants/path-default-wallet]}]]
effects (events/generate-account-for-keypair {:db db} props)]
(is (match?
(update-in effects [:fx 0 1] dissoc :on-success)
{:fx expected-effects}))
(is (some? (get-in effects [:fx 0 1 :on-success])))))
(deftest clear-new-keypair
(deftest clear-create-account-data
(let [db {:wallet {:ui {:create-account {:new-keypair "test-keypair"}}}}
expected-db {:wallet {:ui {:create-account {}}}}
effects (events/clear-new-keypair {:db db})]
effects (events/clear-create-account-data {:db db})]
(is (match? (:db effects) expected-db))))
(deftest get-derived-addresses-test
@@ -52,8 +52,8 @@
:import-private-key
(not-implemented/alert)
:new-key-pair
(rf/dispatch [:wallet/new-keypair-continue
:new-keypair
(rf/dispatch [:wallet/generate-account-for-keypair
{:keypair-name key-pair-name}])
(js/alert "Unknown workflow")))
[workflow key-pair-name])
@@ -108,7 +108,7 @@
:button-one-label (i18n/label :t/i-have-written)
:button-one-props {:disabled? (some false? (vals @checked?))
:customization-color customization-color
:on-press #(rf/dispatch [:wallet/store-seed-phrase
:on-press #(rf/dispatch [:wallet/store-new-seed-phrase
{:seed-phrase (security/mask-data
@seed-phrase)
:random-phrase @random-phrase}])}}]
@@ -65,7 +65,7 @@
quiz-index (reagent/atom 0)
incorrect-count (reagent/atom 0)
show-error? (reagent/atom false)
{:keys [seed-phrase random-phrase]} (rf/sub [:wallet/create-account])
{:keys [seed-phrase random-phrase]} (rf/sub [:wallet/create-account-new-keypair])
unmasked-seed-phrase (security/safe-unmask-data seed-phrase)]
(fn []
(let [current-word-index (get random-indices
@@ -82,7 +82,7 @@
(when (= @quiz-index questions-count)
(rf/dispatch [:navigate-to
:screen/wallet.keypair-name
{:workflow :new-key-pair}])))
{:workflow :new-keypair}])))
(do
(when (> @incorrect-count 0)
(rf/dispatch [:show-bottom-sheet
@@ -23,11 +23,11 @@
:add-divider? true
:on-press #(rf/dispatch [:navigate-to :screen/wallet.enter-seed-phrase
{:recovering-keypair? true}])}
{:icon :i/key
:accessibility-label :import-private-key
:label (i18n/label :t/import-private-key)
:on-press (when (ff/enabled? ::wallet.import-private-key)
#(rf/dispatch [:navigate-to :screen/wallet.import-private-key]))}]]])
(when (ff/enabled? ::wallet.import-private-key)
{:icon :i/key
:accessibility-label :import-private-key
:label (i18n/label :t/import-private-key)
:on-press #(rf/dispatch [:navigate-to :screen/wallet.import-private-key])})]]])
(defn- parse-accounts
[given-accounts]
@@ -1,19 +1,29 @@
(ns status-im.contexts.wallet.add-account.create-account.utils)
(ns status-im.contexts.wallet.add-account.create-account.utils
(:require [status-im.constants :as constants]))
(defn prepare-new-keypair
[{:keys [new-keypair address account-name account-color emoji derivation-path]}]
(assoc new-keypair
:name (:keypair-name new-keypair)
:key-uid (:keyUid new-keypair)
:type :seed
:derived-from address
:accounts [{:keypair-name (:keypair-name new-keypair)
:key-uid (:keyUid new-keypair)
:seed-phrase (:mnemonic new-keypair)
:public-key (:publicKey new-keypair)
:name account-name
:type :seed
:emoji emoji
:colorID account-color
:path derivation-path
:address (:address new-keypair)}]))
(defn first-derived-account
[account-data]
(-> account-data :derived first val))
(defn prepare-new-account
[{keypair-name :keypair-name
{:keys [keyUid address] :as account} :account-data
{:keys [account-name color emoji]} :account-preferences}]
(let [account-to-create (first-derived-account account)
account-config {:address (:address account-to-create)
:key-uid keyUid
:wallet false
:chat false
:type :seed
:path constants/path-default-wallet
:public-key (:publicKey account-to-create)
:name account-name
:emoji emoji
:colorID color
:hidden false}]
{:key-uid keyUid
:name keypair-name
:type :seed
:derived-from address
:last-used-derivation-index 0
:accounts [account-config]}))
@@ -12,14 +12,11 @@
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.constants :as constants]
[status-im.contexts.wallet.add-account.create-account.style :as style]
[status-im.contexts.wallet.add-account.create-account.utils :as create-account.utils]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.sheets.account-origin.view :as account-origin]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.responsiveness :as responsiveness]
[utils.security.core :as security]
[utils.string]))
(defn- get-keypair-data
@@ -57,107 +54,47 @@
:description :text
:description-props {:text formatted-path}}]))
(defn view
(defn- avatar
[{:keys [account-color emoji on-select-emoji]}]
[rn/view {:style style/account-avatar-container}
[quo/account-avatar
{:customization-color account-color
:size 80
:emoji emoji
:type :default}]
[quo/button
{:size 32
:type :grey
:background :photo
:icon-only? true
:on-press #(rf/dispatch [:emoji-picker/open {:on-select on-select-emoji}])
:container-style style/reaction-button-container}
:i/reaction]])
(defn- input
[_]
(let [top (safe-area/get-top)
bottom (safe-area/get-bottom)
{window-width :width} (rn/get-window)
account-color (reagent/atom (rand-nth colors/account-colors))
emoji (reagent/atom (emoji-picker.utils/random-emoji))
account-name (reagent/atom "")
on-change-text #(reset! account-name %)
show-account-origin #(rf/dispatch [:show-bottom-sheet
{:content account-origin/view}])]
(fn []
(let [theme (quo.theme/use-theme)
number-of-accounts (count (rf/sub
[:wallet/accounts-without-watched-accounts]))
{:keys [address customization-color]} (rf/sub [:profile/profile])
{:keys [new-keypair]} (rf/sub [:wallet/create-account])
keypairs (rf/sub [:wallet/keypairs])
selected-keypair-uid (rf/sub [:wallet/selected-keypair-uid])
placeholder (i18n/label :t/default-account-placeholder)
derivation-path (utils/get-derivation-path
number-of-accounts)
keypair (some #(when (= (:key-uid %) selected-keypair-uid)
%)
keypairs)
primary-keypair? (= selected-keypair-uid (:key-uid (first keypairs)))
create-new-keypair-account #(rf/dispatch
[:wallet/add-keypair-and-create-account
{:sha3-pwd (security/safe-unmask-data %)
:new-keypair
(create-account.utils/prepare-new-keypair
{:new-keypair new-keypair
:address address
:account-name @account-name
:account-color @account-color
:emoji @emoji
:derivation-path
derivation-path})}])
create-existing-keypair-account #(rf/dispatch [:wallet/derive-address-and-add-account
{:sha3-pwd (security/safe-unmask-data %)
:emoji @emoji
:color @account-color
:path derivation-path
:account-name @account-name}])
keypair-title (or (:keypair-name new-keypair)
(if primary-keypair?
(i18n/label :t/keypair-title
{:name (:name keypair)})
(:name keypair)))]
(rn/use-unmount #(rf/dispatch [:wallet/clear-new-keypair]))
[floating-button-page/view
{:gradient-cover? true
:footer-container-padding 0
:header-container-style {:padding-top top}
:customization-color @account-color
:header [quo/page-nav
{:type :no-title
:background :blur
:right-side [{:icon-name :i/info
:on-press show-account-origin}]
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]
:footer [standard-auth/slide-button
{:size :size-48
:track-text (i18n/label :t/slide-to-create-account)
:customization-color @account-color
:on-auth-success (fn [password]
(if new-keypair
(create-new-keypair-account password)
(create-existing-keypair-account
password)))
:auth-button-label (i18n/label :t/confirm)
:disabled? (empty? @account-name)
:container-style (style/slide-button-container bottom)
:dependencies [new-keypair]}]}
[rn/view {:style style/account-avatar-container}
[quo/account-avatar
{:customization-color @account-color
:size 80
:emoji @emoji
:type :default}]
[quo/button
{:size 32
:type :grey
:background :photo
:icon-only? true
:on-press #(rf/dispatch [:emoji-picker/open
{:on-select (fn [selected-emoji]
(reset! emoji selected-emoji))}])
:container-style style/reaction-button-container}
:i/reaction]]
[quo/title-input
{:customization-color @account-color
:placeholder placeholder
:on-change-text on-change-text
:max-length constants/wallet-account-name-max-length
:blur? true
:disabled? false
:default-value @account-name
:container-style style/title-input-container}]
[quo/divider-line]
(let [placeholder (i18n/label :t/default-account-placeholder)]
(fn [{:keys [account-color account-name on-change-text]}]
[quo/title-input
{:customization-color account-color
:placeholder placeholder
:on-change-text on-change-text
:max-length constants/wallet-account-name-max-length
:blur? true
:disabled? false
:default-value account-name
:container-style style/title-input-container}])))
(defn- color-picker
[_]
(let [{window-width :width} (rn/get-window)
color-picker-style {:padding-vertical 12
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
window-width)}]
(fn [{:keys [account-color set-account-color]}]
[:<>
[quo/divider-line]
(let [theme (quo.theme/use-theme)]
[rn/view {:style style/color-picker-container}
[quo/text
{:size :paragraph-2
@@ -165,17 +102,168 @@
:style (style/color-label theme)}
(i18n/label :t/colour)]
[quo/color-picker
{:default-selected @account-color
:on-change #(reset! account-color %)
:container-style {:padding-vertical 12
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
window-width)}}]]
[quo/divider-line]
[quo/category
{:list-type :settings
:label (i18n/label :t/origin)
:data (get-keypair-data {:title keypair-title
:primary-keypair? primary-keypair?
:new-keypair? (boolean new-keypair)
:derivation-path derivation-path
:customization-color customization-color})}]]))))
{:default-selected account-color
:on-change set-account-color
:container-style color-picker-style}]])])))
(defn- new-account-origin
[{:keys [keypair-title derivation-path customization-color]}]
(let [{keypair-name :name} (rf/sub [:wallet/selected-keypair])
primary? (rf/sub [:wallet/selected-primary-keypair?])
keypair-name (or keypair-title
(if primary?
(i18n/label :t/keypair-title {:name keypair-name})
keypair-name))]
[:<>
[quo/divider-line]
[quo/category
{:list-type :settings
:label (i18n/label :t/origin)
:data (get-keypair-data {:primary-keypair? primary?
:title keypair-name
:derivation-path derivation-path
:customization-color customization-color})}]]))
(defn- floating-button
[_ & _]
(let [top (safe-area/get-top)
bottom (safe-area/get-bottom)
header [quo/page-nav
{:type :no-title
:background :blur
:right-side [{:icon-name :i/info
:on-press #(rf/dispatch [:show-bottom-sheet
{:content account-origin/view}])}]
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]]
(fn [{:keys [slide-button-props account-color]} & children]
(into
[floating-button-page/view
{:gradient-cover? true
:footer-container-padding 0
:header-container-style {:padding-top top}
:customization-color account-color
:header header
:footer [standard-auth/slide-button
(assoc slide-button-props
:size :size-48
:track-text (i18n/label :t/slide-to-create-account)
:customization-color account-color
:auth-button-label (i18n/label :t/confirm)
:container-style (style/slide-button-container bottom))]}]
children))))
(defn add-new-keypair-variant
[{:keys [on-change-text set-account-color set-emoji]
{:keys [account-name account-color emoji]}
:state}]
(let [on-auth-success (fn [password]
(rf/dispatch
[:wallet/import-and-create-keypair-with-account
{:password password
:account-preferences {:account-name @account-name
:color @account-color
:emoji @emoji}}]))]
(fn [{:keys [customization-color keypair-name]}]
(let [{:keys [new-account-data]} (rf/sub [:wallet/create-account-new-keypair])]
[floating-button
{:account-color @account-color
:slide-button-props {:on-auth-success on-auth-success
:disabled? (empty? @account-name)
:dependencies [new-account-data]}}
[avatar
{:account-color @account-color
:emoji @emoji
:on-select-emoji set-emoji}]
[input
{:account-color @account-color
:account-name @account-name
:on-change-text on-change-text}]
[color-picker
{:account-color @account-color
:set-account-color set-account-color}]
[new-account-origin
{:derivation-path constants/path-default-wallet
:customization-color customization-color
:keypair-title keypair-name}]]))))
(defn derive-account-variant
[{:keys [on-change-text set-account-color set-emoji]
{:keys [account-name account-color emoji]}
:state}]
(let [derivation-path (reagent/atom "")
set-derivation-path #(reset! derivation-path %)]
(fn [{:keys [customization-color]}]
(let [{:keys [derived-from
key-uid]} (rf/sub [:wallet/selected-keypair])
on-auth-success (rn/use-callback
(fn [password]
(let [preferences {:account-name @account-name
:color @account-color
:emoji @emoji}]
(rf/dispatch
[:wallet/derive-address-and-add-account
{:password password
:derived-from-address derived-from
:derivation-path @derivation-path
:account-preferences preferences}])))
[derived-from])]
(rn/use-effect
#(rf/dispatch
[:wallet/next-derivation-path
{:on-success set-derivation-path
:keypair-uid key-uid}])
[key-uid])
[floating-button
{:account-color @account-color
:slide-button-props {:on-auth-success on-auth-success
:disabled? (or (empty? @account-name)
(= "" @derivation-path))}}
[avatar
{:account-color @account-color
:emoji @emoji
:on-select-emoji set-emoji}]
[input
{:account-color @account-color
:account-name @account-name
:on-change-text on-change-text}]
[color-picker
{:account-color @account-color
:set-account-color set-account-color}]
[new-account-origin
{:derivation-path @derivation-path
:customization-color customization-color}]]))))
(defn view
[_]
(let [account-name (reagent/atom "")
account-color (reagent/atom (rand-nth colors/account-colors))
emoji (reagent/atom (emoji-picker.utils/random-emoji))
on-change-text #(reset! account-name %)
set-account-color #(reset! account-color %)
set-emoji #(reset! emoji %)
state {:account-name account-name
:account-color account-color
:emoji emoji}]
(fn []
(let [customization-color (rf/sub [:profile/customization-color])
;; Having a keypair means the user is importing it or creating it.
{:keys [keypair-name]} (rf/sub [:wallet/create-account-new-keypair])]
(rn/use-unmount #(rf/dispatch [:wallet/clear-create-account]))
(if keypair-name
[add-new-keypair-variant
{:customization-color customization-color
:on-change-text on-change-text
:set-account-color set-account-color
:set-emoji set-emoji
:state state
:keypair-name keypair-name}]
[derive-account-variant
{:customization-color customization-color
:on-change-text on-change-text
:set-account-color set-account-color
:set-emoji set-emoji
:state state}])))))
@@ -11,7 +11,7 @@
[rn/view {:style style/bridge-send-wrapper}
[input-amount/view
{:current-screen-id :screen/wallet.bridge-input-amount
:button-one-label (i18n/label :t/confirm-bridge)
:button-one-label (i18n/label :t/review-bridge)
:button-one-props {:icon-left :i/bridge}
:on-navigate-back (fn []
(rf/dispatch [:wallet/clean-disabled-from-networks])
@@ -1,7 +1,8 @@
(ns status-im.contexts.wallet.collectible.utils
(:require [status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.utils.networks :as network-utils]))
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[taoensso.timbre :as log]))
(defn collectible-balance
[collectible]
@@ -23,7 +24,7 @@
(if (supported-collectible-types collectible-type)
true
(do
(println "unsupoorted collectible file type" collectible-type)
(log/debug "unsupported collectible file type:" (or collectible-type "Unknown type"))
false)))
(defn total-owned-collectible
@@ -4,3 +4,7 @@
(def list-container-style
{:margin-horizontal 12
:padding-bottom constants/floating-shell-button-height})
(def collectible-container
{:padding 8
:flex 0.5})
@@ -9,10 +9,14 @@
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
[utils.i18n :as i18n]))
(defn- render-fn
[{:keys [preview-url collection-data ownership collectible-data] :as collectible} index address
on-press on-long-press]
(let [total-owned (utils/total-owned-collectible ownership address)]
(defn- collectible-item
[{:keys [preview-url collection-data collectible-data total-owned on-press on-long-press]
:as collectible}
index]
(let [on-press-fn (rn/use-callback #(when on-press
(on-press collectible)))
on-long-press-fn (rn/use-callback #(when on-long-press
(on-long-press collectible)))]
[quo/collectible-list-item
{:type :card
:image-src (:uri preview-url)
@@ -21,18 +25,15 @@
:supported-file? (utils/supported-file? (:animation-media-type collectible-data))
:gradient-color-index (keyword (str "gradient-" (inc (mod index 5))))
:counter (utils/collectible-owned-counter total-owned)
:container-style {:padding 8
:width "50%"}
:on-press #(when on-press
(on-press collectible))
:on-long-press #(when on-long-press
(on-long-press collectible))}]))
:container-style style/collectible-container
:on-press on-press-fn
:on-long-press on-long-press-fn}]))
(defn view
[{:keys [collectibles filtered? on-collectible-press on-end-reached current-account-address
on-collectible-long-press]}]
(let [no-results-match-query? (and filtered? (empty? collectibles))
theme (quo.theme/use-theme)]
[{:keys [collectibles filtered? on-end-reached
on-collectible-press current-account-address on-collectible-long-press]}]
(let [theme (quo.theme/use-theme)
no-results-match-query? (and filtered? (empty? collectibles))]
(cond
no-results-match-query?
[rn/view {:style {:flex 1 :justify-content :center}}
@@ -48,17 +49,25 @@
:image (resources/get-themed-image :no-collectibles theme)}]
:else
[rn/flat-list
{:data collectibles
:style {:flex 1}
:content-container-style style/list-container-style
:window-size 11
:num-columns 2
:render-fn (fn [item index]
(render-fn item
index
current-account-address
on-collectible-press
on-collectible-long-press))
:on-end-reached on-end-reached
:on-end-reached-threshold 4}])))
;; TODO: https://github.com/status-im/status-mobile/issues/20137
;; 1. If possible, move `collectibles-data` calculation to a subscription
;; 2. Optimization: do not recalculate all the collectibles, process only the new ones
(let [collectibles-data (map-indexed (fn [index {:keys [ownership] :as collectible}]
(assoc collectible
:total-owned (utils/total-owned-collectible
ownership
current-account-address)
:on-long-press on-collectible-long-press
:on-press on-collectible-press
:collectible-index index))
collectibles)]
[rn/flat-list
{:data collectibles-data
:style {:flex 1}
:content-container-style style/list-container-style
:window-size 11
:num-columns 2
:render-fn collectible-item
:on-end-reached on-end-reached
:key-fn :collectible-index
:on-end-reached-threshold 4}]))))
@@ -1,43 +0,0 @@
(ns status-im.contexts.wallet.common.temp
(:require
[react-native.core :as rn]
[status-im.common.resources :as status.resources]
[utils.i18n :as i18n]))
(def buy-tokens-list
[{:title "Ramp"
:description :text
:description-props {:text (i18n/label :t/ramp-description)}
:tag :context
:tag-props {:icon :i/fees
:context "0.49% - 2.9%"}
:action :arrow
:action-props {:alignment :flex-start
:icon :i/external}
:image :icon-avatar
:image-props {:icon (status.resources/get-service-image :ramp)}
:on-press #(rn/open-url "https://ramp.com")}
{:title "MoonPay"
:description :text
:description-props {:text (i18n/label :t/moonpay-description)}
:tag :context
:tag-props {:icon :i/fees
:context "1% - 4.5%"}
:action :arrow
:action-props {:alignment :flex-start
:icon :i/external}
:image :icon-avatar
:image-props {:icon (status.resources/get-service-image :moonpay)}
:on-press #(rn/open-url "https://moonpay.com")}
{:title "Latamex"
:description :text
:description-props {:text (i18n/label :t/latamex-description)}
:tag :context
:tag-props {:icon :i/fees
:context "1% - 1.7%"}
:action :arrow
:action-props {:alignment :flex-start
:icon :i/external}
:image :icon-avatar
:image-props {:icon (status.resources/get-service-image :latamex)}
:on-press #(rn/open-url "https://latamex.com")}])
@@ -42,6 +42,7 @@
(update :prod-preferred-chain-ids chain-ids-string->set)
(update :test-preferred-chain-ids chain-ids-string->set)
(update :type keyword)
(update :operable keyword)
(update :color #(if (seq %) (keyword %) constants/account-default-customization-color))
(update :emoji sanitize-emoji)
(assoc :default-account? (:wallet account))
+12 -9
View File
@@ -2,15 +2,18 @@
(:require
[clojure.string :as string]
[native-module.core :as native-module]
[re-frame.core :as rf]))
[re-frame.core :as rf]
[taoensso.timbre :as log]))
(rf/reg-fx
:effects.wallet/create-account-from-mnemonic
(fn [{:keys [seed-phrase keypair-name]}]
(native-module/create-account-from-mnemonic
{:MnemonicPhrase (if (string? seed-phrase)
seed-phrase
(string/join " " seed-phrase))}
(fn [new-keypair]
(rf/dispatch [:wallet/new-keypair-created
{:new-keypair (assoc new-keypair :keypair-name keypair-name)}])))))
(fn [{:keys [mnemonic-phrase paths on-success]
:or {paths []}}]
(let [phrase (condp #(%1 %2) mnemonic-phrase
string? mnemonic-phrase
coll? (string/join " " mnemonic-phrase)
(log/error "Unexpected value " mnemonic-phrase))]
(native-module/create-account-from-mnemonic
{:MnemonicPhrase phrase
:paths paths}
on-success))))
+35 -43
View File
@@ -16,17 +16,18 @@
[utils.i18n :as i18n]
[utils.number]
[utils.re-frame :as rf]
[utils.security.core :as security]
[utils.transforms :as transforms]))
(rf/reg-event-fx :wallet/show-account-created-toast
(fn [{:keys [db]} [address]]
(let [account (get-in db [:wallet :accounts address])]
(let [account-name (get-in db [:wallet :accounts address :name])]
{:db (update db :wallet dissoc :navigate-to-account :new-account?)
:fx [[:dispatch
[:toasts/upsert
{:id :new-wallet-account-created
:type :positive
:text (i18n/label :t/account-created {:name (:name account)})}]]]})))
:text (i18n/label :t/account-created {:name account-name})}]]]})))
(rf/reg-event-fx :wallet/navigate-to-account
(fn [{:keys [db]} [address]]
@@ -102,7 +103,8 @@
(rf/reg-event-fx
:wallet/remove-account-success
(fn [_ [toast-message _]]
{:fx [[:dispatch [:wallet/get-accounts]]
{:fx [[:dispatch [:wallet/clean-current-viewing-account]]
[:dispatch [:wallet/get-accounts]]
[:dispatch [:wallet/get-keypairs]]
[:dispatch-later
{:ms 100
@@ -172,30 +174,22 @@
[{:keys [db]}]
{:db (update-in db [:wallet :ui] dissoc :scanned-address)})
(rf/reg-event-fx :wallet/create-derived-addresses
(fn [{:keys [db]} [{:keys [sha3-pwd path]} on-success]]
(let [{:keys [address]} (:profile/profile db)]
{:fx [[:json-rpc/call
[{:method "wallet_getDerivedAddresses"
:params [sha3-pwd address [path]]
:on-success on-success
:on-error #(log/info "failed to derive address " %)}]]]})))
(rf/reg-event-fx :wallet/add-account-success
(fn [{:keys [db]} [address]]
{:db (update db
:wallet assoc
:navigate-to-account address
:new-account? true)
{:db (-> db
(assoc-in [:wallet :navigate-to-account] address)
(assoc-in [:wallet :new-account?] true))
:fx [[:dispatch [:wallet/get-accounts]]
[:dispatch [:wallet/get-keypairs]]
[:dispatch [:wallet/clear-new-keypair]]]}))
[:dispatch [:wallet/clear-create-account]]]}))
(rf/reg-event-fx :wallet/add-account
(fn [{:keys [db]}
[{:keys [sha3-pwd emoji account-name color type] :or {type :generated}}
{:keys [public-key address path]}]]
(let [lowercase-address (if address (string/lower-case address) address)
[{:keys [password account-name emoji color type]
:or {type :generated}}
{:keys [public-key address path] :as _derived-account}]]
(let [lowercase-address (some-> address
(string/lower-case))
key-uid (get-in db [:wallet :ui :create-account :selected-keypair-uid])
account-config {:key-uid (when (= type :generated) key-uid)
:wallet false
@@ -209,30 +203,11 @@
:colorID color}]
{:fx [[:json-rpc/call
[{:method "accounts_addAccount"
:params [(when (= type :generated) sha3-pwd) account-config]
:params [(when (= type :generated)
(security/safe-unmask-data password))
account-config]
:on-success [:wallet/add-account-success lowercase-address]
:on-error #(log/info "failed to create account " %)}]]]})))
(rf/reg-event-fx
:wallet/derive-address-and-add-account
(fn [_ [account-details]]
(let [on-success (fn [derived-address-details]
(rf/dispatch [:wallet/add-account account-details
(first derived-address-details)]))]
{:fx [[:dispatch [:wallet/create-derived-addresses account-details on-success]]]})))
(defn add-keypair-and-create-account
[_ [{:keys [sha3-pwd new-keypair]}]]
(let [lowercase-address (if (:address new-keypair)
(string/lower-case (:address new-keypair))
(:address new-keypair))]
{:fx [[:json-rpc/call
[{:method "accounts_addKeypair"
:params [sha3-pwd new-keypair]
:on-success [:wallet/add-account-success lowercase-address]
:on-error #(log/info "failed to create keypair " %)}]]]}))
(rf/reg-event-fx :wallet/add-keypair-and-create-account add-keypair-and-create-account)
:on-error #(log/info "failed to create account " % account-config)}]]]})))
(defn get-keypairs
[_]
@@ -521,3 +496,20 @@
activities (cske/transform-keys transforms/->kebab-case-keyword activities)
sorted-activities (sort :timestamp activities)]
{:db (assoc-in db [:wallet :activities] sorted-activities)})))
(rf/reg-event-fx
:wallet/get-crypto-on-ramps-success
(fn [{:keys [db]} [data]]
{:db (assoc-in db
[:wallet :crypto-on-ramps]
(cske/transform-keys transforms/->kebab-case-keyword data))}))
(rf/reg-event-fx
:wallet/get-crypto-on-ramps
(fn [_]
{:fx [[:json-rpc/call
[{:method "wallet_getCryptoOnRamps"
:on-success [:wallet/get-crypto-on-ramps-success]
:on-error #(log/info "failed to fetch crypto on ramps"
{:error %
:event :wallet/get-crypto-on-ramps})}]]]}))
@@ -8,6 +8,22 @@
[status-im.contexts.wallet.home.tabs.style :as style]
[utils.re-frame :as rf]))
(defn- on-collectible-long-press
[{:keys [preview-url collectible-details id]}]
(let [chain-id (get-in id [:contract-id :chain-id])
address (get-in id [:contract-id :address])]
(rf/dispatch [:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:chain-id chain-id
:address address
:name (:name collectible-details)
:image (:uri preview-url)}])}])))
(defn- on-collectible-press
[{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))
(defn view
[{:keys [selected-tab]}]
(let [collectible-list (rf/sub [:wallet/all-collectibles-list-in-selected-networks])
@@ -18,20 +34,7 @@
:assets [assets/view]
:collectibles [collectibles/view
{:collectibles collectible-list
:on-collectible-long-press (fn [{:keys [preview-url collectible-details id]}]
(let [chain-id (get-in id [:contract-id :chain-id])
address (get-in id [:contract-id :address])]
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[options-drawer/view
{:chain-id chain-id
:address address
:name (:name
collectible-details)
:image (:uri
preview-url)}])}])))
:on-collectible-long-press on-collectible-long-press
:on-end-reached request-collectibles
:on-collectible-press (fn [{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))}]
:on-collectible-press on-collectible-press}]
[activity/view {:activities []}])]))
+30 -9
View File
@@ -64,7 +64,7 @@
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? false})
(send-utils/reset-network-amounts-to-zero
(send-utils/reset-loading-network-amounts-to-zero
sender-network-values))
receiver-network-values (if routes-available?
(send-utils/network-amounts
@@ -74,7 +74,7 @@
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? true})
(send-utils/reset-network-amounts-to-zero
(send-utils/reset-loading-network-amounts-to-zero
receiver-network-values))
network-links (when routes-available?
(send-utils/network-links chosen-route
@@ -93,9 +93,9 @@
(rf/reg-event-fx :wallet/suggested-routes-error
(fn [{:keys [db]} [error]]
(let [cleaned-sender-network-values (-> (get-in db [:wallet :ui :send :sender-network-values])
(send-utils/reset-network-amounts-to-zero))
(send-utils/reset-loading-network-amounts-to-zero))
cleaned-receiver-network-values (-> (get-in db [:wallet :ui :send :receiver-network-values])
(send-utils/reset-network-amounts-to-zero))]
(send-utils/reset-loading-network-amounts-to-zero))]
{:db (-> db
(update-in [:wallet :ui :send]
dissoc
@@ -299,9 +299,27 @@
(rf/reg-event-fx :wallet/disable-from-networks
(fn [{:keys [db]} [chain-ids]]
{:db (-> db
(assoc-in [:wallet :ui :send :disabled-from-chain-ids] chain-ids)
(assoc-in [:wallet :ui :send :loading-suggested-routes?] true))}))
{:db (assoc-in db [:wallet :ui :send :disabled-from-chain-ids] chain-ids)}))
(rf/reg-event-fx :wallet/reset-network-amounts-to-zero
(fn [{:keys [db]}]
(let [sender-network-values (get-in db [:wallet :ui :send :sender-network-values])
receiver-network-values (get-in db [:wallet :ui :send :receiver-network-values])
disabled-from-chain-ids (get-in db [:wallet :ui :send :disabled-from-chain-ids])
sender-network-values (send-utils/reset-network-amounts-to-zero
{:network-amounts sender-network-values
:disabled-chain-ids disabled-from-chain-ids})
receiver-network-values (send-utils/reset-network-amounts-to-zero
{:network-amounts receiver-network-values
:disabled-chain-ids []})]
{:db (-> db
(assoc-in [:wallet :ui :send :sender-network-values] sender-network-values)
(assoc-in [:wallet :ui :send :receiver-network-values] receiver-network-values)
(update-in [:wallet :ui :send]
dissoc
:network-links
(when (empty? sender-network-values) :sender-network-values)
(when (empty? receiver-network-values) :receiver-network-values)))})))
(rf/reg-event-fx :wallet/get-suggested-routes
(fn [{:keys [db now]} [{:keys [amount]}]]
@@ -585,13 +603,16 @@
(rf/reg-event-fx
:wallet/select-from-account
(fn [{db :db} [{:keys [address stack-id start-flow?]}]]
(fn [{db :db} [{:keys [address stack-id network-details start-flow?]}]]
(let [token-symbol (-> db :wallet :ui :send :token-symbol)
token (when token-symbol
;; When this flow has started in the wallet home page, we know the
;; token or collectible to send, but we don't know from which
;; account, so we extract the token data from the picked account.
(utils/get-token-from-account db token-symbol address))]
(let [token (utils/get-token-from-account db token-symbol address)]
(assoc token
:networks (network-utils/network-list token network-details)
:total-balance (utils/calculate-total-token-balance token))))]
{:db (if token-symbol
(-> db
(assoc-in [:wallet :ui :send :token] token)
@@ -10,10 +10,11 @@
[utils.re-frame :as rf]))
(defn- on-press
[address]
[address network-details]
(rf/dispatch [:wallet/select-from-account
{:address address
:stack-id :screen/wallet.select-from}]))
{:address address
:network-details network-details
:stack-id :screen/wallet.select-from}]))
(defn- on-close
[]
@@ -22,9 +23,10 @@
(defn- render-fn
[item]
[quo/account-item
{:on-press #(on-press (:address item))
:account-props item}])
(let [network-details (rf/sub [:wallet/network-details])]
[quo/account-item
{:on-press #(on-press (:address item) network-details)
:account-props item}]))
(defn view
[]

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