Compare commits

..
Author SHA1 Message Date
Icaro Motta e1a868fc0d Experiment with more solutions for using stable handlers
Re-frame docs/on-stable-dom-handlers.md offers a clever solution to cache any
function even if it needs to "close over" dynamic values.

In this commit there are two solutions, one that's independent of React, i.e. a
pure Clojure solution that should be used only with form-2 components and a
second one, that uses hooks and persists state using React refs.

Both solutions are capable of solving the problem of stable handlers. The
solution using a form-2 component is committed here as an implementation
reference since it was taken from re-frame docs. The hooks solution should be
battle tested in more components to make sure it's good enough.
2024-05-20 14:54:10 -03:00
Sean Hagstrom 4d3a564312 tidy: focus on the ergonomics of using use-bind-snapshot 2024-05-20 14:54:10 -03:00
Sean Hagstrom 757b8ebcac tweak: utilise use-layout-effect to safely update atom 2024-05-20 14:54:10 -03:00
Sean Hagstrom 5ff9097410 tidy: refactor from use-callback to use-memo 2024-05-20 14:54:10 -03:00
Sean Hagstrom 6fdb57a753 chore: add use-layout-effect 2024-05-20 14:54:10 -03:00
Sean Hagstrom 8d821c27cb tidy: remove extra debug labels 2024-05-20 14:54:10 -03:00
Sean Hagstrom 3be9bd0bbb wip: refactor to use custom memo implementation and display demo of different behaviors 2024-05-20 14:54:10 -03:00
Sean Hagstrom 541e51b37b tweak: test sharing a state-sub 2024-05-20 14:54:10 -03:00
Sean Hagstrom c3a62f080b tidy: remove unused button stuff 2024-05-20 14:54:10 -03:00
Sean Hagstrom 5346dfec0f tweak: update demo with a variety of helper functions 2024-05-20 14:54:10 -03:00
Sean Hagstrom 83e9f8f0fc tweak: use debug labels for buttons 2024-05-20 14:54:10 -03:00
Sean Hagstrom 691768b691 tweak: only debug buttons with string children 2024-05-20 14:54:10 -03:00
Sean Hagstrom 797578ae73 tidy: rename functions to be more descriptive 2024-05-20 14:54:09 -03:00
Sean Hagstrom 5f7081c30f fix: subscription leak during hot reload by using use-memo 2024-05-20 14:54:09 -03:00
Sean Hagstrom 8efbf7e43d tweak: log when button component renders 2024-05-20 14:54:09 -03:00
Sean Hagstrom 97019fffee tweak: refactor example to use reagent.ratom/track and reagent.ratom/track! functions with message state 2024-05-20 14:54:09 -03:00
Sean Hagstrom 143410871b wip: add small experiment for ui callback with state and memoization 2024-05-20 14:54:09 -03:00
Sean Hagstrom 85382bbc28 tweak: forward on-press events 2024-05-20 14:54:09 -03:00
Mohsen 389a730eff [#19946] feat: add key pair QR code view (#20073) 2024-05-20 19:35:51 +03:00
Siddarth Kumar 4cdbfb6cc6 enable proguard, modify rules & upgrade okhttp lib (#19975)
This commit enables proguard minification and adds exceptions in proguard rules for the following classes :
- org.bouncycastle
- im.status.ethereum.BuildConfig
- com.reactnativenavigation

This commit also upgrades okhttp gradle dependency to 4.11.0

This should shave off a few MBs in the android bundle.
2024-05-20 21:09:03 +05:30
Siddarth Kumar 8fe59a0998 bump RNN to 7.39.0 and remove patches (#20109)
`react-native-navigation` library fixed android build errors for react-native `0.73` in this release :
https://github.com/wix/react-native-navigation/releases/tag/7.39.0

upgrading to this version helps us remove the patches.
2024-05-20 20:21:49 +05:30
Brian Sztamfater d4e7e4cd52 fix: no routes are found in case of valid amount in fiat is entered (#20000)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-05-20 10:08:31 -03:00
Ajay Sivan 3de86b09bd Page nav component alignment fix (#20108) 2024-05-20 05:35:31 -07:00
Brian Sztamfater dc551031fe fix: routes ui for bridging (#19959)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-05-20 08:07:35 -03:00
Omar Basem 29b02a544c fix: multiple address input fixes (#20005)
fix: multiple address input fixes (#20005)
2024-05-20 14:53:15 +04:00
BalogunofAfrica 3e4cbfeb69 feat: recalculate network max value (#19953) 2024-05-20 10:42:22 +01:00
Parvesh Monu 8038fc5ceb fix wrong avatar for community channels in topbar (#20093) 2024-05-20 14:25:37 +05:30
Omar Basem eb1db20161 chore: rename backup screen (#20077)
chore: rename backup screen (#20077)
2024-05-20 09:29:15 +04:00
BalogunofAfrica d558c565b0 feat: support sending multi collectibles (#20045) 2024-05-17 22:10:24 +01:00
Icaro Motta ea58e52dc1 Support hooks & atom state management in previews (#20053)
Change the implementation of component previews to support receiving either
state/set-state from use-state or a Reagent atom, thus allowing us to gradually
change preview namespaces to use hooks instead of having to refactor all at once
in a gigantic PR.

All types of preview fields were tested, including multi-select.

Only the components counter.step and selectors.react previews were adapted
to use-state.
2024-05-17 16:48:57 -03:00
Omar Basem 624593ec35 chore: rename opt to oeth (#19974)
chore: rename opt to oeth (#19974)
2024-05-17 22:23:51 +04:00
Omar Basem 9d302d8192 fix: select asset screen render function (#20086)
fix: select asset screen render function (#20086)
2024-05-17 21:59:13 +04:00
Parvesh Monu 47428368fd Allow user to manually input password when biometric fails (#19989) 2024-05-17 19:46:07 +05:30
Parvesh Monu 4c84dd4a1b Don't load chat view until chat is fetched (#19988) 2024-05-17 19:31:29 +05:30
yqrashawn cfe9d6e539 fix: action/reaction drawer UI issue (#19630) 2024-05-17 20:12:03 +08:00
andrey afd92d2df1 Revert " Hide browser behind feature flag (#20036)"
This reverts commit ba3d4dd4ce.
2024-05-17 12:08:53 +02:00
flexsurfer ba3d4dd4ce Hide browser behind feature flag (#20036) 2024-05-17 12:06:32 +02:00
96 changed files with 2018 additions and 1097 deletions
+6 -5
View File
@@ -59,7 +59,7 @@ react {
/**
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = false
def enableProguardInReleaseBuilds = true
/**
* The preferred build flavor of JavaScriptCore (JSC)
@@ -233,6 +233,7 @@ android {
}
release {
minifyEnabled enableProguardInReleaseBuilds
shrinkResources enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig null
}
@@ -240,10 +241,10 @@ android {
initWith release
applicationIdSuffix ".pr"
versionNameSuffix ".pr"
debuggable false
debuggable false
matchingFallbacks = ["release"]
// necessary to make react-native-config's code generation work
resValue "string", "build_config_package", "im.status.ethereum"
// necessary to make react-native-config's code generation work
resValue "string", "build_config_package", "im.status.ethereum"
}
}
@@ -293,7 +294,7 @@ dependencies {
implementation("com.github.status-im:function:0.0.1")
implementation("com.facebook.fresco:fresco:2.5.0")
implementation("com.facebook.fresco:animated-gif:2.5.0")
implementation("com.squareup.okhttp3:okhttp-tls:4.9.2")
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
implementation("com.google.prefab:cli:2.0.0")
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
}
+13 -1
View File
@@ -58,6 +58,9 @@
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
# to fix : java.security.KeyStoreException: BKS not found
-keep class org.bouncycastle.** { *; }
# okio
-keep class sun.misc.Unsafe { *; }
@@ -75,4 +78,13 @@
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
}
# react-native-config
# https://github.com/lugg/react-native-config?tab=readme-ov-file#problems-with-proguard
-keep class im.status.ethereum.BuildConfig {*;}
# react-native-navigation
# to fix : java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
# at com.reactnativenavigation.views.element.animators.PropertyAnimatorCreator.getChildClass(Unknown Source:13)
-keep class com.reactnativenavigation.** {*;}
+5 -5
View File
@@ -1119,14 +1119,14 @@ PODS:
- React
- ReactNativeCameraKit (14.0.0-beta13):
- React-Core
- ReactNativeNavigation (7.38.3):
- ReactNativeNavigation (7.39.0):
- HMSegmentedControl
- React-Core
- React-CoreModules
- React-RCTImage
- React-RCTText
- ReactNativeNavigation/Core (= 7.38.3)
- ReactNativeNavigation/Core (7.38.3):
- ReactNativeNavigation/Core (= 7.39.0)
- ReactNativeNavigation/Core (7.39.0):
- HMSegmentedControl
- React-Core
- React-CoreModules
@@ -1484,7 +1484,7 @@ SPEC CHECKSUMS:
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 530710e7949eb12c82670bd09e946becf50a3c2a
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
@@ -1551,7 +1551,7 @@ SPEC CHECKSUMS:
ReactCommon: 2947b0bffd82ea0e58ca7928881152d4c6dae9af
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
ReactNativeCameraKit: d95d3e19c514526a234d9f93c6db7e7f10eef9ea
ReactNativeNavigation: 46305e1026fa4cdcf0cfb3822932fc58d090668d
ReactNativeNavigation: 679d8c8bf3b8ae98d285bce810964d10da85dbdb
RNCAsyncStorage: c913ede1fa163a71cea118ed4670bbaaa4b511bb
RNCClipboard: 60fed4b71560d7bfe40e9d35dea9762b024da86d
RNCMaskedView: 71fc32d971f03b7f03d6ab6b86b730c4ee64f5b6
@@ -75,4 +75,17 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
}
@ReactMethod
fun getConnectionStringForExportingKeypairsKeystores(configJSON: String, callback: Callback) {
val jsonConfig = JSONObject(configJSON)
val senderConfig = jsonConfig.getJSONObject("senderConfig")
val keyUID = senderConfig.getString("loggedInKeyUid")
val keyStorePath = utils.getKeyStorePath(keyUID)
senderConfig.put("keystorePath", keyStorePath)
utils.executeRunnableStatusGoMethod(
{ Statusgo.getConnectionStringForExportingKeypairsKeystores(jsonConfig.toString()) },
callback)
}
}
@@ -106,4 +106,22 @@ RCT_EXPORT_METHOD(recover:(NSString *)message
callback(@[result]);
}
RCT_EXPORT_METHOD(getConnectionStringForExportingKeypairsKeystores:(NSString *)configJSON
callback:(RCTResponseSenderBlock)callback) {
NSData *configData = [configJSON dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSMutableDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:&error];
NSMutableDictionary *senderConfig = configDict[@"senderConfig"];
NSString *keyUID = senderConfig[@"loggedInKeyUid"];
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
NSString *keystoreDir = multiaccountKeystoreDir.path;
[senderConfig setValue:keystoreDir forKey:@"keystorePath"];
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
NSString *result = StatusgoGetConnectionStringForExportingKeypairsKeystores(modifiedConfigJSON);
callback(@[result]);
}
@end
+123 -51
View File
@@ -8454,20 +8454,16 @@
},
{
"path": "commons-logging/commons-logging/1.3.1",
"path": "commons-logging/commons-logging/1.3.2",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"commons-logging-1.3.1.pom": {
"sha1": "4bfde82c8e291f8e31227a91e0c5e428ee113e2d",
"sha256": "sha256-jeGLudCI4RAGLLIgVKx4DfW8A0njFzUbjtFuIH//s7g="
"commons-logging-1.3.2.pom": {
"sha1": "fcfa9f6e411771b8be9bee29e9d318867d3e1bc3",
"sha256": "sha256-ZMFGqsSRjMPiHhMij1/kF4VZM7GBN0zML4me8eFWsm0="
},
"commons-logging-1.3.1-api.jar": {
"sha1": "c8395db010f14b2643d838c66703ad7c9325ff3c",
"sha256": "sha256-F+1DKWd0Dhql/EJKJGrawLoAamu/2pjKvGkoNRqOuFQ="
},
"commons-logging-1.3.1.jar": {
"sha1": "8cff7dc1e492911f3dd7640ebfb60d6206a1dd40",
"sha256": "sha256-lUB7tDN7rWuPsuZHpH+VIZmxUg7ztreTF9H+D8eQuPw="
"commons-logging-1.3.2.jar": {
"sha1": "3dc966156ef19d23c839715165435e582fafa753",
"sha256": "sha256-a4WEJPUYAV8yv80Rg6Nz9Kgn1y0Ca2Ax2gyRzw6PNIk="
}
}
},
@@ -12764,20 +12760,20 @@
},
{
"path": "com/squareup/okhttp3/okhttp-tls/4.9.2",
"path": "com/squareup/okhttp3/okhttp-tls/4.11.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"okhttp-tls-4.9.2.pom": {
"sha1": "dec05ee1b4de176f92a12361b1cc82eb7b45857d",
"sha256": "sha256-pzMpEUHs6TYBsocbxdsl3laPLAqVohrGEBOkQdQbDBI="
"okhttp-tls-4.11.0.pom": {
"sha1": "93518ebb24213d6dcbde8e0c21913e40672f80c3",
"sha256": "sha256-0SYiMcXxtb/bVe/7+SXas1/dWlNFEvhsSd3HIGY/IEg="
},
"okhttp-tls-4.9.2.jar": {
"sha1": "2337dfb8b20de9cecd4ea36d54d15a3d85a3f385",
"sha256": "sha256-W8xRWQAJ2M/xShfi7i3cQ6J1HOQZmdhiQaNG8JwiB34="
"okhttp-tls-4.11.0.jar": {
"sha1": "5ac74e5e234dc2d5cd434ac87df377858a2dcf40",
"sha256": "sha256-SuTHCSwBeBhSRQabkSdGX9V8dkSF81ev7USlxIoFNf0="
},
"okhttp-tls-4.9.2.module": {
"sha1": "d5ab02f5e49911694f95a23a0a93dd3de27f8dd1",
"sha256": "sha256-s001IZvRHujsteSz3Qf0W+iym6Bep5z57dqRYcwlj9E="
"okhttp-tls-4.11.0.module": {
"sha1": "e790e6e5d0e88f9fc0c70df981e86daf29f411fa",
"sha256": "sha256-2m5O5qfdybnUZusr5ScBAmsXms2wClyso08uXTdeSMI="
}
}
},
@@ -12850,6 +12846,25 @@
}
},
{
"path": "com/squareup/okhttp3/okhttp/4.11.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"okhttp-4.11.0.pom": {
"sha1": "723ab52cf1ac14363cb36ab084b0af810c095bef",
"sha256": "sha256-ei1Cezixfgdtpk7o0hAuZIiNyyOK7l4tukp3UslKP94="
},
"okhttp-4.11.0.jar": {
"sha1": "436932d695b2c43f2c86b8111c596179cd133d56",
"sha256": "sha256-7o9r1s0SVwE9dIMw9MoUdjip+8tS+ziNWsk89TQIdF0="
},
"okhttp-4.11.0.module": {
"sha1": "db24464b688785ba9c5765df8b5508a9b8994b40",
"sha256": "sha256-VnwltR13eWF0Q5GE11JBK6l+2f22X8cYQNvFVjvrj6g="
}
}
},
{
"path": "com/squareup/okhttp3/parent/3.9.1",
"repo": "https://repo.maven.apache.org/maven2",
@@ -12872,6 +12887,25 @@
}
},
{
"path": "com/squareup/okio/okio-jvm/3.2.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"okio-jvm-3.2.0.pom": {
"sha1": "749720d97fe3dc16e0d84a05628f4c818b375a85",
"sha256": "sha256-XEUflKdr6oYbbvK/hOj1cgBUWWjIZVWr3+0Tx8otSJ0="
},
"okio-jvm-3.2.0.jar": {
"sha1": "332d1c5dc82b0241cb1d35bb0901d28470cc89ca",
"sha256": "sha256-tkK670xXAFXeTLPRZnsrFtztkB/4BmNFoGNpGqBgJaQ="
},
"okio-jvm-3.2.0.module": {
"sha1": "09f966bc7d27d5151fa3367e637e098cf7cf4179",
"sha256": "sha256-p3jzkIXtar/NaHESmGxjhapXrC2IQLIdlGs8IJXzDqQ="
}
}
},
{
"path": "com/squareup/okio/okio-jvm/3.9.0",
"repo": "https://repo.maven.apache.org/maven2",
@@ -12891,25 +12925,6 @@
}
},
{
"path": "com/squareup/okio/okio-metadata/2.8.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"okio-metadata-2.8.0.pom": {
"sha1": "dc508270653b48fd92c98866c5f1ed6e3e033cad",
"sha256": "sha256-v8xCxsWC2Zl4UgnmAs30RRoyZJrsbg7CaLdIhOA0QAg="
},
"okio-metadata-2.8.0.jar": {
"sha1": "2a068c26cd04cbd7214ae6a4146c5f5424bdb393",
"sha256": "sha256-99w4g86uLh/jQl4bVMXfKLiFfF/QA4G1If2mB5DylSw="
},
"okio-metadata-2.8.0.module": {
"sha1": "a5b10ac12aa5f879996e516be24aaeb9b4459873",
"sha256": "sha256-pO72Qb5eVGPSeJw8c2AfmpnzbhN3ygB+MPD+5ToFTNw="
}
}
},
{
"path": "com/squareup/okio/okio-parent/1.13.0",
"repo": "https://repo.maven.apache.org/maven2",
@@ -13026,6 +13041,29 @@
}
},
{
"path": "com/squareup/okio/okio/3.2.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"okio-3.2.0.pom": {
"sha1": "85284557b21661be1c4983910fef4e35532e1e34",
"sha256": "sha256-i0b1jZua6xF4Nh1YpoZfTa1mWTDF/3tV4LqmHvOpcqE="
},
"okio-3.2.0-all.jar": {
"sha1": "22e2a4f865203033fc0f35fd5892a213d21a4710",
"sha256": "sha256-Uf+6hylix9O+0SjfKbDeqz7qMfwjfAoMgVjcmQqEh44="
},
"okio-3.2.0.jar": {
"sha1": "afd4b7185a6976c2ac6bfb7b126c257ee9b3e765",
"sha256": "sha256-3KkyyyAptsniZ3D4fbCLFNSB/+gTGlnzaaI4XBG+Ti0="
},
"okio-3.2.0.module": {
"sha1": "32c2edb224d6eeaee24f8086e3ac41b92138fadb",
"sha256": "sha256-aB9c7BcN5FuVST6e5wWGjrNa34mO4G+W4i0ZclDBsQQ="
}
}
},
{
"path": "com/squareup/okio/okio/3.9.0",
"repo": "https://repo.maven.apache.org/maven2",
@@ -15897,17 +15935,6 @@
}
},
{
"path": "org/apache/commons/commons-parent/67",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"commons-parent-67.pom": {
"sha1": "761d110d7313f09bfc20ec1fb1f420da3314958e",
"sha256": "sha256-UHrZeCzW5L8io0Eyk2TG2vqqAqsmswy8Z4XPsFlQZ1Y="
}
}
},
{
"path": "org/apache/commons/commons-parent/69",
"repo": "https://repo.maven.apache.org/maven2",
@@ -20025,6 +20052,21 @@
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.10",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"kotlin-stdlib-jdk7-1.6.10.pom": {
"sha1": "5da7f12df7646d63f35e8a894157143c93efceb4",
"sha256": "sha256-YSIR/5MPW1LHJP92NBfVqigd1+AyXDs1yNGBIKao300="
},
"kotlin-stdlib-jdk7-1.6.10.jar": {
"sha1": "e1c380673654a089c4f0c9f83d0ddfdc1efdb498",
"sha256": "sha256-Ku3NxrabM731zCNbzqiOfPZgEUa7a83/2zErus174mE="
}
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.20",
"repo": "https://repo.maven.apache.org/maven2",
@@ -20235,6 +20277,36 @@
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.10",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"kotlin-stdlib-jdk8-1.6.10.pom": {
"sha1": "9ad76ce2a9e0473c5d5d4ec01add1b061beb521d",
"sha256": "sha256-Q6ZJ+nN7+zX6SvTm3jPi8IpdGRBNdYLqQNvNK2N5Csw="
},
"kotlin-stdlib-jdk8-1.6.10.jar": {
"sha1": "e80fe6ac3c3573a80305f5ec43f86b829e8ab53d",
"sha256": "sha256-FFbYLQOeow2EhbAykB9Su/B+fNvoux+HCK0yqFdMQc4="
}
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.20",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"kotlin-stdlib-jdk8-1.6.20.pom": {
"sha1": "6207ba2d7a89316eafea7f135ef1fc17e41c424b",
"sha256": "sha256-GEap+GBLC+HHGiEovb2diQJyAnlCf2ItK5pECsmjwwk="
},
"kotlin-stdlib-jdk8-1.6.20.jar": {
"sha1": "dab8089bca6ac0e394c37281ea8cff2f99acd421",
"sha256": "sha256-/asb8SDiteerbXiI6evAJOxrjKcpNhKWOV2rY0shNpU="
}
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0",
"repo": "https://repo.maven.apache.org/maven2",
+4 -3
View File
@@ -597,12 +597,13 @@ com.google.test.platform:core-proto:0.0.2-dev
com.ibm.icu:icu4j:53.1
com.intellij:annotations:12.0
com.parse.bolts:bolts-tasks:1.4.0
com.squareup.okhttp3:okhttp-tls:4.9.2
com.squareup.okhttp3:okhttp-tls:4.11.0
com.squareup.okhttp3:okhttp-urlconnection:4.9.2
com.squareup.okhttp3:okhttp:4.9.2
com.squareup.okio:okio-metadata:2.8.0
com.squareup.okio:okio:2.8.0
com.squareup.okhttp3:okhttp:4.11.0
com.squareup.okio:okio-jvm:3.2.0
com.squareup.okio:okio:2.9.0
com.squareup.okio:okio:3.2.0
com.squareup:javapoet:1.8.0
com.squareup:javapoet:1.10.0
com.squareup:javapoet:1.13.0
+8 -4
View File
@@ -528,7 +528,7 @@ https://repo.maven.apache.org/maven2/commons-io/commons-io/2.4/commons-io-2.4.po
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.1/commons-io-2.16.1.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.1/commons-logging-1.3.1.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.2/commons-logging-1.3.2.pom
https://repo.maven.apache.org/maven2/com/adobe/xmp/xmpcore/6.1.11/xmpcore-6.1.11.pom
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/commons/0.9.6.0/commons-0.9.6.0.pom
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/core/0.9.6.0/core-0.9.6.0.pom
@@ -806,15 +806,16 @@ https://repo.maven.apache.org/maven2/com/squareup/javapoet/1.8.0/javapoet-1.8.0.
https://repo.maven.apache.org/maven2/com/squareup/javapoet/1.10.0/javapoet-1.10.0.pom
https://repo.maven.apache.org/maven2/com/squareup/javapoet/1.13.0/javapoet-1.13.0.pom
https://repo.maven.apache.org/maven2/com/squareup/javawriter/2.5.0/javawriter-2.5.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp-tls/4.9.2/okhttp-tls-4.9.2.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp-tls/4.11.0/okhttp-tls-4.11.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp-urlconnection/4.9.2/okhttp-urlconnection-4.9.2.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.9.1/okhttp-3.9.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.9.2/okhttp-4.9.2.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.11.0/okhttp-4.11.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.2.0/okio-jvm-3.2.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.0/okio-jvm-3.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-metadata/2.8.0/okio-metadata-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.13.0/okio-parent-1.13.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.17.4/okio-parent-1.17.4.pom
@@ -823,6 +824,7 @@ https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.p
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.2.0/okio-3.2.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.1/all-1.2.1.pom
@@ -1032,7 +1034,6 @@ https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/39/common
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/42/commons-parent-42.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/48/commons-parent-48.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/52/commons-parent-52.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/67/commons-parent-67.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/69/commons-parent-69.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.2.6/httpclient-4.2.6.pom
@@ -1300,6 +1301,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.30/kotlin-stdlib-jdk7-1.5.30.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.31/kotlin-stdlib-jdk7-1.5.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.0/kotlin-stdlib-jdk7-1.6.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.10/kotlin-stdlib-jdk7-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.20/kotlin-stdlib-jdk7-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.20-RC2/kotlin-stdlib-jdk7-1.8.20-RC2.pom
@@ -1314,6 +1316,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.30/kotlin-stdlib-jdk8-1.5.30.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.31/kotlin-stdlib-jdk8-1.5.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.0/kotlin-stdlib-jdk8-1.6.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.10/kotlin-stdlib-jdk8-1.6.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.20/kotlin-stdlib-jdk8-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.20-RC2/kotlin-stdlib-jdk8-1.8.20-RC2.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.21/kotlin-stdlib-jdk8-1.8.21.pom
+1 -1
View File
@@ -55,7 +55,7 @@
"react-native-keychain": "8.1.2",
"react-native-linear-gradient": "^2.8.0",
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-navigation": "7.38.3",
"react-native-navigation": "7.39.0",
"react-native-orientation-locker": "^1.5.0",
"react-native-permissions": "4.1.5",
"react-native-reanimated": "3.6.1",
@@ -1,22 +0,0 @@
# https://github.com/wix/react-native-navigation/issues/7819
--- ./node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter.kt
+++ ./node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter-patched.kt
@@ -194,8 +194,8 @@
class WixAccessibilityDelegateCompat: AccessibilityDelegateCompat(){
override fun onInitializeAccessibilityNodeInfo(
- host: View?,
- info: AccessibilityNodeInfoCompat?
+ host: View,
+ info: AccessibilityNodeInfoCompat
) {
super.onInitializeAccessibilityNodeInfo(host, info)
@@ -216,4 +216,4 @@
}
-}
\ No newline at end of file
+}
-19
View File
@@ -1,19 +0,0 @@
# https://github.com/wix/react-native-navigation/issues/7819
--- ./node_modules/react-native-navigation/lib/android/app/build.gradle
+++ ./node_modules/react-native-navigation/lib/android/app/build-patched.gradle
@@ -62,11 +62,11 @@
}
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = JavaVersion.VERSION_1_8
+ jvmTarget = JavaVersion.VERSION_17
}
flavorDimensions "RNN.reactNativeVersion"
+8
View File
@@ -601,3 +601,11 @@
(.createAccountFromMnemonicAndDeriveAccountsForPaths ^js (account-manager)
(types/clj->json mnemonic)
#(callback (types/json->clj %))))
(defn get-connection-string-for-exporting-keypairs-keystores
"Generates connection string form status-go for the purpose of exporting keypairs and keystores on sender side"
[config-json callback]
(log/info "[native-module] Fetching Export Keypairs Connection String"
{:fn :get-connection-string-for-exporting-keypairs-keystores
:config-json config-json})
(.getConnectionStringForExportingKeypairsKeystores ^js (network) config-json callback))
@@ -35,6 +35,7 @@
size 40
customization-color (if (= type :primary) :blue nil)}}
children]
(when (string? children) (js/console.log "button - " children))
(let [[pressed-state? set-pressed-state] (rn/use-state false)
theme (quo.theme/use-theme)
{:keys [icon-color background-color label-color border-color blur-type
@@ -6,24 +6,26 @@
(h/describe "Drawers: drawer-action"
(h/test "default render"
(h/render-with-theme-provider [drawer-action/view {}])
(h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes internal state to :pressed"
(h/render-with-theme-provider [drawer-action/view {}])
(h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
(h/test "render default action with state :selected"
(h/render-with-theme-provider [drawer-action/view {:state :selected}])
(h/render-with-theme-provider [drawer-action/view
{:state :selected :accessibility-label :container}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "call on-press"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider [drawer-action/view {:on-press on-press}])
(h/render-with-theme-provider [drawer-action/view
{:on-press on-press :accessibility-label :container}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/was-called on-press)))
@@ -38,8 +40,9 @@
(h/test "render :toggle action with state :selected"
(h/render-with-theme-provider [drawer-action/view
{:action :toggle
:state :selected}])
{:accessibility-label :container
:action :toggle
:state :selected}])
(h/is-truthy (h/query-by-label-text "toggle-on"))
(h/has-style (h/query-by-label-text :container)
{:backgroundColor :transparent}))
@@ -51,4 +54,5 @@
:description "Just a small desc"}])
(h/is-truthy (h/query-by-label-text :left-icon))
(h/is-truthy (h/query-by-text "Check contact"))
(h/has-style (h/query-by-text "Check contact") {:color colors/neutral-100})
(h/is-truthy (h/query-by-text "Just a small desc"))))
@@ -4,6 +4,8 @@
[:=>
[:cat
[:map {:closed true}
[:accessibility-label {:optional true} [:maybe :keyword]]
[:type {:optional true} [:maybe [:enum :main :danger]]]
[:action {:optional true} [:maybe [:enum :arrow :toggle]]]
[:icon {:optional true} [:maybe :keyword]]
[:description {:optional true} [:maybe :string]]
@@ -28,6 +28,23 @@
{:flex 1
:margin-right 12})
(defn text
[{:keys [theme blur? type]}]
(let [base {:weight :medium}
theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]
color
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-100
colors/white
theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50
colors/danger-60
theme)
[:blur :danger] colors/danger-60)]
(assoc-in base [:style :color] color)))
(defn- neutral-color
[theme blur?]
(if blur?
@@ -41,8 +58,14 @@
:margin-top 1})
(defn icon-color
[{:keys [theme blur?]}]
(neutral-color theme blur?))
[{:keys [theme blur? type]}]
(let [theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]]
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50 colors/danger-60 theme)
[:blur :danger] colors/danger-60)))
(defn desc
[{:keys [theme blur?]}]
@@ -10,11 +10,13 @@
[schema.core :as schema]))
(defn view-internal
[{:keys [action icon description state title on-press
customization-color blur?]
:or {customization-color :blue
blur? false}}]
[{:keys [action icon description state title on-press customization-color
blur? accessibility-label]
action-type :type
:or {customization-color :blue
blur? false}}]
(let [theme (quo.theme/use-theme)
action-type (or action-type :main)
[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))]
@@ -29,16 +31,21 @@
:pressed? pressed?
:description? (not-empty description)
:blur? blur?})
:accessibility-label :container}
:accessibility-label accessibility-label}
(when icon
[icon/icon icon
{:accessibility-label :left-icon
:container-style (style/left-icon)
:color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}])
[rn/view {:style (style/text-container)}
[text/text {:weight :medium}
[rn/view
{:style (style/text-container)}
[text/text
(style/text {:theme theme
:type action-type
:blur? blur?})
title]
(when (seq description)
@@ -61,6 +68,7 @@
[icon/icon :i/chevron-right
{:accessibility-label :arrow-icon
:color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}]
(= state :selected)
@@ -133,8 +133,7 @@
:on-focus on-focus
:on-blur on-blur
:on-change-text on-change}]
(when (or (= status :default)
(= status :active))
(when (empty? value)
[rn/view
{:style style/buttons-container
:accessibility-label :paste-scan-buttons-container}
@@ -155,7 +154,9 @@
:inner-style (style/accessory-button blur? theme)
:on-press on-scan}
:main-icons/scan])])
(when (= status :typing)
(when (or (= status :typing)
(and (= status :active)
(not-empty value)))
[rn/view
{:style style/buttons-container
:accessibility-label :clear-button-container}
@@ -168,7 +169,10 @@
{:style style/buttons-container
:accessibility-label :loading-button-container}
[loading-icon blur? theme]])
(when (and (= status :loading) valid-ens-or-address?)
(when (and (or (= status :loading)
(= status :default))
valid-ens-or-address?
(not-empty value))
[rn/view
{:style style/buttons-container
:accessibility-label :positive-button-container}
+17 -42
View File
@@ -3,39 +3,14 @@
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(defn- primary-name-top-offset
[size]
(when (= size 15)
(cond platform/ios? 1
platform/android? -0.5
:else 0)))
(defn- primary-name-margin-bottom-offset
[size]
(when (and (= size 15)
(or platform/ios? platform/android?))
-0.25))
(defn- primary-name-layout-offsets
[size]
;; NOTE(seanstrom): We need to sometimes offset the primary-name to align the baseline of the text
;; while avoiding shifting elements downward.
{:top (primary-name-top-offset size)
:margin-bottom (primary-name-margin-bottom-offset size)})
(defn container
[size]
{:flex-shrink 1
:flex-wrap :nowrap
:flex-direction :row
:align-items :baseline
;; NOTE(seanstrom): Because we're offseting the primary-name we need to inverse the offset on the
;; container to avoid shifting elements downward
:top (* -1 (primary-name-top-offset size))})
(def details-container
{:flex-direction :row
:margin-left 8})
(cond->
{:flex-shrink 1
:flex-wrap :nowrap
:flex-direction :row
:align-items :center
:height (if (= size 15) 22 18)}))
(defn middle-dot
[theme]
@@ -48,11 +23,15 @@
(defn primary-name
[muted? theme size]
(merge (primary-name-layout-offsets size)
{:color (if muted?
colors/neutral-50
(colors/theme-colors colors/neutral-100 colors/white theme))
:flex-shrink 1}))
{:color (if muted?
colors/neutral-50
(colors/theme-colors colors/neutral-100 colors/white theme))
;; iOS: primary-name height is 22.3 / 18.7
;; Android: primary-name height is 21.8 / 18.5
:margin-vertical (if (= size 15)
(if platform/ios? -0.15 0)
(if platform/ios? -0.35 -0.25))
:flex-shrink 1})
(defn secondary-name
[theme]
@@ -60,13 +39,9 @@
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(defn icon-container
[is-first?]
[is-first? size]
{:margin-left (if is-first? 4 2)
;; NOTE(seanstrom): Because we're using flex baseline to align elements
;; we need to offset the icon container to match the designs.
:top (cond platform/ios? 1
platform/android? 2
:else 0)})
:padding-top (if (= size 15) 6 4)})
(defn time-text
[theme]
+40 -28
View File
@@ -13,7 +13,35 @@
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?
muted? size]
:or {size 13}}]
(let [theme (quo.theme/use-theme)]
(let [theme (quo.theme/use-theme)
short-chat-key-component
(when (and (not verified?) short-chat-key)
[text/text
{:weight :monospace
:size :label
:number-of-lines 1
:style (style/chat-key-text theme)}
short-chat-key])
time-str-component
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])
middle-dot-seperator-component
(when (and short-chat-key-component time-str-component)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])]
[rn/view
{:style (merge (style/container size) style)}
[text/text
@@ -23,7 +51,7 @@
:accessibility-label :author-primary-name
:style (style/primary-name muted? theme size)}
primary-name]
(when (not (string/blank? secondary-name))
(when-not (string/blank? secondary-name)
[:<>
[text/text
{:size :label
@@ -41,38 +69,22 @@
[icons/icon :main-icons2/contact
{:size 12
:no-color true
:container-style (style/icon-container true)}])
:container-style (style/icon-container true size)}])
(cond
verified?
[icons/icon :main-icons2/verified
{:size 12
:no-color true
:container-style (style/icon-container contact?)}]
:container-style (style/icon-container contact? size)}]
untrustworthy?
[icons/icon :main-icons2/untrustworthy
{:size 12
:no-color true
:container-style (style/icon-container contact?)}])
[rn/view {:style style/details-container}
(when (and (not verified?) short-chat-key)
[text/text
{:weight :monospace
:size :label
:number-of-lines 1
:style (style/chat-key-text theme)}
short-chat-key])
(when (and (not verified?) time-str short-chat-key)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])]]))
:container-style (style/icon-container contact? size)}])
(when (or short-chat-key-component time-str-component)
[rn/view {:style {:width 8}}])
short-chat-key-component
middle-dot-seperator-component
time-str-component]))
@@ -261,7 +261,10 @@
{:opacity center-opacity}
nil)
(style/center-content-container
(and (= type :title) (= text-align :center))))
(case type
:title (= text-align :center)
(:dropdown :wallet-networks) true
false)))
props-with-style (assoc props
:center-content-container-style
center-content-container-style)]
+3 -2
View File
@@ -5,7 +5,8 @@
[react-native.core :as rn]))
(defn view
[{:keys [reactions on-press on-long-press add-reaction? on-press-add use-case container-style]}]
[{:keys [reactions on-press on-long-press hide-new-reaction-button? on-press-add use-case
container-style]}]
[rn/view {:style (merge style/container container-style)}
(for [emoji-reaction reactions
:let [{:keys [emoji emoji-id emoji-reaction-id quantity own]} emoji-reaction]]
@@ -19,7 +20,7 @@
:on-press #(on-press emoji-reaction)
:on-long-press #(on-long-press emoji-reaction)
:accessibility-label (str "emoji-reaction-" emoji-id)}])
(when add-reaction?
(when-not hide-new-reaction-button?
[react-selector/view
{:on-press on-press-add
:state :add-reaction
@@ -1,12 +1,31 @@
(ns quo.components.selectors.reactions-selector.style
(:require
[quo.foundations.colors :as colors]))
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(defn container
[pressed? theme]
{:padding 10
:border-radius 12
:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))})
(merge
{:border-radius 12
:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))}
(if platform/ios?
{:padding 9.5
:padding-horizontal 8}
{:padding 8})))
(def emoji-text-style
(merge
{:line-height 20
:text-align :center}
(if platform/ios?
{:line-height 20
:font-size 17
:text-align :center}
{:font-size 18
:height 24
:width 24
:text-align :center
:text-align-vertical :center})))
@@ -20,4 +20,6 @@
:style (merge (style/container pressed? theme)
container-style)
:on-press on-press}
[rn/text (reactions.resource/system-emojis emoji)]]))
[rn/text
{:style style/emoji-text-style}
(reactions.resource/system-emojis emoji)]]))
@@ -6,7 +6,8 @@
[:props
[:map {:closed true}
[:status {:optional true} [:maybe [:enum :default :error]]]
[:on-change-text {:optional true} [:maybe fn?]]
[:on-inc-press {:optional true} [:maybe fn?]]
[:on-dec-press {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]]
[:min-value {:optional true} [:maybe :int]]
[:max-value {:optional true} [:maybe :int]]
@@ -13,7 +13,7 @@
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:action :none}])
(def default-details
@@ -48,7 +48,7 @@
(when show-optimism?
[network-amount
{:network :optimism
:amount (str (:amount optimism) " " (or (:token-symbol optimism) "OPT"))
:amount (str (:amount optimism) " " (or (:token-symbol optimism) "OETH"))
:divider? show-arbitrum?
:theme theme}])
(when show-arbitrum?
@@ -6,14 +6,16 @@
(h/describe "Wallet: Token Input"
(h/test "Token label renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
{:token :snt
:currency :eur
:currency-symbol "€"
:conversion 1}])
(h/is-truthy (h/get-by-text "SNT")))
(h/test "Amount renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
{:token :snt
:currency :eur
:currency-symbol "€"
:conversion 1}])
(h/is-truthy (h/get-by-text "€0.00"))))
@@ -12,30 +12,22 @@
{:padding-horizontal 20
:padding-bottom 4
:height 36
:flex-direction :row
:justify-content :space-between})
:flex-direction :row})
(defn token-name
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 8
:padding-bottom 2})
(def token-label-container
{:position :absolute
:left 40 ; token image size + margin
:right 0
:bottom 0
:top 0
:flex-direction :row
:align-items :flex-end})
:padding-bottom 3})
(def text-input-container
{:position :absolute
:top 0
:bottom 0
:left 40 ; token image size + margin
:right 0})
{:flex-direction :row
:align-items :flex-end})
(defn input-container
[window-width]
{:width (- window-width 120)
:margin-left 8
:margin-right 8})
(def text-input-dimensions
(-> typography/heading-1
@@ -54,7 +46,8 @@
:color
(if error?
(colors/resolve-color :danger theme)
(colors/theme-colors colors/neutral-100 colors/white theme))))
(colors/theme-colors colors/neutral-100 colors/white theme))
:flex-shrink 1))
(defn placeholder-text
[theme]
+51 -61
View File
@@ -9,32 +9,34 @@
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.schema :as component-schema]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.common :as common]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
[schema.core :as schema]
[utils.number :as number]))
(defn fiat-format
[currency num-value conversion]
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2)))
[currency-symbol num-value conversion]
(str currency-symbol (.toFixed (* num-value conversion) 2)))
(defn crypto-format
[num-value conversion crypto-decimals token]
(str (.toFixed (/ num-value conversion) (or crypto-decimals 2))
(str (number/remove-trailing-zeroes
(.toFixed (/ num-value conversion) (or crypto-decimals 2)))
" "
(string/upper-case (or (clj->js token) ""))))
(defn calc-value
[{:keys [crypto? currency token value conversion crypto-decimals]}]
[{:keys [crypto? currency-symbol token value conversion crypto-decimals]}]
(let [num-value (if (string? value)
(or (parse-double value) 0)
value)]
(if crypto?
(fiat-format currency num-value conversion)
(fiat-format currency-symbol num-value conversion)
(crypto-format num-value conversion crypto-decimals token))))
(defn- data-info
[{:keys [theme token crypto-decimals conversion networks title crypto? currency amount error?]}]
[{:keys [theme token crypto-decimals conversion networks title crypto? currency-symbol amount
error?]}]
[rn/view {:style style/data-container}
[network-tag/view
{:networks networks
@@ -45,7 +47,7 @@
:weight :medium
:style (style/fiat-amount theme)}
(calc-value {:crypto? crypto?
:currency currency
:currency-symbol currency-symbol
:token token
:value amount
:conversion conversion
@@ -59,20 +61,6 @@
:weight :semi-bold}
(string/upper-case (or (clj->js text) ""))])
(defn- token-label
[{:keys [theme value text]}]
[rn/view
{:style style/token-label-container
:pointer-events :none}
[rn/text-input
{:max-length 12
:style style/text-input-dimensions
:editable false
:placeholder "0"
:opacity 0
:value value}]
[token-name-text theme text]])
(defn input-section
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
on-token-press]}]
@@ -92,36 +80,45 @@
(oops/oget "nativeEvent.selection")
(js->clj :keywordize-keys true)
(on-selection-change))))]
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection]
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
handle-on-swap]
:or {show-keyboard? true}}]
(let [theme (quo.theme/use-theme)]
[rn/view {:style {:flex 1}}
[rn/pressable {:on-press on-token-press}
[token/view
{:token token
:size :size-32}]]
[rn/pressable
{:style style/text-input-container
:on-press focus-input}
[rn/text-input
(cond-> {:style (style/text-input theme error?)
:placeholder-text-color (style/placeholder-text theme)
:auto-focus true
:ref set-ref
:placeholder "0"
:keyboard-type :numeric
:max-length 12
:on-change-text handle-on-change-text
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?
:on-selection-change handle-selection-change
:selection (clj->js selection)}
controlled-input? (assoc :value value)
(not controlled-input?) (assoc :default-value value-internal))]]
[token-label
{:theme theme
:text (if crypto? token currency)
:value (if controlled-input? value value-internal)}]]))))
(let [theme (quo.theme/use-theme)
window-width (:width (rn/get-window))]
[rn/pressable
{:style {:width "100%"
:flex-direction :row}
:on-press on-token-press}
[token/view
{:token token
:size :size-32}]
[rn/view {:style (style/input-container window-width)}
[rn/pressable
{:style style/text-input-container
:on-press focus-input}
[rn/text-input
(cond-> {:style (style/text-input theme error?)
:placeholder-text-color (style/placeholder-text theme)
:auto-focus true
:ref set-ref
:placeholder "0"
:keyboard-type :numeric
:on-change-text handle-on-change-text
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?
:on-selection-change handle-selection-change
:selection (clj->js selection)}
controlled-input? (assoc :value value)
(not controlled-input?) (assoc :default-value value-internal))]
[token-name-text theme (if crypto? token currency)]]]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press handle-on-swap
:type :outline
:accessibility-label :reorder}
:i/reorder]]))))
(defn- view-internal
[{:keys [container-style value on-swap] :as props}]
@@ -141,15 +138,8 @@
:value-internal value-internal
:theme theme
:set-value-internal set-value-internal
:crypto? crypto?)]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press handle-on-swap
:type :outline
:accessibility-label :reorder}
:i/reorder]]
:handle-on-swap handle-on-swap
:crypto? crypto?)]]
[divider-line/view {:container-style (style/divider theme)}]
[data-info
(assoc props
+1 -1
View File
@@ -257,7 +257,7 @@
(def ^:private get-network-full-name
{:eth :ethereum
:opt :optimism
:oeth :optimism
:arb1 :arbitrum})
(def ^:private networks-short-name
-5
View File
@@ -1,5 +0,0 @@
(ns quo.foundations.common)
(def currency-label
{:eur "€"
:usd "$"})
+37
View File
@@ -181,6 +181,14 @@
#(let [ret (handler)] (if (fn? ret) ret js/undefined))
(get-js-deps deps))))
(defn use-layout-effect
([handler]
(use-layout-effect handler nil))
([handler deps]
(react/useLayoutEffect
#(let [ret (handler)] (if (fn? ret) ret js/undefined))
(get-js-deps deps))))
(defn use-mount
[handler]
(use-effect handler []))
@@ -195,6 +203,35 @@
([handler deps]
(react/useCallback handler (get-js-deps deps))))
(defn use-fn-factory-factory
"A dirty code translation from the form-2 solution `make-fn-factory`."
[f]
(let [*args1 (use-ref-atom nil)
cached (use-ref-atom
(fn [& args2]
(apply f (concat @*args1 args2))))
factory (use-ref-atom
(fn factory
[& args1]
(reset! *args1 args1)
@cached))]
@factory))
(defn use-fn-factory
[f & args]
(let [factory (use-fn-factory-factory f)]
(apply factory args)))
(defn make-fn-factory
"Should be used in a form-2 component."
[f]
(let [*args1 (atom nil)
cached (fn [& args2]
(apply f (concat @*args1 args2)))]
(fn [& args1]
(reset! *args1 args1)
cached)))
(defn use-memo
[handler deps]
(react/useMemo handler (get-js-deps deps)))
+2 -2
View File
@@ -14,11 +14,11 @@
[{:keys [on-press allow-multiple-presses? throttle-duration]} throttle-id]
(if allow-multiple-presses?
on-press
(fn []
(fn [event]
(let [id @throttle-id]
(when (and id (not (get @throttle id)))
(swap! throttle assoc id true)
(on-press)
(on-press event)
(js/setTimeout
#(swap! throttle dissoc id)
(or throttle-duration 500)))))))
@@ -8,7 +8,6 @@
(defn sheet
[{:keys [max-height]}]
{:position :absolute
:overflow :hidden
:bottom 0
:left 0
:right 0
@@ -37,7 +37,7 @@
[state]
(set-input-error state (upper-limit-exceeded? state)))
(defn- set-input-value
(defn set-input-value
[state value]
(-> state
(assoc :value value)
@@ -58,7 +58,7 @@
(defn view
[{:keys [header footer customization-color footer-container-padding header-container-style
gradient-cover?]
gradient-cover? keyboard-should-persist-taps]
:or {footer-container-padding (safe-area/get-top)}}
& children]
(reagent/with-let [scroll-view-ref (atom nil)
@@ -108,7 +108,8 @@
:padding-bottom (when @keyboard-did-show?
@footer-container-height)}
:always-bounce-vertical @keyboard-did-show?
:shows-vertical-scroll-indicator false}
:shows-vertical-scroll-indicator false
:keyboard-should-persist-taps keyboard-should-persist-taps}
(into [rn/view {:on-layout set-content-container-height}]
children)]
[rn/keyboard-avoiding-view
@@ -33,6 +33,8 @@
args-with-biometric-btn])
:on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
:on-fail (fn [err]
(rf/dispatch [:standard-auth/authorize-with-password
args-with-biometric-btn])
(when on-auth-fail (on-auth-fail err))
(rf/dispatch [:standard-auth/on-biometric-fail err]))}]]]}))
+11 -4
View File
@@ -251,7 +251,7 @@
(def regx-community-universal-link #"((^https?://status.app/)|(^status-app://))c/([\x00-\x7F]+)$")
(def regx-deep-link #"((^ethereum:.*)|(^status-app://[\x00-\x7F]+$))")
(def regx-ens #"^(?=.{5,255}$)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$")
(def regx-multichain-address #"^(?:(?:eth:|arb1:|opt:)(?=:|))*0x[0-9a-fA-F]{40}$")
(def regx-multichain-address #"^(?:(?:eth:|arb1:|oeth:)(?=:|))*0x[0-9a-fA-F]{40}$")
(def regx-address-contains #"(?i)0x[a-fA-F0-9]{40}")
(def regx-starts-with-uuid #"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
@@ -468,13 +468,13 @@
(def ^:const mainnet-short-name "eth")
(def ^:const ethereum-short-name "eth")
(def ^:const optimism-short-name "opt")
(def ^:const optimism-short-name "oeth")
(def ^:const arbitrum-short-name "arb1")
(def ^:const default-multichain-address-prefix "eth:opt:arb1:")
(def ^:const default-multichain-address-prefix "eth:oeth:arb1:")
(def ^:const mainnet-abbreviated-name "Eth.")
(def ^:const optimism-abbreviated-name "Opt.")
(def ^:const optimism-abbreviated-name "Oeth.")
(def ^:const arbitrum-abbreviated-name "Arb1.")
(def ^:const mainnet-network-name :mainnet)
@@ -506,11 +506,18 @@
(def ^:const send-type-stickers-buy 4)
(def ^:const send-type-bridge 5)
(def ^:const send-type-erc-721-transfer 6)
(def ^:const send-type-erc-1155-transfer 7)
(def ^:const bridge-name-transfer "Transfer")
(def ^:const bridge-name-erc-721-transfer "ERC721Transfer")
(def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer")
(def ^:const bridge-name-hop "Hop")
(def ^:const wallet-contract-type-uknown 0)
(def ^:const wallet-contract-type-erc-20 1)
(def ^:const wallet-contract-type-erc-721 2)
(def ^:const wallet-contract-type-erc-1155 3)
(def ^:const alert-banner-height 40)
(def ^:const status-hostname "status.app")
@@ -15,7 +15,7 @@
:emoji-id emoji-id}])))
(defn- on-long-press
[{:keys [message-id emoji-id user-message-content reactions-order theme]}]
[{:keys [message-id emoji-id user-message-content-render-fn reactions-order theme]}]
(rf/dispatch
[:reactions/get-authors-by-message-id
{:message-id message-id
@@ -31,19 +31,19 @@
[drawers/reaction-authors
{:reactions-order reactions-order
:theme theme}])
:selected-item (fn [] user-message-content)
:selected-item (fn [] [user-message-content-render-fn
{:hide-reactions? true}])
:padding-bottom-override 0}]))}]))
(defn- on-press-add
[{:keys [chat-id message-id user-message-content]}]
[{:keys [chat-id message-id user-message-content-render-fn]}]
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch
[:show-bottom-sheet
{:content (fn [] [drawers/reactions
{:chat-id chat-id
:message-id message-id}])
:selected-item (fn []
user-message-content)}]))
:selected-item (fn [] [user-message-content-render-fn])}]))
(defn- add-emoji-key
[reaction]
@@ -52,23 +52,25 @@
(get constants/reactions (:emoji-id reaction))))
(defn message-reactions-row
[{:keys [message-id chat-id pinned-by preview?]} user-message-content]
[{:keys [message-id chat-id pinned-by hide-new-reaction-button?]} user-message-content-render-fn]
(let [theme (quo.theme/use-theme)
reactions (rf/sub [:chats/message-reactions message-id chat-id])]
[:<>
(when (seq reactions)
[quo/react
{:container-style {:margin-left 44
:margin-top 8}
:reactions (map add-emoji-key reactions)
:add-reaction? (not preview?)
:use-case (when pinned-by :pinned)
:on-press #(on-press (assoc % :message-id message-id))
:on-long-press #(on-long-press (assoc %
:message-id message-id
:theme theme
:reactions-order (map :emoji-id reactions)
:user-message-content user-message-content))
:on-press-add #(on-press-add {:chat-id chat-id
:message-id message-id
:user-message-content user-message-content})}])]))
(when (seq reactions)
[quo/react
{:container-style {:margin-left 44
:margin-top 8}
:reactions (map add-emoji-key reactions)
:hide-new-reaction-button? hide-new-reaction-button?
:use-case (when pinned-by :pinned)
:on-press #(on-press (assoc % :message-id message-id))
:on-long-press #(on-long-press (assoc %
:message-id message-id
:theme theme
:reactions-order (map :emoji-id
reactions)
:user-message-content-render-fn
user-message-content-render-fn))
:on-press-add #(on-press-add {:chat-id chat-id
:message-id message-id
:user-message-content-render-fn
user-message-content-render-fn})}])))
@@ -16,22 +16,20 @@
(assoc :margin-top 4)))
(defn user-message-content
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen? preview?]}]
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen?]}]
{:border-radius 16
:padding-horizontal (if preview? 12 8)
:padding-top (if preview? 8 4)
:padding-bottom (if preview?
12
(if (or small-screen?
(and
(> 3 window-scale)
six-reactions?))
(* message-padding-scaling-ratio window-scale)
4))
:padding-horizontal 8
:padding-top 4
:padding-bottom (if (or small-screen?
(and
(> 3 window-scale)
six-reactions?))
(* message-padding-scaling-ratio window-scale)
4)
:opacity (if (and outgoing (= outgoing-status :sending))
0.5
1)})
(def drawer-message-container
{:padding-top 4
:padding-bottom 8})
:padding-bottom 4})
@@ -35,19 +35,19 @@
(def delivery-state-showing-time-ms 3000)
(defn avatar-container
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions?
in-reaction-and-action-menu? show-user-info? in-pinned-view?]
[{:keys [content last-in-group? pinned-by quoted-message from]} hide-reactions?
in-reaction-or-action-menu? show-user-info? in-pinned-view?]
(if (or (and (seq (:response-to content))
quoted-message)
last-in-group?
show-user-info?
pinned-by
(not show-reactions?)
in-reaction-and-action-menu?)
hide-reactions?
in-reaction-or-action-menu?)
[avatar/avatar
{:public-key from
:size :small
:hide-ring? (or in-pinned-view? in-reaction-and-action-menu?)}]
:hide-ring? (or in-pinned-view? in-reaction-or-action-menu?)}]
[rn/view {:padding-top 4 :width 32}]))
(defn author
@@ -58,15 +58,15 @@
quoted-message
from
timestamp]}
show-reactions?
in-reaction-and-action-menu?
hide-reactions?
in-reaction-or-action-menu?
show-user-info?]
(when (or (and (seq (:response-to content)) quoted-message)
last-in-group?
pinned-by
show-user-info?
(not show-reactions?)
in-reaction-and-action-menu?)
hide-reactions?
in-reaction-or-action-menu?)
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
[quo/author
@@ -158,8 +158,8 @@
(defn user-message-content
[]
(let [show-delivery-state? (reagent/atom false)]
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
show-user-info? preview?]}]
(fn [{:keys [message-data context keyboard-shown? hide-reactions?
in-reaction-or-action-menu? show-user-info?]}]
(let [theme (quo.theme/use-theme)
{:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned
last-in-group? message-id chat-id]} message-data
@@ -198,13 +198,13 @@
:message-sent)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
:style (style/user-message-content
{:first-in-group? (:first-in-group? message-data)
:outgoing outgoing
:outgoing-status outgoing-status
:small-screen? rn/small-screen?
:window-scale window-scale
:six-reactions? six-reactions?
:preview? preview?})
{:first-in-group? (:first-in-group? message-data)
:outgoing outgoing
:outgoing-status outgoing-status
:small-screen? rn/small-screen?
:window-scale window-scale
:six-reactions? six-reactions?
:in-reaction-or-action-menu? in-reaction-or-action-menu?})
:on-press (fn []
(if (and platform/ios? keyboard-shown?)
(do
@@ -226,18 +226,16 @@
[rn/view
{:style {:padding-horizontal 4
:flex-direction :row}}
[avatar-container message-data show-reactions? in-reaction-and-action-menu? show-user-info?
[avatar-container message-data hide-reactions? in-reaction-or-action-menu? show-user-info?
(:in-pinned-view? context)]
(into
(if show-reactions?
[rn/view]
[gesture/scroll-view])
(if hide-reactions?
[gesture/scroll-view]
[rn/view])
[{:style {:margin-left 8
:flex 1
:gap 1
:max-height (when-not show-reactions?
(* 0.4 height))}}
[author message-data show-reactions? in-reaction-and-action-menu? show-user-info?]
:max-height (when hide-reactions? (* 0.4 height))}}
[author message-data hide-reactions? in-reaction-or-action-menu? show-user-info?]
(condp = content-type
constants/content-type-text
[content.text/text-content message-data context]
@@ -272,17 +270,19 @@
(when @show-delivery-state?
[status/status outgoing-status])])]
(when show-reactions?
[reactions/message-reactions-row (assoc message-data :preview? preview?)
[rn/view {:pointer-events :none}
[user-message-content
{:theme theme
:message-data message-data
:context context
:in-reaction-and-action-menu? true
:keyboard-shown? keyboard-shown?
:preview? true
:show-reactions? true}]]])]]))))
(when-not hide-reactions?
[reactions/message-reactions-row (assoc message-data :hide-new-reaction-button? true)
(fn [override-opts]
[rn/view
{:pointer-events :none
:style style/drawer-message-container}
[user-message-content
(merge {:theme theme
:message-data message-data
:context context
:in-reaction-or-action-menu? true
:keyboard-shown? keyboard-shown?}
override-opts)]])])]]))))
(defn on-long-press
[{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?]
@@ -299,12 +299,11 @@
{:pointer-events :none
:style style/drawer-message-container}
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:in-reaction-and-action-menu? true
:show-user-info? false
:show-reactions? true}]]))}]))
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:in-reaction-or-action-menu? true
:show-user-info? false}]]))}]))
(defn check-if-system-message?
[content-type]
@@ -349,5 +348,4 @@
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:show-reactions? true}])]))
:keyboard-shown? keyboard-shown?}])]))
@@ -105,61 +105,67 @@
;; https://github.com/status-im/status-mobile/issues/15298 is implemented
(not= content-type constants/content-type-image)
(not= content-type constants/content-type-audio))
[{:type :main
:on-press #(rf/dispatch [:chat.ui/edit-message message-data])
:label (i18n/label :t/edit-message)
:icon :i/edit
:id :edit}])
[{:type :main
:on-press #(rf/dispatch [:chat.ui/edit-message message-data])
:label (i18n/label :t/edit-message)
:icon :i/edit
:accessibility-label :edit-message
:id :edit}])
(when (and able-to-send-message? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?)))
[{:type :main
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
:label (i18n/label :t/message-reply)
:icon :i/reply
:id :reply}])
[{:type :main
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
:label (i18n/label :t/message-reply)
:icon :i/reply
:accessibility-label :reply-message
:id :reply}])
(when (and (not (or deleted? deleted-for-me?))
(not= content-type constants/content-type-audio))
[{:type :main
:on-press #(clipboard/set-string
(reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/copy-text)
:icon :i/copy
:id :copy}])
[{:type :main
:on-press #(clipboard/set-string
(reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/copy-text)
:accessibility-label :copy-text
:icon :i/copy
:id :copy}])
;; pinning images are temporarily disabled
(when (and message-pin-enabled
(not= content-type constants/content-type-image))
[{:type :main
:on-press #(pin-message message-data)
:label (i18n/label (if pinned-by
(if community? :t/unpin-from-channel :t/unpin-from-chat)
(if community? :t/pin-to-channel :t/pin-to-chat)))
:icon :i/pin
:id (if pinned-by :unpin :pin)}])
[{:type :main
:on-press #(pin-message message-data)
:label (i18n/label (if pinned-by
(if community? :t/unpin-from-channel :t/unpin-from-chat)
(if community? :t/pin-to-channel :t/pin-to-chat)))
:accessibility-label (if pinned-by :unpin-message :pin-message)
:icon :i/pin
:id (if pinned-by :unpin :pin)}])
(when-not (or deleted? deleted-for-me?)
[{:type :danger
:on-press (fn []
(rf/dispatch
[:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message-for-me message-data
config/delete-message-for-me-undo-time-limit-ms]))
[{:type :danger
:on-press (fn []
(rf/dispatch
[:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message-for-me message-data
config/delete-message-for-me-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-me)
:icon :i/delete
:id :delete-for-me}])
:label (i18n/label :t/delete-for-me)
:accessibility-label :delete-for-me
:icon :i/delete
:id :delete-for-me}])
(when (cond
deleted? false
outgoing true
community? can-delete-message-for-everyone?
group-chat group-admin?
:else false)
[{:type :danger
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message message-data
config/delete-message-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-everyone)
:icon :i/delete
:id :delete-for-all}])))
[{:type :danger
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message message-data
config/delete-message-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-everyone)
:accessibility-label :delete-for-everyone
:icon :i/delete
:id :delete-for-all}])))
(defn extract-id
[reactions id]
@@ -180,7 +186,7 @@
[rn/view
{:style {:flex-direction :row
:justify-content :space-between
:padding-horizontal 30
:padding-horizontal 22
:padding-top 5
:padding-bottom 15}}
(for [[id reaction-name] constants/reactions
@@ -221,10 +227,10 @@
(for [action main-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/menu-item
[quo/drawer-action
{:type :main
:title (:label action)
:accessibility-label (:label action)
:accessibility-label (:accessibility-label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -238,10 +244,10 @@
(for [action danger-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/menu-item
[quo/drawer-action
{:type :danger
:title (:label action)
:accessibility-label (:label action)
:accessibility-label (:accessibility-label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -255,10 +261,10 @@
(for [action admin-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/menu-item
[quo/drawer-action
{:type :danger
:title (:label action)
:accessibility-label (:label action)
:accessibility-label (:accessibility-label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -114,20 +114,20 @@
(defn list-footer-avatar
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color
emoji chat-type chat-name last-message]}]
emoji chat-type chat-name empty-chat?]}]
(let [scale (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[1 0.4]
messages.constants/default-extrapolation-option)
top (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[-44 -12]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[16 -8]
messages.constants/default-extrapolation-option)
community-channel? (= chat-type constants/community-chat-type)]
@@ -155,15 +155,15 @@
:size :big}])]))
(defn chat-display-name
[{:keys [distance-from-list-top display-name contact theme last-message]}]
[{:keys [distance-from-list-top display-name contact theme empty-chat?]}]
(let [top (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 -35]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 40]
messages.constants/default-extrapolation-option)]
[reanimated/view
@@ -212,11 +212,11 @@
muted?)))}]}]))
(defn bio-and-actions
[{:keys [distance-from-list-top bio chat-id customization-color last-message description]}]
[{:keys [distance-from-list-top bio chat-id customization-color empty-chat? description]}]
(let [has-bio (seq (or bio description))
top (reanimated/interpolate
distance-from-list-top
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[(if has-bio 8 16) (if has-bio -28 -20)]
messages.constants/default-extrapolation-option)]
[reanimated/view
@@ -227,43 +227,43 @@
(defn footer-component
[{:keys [chat distance-from-list-top customization-color]}]
(let [theme (quo.theme/use-theme)
(let [theme (quo.theme/use-theme)
{:keys [chat-id chat-name emoji chat-type
group-chat color description
last-message]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (if group-chat
(rf/sub [:chats/group-chat-image chat-id])
(rf/sub [:chats/photo-path chat-id]))
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin
32)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
bottom (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[32 -4]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
empty-chat?]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (if group-chat
(rf/sub [:chats/group-chat-image chat-id])
(rf/sub [:chats/photo-path chat-id]))
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin
32)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
bottom (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[32 -4]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
[:<>
[reanimated/view
{:style (style/background-container background-color background-opacity top-margin)}]
@@ -281,21 +281,21 @@
:emoji emoji
:chat-type chat-type
:chat-name chat-name
:last-message last-message}]
:empty-chat? empty-chat?}]
[chat-display-name
{:distance-from-list-top distance-from-list-top
:display-name display-name
:theme theme
:contact contact
:group-chat group-chat
:last-message last-message}]
:empty-chat? empty-chat?}]
[bio-and-actions
{:distance-from-list-top distance-from-list-top
:bio bio
:chat-id chat-id
:customization-color customization-color
:description description
:last-message last-message}]]]]))
:empty-chat? empty-chat?}]]]]))
(defn list-footer
[props]
@@ -50,18 +50,26 @@
messages.constants/top-bar-height
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))]
messages.constants/content-animation-start-position-android))
community-channel? (= chat-type constants/community-chat-type)]
[reanimated/view
{:style (style/header-content-container header-opacity header-position)}
(if group-chat
(cond
community-channel?
[quo/channel-avatar
{:size :size-32
:full-name chat-name
:customization-color color
:emoji (when-not (string/blank? emoji)
(string/trim emoji))}]
group-chat
[quo/group-avatar
{:customization-color color
:size :size-32
:picture photo-path
:override-theme :dark
:emoji (when-not (string/blank? emoji)
(string/trim emoji))
:chat-name chat-name}]
:else
[quo/user-avatar
{:full-name display-name
:online? online?
@@ -13,13 +13,15 @@
(defn- chat-screen
[{:keys [insets] :as props}]
(let [alert-banners-top-margin (rf/sub [:alert-banners/top-margin])]
[rn/keyboard-avoiding-view
{:style style/keyboard-avoiding-container
:keyboard-vertical-offset (- (if platform/ios? alert-banners-top-margin 0) (:bottom insets))}
[list.view/messages-list-content props]
[messages.navigation/view props]
[composer.view/composer props]]))
(let [alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
chat-exist? (rf/sub [:chats/current-chat-exist?])]
(when chat-exist?
[rn/keyboard-avoiding-view
{:style style/keyboard-avoiding-container
:keyboard-vertical-offset (- (if platform/ios? alert-banners-top-margin 0) (:bottom insets))}
[list.view/messages-list-content props]
[messages.navigation/view props]
[composer.view/composer props]])))
(defn lazy-chat-screen
[chat-screen-layout-calculations-complete?]
@@ -6,6 +6,7 @@
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.contexts.chat.messenger.placeholder.style :as style]
[utils.re-frame :as rf]
[utils.worklets.chat.messenger.placeholder :as worklets]))
(defn- loading-skeleton
@@ -17,9 +18,14 @@
(defn view
[chat-screen-layout-calculations-complete?]
(let [theme (quo.theme/use-theme)
top (safe-area/get-top)
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
z-index (worklets/placeholder-z-index chat-screen-layout-calculations-complete?)]
(let [theme (quo.theme/use-theme)
top (safe-area/get-top)
chat-exist? (rf/sub [:chats/current-chat-exist?])
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
z-index (worklets/placeholder-z-index chat-screen-layout-calculations-complete?)]
[reanimated/view {:style (style/container top opacity z-index theme)}
(when-not chat-exist?
[quo/page-nav
{:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}])
[loading-skeleton]]))
@@ -1,7 +1,7 @@
(ns status-im.contexts.preview.quo.counter.step
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
@@ -17,13 +17,13 @@
(defn view
[]
(let [state (reagent/atom {:value "5"
:type :neutral
:in-blur-view? false})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:in-blur-view? @state)
:show-blur-background? (:in-blur-view? @state)}
[quo/step (dissoc @state :value) (:value @state)]])))
(let [[state set-state] (rn/use-state {:value "5"
:type :neutral
:in-blur-view? false})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor
:blur? (:in-blur-view? state)
:show-blur-background? (:in-blur-view? state)}
[quo/step (dissoc state :value) (:value state)]]))
@@ -16,7 +16,7 @@
:blur? false
:title "Collectibles vault"
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:description "0x0ah...78b"
:account-avatar-emoji "🍿"
:customization-color (or customization-color :blue)}]
@@ -21,7 +21,7 @@
:name "Trip to Vegas"
:address "0x0ah...78b"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:action :none
:on-press (fn [] (js/alert "Item pressed"))
:on-options-press (fn [] (js/alert "Options pressed"))
@@ -14,7 +14,7 @@
[]
(let [state (reagent/atom {:address "0x0ah...78b"
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]})]
{:network-name :optimism :short-name "oeth"}]})]
(fn []
[preview/preview-container
{:state state
+118 -72
View File
@@ -46,70 +46,94 @@
(str (humanize k) ":"))
(defn- customizer-boolean
[{:keys [label state] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->boolean-label (:key args)))
field-value (reagent/cursor state [(:key args)])
active? @field-value]
[{:keys [label state set-state] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->boolean-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style (style/boolean-container)}
[rn/pressable
{:style (style/boolean-button {:active? active? :left? true} theme)
:on-press #(reset! field-value true)}
[rn/text {:style (style/field-text active? theme)}
{:style (style/boolean-button {:active? field-value :left? true} theme)
:on-press #(set-field-value true)}
[rn/text {:style (style/field-text field-value theme)}
"True"]]
[rn/pressable
{:style (style/boolean-button {:active? (not active?) :left? false} theme)
:on-press #(reset! field-value false)}
[rn/text {:style (style/field-text (not active?) theme)}
{:style (style/boolean-button {:active? (not field-value) :left? false} theme)
:on-press #(set-field-value false)}
[rn/text {:style (style/field-text (not field-value) theme)}
"False"]]]]))
(defn- customizer-text
[{:keys [label state limit suffix] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[{:keys [label state set-state limit suffix] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[rn/text-input
(merge
{:value @field-value
{:value field-value
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(reset! field-value (if (and suffix
(> (count text) (count @field-value)))
(str (string/replace text suffix "") suffix)
text))
(reagent/flush))}
(set-field-value (if (and suffix
(> (count text) (count field-value)))
(str (string/replace text suffix "") suffix)
text))
(when-not (fn? set-state)
(reagent/flush)))}
(when limit
{:max-length limit}))]]]))
(defn- customizer-number
[{:keys [label state default] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[{:keys [label state set-state default] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[rn/text-input
(merge
{:value (str @field-value)
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(reset! field-value (utils.number/parse-int text default))
(reagent/flush))})]]]))
{:value (str field-value)
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(set-field-value (utils.number/parse-int text default))
(when-not (fn? set-state)
(reagent/flush)))}]]]))
(defn- find-selected-option
[id v]
(first (filter #(= (:key %) id) v)))
(defn- customizer-select-modal
[{:keys [open options field-value]}]
[{:keys [open options field-value set-field-value]}]
(let [theme (quo.theme/use-theme)]
[rn/modal
{:visible @open
@@ -125,17 +149,17 @@
:let [v (or v (humanize k))]]
^{:key k}
[rn/pressable
{:style (style/select-option (= @field-value k) theme)
{:style (style/select-option (= field-value k) theme)
:on-press (fn []
(reset! open false)
(reset! field-value k))}
[rn/text {:style (style/field-text (= @field-value k) theme)}
(set-field-value k))}
[rn/text {:style (style/field-text (= field-value k) theme)}
v]]))]
[rn/view {:style (style/footer theme)}
[rn/pressable
{:style (style/select-button theme)
:on-press (fn []
(reset! field-value nil)
(set-field-value nil)
(reset! open false))}
[rn/text {:style (style/field-text false theme)}
"Clear"]]
@@ -163,22 +187,31 @@
(defn- customizer-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state options] :as args}]
(fn [{:keys [label state set-state options] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])
selected-option (find-selected-option @field-value options)]
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))
selected-option (find-selected-option field-value options)]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[customizer-select-modal
{:open open
:options options
:field-value field-value}]
{:open open
:options options
:field-value field-value
:set-field-value set-field-value}]
[customizer-select-button {:open open :selected-option selected-option} theme]]]))))
(defn- customizer-multi-select-modal
[{:keys [open-atom options selected-keys-atom]}]
[{:keys [open-atom options field-value set-field-value]}]
(let [theme (quo.theme/use-theme)]
[rn/modal
{:visible @open-atom
@@ -193,13 +226,13 @@
(for [{k :key v :value} options
:let [v (or v (humanize k))]]
^{:key k}
(let [checked? (boolean (some #(= k %) @selected-keys-atom))
(let [checked? (boolean (some #(= k %) field-value))
remove-key (fn [v] (filterv #(not= % k) v))
on-press (fn []
(swap! selected-keys-atom
(if checked? remove-key conj)
k))]
(set-field-value
(if checked?
(remove-key field-value)
(conj field-value k))))]
[rn/pressable
{:style (style/multi-select-option theme)
:on-press on-press}
@@ -212,7 +245,7 @@
[rn/pressable
{:style (style/select-button theme)
:on-press (fn []
(reset! selected-keys-atom nil)
(set-field-value nil)
(reset! open-atom false))}
[rn/text {:style (style/field-text false theme)}
"Clear"]]
@@ -246,41 +279,51 @@
(defn- customizer-multi-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state options] :as args}]
(fn [{:keys [label state set-state options] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->text-label (:key args)))
selected-keys (reagent/cursor state [(:key args)])
selected-options (filter-by-keys options @selected-keys)]
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))
selected-options (filter-by-keys options field-value)]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[customizer-multi-select-modal
{:open-atom open
:selected-keys-atom selected-keys
:options options}]
{:open-atom open
:field-value field-value
:set-field-value set-field-value
:options options}]
[customizer-multi-select-button {:open open :selected-options selected-options} theme]]]))))
(defn customizer
[state descriptors theme]
[state set-state descriptors theme]
[rn/view
{:style {:flex-shrink 1
:padding-horizontal 20}}
(doall
(for [desc descriptors
:let [desc-path (:path desc)
new-state (if desc-path
(reagent/cursor state desc-path)
state)
descriptor (assoc desc :state new-state)]]
descriptor (if (fn? set-state)
(assoc desc :state state :set-state set-state)
(let [new-state (if desc-path
(reagent/cursor state desc-path)
state)]
(assoc desc :state new-state)))]]
^{:key (:key desc)}
[:<>
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor theme]
:number [customizer-number descriptor theme]
:select [customizer-select descriptor]
:multi-select [customizer-multi-select descriptor]
nil)]))])
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor theme]
:number [customizer-number descriptor theme]
:select [customizer-select descriptor]
:multi-select [customizer-multi-select descriptor]
nil)))])
(defn customization-color-option
([]
@@ -325,7 +368,7 @@
children)])
(defn- f-preview-container
[{:keys [title state descriptor blur? blur-dark-only?
[{:keys [title state set-state descriptor blur? blur-dark-only?
component-container-style
blur-container-style blur-view-props blur-height show-blur-background? full-screen?]
:or {blur-height 200}}
@@ -352,7 +395,7 @@
:on-press rn/dismiss-keyboard!}
(when descriptor
[rn/view {:style style/customizer-container}
[customizer state descriptor theme]])
[customizer state set-state descriptor theme]])
(if blur?
[rn/view {:style (merge style/component-container component-container-style)}
(into [blur-view
@@ -371,8 +414,11 @@
(into [rn/view {:style (merge style/component-container component-container-style)}]
children))]
(when state
(let [decr-state (if descriptor (select-keys @state (mapv :key (flatten descriptor))) @state)
state-str (with-out-str (cljs.pprint/pprint decr-state))]
(let [actual-state (if (fn? set-state) state @state)
decr-state (if descriptor
(select-keys actual-state (mapv :key (flatten descriptor)))
actual-state)
state-str (with-out-str (cljs.pprint/pprint decr-state))]
[rn/view {:style {:margin 50}}
[quo/text {:style {:margin-bottom 10}} "State map (click on map to copy)"]
[rn/pressable
@@ -4,18 +4,17 @@
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.contexts.preview.quo.preview :as preview]))
(defn- gen-quantity
(defn gen-quantity
[max-count _]
(rand-int max-count))
(def ^:private memo-gen-quantity (memoize gen-quantity))
(def memo-gen-quantity (memoize gen-quantity))
(def ^:private descriptor
[{:key :add-reaction?
(def descriptor
[{:key :hide-new-reaction-button?
:type :boolean}
{:label "Reactions"
:key :reaction-ids
@@ -37,40 +36,44 @@
(defn preview-react
[]
(let [state (reagent/atom {:add-reaction? true
:max-count 1000
:reaction-ids [1 2 3]
:use-case :default})
pressed-reactions (reagent/atom #{1})]
(let [[state set-state]
(rn/use-state {:hide-new-reaction-button? true
:max-count 1000
:reaction-ids [1 2 3]
:use-case :default})
(fn []
(let [reactions (mapv (fn [reaction-id]
{:emoji-reaction-id reaction-id
:emoji-id reaction-id
:emoji (get constants/reactions reaction-id)
:quantity (memo-gen-quantity (:max-count @state) reaction-id)
:own (contains? @pressed-reactions reaction-id)})
(:reaction-ids @state))]
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view
{:padding-bottom 150
:padding-vertical 60
:padding-horizontal 20
:border-radius 16
:background-color (when (= :pinned (:use-case @state))
(colors/custom-color :blue 50 10))
:align-items :flex-start}
[quo/react
{:reactions reactions
:add-reaction? (:add-reaction? @state)
:use-case (:use-case @state)
:on-press (fn [reaction]
(let [reaction-id (:emoji-id reaction)
change-pressed (partial swap! pressed-reactions)]
(if (contains? @pressed-reactions reaction-id)
(change-pressed disj reaction-id)
(change-pressed conj reaction-id))))
:on-long-press identity
:on-press-new identity}]]]))))
[pressed-reactions set-pressed-reactions] (rn/use-state #{1})
reactions (mapv (fn [reaction-id]
{:emoji-reaction-id reaction-id
:emoji-id reaction-id
:emoji (get constants/reactions reaction-id)
:quantity (memo-gen-quantity (:max-count state) reaction-id)
:own (contains? pressed-reactions reaction-id)})
(:reaction-ids state))
on-press (fn [reaction]
(let [reaction-id (:emoji-id reaction)]
(if (contains? pressed-reactions reaction-id)
(set-pressed-reactions (disj pressed-reactions reaction-id))
(set-pressed-reactions (conj pressed-reactions
reaction-id)))))]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[rn/view
{:padding-bottom 150
:padding-vertical 60
:padding-horizontal 20
:border-radius 16
:background-color (when (= :pinned (:use-case state))
(colors/custom-color :blue 50 10))
:align-items :flex-start}
[quo/react
{:reactions reactions
:hide-new-reaction-button? (:hide-new-reaction-button? state)
:use-case (:use-case state)
:on-press on-press
:on-long-press identity
:on-press-new identity}]]]))
@@ -82,7 +82,7 @@
[network]
(case network
:ethereum "eth:"
:optimism "opt:"
:optimism "oeth:"
:arbitrum "arb1:"
(str (name network) ":")))
@@ -13,7 +13,7 @@
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:state :default
:action :none}
{:account-props {:customization-color :purple
@@ -23,7 +23,7 @@
:name "My savings"
:address "0x0ah...72b"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:state :default
:action :none}
{:account-props {:customization-color :army
@@ -33,7 +33,7 @@
:name "Coin vault"
:address "0x0ah...73c"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:state :default
:action :none}
{:account-props {:customization-color :orange
@@ -43,7 +43,7 @@
:name "Crypto fortress"
:address "0x0ah...74e"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:state :default
:action :none}
{:account-props {:customization-color :yellow
@@ -53,7 +53,7 @@
:name "Block treasure"
:address "0x0ah...75f"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}]
{:network-name :optimism :short-name "oeth"}]
:state :default
:action :none}])
@@ -3,32 +3,173 @@
[quo.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[reagent.ratom]
[status-im.constants :as constants]
[status-im.contexts.profile.contact.contact-request.style :as style]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
;; ---
(def ^:private lookup-sentinel (js-obj))
(defn memo
"Returns a memoized version of a referentially transparent function. The
memoized version of the function keeps a cache of the mapping from arguments
to results and, when calls with the same arguments are repeated often, has
higher performance at the expense of higher memory use."
[mem f]
(fn [& args]
(js/console.log "lookup")
(let [v (get @mem args lookup-sentinel)]
(if (identical? v lookup-sentinel)
(let [ret (apply f args)]
(js/console.log "swap")
(swap! mem assoc args ret)
ret)
v))))
(defn make-snapshot-handler-factory
[snapshot]
(let [storage (rn/use-memo #(atom {}) [])
capture (rn/use-memo #(atom snapshot) [])
_update (rn/use-layout-effect
(fn []
(swap! capture (fn [_] snapshot)))
snapshot)
factory (rn/use-memo
(fn []
(fn [handler]
((memo storage
(fn [callback]
(fn [event]
(callback @capture event))))
handler)))
[storage capture])]
{:factory factory
:storage storage}))
(defn use-bind-snapshot
[snapshot]
(let [{:keys [factory storage]}
(make-snapshot-handler-factory snapshot)]
(rn/use-unmount (fn []
(js/console.log "unmount bind-snapshot")
(prn "unmount storage" storage)))
factory))
;; ---
(defn on-message-submit
[public-key message _event]
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:contact.ui/send-contact-request public-key message])
(rf/dispatch [:toasts/upsert
{:id :send-contact-request
:type :positive
:text (i18n/label
:t/contact-request-was-sent)}]))
(defn on-message-change
[set-message full-name message-text]
;; This is just an example tap to check that when full-name is recomputed,
;; this function sees the most up-to-date value.
(tap> [:on-message-change full-name message-text])
(set-message message-text))
(defn use-event
[f scope]
(let [bind (use-bind-snapshot scope)]
(bind f)))
(defn use-events
[fs scope]
(let [bind (use-bind-snapshot scope)]
(->> fs
(reduce-kv
(fn [acc label f]
(assoc acc label (bind f)))
{}))))
(defn view--using-factory-with-form-2
[]
(let [on-change-factory (rn/make-fn-factory on-message-change)
on-submit-factory (rn/make-fn-factory on-message-submit)]
(fn []
(let [{:keys [public-key customization-color]
:as profile} (rf/sub [:contacts/current-contact])
full-name (profile.utils/displayed-name profile)
profile-picture (profile.utils/photo profile)
input-ref (rn/use-ref-atom nil)
[message set-message] (rn/use-state "")
on-change (on-change-factory set-message full-name)
on-submit (on-submit-factory public-key message)]
(rn/use-mount
(fn []
(let [listener (.addListener rn/keyboard
"keyboardDidHide"
(fn [_event]
(when (and platform/android? @input-ref)
(.blur ^js @input-ref))))]
#(.remove ^js listener))))
[:<>
[quo/drawer-top
{:type :context-tag
:context-tag-type :default
:title (i18n/label :t/send-contact-request)
:full-name full-name
:profile-picture profile-picture
:customization-color customization-color}]
[quo/text {:style style/message-prompt-wrapper}
(i18n/label :t/contact-request-message-prompt)]
[rn/view {:style style/message-input-wrapper}
[quo/input
{:type :text
:ref #(reset! input-ref %)
:multiline? true
:char-limit constants/contact-request-message-max-length
:max-length constants/contact-request-message-max-length
:placeholder (i18n/label :t/type-something)
:auto-focus true
:accessibility-label :contact-request-message
:label (i18n/label :t/message)
:on-change-text on-change
:container-style {:flex-shrink 1}
:input-container-style {:flex-shrink 1}}]]
[quo/bottom-actions
{:container-style {:style {:flex 1}}
:actions :one-action
:button-one-props {:disabled? (string/blank? message)
:accessibility-label :send-contact-request
:customization-color :purple
:on-press on-submit}
:button-one-label "Past Present Sub"}]
[quo/bottom-actions
{:container-style {:style {:flex 1}}
:actions :two-actions
:button-one-props {:accessibility-label :send-contact-request
:customization-color :blue
:on-press on-submit}
:button-one-label "Snapshot"
:button-two-props {:accessibility-label :test-button
:customization-color :orange
:on-press on-submit}
:button-two-label "Sub"}]]))))
(defn view--using-factory-hook
[]
(let [{:keys [public-key customization-color]
:as profile} (rf/sub [:contacts/current-contact])
customization-color customization-color
full-name (profile.utils/displayed-name profile)
profile-picture (profile.utils/photo profile)
input-ref (rn/use-ref-atom nil)
[message set-message] (rn/use-state "")
on-message-change (rn/use-callback #(set-message %))
on-message-submit (rn/use-callback (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:contact.ui/send-contact-request
public-key message])
(rf/dispatch [:toasts/upsert
{:id :send-contact-request
:type :positive
:text (i18n/label
:t/contact-request-was-sent)}]))
[public-key message])]
on-change (rn/use-fn-factory on-message-change set-message full-name)
on-submit (rn/use-fn-factory on-message-submit public-key message)]
;; `on-change` is always the same function instance, even if the arguments
;; `set-message` and `full-name` change.
(tap> {:hashes {:on-change (hash on-change)}})
(rn/use-mount
(fn []
(let [listener (.addListener rn/keyboard
@@ -58,7 +199,7 @@
:auto-focus true
:accessibility-label :contact-request-message
:label (i18n/label :t/message)
:on-change-text on-message-change
:on-change-text on-change
:container-style {:flex-shrink 1}
:input-container-style {:flex-shrink 1}}]]
[quo/bottom-actions
@@ -66,7 +207,19 @@
:actions :one-action
:button-one-props {:disabled? (string/blank? message)
:accessibility-label :send-contact-request
:customization-color customization-color
:on-press on-message-submit}
:button-one-label (i18n/label :t/send-contact-request)}]]))
:customization-color :purple
:on-press on-submit}
:button-one-label "Past Present Sub"}]
[quo/bottom-actions
{:container-style {:style {:flex 1}}
:actions :two-actions
:button-one-props {:accessibility-label :send-contact-request
:customization-color :blue
:on-press on-submit}
:button-one-label "Snapshot"
:button-two-props {:accessibility-label :test-button
:customization-color :orange
:on-press on-submit}
:button-two-label "Sub"}]]))
(def view view--using-factory-hook)
@@ -1,8 +1,12 @@
(ns status-im.contexts.settings.wallet.events
(:require
[native-module.core :as native-module]
[status-im.contexts.syncing.utils :as sync-utils]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
[utils.re-frame :as rf]
[utils.security.core :as security]
[utils.transforms :as transforms]))
(rf/reg-event-fx
:wallet/rename-keypair-success
@@ -30,3 +34,22 @@
:on-error #(log/info "failed to rename keypair " %)}]]]})
(rf/reg-event-fx :wallet/rename-keypair rename-keypair)
(defn get-key-pair-export-connection
[{:keys [db]} [{:keys [sha3-pwd keypair-key-uid callback]}]]
(let [key-uid (get-in db [:profile/profile :key-uid])
config-map (transforms/clj->json {:senderConfig {:loggedInKeyUid key-uid
:keystorePath ""
:keypairsToExport [keypair-key-uid]
:password (security/safe-unmask-data
sha3-pwd)}
:serverConfig {:timeout 0}})
handle-connection (fn [response]
(when (sync-utils/valid-connection-string? response)
(callback response)
(rf/dispatch [:hide-bottom-sheet])))]
(native-module/get-connection-string-for-exporting-keypairs-keystores
config-map
handle-connection)))
(rf/reg-event-fx :wallet/get-key-pair-export-connection get-key-pair-export-connection)
@@ -7,13 +7,23 @@
[data]
(rf/dispatch [:open-modal :screen/settings.rename-keypair data]))
(defn on-show-qr
[data]
(rf/dispatch [:open-modal :screen/settings.encrypted-key-pair-qr data]))
(defn view
[props data]
[:<>
[quo/drawer-top props]
[quo/action-drawer
[(when (= (:type props) :keypair)
[{:icon :i/edit
:accessibility-label :rename-key-pair
:label (i18n/label :t/rename-key-pair)
:on-press #(on-rename-request data)}])]]])
(let [has-paired-device (rf/sub [:pairing/has-paired-devices])]
[:<>
[quo/drawer-top props]
[quo/action-drawer
[(when has-paired-device
[{:icon :i/qr-code
:accessibility-label :show-key-pr-qr
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
:on-press #(on-show-qr data)}])
(when (= (:type props) :keypair)
[{:icon :i/edit
:accessibility-label :rename-key-pair
:label (i18n/label :t/rename-key-pair)
:on-press #(on-rename-request data)}])]]]))
@@ -0,0 +1,38 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.hooks :as hooks]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))
(def code-valid-for-ms 120000)
(def one-min-ms 60000)
(defn current-ms
[]
(* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000))))
(defn view
[on-clear]
(let [[valid-for-ms set-valid-for-ms] (rn/use-state code-valid-for-ms)
[timestamp set-timestamp] (rn/use-state current-ms)
clock (rn/use-callback (fn []
(let [remaining (- code-valid-for-ms
(- (current-ms)
timestamp))]
(when (pos? remaining)
(set-valid-for-ms remaining))
(when (zero? remaining)
(set-timestamp (current-ms))
(set-valid-for-ms code-valid-for-ms)
(on-clear))))
[code-valid-for-ms])]
(hooks/use-interval clock on-clear 1000)
[quo/text
{:size :paragraph-2
:style {:color (if (< valid-for-ms one-min-ms)
colors/danger-60
colors/white-opa-40)}}
(i18n/label :t/valid-for-time {:valid-for (datetime/ms-to-duration valid-for-ms)})]))
@@ -0,0 +1,46 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style
(:require
[quo.foundations.colors :as colors]
[react-native.safe-area :as safe-area]))
(defn container-main
[]
{:background-color colors/neutral-95
:padding-top (safe-area/get-top)
:flex 1})
(def page-container
{:margin-top 14
:margin-horizontal 20})
(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between})
(def standard-auth
{:margin-top 12
:flex 1})
(def qr-container
{:margin-top 12
:background-color colors/white-opa-5
:border-radius 20
:flex 1
:padding 12})
(def sub-text-container
{:margin-bottom 8
:justify-content :space-between
:align-items :center
:flex-direction :row})
(def valid-cs-container
{:flex 1
:margin 12})
(def warning-text
{:margin-horizontal 16
:margin-top 20
:text-align :center
:color colors/white-opa-70})
@@ -0,0 +1,98 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[status-im.common.qr-codes.view :as qr-codes]
[status-im.common.resources :as resources]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view :as countdown]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style :as style]
[status-im.contexts.syncing.utils :as sync-utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn navigate-back [] (rf/dispatch [:navigate-back]))
(defn view
[]
(let [{:keys [key-uid]} (rf/sub [:get-screen-params])
{:keys [customization-color]} (rf/sub [:profile/profile-with-image])
[code set-code] (rn/use-state nil)
valid-connection-string? (rn/use-memo #(sync-utils/valid-connection-string? code) [code])
validate-and-set-code (rn/use-callback (fn [connection-string]
(when (sync-utils/valid-connection-string?
connection-string)
(set-code connection-string))))
cleanup-clock (rn/use-callback #(set-code nil))
on-auth-success (rn/use-callback (fn [entered-password]
(rf/dispatch
[:wallet/get-key-pair-export-connection
{:sha3-pwd entered-password
:keypair-key-uid key-uid
:callback validate-and-set-code}]))
[key-uid])]
[rn/view {:style (style/container-main)}
[rn/scroll-view
[quo/page-nav
{:type :no-title
:icon-name :i/close
:background :blur
:on-press navigate-back}]
[rn/view {:style style/page-container}
[rn/view {:style style/title-container}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}}
(i18n/label :t/encrypted-key-pairs)]]
[rn/view {:style style/qr-container}
(if valid-connection-string?
[qr-codes/qr-code {:url code}]
[rn/view {:style {:flex-direction :row}}
[rn/image
{:source (resources/get-image :qr-code)
:style {:width "100%"
:background-color colors/white-opa-70
:border-radius 12
:aspect-ratio 1}}]])
(when valid-connection-string?
[rn/view {:style style/valid-cs-container}
[rn/view {:style style/sub-text-container}
[quo/text
{:size :paragraph-2
:style {:color colors/white-opa-40}}
(i18n/label :t/encrypted-key-pairs-code)]
[countdown/view cleanup-clock]]
[quo/input
{:default-value code
:type :password
:default-shown? true
:editable false}]
[quo/button
{:on-press (fn []
(clipboard/set-string code)
(rf/dispatch [:toasts/upsert
{:type :positive
:text (i18n/label
:t/sharing-copied-to-clipboard)}]))
:type :grey
:container-style {:margin-top 12}
:icon-left :i/copy}
(i18n/label :t/copy-qr)]])
(when-not valid-connection-string?
[rn/view {:style style/standard-auth}
[standard-auth/slide-button
{:blur? true
:size :size-40
:track-text (i18n/label :t/slide-to-reveal-qr-code)
:customization-color customization-color
:on-auth-success on-auth-success
:auth-button-label (i18n/label :t/reveal-qr-code)
:auth-button-icon-left :i/reveal}]])]]
(when-not valid-connection-string?
[quo/text
{:size :paragraph-2
:style style/warning-text}
(i18n/label :t/make-sure-no-camera-warning)])]]))
@@ -50,5 +50,5 @@
(-> (h/wait-for #(h/get-by-label-text :share-qr-code-settings))
(.then (fn []
(h/is-truthy (h/get-by-text "eth:"))
(h/is-truthy (h/get-by-text "opt:"))
(h/is-truthy (h/get-by-text "oeth:"))
(h/is-truthy (h/get-by-text "arb1:"))))))))))
@@ -27,8 +27,8 @@
config/mainnet-chain-explorer-link
address])}
{:icon :i/link
:accessibility-label :view-on-opt
:label (i18n/label :t/view-on-opt)
:accessibility-label :view-on-oeth
:label (i18n/label :t/view-on-oeth)
:right-icon :i/external
:on-press #(rf/dispatch
[:wallet/navigate-to-chain-explorer-from-bottom-sheet
@@ -27,7 +27,7 @@
{: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.check-your-backup]}]]]})
:fx [[:dispatch-later [{:ms 20 :dispatch [:navigate-to :screen/wallet.confirm-backup]}]]]})
(rf/reg-event-fx :wallet/store-seed-phrase store-seed-phrase)
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.style)
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.style)
(def header-container
{:margin-horizontal 20
@@ -1,9 +1,9 @@
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.view
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.view
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.style :as style]
[status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
@@ -95,7 +95,7 @@
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :top-bar}]
[quo/page-top
{:title (i18n/label :t/check-your-backup)
{:title (i18n/label :t/confirm-backup)
:description :text
:description-text (i18n/label :t/confirm-the-position)}]
[rn/flat-list
@@ -42,7 +42,7 @@
:name name
:address address}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}
{:network-name :optimism :short-name "oeth"}
{:network-name :arbitrum :short-name "arb1"}]
:state :default
:action :none}))))
@@ -7,4 +7,5 @@
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :bridge-to-chain-id])))}
{:screen-id :screen/wallet.bridge-input-amount
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))}
{:screen-id :screen/wallet.transaction-confirmation}])
{:screen-id :screen/wallet.transaction-confirmation}
{:screen-id :screen/wallet.transaction-progress}])
@@ -6,7 +6,7 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def ^:private supported-networks #{:eth :arb1 :opt})
(def ^:private supported-networks #{:eth :arb1 :oeth})
(defn- contains-supported-address?
[s]
@@ -4,7 +4,7 @@
[status-im.common.qr-codes.view :as qr-codes]
[status-im.constants :as constants]
[utils.money :as money]
[utils.number]))
[utils.number :as number]))
(defn get-first-name
[full-name]
@@ -56,16 +56,6 @@
(inc max-decimals)
max-decimals)))
(defn remove-trailing-zeroes
[num]
(let [parts (clojure.string/split (str num) #"\.")]
(str (first parts)
(if-let [decimals (second parts)]
(if (seq (clojure.string/replace decimals #"0+$" ""))
(str "." (clojure.string/replace decimals #"0+$" ""))
"")
""))))
(defn get-crypto-decimals-count
[{:keys [market-values-per-currency]}]
(let [price (get-in market-values-per-currency [:usd :price])
@@ -83,8 +73,8 @@
one-cent-value (if (pos? price) (/ 0.01 price) 0)
decimals-count (calc-max-crypto-decimals one-cent-value)]
(if (< token-units one-cent-value)
(str "<" (remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
(remove-trailing-zeroes (.toFixed token-units decimals-count))))))
(str "<" (number/remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
(number/remove-trailing-zeroes (.toFixed token-units decimals-count))))))
(defn get-market-value
[currency {:keys [market-values-per-currency]}]
@@ -12,9 +12,9 @@
constants/ethereum-sepolia-chain-id))
(is (= (utils/network->chain-id {:network "optimism" :testnet-enabled? true :goerli-enabled? false})
constants/optimism-sepolia-chain-id))
(is (= (utils/network->chain-id {:network "opt" :testnet-enabled? false :goerli-enabled? true})
(is (= (utils/network->chain-id {:network "oeth" :testnet-enabled? false :goerli-enabled? true})
constants/optimism-mainnet-chain-id))
(is (= (utils/network->chain-id {:network :opt :testnet-enabled? true :goerli-enabled? true})
(is (= (utils/network->chain-id {:network :oeth :testnet-enabled? true :goerli-enabled? true})
constants/optimism-goerli-chain-id))
(is (= (utils/network->chain-id {:network :arb1 :testnet-enabled? false :goerli-enabled? false})
constants/arbitrum-mainnet-chain-id))
@@ -25,24 +25,24 @@
(testing "network-preference-prefix->network-names function"
(is (= (utils/network-preference-prefix->network-names "eth")
(seq [:mainnet])))
(is (= (utils/network-preference-prefix->network-names "eth:opt")
(is (= (utils/network-preference-prefix->network-names "eth:oeth")
(seq [:mainnet :optimism])))
(is (= (utils/network-preference-prefix->network-names "eth:opt:arb1")
(is (= (utils/network-preference-prefix->network-names "eth:oeth:arb1")
(seq [:mainnet :optimism :arbitrum])))))
(deftest short-names->network-preference-prefix-test
(are [expected short-names]
(= expected (utils/short-names->network-preference-prefix short-names))
"eth:" ["eth"]
"eth:opt:" ["eth" "opt"]
"eth:opt:arb1:" ["eth" "opt" "arb1"]))
"eth:" ["eth"]
"eth:oeth:" ["eth" "oeth"]
"eth:oeth:arb1:" ["eth" "oeth" "arb1"]))
(deftest network-preference-prefix->network-names-test
(are [expected short-names]
(= expected (utils/network-preference-prefix->network-names short-names))
(seq [:mainnet]) "eth"
(seq [:mainnet :optimism]) "eth:opt"
(seq [:mainnet :optimism :arbitrum]) "eth:opt:arb1"))
(seq [:mainnet :optimism]) "eth:oeth"
(seq [:mainnet :optimism :arbitrum]) "eth:oeth:arb1"))
(deftest test-network-ids->formatted-text
(testing "Empty network-ids should return an empty string"
@@ -102,7 +102,7 @@
:address "x000"}]
(is (= (utils/get-wallet-qr wallet-multichain)
"eth:opt:x000"))
"eth:oeth:x000"))
(is (= (utils/get-wallet-qr wallet-singlechain)
"x000")))))
+2 -2
View File
@@ -250,7 +250,7 @@
{:db (-> db
(assoc-in [:wallet :ui :send :token] token)
(assoc-in [:wallet :ui :send :to-address] to-address)
(assoc-in [:wallet :ui :send :tx-type] :bridge))
(assoc-in [:wallet :ui :send :tx-type] :tx/bridge))
:fx [[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen stack-id
@@ -259,7 +259,7 @@
(rf/reg-event-fx :wallet/start-bridge
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :send :tx-type] :bridge)
{:db (assoc-in db [:wallet :ui :send :tx-type] :tx/bridge)
:fx [[:dispatch [:open-modal :screen/wallet.bridge-select-asset]]]}))
(rf/reg-event-fx :wallet/select-bridge-network
@@ -12,7 +12,7 @@
name ""
ens ""
test? false
;; the chain short names should be a string like eth: or eth:arb:opt:
;; the chain short names should be a string like eth: or eth:arb:oeth:
chain-short-names (str constants/mainnet-short-name ":")}}]]
(let [address-to-save {:address address
:name name
+48 -14
View File
@@ -35,6 +35,7 @@
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
receiver-network-values (get-in db [:wallet :ui :send :receiver-network-values])
sender-network-values (get-in db [:wallet :ui :send :sender-network-values])
tx-type (get-in db [:wallet :ui :send :tx-type])
disabled-from-chain-ids (or (get-in db [:wallet :ui :send :disabled-from-chain-ids]) [])
token-decimals (if collectible 0 (:decimals token))
native-token? (and token (= token-display-name "ETH"))
@@ -61,6 +62,7 @@
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? false})
(send-utils/reset-network-amounts-to-zero
sender-network-values))
@@ -70,6 +72,7 @@
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? true})
(send-utils/reset-network-amounts-to-zero
receiver-network-values))
@@ -114,6 +117,7 @@
dissoc
:suggested-routes
:route
:amount
:from-values-by-chain
:to-values-by-chain
:sender-network-values
@@ -144,7 +148,8 @@
{:prefix prefix
:testnet-enabled? testnet-enabled?
:goerli-enabled? goerli-enabled?})
collectible-tx? (= (-> db :wallet :ui :send :tx-type) :collectible)
collectible-tx? (send-utils/tx-type-collectible?
(-> db :wallet :ui :send :tx-type))
collectible (when collectible-tx?
(-> db :wallet :ui :send :collectible))
one-collectible? (when collectible-tx?
@@ -235,13 +240,19 @@
:collectible
:token-display-name
:amount
(when (= transaction-type :collectible) :tx-type))})))
(when (send-utils/tx-type-collectible?
transaction-type)
:tx-type))})))
(rf/reg-event-fx
:wallet/set-collectible-to-send
(fn [{db :db} [{:keys [collectible current-screen]}]]
(let [collection-data (:collection-data collectible)
collectible-data (:collectible-data collectible)
contract-type (:contract-type collectible)
tx-type (if (= contract-type constants/wallet-contract-type-erc-1155)
:tx/collectible-erc-1155
:tx/collectible-erc-721)
collectible-id (get-in collectible [:id :token-id])
one-collectible? (= (collectible.utils/collectible-balance collectible) 1)
token-display-name (cond
@@ -255,7 +266,7 @@
(update-in [:wallet :ui :send] dissoc :token)
(assoc-in [:wallet :ui :send :collectible] collectible)
(assoc-in [:wallet :ui :send :token-display-name] token-display-name)
(assoc-in [:wallet :ui :send :tx-type] :collectible))
(assoc-in [:wallet :ui :send :tx-type] tx-type))
recipient-set? (-> db :wallet :ui :send :recipient)]
{:db (cond-> collectible-tx
one-collectible? (assoc-in [:wallet :ui :send :amount] 1))
@@ -314,7 +325,7 @@
amount-in (send-utils/amount-in-hex amount (if token token-decimal 0))
from-address wallet-address
disabled-from-chain-ids disabled-from-chain-ids
disabled-to-chain-ids (if (= transaction-type :bridge)
disabled-to-chain-ids (if (= transaction-type :tx/bridge)
(filter #(not= % bridge-to-chain-id) network-chain-ids)
(filter (fn [chain-id]
(not (some #(= chain-id %)
@@ -322,8 +333,9 @@
network-chain-ids))
from-locked-amount {}
transaction-type-param (case transaction-type
:collectible constants/send-type-erc-721-transfer
:bridge constants/send-type-bridge
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
:tx/bridge constants/send-type-bridge
constants/send-type-transfer)
balances-per-chain (when token (:balances-per-chain token))
token-available-networks-for-suggested-routes
@@ -335,18 +347,28 @@
token-networks-ids (when token (mapv #(:chain-id %) (:networks token)))
sender-network-values (when token-available-networks-for-suggested-routes
(send-utils/loading-network-amounts
{:valid-networks token-available-networks-for-suggested-routes
{:valid-networks (if (= transaction-type :tx/bridge)
(filter
#(not= bridge-to-chain-id %)
token-available-networks-for-suggested-routes)
token-available-networks-for-suggested-routes)
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type transaction-type
:receiver? false}))
receiver-network-values (when token-available-networks-for-suggested-routes
(send-utils/loading-network-amounts
{:valid-networks token-available-networks-for-suggested-routes
{:valid-networks (if (= transaction-type :tx/bridge)
(filter
#(= bridge-to-chain-id %)
token-available-networks-for-suggested-routes)
token-available-networks-for-suggested-routes)
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:receiver? true}))
:tx-type transaction-type
:receiver? true}))
request-params [transaction-type-param
from-address
to-address
@@ -387,7 +409,10 @@
{:db (-> db
(assoc-in [:wallet :transactions] transaction-details)
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]]})))
:fx [[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen :screen/wallet.transaction-confirmation
:flow-id :wallet-send-flow}]]]})))
(rf/reg-event-fx :wallet/close-transaction-progress-page
(fn [_]
@@ -396,7 +421,7 @@
[:dispatch [:wallet/clean-send-address]]
[:dispatch [:wallet/clean-disabled-from-networks]]
[:dispatch [:wallet/select-address-tab nil]]
[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]]}))
[:dispatch [:dismiss-modal :screen/wallet.transaction-progress]]]}))
(defn- transaction-data
[{:keys [from-address to-address token-address route data eth-transfer?]}]
@@ -452,6 +477,14 @@
:TokenID token-id
:ChainID to-chain-id))
(= bridge-name constants/bridge-name-erc-1155-transfer)
(assoc :ERC1155TransferTx
(assoc tx-data
:Recipient to-address
:TokenID token-id
:ChainID to-chain-id
:Amount amount-in))
(= bridge-name constants/bridge-name-transfer)
(assoc :TransferTx tx-data)
@@ -491,8 +524,9 @@
from-address (get-in db [:wallet :current-viewing-account-address])
transaction-type (get-in db [:wallet :ui :send :tx-type])
transaction-type-param (case transaction-type
:collectible constants/send-type-erc-721-transfer
:bridge constants/send-type-bridge
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
:tx/bridge constants/send-type-bridge
constants/send-type-transfer)
token (get-in db [:wallet :ui :send :token])
collectible (get-in db [:wallet :ui :send :collectible])
@@ -1,11 +1,13 @@
(ns status-im.contexts.wallet.send.flow-config)
(ns status-im.contexts.wallet.send.flow-config
(:require
[status-im.contexts.wallet.send.utils :as send-utils]))
(defn- collectible-selected?
[db]
(let [collectible-stored (-> db :wallet :ui :send :collectible)
tx-type (-> db :wallet :ui :send :tx-type)]
(and (some? collectible-stored)
(= tx-type :collectible))))
(send-utils/tx-type-collectible? tx-type))))
(defn- token-selected?
[db]
@@ -19,9 +21,11 @@
{:screen-id :screen/wallet.select-asset
:skip-step? (fn [db] (or (token-selected? db) (collectible-selected? db)))}
{:screen-id :screen/wallet.send-input-amount
:skip-step? (fn [db] (= (get-in db [:wallet :ui :send :tx-type]) :collectible))}
:skip-step? (fn [db]
(send-utils/tx-type-collectible? (get-in db [:wallet :ui :send :tx-type])))}
{:screen-id :screen/wallet.select-collectible-amount
:skip-step? (fn [db]
(or (not (collectible-selected? db))
(some? (get-in db [:wallet :ui :send :amount]))))}
{:screen-id :screen/wallet.transaction-confirmation}])
{:screen-id :screen/wallet.transaction-confirmation}
{:screen-id :screen/wallet.transaction-progress}])
@@ -53,6 +53,7 @@
"2500")
:has-error false}}
:total-balance 100
:available-balance 100
:market-values-per-currency {:usd {:price 10}}}
:wallet/wallet-send-loading-suggested-routes? false
:wallet/wallet-send-route [{:from {:chainid 1
@@ -68,6 +69,7 @@
:view-id :screen/wallet.send-input-amount
:wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064"
:profile/currency-symbol "$"
:profile/currency :usd
:wallet/token-by-symbol {:symbol :eth
:total-balance 100
:market-values-per-currency {:usd {:price 10}}}
@@ -77,7 +79,16 @@
:wallet/wallet-send-sender-network-values nil
:wallet/wallet-send-receiver-network-values nil
:wallet/wallet-send-network-links nil
:wallet/wallet-send-receiver-preferred-networks [1]})
:wallet/wallet-send-receiver-preferred-networks [1]
:wallet/wallet-send-enabled-networks [{:source 879
:short-name "eth"
:network-name :mainnet
:abbreviated-name "Eth."
:chain-id 1
:related-chain-id 1
:layer 1}]
:wallet/wallet-send-enabled-from-chain-ids [1]
:wallet/wallet-send-amount nil})
(h/describe "Send > input amount screen"
(h/setup-restorable-re-frame)
@@ -164,6 +175,6 @@
(h/is-truthy (h/get-by-label-text :container-error))
(h/fire-event :press (h/query-by-label-text :reorder))
(-> (h/wait-for #(h/get-by-text "Max: 1000.00 USD"))
(-> (h/wait-for #(h/get-by-text "Max: $1000.00"))
(.then (fn []
(h/wait-for #(h/is-truthy (h/get-by-label-text :container))))))))
@@ -16,11 +16,13 @@
[status-im.contexts.wallet.send.utils :as send-utils]
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
[utils.address :as address]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.number :as number]
[utils.re-frame :as rf]))
(defn- make-limit-label
(defn- make-limit-label-crypto
[amount currency]
(str amount
" "
@@ -28,6 +30,10 @@
name
string/upper-case)))
(defn- make-limit-label-fiat
[amount currency-symbol]
(str currency-symbol amount))
(defn- estimated-fees
[{:keys [loading-routes? fees amount receiver]}]
[rn/view {:style style/estimated-fees-container}
@@ -61,6 +67,7 @@
(every? (fn [{:keys [total-amount]}]
(and
total-amount
(money/bignumber? total-amount)
(money/equal-to total-amount
(money/bignumber "0"))))
sender-network-values))
@@ -127,112 +134,138 @@
crypto-currency? (reagent/atom initial-crypto-currency?)
on-navigate-back on-navigate-back]
(fn []
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
clear-input! #(set-input-state controlled-input/delete-all)
handle-on-confirm (fn []
(rf/dispatch [:wallet/set-token-amount-to-send
{:amount
(controlled-input/input-value
input-state)
:stack-id current-screen-id}]))
{fiat-currency :currency} (rf/sub [:profile/profile])
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
[just-toggled-mode? set-just-toggled-mode?] (rn/use-state false)
clear-input! #(set-input-state controlled-input/delete-all)
handle-on-confirm (fn []
(rf/dispatch [:wallet/set-token-amount-to-send
{:amount
(controlled-input/input-value
input-state)
:stack-id current-screen-id}]))
{fiat-currency :currency} (rf/sub [:profile/profile])
{token-symbol :symbol
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
token-networks :networks
token-decimals :decimals} (rf/sub [:wallet/wallet-send-token])
send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
enabled-from-chain-ids (rf/sub
[:wallet/wallet-send-enabled-from-chain-ids])
{token-balance :total-balance
available-balance :available-balance
:as
token} (rf/sub
[:wallet/current-viewing-account-tokens-filtered
(str token-symbol)])
conversion-rate (-> token :market-values-per-currency :usd :price)
loading-routes? (rf/sub
[:wallet/wallet-send-loading-suggested-routes?])
route (rf/sub [:wallet/wallet-send-route])
to-address (rf/sub [:wallet/wallet-send-to-address])
on-confirm (or default-on-confirm handle-on-confirm)
crypto-decimals (or default-crypto-decimals
(utils/get-crypto-decimals-count token))
crypto-limit (or default-limit-crypto
(utils/get-standard-crypto-format
token
token-balance))
fiat-limit (.toFixed (* token-balance conversion-rate) 2)
current-limit (if @crypto-currency? crypto-limit fiat-limit)
valid-input? (not (or (string/blank?
(controlled-input/input-value
input-state))
(<= (controlled-input/numeric-value
input-state)
0)
(> (controlled-input/numeric-value
input-state)
current-limit)))
current-currency (if @crypto-currency? token-symbol fiat-currency)
input-num-value (controlled-input/numeric-value input-state)
confirm-disabled? (or (nil? route)
(empty? route)
(string/blank? (controlled-input/input-value
input-state))
(<= input-num-value 0)
(> input-num-value current-limit))
amount-text (str (controlled-input/input-value input-state)
" "
token-symbol)
first-route (first route)
native-currency-symbol (when-not confirm-disabled?
(get-in first-route
[:from :native-currency-symbol]))
native-token (when native-currency-symbol
(rf/sub [:wallet/token-by-symbol
native-currency-symbol]))
fee-in-native-token (when-not confirm-disabled?
(send-utils/calculate-full-route-gas-fee route))
fee-in-crypto-formatted (when fee-in-native-token
(utils/get-standard-crypto-format
native-token
fee-in-native-token))
fee-in-fiat (when-not confirm-disabled?
(utils/calculate-token-fiat-value
{:currency fiat-currency
:balance fee-in-native-token
:token native-token}))
currency-symbol (rf/sub [:profile/currency-symbol])
fee-formatted (when fee-in-fiat
(utils/get-standard-fiat-format
fee-in-crypto-formatted
currency-symbol
fee-in-fiat))
show-select-asset-sheet #(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[select-asset-bottom-sheet
clear-input!])}])
sender-network-values (rf/sub
[:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub
[:wallet/wallet-send-receiver-network-values])
token} (rf/sub
[:wallet/current-viewing-account-tokens-filtered
(str token-symbol) enabled-from-chain-ids])
currency-symbol (rf/sub [:profile/currency-symbol])
currency (rf/sub [:profile/currency])
conversion-rate (-> token :market-values-per-currency currency :price)
loading-routes? (rf/sub
[:wallet/wallet-send-loading-suggested-routes?])
route (rf/sub [:wallet/wallet-send-route])
to-address (rf/sub [:wallet/wallet-send-to-address])
on-confirm (or default-on-confirm handle-on-confirm)
crypto-decimals (or token-decimals default-crypto-decimals)
current-crypto-limit (or default-limit-crypto
(utils/get-standard-crypto-format
token
token-balance))
available-crypto-limit (or default-limit-crypto
(utils/get-standard-crypto-format
token
available-balance))
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
available-fiat-limit (.toFixed (* available-balance conversion-rate) 2)
current-limit (if @crypto-currency?
current-crypto-limit
current-fiat-limit)
available-limit (if @crypto-currency?
available-crypto-limit
available-fiat-limit)
valid-input? (not (or (string/blank?
(controlled-input/input-value
input-state))
(<= (controlled-input/numeric-value
input-state)
0)
(> (controlled-input/numeric-value
input-state)
available-limit)))
input-num-value (controlled-input/numeric-value input-state)
input-amount (controlled-input/input-value input-state)
confirm-disabled? (or (nil? route)
(empty? route)
(string/blank? (controlled-input/input-value
input-state))
(<= input-num-value 0)
(> input-num-value current-limit))
amount (if @crypto-currency?
input-amount
(number/remove-trailing-zeroes
(.toFixed (/ input-amount conversion-rate)
crypto-decimals)))
send-amount (rf/sub [:wallet/wallet-send-amount])
amount-text (str (number/remove-trailing-zeroes
(.toFixed (js/parseFloat send-amount)
(min token-decimals 6)))
" "
token-symbol)
first-route (first route)
native-currency-symbol (when-not confirm-disabled?
(get-in first-route
[:from :native-currency-symbol]))
native-token (when native-currency-symbol
(rf/sub [:wallet/token-by-symbol
native-currency-symbol]))
fee-in-native-token (when-not confirm-disabled?
(send-utils/calculate-full-route-gas-fee route))
fee-in-crypto-formatted (when fee-in-native-token
(utils/get-standard-crypto-format
native-token
fee-in-native-token))
fee-in-fiat (when-not confirm-disabled?
(utils/calculate-token-fiat-value
{:currency fiat-currency
:balance fee-in-native-token
:token native-token}))
fee-formatted (when fee-in-fiat
(utils/get-standard-fiat-format
fee-in-crypto-formatted
currency-symbol
fee-in-fiat))
show-select-asset-sheet #(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[select-asset-bottom-sheet
clear-input!])}])
sender-network-values (rf/sub
[:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub
[:wallet/wallet-send-receiver-network-values])
token-not-supported-in-receiver-networks? (every? #(= (:type %) :not-available)
(filter #(not= (:type %) :add)
receiver-network-values))
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
routes (when suggested-routes
(or (:best suggested-routes) []))
no-routes-found? (and
(every-network-value-is-zero?
sender-network-values)
(not (nil? routes))
(not loading-routes?)
(not token-not-supported-in-receiver-networks?))
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
receiver-preferred-networks (rf/sub
[:wallet/wallet-send-receiver-preferred-networks])
receiver-preferred-networks-set (set receiver-preferred-networks)
sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
(contains?
receiver-preferred-networks-set
receiver-selected-network))
receiver-networks))]
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
routes (when suggested-routes
(or (:best suggested-routes) []))
no-routes-found? (and
(every-network-value-is-zero?
sender-network-values)
(not (nil? routes))
(not loading-routes?)
(not token-not-supported-in-receiver-networks?))
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
receiver-preferred-networks (rf/sub
[:wallet/wallet-send-receiver-preferred-networks])
receiver-preferred-networks-set (set receiver-preferred-networks)
sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
(contains?
receiver-preferred-networks-set
receiver-selected-network))
receiver-networks))
input-error (controlled-input/input-error input-state)
limit-insufficient? (> (controlled-input/numeric-value input-state)
current-limit)
should-try-again? (and (not limit-insufficient?) no-routes-found?)]
(rn/use-mount
(fn []
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
@@ -242,6 +275,9 @@
(fn []
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
[current-limit])
(rn/use-effect
#(when input-error (debounce/clear-all))
[input-error])
[rn/view
{:style style/screen
:accessibility-label (str "container"
@@ -253,22 +289,40 @@
[quo/token-input
{:container-style style/input-container
:token token-symbol
:currency current-currency
:crypto-decimals crypto-decimals
:currency fiat-currency
:currency-symbol currency-symbol
:crypto-decimals (min token-decimals 6)
:error? (controlled-input/input-error input-state)
:networks (seq token-networks)
:title (i18n/label :t/send-limit
{:limit (make-limit-label current-limit current-currency)})
:networks (seq send-enabled-networks)
:title (i18n/label
:t/send-limit
{:limit (if @crypto-currency?
(make-limit-label-crypto current-limit token-symbol)
(make-limit-label-fiat current-limit currency-symbol))})
:conversion conversion-rate
:show-keyboard? false
:value (controlled-input/input-value input-state)
:on-swap #(reset! crypto-currency? %)
:value input-amount
:on-swap (fn [swap-to-crypto-currency?]
(set-just-toggled-mode? true)
(reset! crypto-currency? swap-to-crypto-currency?)
(set-input-state
(fn [input-state]
(controlled-input/set-input-value
input-state
(let [value (controlled-input/input-value input-state)
new-value (if swap-to-crypto-currency?
(.toFixed (/ value conversion-rate)
crypto-decimals)
(.toFixed (* value conversion-rate) 12))]
(number/remove-trailing-zeroes new-value))))))
:on-token-press show-select-asset-sheet}]
[routes/view
{:token token
:input-value (controlled-input/input-value input-state)
:input-value input-amount
:value amount
:valid-input? valid-input?
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:lock-fetch-routes? just-toggled-mode?
:current-screen-id current-screen-id}]
(when (and (not loading-routes?)
sender-network-values
@@ -280,7 +334,7 @@
:fees fee-formatted
:amount amount-text
:receiver (address/get-shortened-key to-address)}])
(when no-routes-found?
(when (or no-routes-found? limit-insufficient?)
[rn/view {:style style/no-routes-found-container}
[quo/info-message
{:type :error
@@ -290,32 +344,49 @@
(i18n/label :t/no-routes-found)]])
[quo/bottom-actions
{:actions :one-action
:button-one-label (if no-routes-found?
:button-one-label (if should-try-again?
(i18n/label :t/try-again)
button-one-label)
:button-one-props (merge button-one-props
{:disabled? (and (not no-routes-found?) confirm-disabled?)
:button-one-props (merge (when-not should-try-again? button-one-props)
{:disabled? (and (not should-try-again?) confirm-disabled?)
:on-press (cond
no-routes-found?
#(rf/dispatch [:wallet/get-suggested-routes
{:amount (controlled-input/input-value
input-state)}])
should-try-again?
#(let [input-amount (controlled-input/input-value
input-state)
amount (if @crypto-currency?
input-amount
(.toFixed (* token-balance
conversion-rate)
2))]
(rf/dispatch [:wallet/get-suggested-routes
{:amount amount}]))
sending-to-unpreferred-networks?
#(show-unpreferred-networks-alert on-confirm)
:else
on-confirm)}
(when no-routes-found?
(when should-try-again?
{:type :grey}))}]
[quo/numbered-keyboard
{:container-style (style/keyboard-container bottom)
:left-action :dot
:delete-key? true
:on-press (fn [c]
(when-not loading-routes?
(set-input-state #(controlled-input/add-character % c))))
(let [new-text (str input-amount c)
max-decimals (if @crypto-currency? crypto-decimals 2)
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
regex (re-pattern regex-pattern)]
(when (and (not loading-routes?)
(re-matches regex new-text))
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state #(controlled-input/add-character % c)))))
:on-delete (fn []
(when-not loading-routes?
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state controlled-input/delete-last)))
:on-long-press-delete (fn []
(when-not loading-routes?
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state controlled-input/delete-all)))}]]))))
@@ -16,8 +16,8 @@
(def network-link-1x-height 56)
(def network-link-2x-height 111)
(defn fetch-routes
[amount valid-input? bounce-duration-ms]
(defn- fetch-routes
[{:keys [amount bounce-duration-ms valid-input?]}]
(if valid-input?
(debounce/debounce-and-dispatch
[:wallet/get-suggested-routes {:amount amount}]
@@ -174,8 +174,8 @@
:text (i18n/label :t/at-least-one-network-must-be-activated)}]))))
(defn view
[{:keys [token theme input-value valid-input?
on-press-to-network current-screen-id
[{:keys [token theme input-value value valid-input?
lock-fetch-routes? on-press-to-network current-screen-id
token-not-supported-in-receiver-networks?]}]
(let [token-symbol (:symbol token)
nav-current-screen-id (rf/sub [:view-id])
@@ -198,12 +198,21 @@
:disabled-chain-ids disabled-from-chain-ids})
show-routes? (not-empty sender-network-values)]
(rn/use-effect
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
(fetch-routes input-value valid-input? 2000))
(fn []
(when (and active-screen?
(> (count token-available-networks-for-suggested-routes) 0)
(not lock-fetch-routes?))
(fetch-routes
{:amount value
:valid-input? valid-input?
:bounce-duration-ms 2000})))
[input-value valid-input?])
(rn/use-effect
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
(fetch-routes input-value valid-input? 0))
(fetch-routes
{:amount value
:valid-input? valid-input?
:bounce-duration-ms 0}))
[disabled-from-chain-ids])
[rn/scroll-view {:content-container-style style/routes-container}
(when show-routes?
@@ -238,5 +247,8 @@
:loading-routes? loading-routes?
:theme theme
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:on-save #(fetch-routes input-value valid-input? 0)}]]]))
:on-save #(fetch-routes
{:amount input-value
:valid-input? valid-input?
:bounce-duration-ms 0})}]]]))
@@ -156,24 +156,26 @@
local-suggestion-address (rf/sub [:wallet/local-suggestions->full-address])
color (rf/sub [:wallet/current-viewing-account-color])]
[floating-button-page/view
{:footer-container-padding 0
:header [account-switcher/view
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]
:footer (when (> (count @input-value) 0)
[quo/button
{:accessibility-label :continue-button
:type :primary
:disabled? (not valid-ens-or-address?)
:on-press #(rf/dispatch
[:wallet/select-send-address
{:address (or local-suggestion-address
@input-value)
:stack-id
:screen/wallet.select-address}])
:customization-color color}
(i18n/label :t/continue)])}
{:footer-container-padding 0
:keyboard-should-persist-taps true
:header [account-switcher/view
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]
:footer (when (> (count @input-value) 0)
[quo/button
{:accessibility-label :continue-button
:type :primary
:disabled? (not valid-ens-or-address?)
:on-press #(rf/dispatch
[:wallet/select-send-address
{:address (or
local-suggestion-address
@input-value)
:stack-id
:screen/wallet.select-address}])
:customization-color color}
(i18n/label :t/continue)])}
[quo/page-top
{:title (i18n/label :t/send-to)
:title-accessibility-label :title-label}]
@@ -3,7 +3,6 @@
[clojure.string :as string]
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
[status-im.contexts.wallet.common.collectibles-tab.view :as collectibles-tab]
@@ -59,33 +58,32 @@
(defn view
[]
(let [selected-tab (reagent/atom (:id (first tabs-data)))
search-text (reagent/atom "")
on-change-text #(reset! search-text %)
on-change-tab #(reset! selected-tab %)
on-close (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:navigate-back]))]
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
[search-text set-search-text] (rn/use-state "")
on-change-text #(set-search-text %)
on-change-tab #(set-selected-tab %)
on-close (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:navigate-back]))]
(rn/use-unmount (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])))
(fn []
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press on-close
:switcher-type :select-account}]
[quo/page-top
{:title (i18n/label :t/select-asset)
:title-accessibility-label :title-label}]
[quo/segmented-control
{:size 32
:blur? false
:symbol false
:default-active :tab/assets
:container-style {:margin-horizontal 20
:margin-vertical 8}
:data tabs-data
:on-change on-change-tab}]
[tab-view @search-text @selected-tab on-change-text]])))
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press on-close
:switcher-type :select-account}]
[quo/page-top
{:title (i18n/label :t/select-asset)
:title-accessibility-label :title-label}]
[quo/segmented-control
{:size 32
:blur? false
:symbol false
:default-active :tab/assets
:container-style {:margin-horizontal 20
:margin-vertical 8}
:data tabs-data
:on-change on-change-tab}]
[tab-view search-text selected-tab on-change-text]]))
@@ -26,7 +26,7 @@
:weight :semi-bold
:style style/title-container
:accessibility-label :send-label}
(if (= transaction-type :bridge)
(if (= transaction-type :tx/bridge)
(i18n/label :t/bridge)
(i18n/label :t/send))]
[quo/summary-tag
@@ -34,7 +34,7 @@
:label (str amount " " token-display-name)
:type (if collectible? :collectible :token)
:image-source (if collectible? image-url :eth)}]]
(if (= transaction-type :bridge)
(if (= transaction-type :tx/bridge)
(map-indexed
(fn [idx path]
(let [from-network (:from path)
@@ -98,7 +98,7 @@
:style style/title-container
:accessibility-label :send-label}
(i18n/label :t/to)]
(if (= transaction-type :bridge)
(if (= transaction-type :tx/bridge)
[quo/summary-tag
{:type :network
:image-source (:source to-network)
@@ -107,7 +107,7 @@
[quo/summary-tag
{:type :address
:label (utils/get-shortened-address to-address)}])]
(when (= transaction-type :bridge)
(when (= transaction-type :tx/bridge)
[rn/view
{:style {:flex-direction :row
:margin-top 4}}
@@ -198,7 +198,7 @@
{:amount (str max-fees)
:symbol currency-symbol})}]
[data-item
{:title (if (= transaction-type :bridge)
{:title (if (= transaction-type :tx/bridge)
(i18n/label :t/bridged-to
{:network (:abbreviated-name to-network)})
(i18n/label :t/user-gets {:name (utils/get-shortened-address to-address)}))
@@ -249,7 +249,7 @@
:footer (when (and route (seq route))
[standard-auth/slide-button
{:size :size-48
:track-text (if (= transaction-type :bridge)
:track-text (if (= transaction-type :tx/bridge)
(i18n/label :t/slide-to-bridge)
(i18n/label :t/slide-to-send))
:container-style {:z-index 2}
@@ -282,12 +282,12 @@
:theme theme}]
[user-summary
{:token-display-name token-display-name
:summary-type (if (= transaction-type :bridge)
:summary-type (if (= transaction-type :tx/bridge)
:status-account
:account)
:accessibility-label :summary-to-label
:label (i18n/label :t/to-capitalized)
:account-props (if (= transaction-type :bridge)
:account-props (if (= transaction-type :tx/bridge)
from-account-props
user-props)
:network-values to-values-by-chain
+27 -14
View File
@@ -94,7 +94,7 @@
network-amounts))
(defn network-amounts
[{:keys [network-values disabled-chain-ids receiver-networks token-networks-ids receiver?]}]
[{:keys [network-values disabled-chain-ids receiver-networks token-networks-ids tx-type receiver?]}]
(let [disabled-set (set disabled-chain-ids)
receiver-networks-set (set receiver-networks)
network-values-keys (set (keys network-values))
@@ -150,11 +150,12 @@
(vec))
(and receiver?
routes-found?
(< (count network-values-with-not-available-chains) available-networks-count))
(< (count network-values-with-not-available-chains) available-networks-count)
(not= tx-type :tx/bridge))
(conj {:type :add}))))
(defn loading-network-amounts
[{:keys [valid-networks disabled-chain-ids receiver-networks token-networks-ids receiver?]}]
[{:keys [valid-networks disabled-chain-ids receiver-networks token-networks-ids tx-type receiver?]}]
(let [disabled-set (set disabled-chain-ids)
receiver-networks-set (set receiver-networks)
receiver-networks-count (count receiver-networks)
@@ -164,11 +165,13 @@
(filter #(not (token-networks-ids-set %)) receiver-networks)
[])
not-available-networks-set (set not-available-networks)
valid-networks (concat valid-networks
disabled-chain-ids
(when receiver?
(filter #(not (valid-networks-set %))
not-available-networks)))]
valid-networks (-> (concat valid-networks
(when (not (and receiver? (= tx-type :tx/bridge)))
disabled-chain-ids)
(when receiver?
(filter #(not (valid-networks-set %))
not-available-networks)))
(distinct))]
(cond-> (->> valid-networks
(map
(fn [chain-id]
@@ -181,16 +184,18 @@
(and (not receiver?) (contains? disabled-set chain-id)) :disabled)}
(and (not receiver?) (contains? disabled-set chain-id))
(assoc :total-amount (money/bignumber "0")))))
(filter
(fn [network-amount]
(or (and receiver?
(or (= tx-type :tx/bridge)
(contains? receiver-networks-set (:chain-id network-amount))))
(not receiver?))))
(sort-by (fn [network-amount]
(get network-priority-score
(network-utils/id->network (:chain-id network-amount)))))
(filter
(fn [network-amount]
(or (and receiver? (contains? receiver-networks-set (:chain-id network-amount)))
(and (not receiver?)
(not (contains? disabled-chain-ids (:chain-id network-amount)))))))
(vec))
(and receiver? (< receiver-networks-count available-networks-count)) (conj {:type :add}))))
(and receiver? (< receiver-networks-count available-networks-count) (not= tx-type :tx/bridge))
(conj {:type :add}))))
(defn network-links
[route from-values-by-chain to-values-by-chain]
@@ -208,3 +213,11 @@
:position-diff position-diff})))
[]
route))
(def ^:private collectible-tx-set
#{:tx/collectible-erc-721
:tx/collectible-erc-1155})
(defn tx-type-collectible?
[tx-type]
(contains? collectible-tx-set tx-type))
+237 -133
View File
@@ -33,9 +33,9 @@
(deftest test-network-amounts-by-chain
(testing "Correctly calculates network amounts for transaction with native token"
(let [route [{:amount-in "0xde0b6b3a7640000"
:to {:chain-id "1"}}
:to {:chain-id 1}}
{:amount-in "0xde0b6b3a7640000"
:to {:chain-id "2"}}]
:to {:chain-id 10}}]
token-decimals 18
native-token? true
receiver? true
@@ -43,17 +43,17 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {"1" (money/bignumber "1")
"2" (money/bignumber "1")}]
expected {1 (money/bignumber "1")
10 (money/bignumber "1")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value)))))
(testing
"Correctly calculates network amounts for transaction with native token and multiple routes to same chain-id"
(let [route [{:amount-in "0xde0b6b3a7640000"
:to {:chain-id "1"}}
:to {:chain-id 1}}
{:amount-in "0xde0b6b3a7640000"
:to {:chain-id "1"}}]
:to {:chain-id 1}}]
token-decimals 18
native-token? true
receiver? true
@@ -61,15 +61,15 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {"1" (money/bignumber "2")}]
expected {1 (money/bignumber "2")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value)))))
(testing "Correctly calculates network amounts for transaction with non-native token"
(let [route [{:amount-out "0x1e8480"
:from {:chain-id "1"}}
:from {:chain-id 1}}
{:amount-out "0x1e8480"
:from {:chain-id "2"}}]
:from {:chain-id 10}}]
token-decimals 6
native-token? false
receiver? false
@@ -77,20 +77,20 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {"1" (money/bignumber "2")
"2" (money/bignumber "2")}]
expected {1 (money/bignumber "2")
10 (money/bignumber "2")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value))))))
(deftest test-network-values-for-ui
(testing "Sanitizes values correctly for display"
(let [amounts {"1" (money/bignumber "0")
"2" (money/bignumber "2.5")
"3" (money/bignumber "0.005")}
(let [amounts {1 (money/bignumber "0")
10 (money/bignumber "2.5")
42161 (money/bignumber "0.005")}
result (utils/network-values-for-ui amounts)
expected {"1" "<0.01"
"2" (money/bignumber "2.5")
"3" (money/bignumber "0.005")}]
expected {1 "<0.01"
10 (money/bignumber "2.5")
42161 (money/bignumber "0.005")}]
(doseq [[chain-id exp-value] expected]
(is #(or (= (get result chain-id) exp-value)
(money/equal-to (get result chain-id) exp-value)))))))
@@ -168,32 +168,32 @@
(deftest test-token-available-networks-for-suggested-routes
(testing "Excludes disabled chain-ids correctly"
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
disabled-chain-ids ["10"]
expected ["1" "42161"]]
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
disabled-chain-ids [10]
expected [1 42161]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
disabled-chain-ids})))))
(testing "Returns all chains when no disabled chains are specified"
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
disabled-chain-ids []
expected ["1" "10" "42161"]]
expected [1 10 42161]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
disabled-chain-ids})))))
(testing "Returns empty list when all chains are disabled"
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
disabled-chain-ids ["1" "10" "42161"]
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
disabled-chain-ids [1 10 42161]
expected []]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
@@ -201,9 +201,9 @@
disabled-chain-ids})))))
(testing "Handles non-existent chain-ids gracefully"
(let [balances-per-chain {"59144" {:chain-id "59144" :balance 400}}
disabled-chain-ids ["1" "10" "42161"]
expected ["59144"]]
(let [balances-per-chain {59144 {:chain-id 59144 :balance 400}}
disabled-chain-ids [1 10 42161]
expected [59144]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
@@ -211,10 +211,10 @@
(deftest test-reset-network-amounts-to-zero
(testing "Correctly resets loading network amounts to zero and changes type to default"
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}]
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -222,10 +222,10 @@
(is (every? identity comparisons))))
(testing "Leaves non-loading types unchanged"
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id "1" :total-amount (money/bignumber "100") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :disabled}]
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :disabled}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -242,10 +242,10 @@
(is (every? identity comparisons))))
(testing "Applies transformations to multiple loading entries"
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :loading}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :default}]
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :loading}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :default}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -253,14 +253,14 @@
(is (every? identity comparisons))))
(testing "Mix of loading and non-loading types"
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}
{:chain-id "42161" :total-amount (money/bignumber "300") :type :loading}
{:chain-id "59144" :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}
{:chain-id "42161" :total-amount (money/bignumber "0") :type :default}
{:chain-id "59144" :total-amount (money/bignumber "0") :type :disabled}]
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}
{:chain-id 42161 :total-amount (money/bignumber "300") :type :loading}
{:chain-id 59144 :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}
{:chain-id 42161 :total-amount (money/bignumber "0") :type :default}
{:chain-id 59144 :total-amount (money/bignumber "0") :type :disabled}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -269,42 +269,46 @@
(deftest test-network-amounts
(testing "Handles disabled and receiver networks correctly when receiver? is true"
(let [network-values {"1" (money/bignumber "100")
"10" (money/bignumber "200")}
disabled-chain-ids ["1"]
receiver-networks ["10"]
token-networks-ids ["1" "10" "42161"]
(let [network-values {1 (money/bignumber "100")
10 (money/bignumber "200")}
disabled-chain-ids [1]
receiver-networks [10]
token-networks-ids [1 10 42161]
receiver? true
expected [{:chain-id "1"
expected [{:chain-id 1
:total-amount (money/bignumber "100")
:type :default}
{:chain-id "10"
{:chain-id 10
:total-amount (money/bignumber "200")
:type :default}
{:type :add}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Adds default amount for non-disabled non-receiver networks when receiver? is false"
(let [network-values {"1" (money/bignumber "100")}
disabled-chain-ids ["10"]
(let [network-values {1 (money/bignumber "100")}
disabled-chain-ids [10]
receiver-networks []
token-networks-ids ["1" "10" "42161"]
token-networks-ids [1 10 42161]
receiver? false
expected [{:chain-id "1"
expected [{:chain-id 1
:total-amount (money/bignumber "100")
:type :default}
{:chain-id "10"
{:chain-id 10
:total-amount (money/bignumber "0")
:type :disabled}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
@@ -315,90 +319,139 @@
token-networks-ids []
receiver? true
expected []
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (= expected result))))
(testing "Processes case with multiple network interactions"
(let [network-values {"1" (money/bignumber "300")
"10" (money/bignumber "400")
"42161" (money/bignumber "500")}
disabled-chain-ids ["1" "42161"]
receiver-networks ["10"]
token-networks-ids ["1" "10" "42161"]
(let [network-values {1 (money/bignumber "300")
10 (money/bignumber "400")
42161 (money/bignumber "500")}
disabled-chain-ids [1 42161]
receiver-networks [10]
token-networks-ids [1 10 42161]
receiver? true
expected [{:chain-id "1"
expected [{:chain-id 1
:total-amount (money/bignumber "300")
:type :default}
{:chain-id "10"
{:chain-id 10
:total-amount (money/bignumber "400")
:type :default}
{:chain-id "42161"
{:chain-id 42161
:total-amount (money/bignumber "500")
:type :default}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Does not assign :not-available type when receiver? is false"
(let [network-values {"1" (money/bignumber "100")}
disabled-chain-ids ["10"]
receiver-networks ["1"]
token-networks-ids ["1" "10"]
(let [network-values {1 (money/bignumber "100")}
disabled-chain-ids [10]
receiver-networks [1]
token-networks-ids [1 10]
receiver? false
expected [{:chain-id "1"
expected [{:chain-id 1
:total-amount (money/bignumber "100")
:type :default}
{:chain-id "10"
{:chain-id 10
:total-amount (money/bignumber "0")
:type :disabled}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is true"
(let [network-values {"1" (money/bignumber "100")}
(let [network-values {1 (money/bignumber "100")}
disabled-chain-ids []
receiver-networks ["1" "10"]
token-networks-ids ["1"]
receiver-networks [1 10]
token-networks-ids [1]
receiver? false
expected [{:chain-id "1"
expected [{:chain-id 1
:total-amount (money/bignumber "100")
:type :default}
{:chain-id "10"
{:chain-id 10
:total-amount nil
:type :not-available}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Handles disabled and receiver networks correctly when to? is false and tx-type is :tx/bridge"
(let [network-values {10 (money/bignumber "200")}
disabled-chain-ids [1]
receiver-networks [10]
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? false
expected [{:chain-id 1
:total-amount (money/bignumber "0")
:type :disabled}
{:chain-id 10
:total-amount (money/bignumber "200")
:type :default}]
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Handles disabled and receiver networks correctly when to? is true and tx-type is :tx/bridge"
(let [network-values {10 (money/bignumber "200")}
disabled-chain-ids [1]
receiver-networks [10]
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? true
expected [{:chain-id 10
:total-amount (money/bignumber "200")
:type :default}]
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result))))))
(deftest test-loading-network-amounts
(testing "Assigns :loading type to valid networks except for disabled ones"
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["42161"]
receiver-networks ["1" "10"]
token-networks-ids ["1" "10" "42161"]
(let [valid-networks [1 10 42161]
disabled-chain-ids [42161]
receiver-networks [1 10]
token-networks-ids [1 10 42161]
receiver? true
expected [{:chain-id "1" :type :loading}
{:chain-id "10" :type :loading}
expected [{:chain-id 1 :type :loading}
{:chain-id 10 :type :loading}
{:type :add}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -406,18 +459,20 @@
(is (every? identity comparisons))))
(testing "Assigns :disabled type with zero total-amount to disabled networks when receiver? is false"
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["10" "42161"]
receiver-networks ["1"]
token-networks-ids ["1" "10" "42161"]
(let [valid-networks [1 10 42161]
disabled-chain-ids [10 42161]
receiver-networks [1]
token-networks-ids [1 10 42161]
receiver? false
expected [{:chain-id "1" :type :loading}
{:chain-id "10" :type :disabled :total-amount (money/bignumber "0")}
{:chain-id "42161" :type :disabled :total-amount (money/bignumber "0")}]
expected [{:chain-id 1 :type :loading}
{:chain-id 10 :type :disabled :total-amount (money/bignumber "0")}
{:chain-id 42161 :type :disabled :total-amount (money/bignumber "0")}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -425,17 +480,19 @@
(is (every? identity comparisons))))
(testing "Filters out networks not in receiver networks when receiver? is true"
(let [valid-networks ["1" "10" "42161" "59144"]
disabled-chain-ids ["10"]
receiver-networks ["1" "42161"]
token-networks-ids ["1" "10" "42161"]
(let [valid-networks [1 10 42161 59144]
disabled-chain-ids [10]
receiver-networks [1 42161]
token-networks-ids [1 10 42161]
receiver? true
expected [{:chain-id "1" :type :loading}
{:chain-id "42161" :type :loading}]
expected [{:chain-id 1 :type :loading}
{:chain-id 42161 :type :loading}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -444,17 +501,19 @@
(testing
"Appends :add type if receiver network count is less than available networks and receiver? is true"
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["10"]
receiver-networks ["1"]
token-networks-ids ["1" "10" "42161"]
(let [valid-networks [1 10 42161]
disabled-chain-ids [10]
receiver-networks [1]
token-networks-ids [1 10 42161]
receiver? true
expected [{:chain-id "1" :type :loading}
expected [{:chain-id 1 :type :loading}
{:type :add}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -463,16 +522,18 @@
(testing
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is false"
(let [valid-networks ["42161"]
(let [valid-networks [42161]
disabled-chain-ids []
receiver-networks ["1"]
token-networks-ids ["42161"]
receiver-networks [1]
token-networks-ids [42161]
receiver? false
expected [{:chain-id "42161" :type :loading}]
expected [{:chain-id 42161 :type :loading}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -481,17 +542,60 @@
(testing
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is true"
(let [valid-networks ["42161"]
(let [valid-networks [42161]
disabled-chain-ids []
receiver-networks ["1"]
token-networks-ids ["42161"]
receiver-networks [1]
token-networks-ids [42161]
receiver? true
expected [{:chain-id "1" :type :not-available}
expected [{:chain-id 1 :type :not-available}
{:type :add}]
tx-type :send
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
result)]
(is (every? identity comparisons))))
(testing
"Assigns :loading type to valid networks and :disabled for disabled ones when tx-type is :tx/bridge and to? false"
(let [valid-networks [1 10]
disabled-chain-ids [10]
receiver-networks []
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? false
expected [{:chain-id 1 :type :loading}
{:chain-id 10 :type :disabled :total-amount (money/bignumber "0")}]
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
result)]
(is (every? identity comparisons))))
(testing
"Assigns :loading type to valid networks, ignore disabled ones and do not add {:type :add} when tx-type is :tx/bridge and to? true"
(let [valid-networks [1]
disabled-chain-ids [10]
receiver-networks []
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? true
expected [{:chain-id 1 :type :loading}]
result (utils/loading-network-amounts {:valid-networks valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -500,22 +604,22 @@
(deftest test-network-links
(testing "Calculates position differences correctly"
(let [route [{:from {:chain-id "1"} :to {:chain-id "42161"}}
{:from {:chain-id "10"} :to {:chain-id "1"}}
{:from {:chain-id "42161"} :to {:chain-id "10"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "42161"} {:chain-id "1"} {:chain-id "10"}]
expected [{:from-chain-id "1" :to-chain-id "42161" :position-diff 0}
{:from-chain-id "10" :to-chain-id "1" :position-diff 0}
{:from-chain-id "42161" :to-chain-id "10" :position-diff 0}]
(let [route [{:from {:chain-id 1} :to {:chain-id 42161}}
{:from {:chain-id 10} :to {:chain-id 1}}
{:from {:chain-id 42161} :to {:chain-id 10}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 42161} {:chain-id 1} {:chain-id 10}]
expected [{:from-chain-id 1 :to-chain-id 42161 :position-diff 0}
{:from-chain-id 10 :to-chain-id 1 :position-diff 0}
{:from-chain-id 42161 :to-chain-id 10 :position-diff 0}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result))))
(testing "Handles cases with no position difference"
(let [route [{:from {:chain-id "1"} :to {:chain-id "1"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
expected [{:from-chain-id "1" :to-chain-id "1" :position-diff 0}]
(let [route [{:from {:chain-id 1} :to {:chain-id 1}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
expected [{:from-chain-id 1 :to-chain-id 1 :position-diff 0}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result))))
@@ -528,9 +632,9 @@
(is (= expected result))))
(testing "Verifies negative position differences"
(let [route [{:from {:chain-id "1"} :to {:chain-id "42161"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
expected [{:from-chain-id "1" :to-chain-id "42161" :position-diff -2}]
(let [route [{:from {:chain-id 1} :to {:chain-id 42161}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
expected [{:from-chain-id 1 :to-chain-id 42161 :position-diff -2}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result)))))
+10 -4
View File
@@ -57,6 +57,8 @@
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
[status-im.contexts.profile.settings.view :as settings]
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as
encrypted-key-pair-qr]
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
@@ -85,8 +87,8 @@
wallet-key-pair-name]
[status-im.contexts.wallet.add-account.create-account.new-keypair.backup-recovery-phrase.view :as
wallet-backup-recovery-phrase]
[status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.view :as
wallet-check-your-backup]
[status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.view :as
wallet-confirm-backup]
[status-im.contexts.wallet.add-account.create-account.select-keypair.view :as wallet-select-keypair]
[status-im.contexts.wallet.add-account.create-account.view :as wallet-create-account]
[status-im.contexts.wallet.bridge.bridge-to.view :as wallet-bridge-to]
@@ -430,9 +432,9 @@
:options {:insets {:top? true :bottom? true}}
:component wallet-backup-recovery-phrase/view}
{:name :screen/wallet.check-your-backup
{:name :screen/wallet.confirm-backup
:options {:insets {:top? true :bottom? true}}
:component wallet-check-your-backup/view}
:component wallet-confirm-backup/view}
{:name :screen/wallet.keypair-name
:options {:insets {:top? true}}
@@ -509,6 +511,10 @@
:options (assoc options/dark-screen :sheet? true)
:component keypair-rename/view}
{:name :screen/settings.encrypted-key-pair-qr
:options options/transparent-screen-options
:component encrypted-key-pair-qr/view}
{:name :screen/settings.saved-addresses
:options options/transparent-modal-screen-options
:component saved-addresses-settings/view}
+25 -17
View File
@@ -169,23 +169,31 @@
:chats/current-chat-chat-view
:<- [:chats/current-chat]
(fn [current-chat]
(select-keys current-chat
[:chat-id
:able-to-send-message?
:group-chat
:admins
:invitation-admin
:public?
:chat-type
:color
:contact-request-state
:chat-name
:synced-to
:synced-from
:community-id
:emoji
:description
:last-message])))
(assoc
(select-keys current-chat
[:chat-id
:able-to-send-message?
:group-chat
:admins
:invitation-admin
:public?
:chat-type
:color
:contact-request-state
:chat-name
:synced-to
:synced-from
:community-id
:emoji
:description])
:empty-chat?
(not (:last-message current-chat)))))
(re-frame/reg-sub
:chats/current-chat-exist?
:<- [:chats/current-chat-chat-view]
(fn [current-chat]
(boolean (:chat-id current-chat))))
(re-frame/reg-sub
:chats/current-chat-color
+15
View File
@@ -192,3 +192,18 @@
chats)
(let [result (rf/sub [sub-name chat-id])]
(= image-data result)))))
(h/deftest-sub :chats/current-chat-exist?
[sub-name]
(testing "current chat without chat-id"
(let [chats {chat-id (dissoc one-to-one-chat :chat-id)}]
(swap! rf-db/app-db assoc
:chats chats
:current-chat-id chat-id)
(is (false? (rf/sub [sub-name])))))
(testing "current chat with chat-id"
(let [chats {chat-id one-to-one-chat}]
(swap! rf-db/app-db assoc
:chats chats
:current-chat-id chat-id)
(is (true? (rf/sub [sub-name]))))))
+6
View File
@@ -28,3 +28,9 @@
:<- [:syncing]
(fn [syncing]
(:pairing-status syncing)))
(re-frame/reg-sub
:pairing/has-paired-devices
:<- [:pairing/enabled-installations]
(fn [installations]
(> (count installations) 1)))
+6 -6
View File
@@ -21,7 +21,7 @@
:chain-id 4
:layer 2}
{:test? true
:short-name "opt"
:short-name "oeth"
:related-chain-id 10
:chain-id 5
:layer 2}]
@@ -34,7 +34,7 @@
:chain-id 42161
:layer 2}
{:test? false
:short-name "opt"
:short-name "oeth"
:chain-id 10
:layer 2}]})
@@ -54,8 +54,8 @@
:chain-id 42161
:layer 2}
{:network-name :optimism
:short-name "opt"
:abbreviated-name "Opt."
:short-name "oeth"
:abbreviated-name "Oeth."
:chain-id 10
:layer 2}]
(map #(dissoc % :source :related-chain-id) (rf/sub [sub-name]))))))
@@ -77,8 +77,8 @@
:chain-id 42161
:layer 2}
:optimism {:network-name :optimism
:short-name "opt"
:abbreviated-name "Opt."
:short-name "oeth"
:abbreviated-name "Oeth."
:chain-id 10
:layer 2}}
(rf/sub [sub-name])))))
+5
View File
@@ -24,6 +24,11 @@
:<- [:wallet/wallet-send]
:-> :transaction-ids)
(rf/reg-sub
:wallet/wallet-send-amount
:<- [:wallet/wallet-send]
:-> :amount)
(rf/reg-sub
:wallet/send-transaction-progress
:<- [:wallet/send-transaction-ids]
+21 -3
View File
@@ -290,11 +290,13 @@
:wallet/current-viewing-account-tokens-filtered
:<- [:wallet/current-viewing-account]
:<- [:wallet/network-details]
(fn [[account networks] [_ query]]
(fn [[account networks] [_ query chain-ids]]
(let [tokens (map (fn [token]
(assoc token
:networks (network-utils/network-list token networks)
:total-balance (utils/calculate-total-token-balance token)))
:networks (network-utils/network-list token networks)
:available-balance (utils/calculate-total-token-balance token)
:total-balance (utils/calculate-total-token-balance token
chain-ids)))
(:tokens account))
sorted-tokens (sort-by :name compare tokens)]
(if query
@@ -452,3 +454,19 @@
:wallet/public-address
:<- [:wallet/create-account]
:-> :public-address)
(rf/reg-sub
:wallet/wallet-send-enabled-networks
:<- [:wallet/wallet-send-token]
:<- [:wallet/wallet-send-disabled-from-chain-ids]
(fn [[{:keys [networks]} disabled-from-chain-ids]]
(->> networks
(filter #(not (contains? (set disabled-from-chain-ids)
(:chain-id %))))
set)))
(rf/reg-sub
:wallet/wallet-send-enabled-from-chain-ids
:<- [:wallet/wallet-send-enabled-networks]
(fn [send-enabled-networks]
(map :chain-id send-enabled-networks)))
+5 -5
View File
@@ -163,7 +163,7 @@
:related-chain-id 42161
:layer 2}
{:test? true
:short-name "opt"
:short-name "oeth"
:related-chain-id 10
:layer 2}]
:prod [{:test? false
@@ -175,7 +175,7 @@
:chain-id 42161
:layer 2}
{:test? false
:short-name "opt"
:short-name "oeth"
:chain-id 10
:layer 2}]})
@@ -477,9 +477,9 @@
:chain-id 42161
:related-chain-id nil
:layer 2}
{:short-name "opt"
{:short-name "oeth"
:network-name :optimism
:abbreviated-name "Opt."
:abbreviated-name "Oeth."
:chain-id 10
:related-chain-id nil
:layer 2}]
@@ -625,7 +625,7 @@
address
emoji]} wallet-account
network-options [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "opt"}
{:network-name :optimism :short-name "oeth"}
{:network-name :arbitrum :short-name "arb1"}]
size-option 20]
(is
+12 -1
View File
@@ -1,4 +1,5 @@
(ns utils.number)
(ns utils.number
(:require [clojure.string :as string]))
(defn naive-round
"Quickly and naively round number `n` up to `decimal-places`.
@@ -29,3 +30,13 @@
if `num` exceeds a given bound, then returns the bound exceeded."
[number lower-bound upper-bound]
(max lower-bound (min number upper-bound)))
(defn remove-trailing-zeroes
[num]
(let [parts (string/split (str num) #"\.")]
(str (first parts)
(if-let [decimals (second parts)]
(if (seq (string/replace decimals #"0+$" ""))
(str "." (string/replace decimals #"0+$" ""))
"")
""))))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.179.17",
"commit-sha1": "0dbbf7c641691b3b5b6f4eb241d133aa7d42bf82",
"src-sha256": "0fp6zwb35pwmgb88xyqilw5dj8007cq9m186s915glnf94a45b7x"
"version": "v0.179.19",
"commit-sha1": "3103c298015483cb4d1ee90c8f432fcefe21927d",
"src-sha256": "0ks0ks1fxfn1vdnl5j1pygvyv8gbiixihxrc1ac39yi5q61hwccb"
}
+8 -2
View File
@@ -524,6 +524,8 @@
"enable": "Enable",
"enable-notifications-sub-title": "Receive notifications about your new messages or wallet transactions",
"encrypt-with-password": "Encrypt with password",
"encrypted-key-pairs": "Encrypted key pairs",
"encrypted-key-pairs-code": "Encrypted key pairs code",
"ending-not-allowed": "{{ending}} ending is not allowed",
"ends-with-space": "Cannot end with space",
"ens-10-SNT": "10 SNT",
@@ -939,6 +941,7 @@
"main-wallet": "Main Wallet",
"make-admin": "Make admin",
"make-moderator": "Make moderator",
"make-sure-no-camera-warning": "Make sure no camera or person can see this screen before revealing",
"manage-keys-and-storage": "Manage keys and storage",
"mark-as-read": "Mark as read",
"mark-all-read": "Mark all read",
@@ -1272,6 +1275,7 @@
"reset-card-description": "This operation will reset card to initial state. It will erase all card data including private keys. Operation is not reversible.",
"retry": "Retry",
"reveal-sync-code": "Reveal sync code",
"reveal-qr-code": "Reveal QR code",
"revoke-access": "Revoke access",
"save": "Save",
"save-address": "Save address",
@@ -1337,6 +1341,7 @@
"show-more": "Show more",
"show-qr": "Show QR code",
"show-transaction-data": "Show transaction data",
"show-encrypted-qr-of-key-pairs": "Show encrypted QR of key pairs on device",
"sign-and-send": "Sign and send",
"sign-in": "Sign in",
"sign-message": "Sign Message",
@@ -1970,6 +1975,7 @@
"slide-to-request-to-join": "Slide to request to join",
"slide-to-reveal-code": "Slide to reveal code",
"slide-to-create-account": "Slide to create account",
"slide-to-reveal-qr-code": "Slide to reveal QR code",
"minimum-received": "Minimum received",
"powered-by-paraswap": "Powered by Paraswap",
"priority": "Priority",
@@ -2447,7 +2453,7 @@
"opensea": "OpenSea",
"mainnet": "Mainnet",
"view-on-eth": "View on Etherscan",
"view-on-opt": "View on Optimism Explorer",
"view-on-oeth": "View on Optimism Explorer",
"view-on-arb": "View on Arbiscan",
"copy-address": "Copy address",
"show-address-qr": "Show address QR",
@@ -2557,7 +2563,7 @@
"watched-account-removed": "Watched address has been removed",
"account-removed": "Account has been removed",
"share-address-title": "{{address}} address",
"check-your-backup": "Check your backup",
"confirm-backup": "Confirm backup",
"confirm-the-position": "Confirm the position of certain words in your recovery phrase",
"do-not-cheat": "Don't try to cheat",
"do-not-cheat-description": "These 12 words give access to all of your funds so it is important that you write them in the correct order, take it seriously.",
+4 -4
View File
@@ -9281,10 +9281,10 @@ react-native-lottie-splash-screen@^1.0.1:
lottie-ios "3.2.3"
lottie-react-native "^5.1.3"
react-native-navigation@7.38.3:
version "7.38.3"
resolved "https://registry.yarnpkg.com/react-native-navigation/-/react-native-navigation-7.38.3.tgz#ce1715bcf51a37296792e8f39ae8d1a4da3593a7"
integrity sha512-KCelGUYcUe+UreiEofjG6lBf6ie9+1xvFr77+GbTVCPCsO2GkBOuy8R/B3eoZvobLhalcLMHzka/bN9BLGUeeQ==
react-native-navigation@7.39.0:
version "7.39.0"
resolved "https://registry.yarnpkg.com/react-native-navigation/-/react-native-navigation-7.39.0.tgz#41655d5a822d53362dc1028e5d185d167f52f0bb"
integrity sha512-7xc4aGp3v/Eeh8MgIjApoZEE0GuefiMRQh/wpa43t1l1v5hqxzYV9J6dMd5XLzSbIYnJ1ZLd0gCHR5WQdE4O2Q==
dependencies:
hoist-non-react-statics "3.x.x"
lodash "4.17.x"