Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a9ad0ccea | ||
|
|
a8a08c82b0 | ||
|
|
aa28678188 | ||
|
|
67aa733736 |
@@ -215,13 +215,15 @@ build-fdroid: ##@build Build release for F-Droid
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
build-android: export BUILD_TYPE ?= nightly
|
||||
build-android: export ORG_GRADLE_PROJECT_versionCode ?= $(TMP_BUILD_NUMBER)
|
||||
build-android: export ANDROID_ABI_SPLIT ?= false
|
||||
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||
build-android: ##@build Build unsigned Android APK
|
||||
@scripts/build-android.sh
|
||||
|
||||
release-android: export TARGET := keytool
|
||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
release-android: keystore build-android ##@build Build signed Android APK
|
||||
@scripts/sign-android.sh result/app-arm64-v8a-release-unsigned.apk
|
||||
@scripts/sign-android.sh result/app-release-unsigned.apk
|
||||
|
||||
release-ios: export TARGET := ios
|
||||
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||
|
||||
@@ -211,7 +211,7 @@ android {
|
||||
reset()
|
||||
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
||||
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||
universalApk false
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
|
||||
@@ -38,10 +38,10 @@ KEYSTORE_PASSWORD=password
|
||||
KEYSTORE_ALIAS=status
|
||||
KEYSTORE_KEY_PASSWORD=password
|
||||
|
||||
# Splitting by CPU Architecture produces smaller APKs.
|
||||
ANDROID_ABI_SPLIT=true
|
||||
# By default its better to only build apk for most recent devices.
|
||||
ANDROID_ABI_INCLUDE=arm64-v8a
|
||||
# By default we build a mostly universal APK
|
||||
ANDROID_ABI_SPLIT=false
|
||||
# Some platforms are excluded though
|
||||
ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86;x86_64
|
||||
|
||||
org.gradle.jvmargs=-Xmx8704M -XX:+UseParallelGC
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -72,7 +72,11 @@ pipeline {
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
def urls = apks.collect { s5cmd.upload(it) }
|
||||
env.PKG_URL = urls.first()
|
||||
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||
env.PKG_URL = urls.find { it.contains('universal') }
|
||||
} else { /* If no universal is available pick first. */
|
||||
env.PKG_URL = urls.first()
|
||||
}
|
||||
jenkins.setBuildDesc(APK: env.PKG_URL)
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
buildUrl ? lib.getEnvWithDefault "ORG_GRADLE_PROJECT_buildUrl" null,
|
||||
statusGoSrcOverride ? lib.getEnvWithDefault "STATUS_GO_SRC_OVERRIDE" null,
|
||||
# If APKs should be split based on architectures
|
||||
androidAbiSplit ? lib.getEnvWithDefault "ANDROID_ABI_SPLIT" "true",
|
||||
androidAbiSplit ? lib.getEnvWithDefault "ANDROID_ABI_SPLIT" "false",
|
||||
# Android architectures to build for
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude ? lib.getEnvWithDefault "ANDROID_ABI_INCLUDE" "arm64-v8a",
|
||||
androidAbiInclude ? lib.getEnvWithDefault "ANDROID_ABI_INCLUDE" "armeabi-v7a;arm64-v8a;x86",
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 424 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 752 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 547 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB |
@@ -13,7 +13,7 @@ export BUILD_TYPE=debug
|
||||
|
||||
# Install the APK on running emulator or android device.
|
||||
installAndLaunchApp() {
|
||||
adb install -r ./result/app-arm64-v8a-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1
|
||||
adb install -r ./result/app-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1
|
||||
"${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1
|
||||
# connected android devices need this port to be exposed for metro
|
||||
adb reverse "tcp:${RCT_METRO_PORT}" "tcp:${RCT_METRO_PORT}"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(ns legacy.status-im.data-store.communities
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[status-im.constants :as constants]
|
||||
[utils.transforms :as transforms]))
|
||||
[clojure.walk :as walk]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(defn <-revealed-accounts-rpc
|
||||
[accounts]
|
||||
@@ -22,26 +22,19 @@
|
||||
(reduce #(assoc %1 (key-fn %2) (<-request-to-join-community-rpc %2)) {} requests))
|
||||
|
||||
(defn <-chats-rpc
|
||||
"This transformation from RPC is optimized differently because there can be
|
||||
thousands of members in all chats and we don't want to transform them from JS
|
||||
to CLJS because they will only be used to list community members or community
|
||||
chat members."
|
||||
[chats-js]
|
||||
(let [chat-key-fn (fn [k]
|
||||
(case k
|
||||
"tokenGated" :token-gated?
|
||||
"canPost" :can-post?
|
||||
"can-view" :can-view?
|
||||
"hideIfPermissionsNotMet" :hide-if-permissions-not-met?
|
||||
(keyword k)))
|
||||
chat-val-fn (fn [k v]
|
||||
(if (= "members" k)
|
||||
v
|
||||
(transforms/js->clj v)))]
|
||||
(transforms/<-js-map
|
||||
chats-js
|
||||
{:val-fn (fn [_ v]
|
||||
(transforms/<-js-map v {:key-fn chat-key-fn :val-fn chat-val-fn}))})))
|
||||
[chats]
|
||||
(reduce-kv (fn [acc k v]
|
||||
(assoc acc
|
||||
(name k)
|
||||
(-> v
|
||||
(assoc :token-gated? (:tokenGated v)
|
||||
:can-post? (:canPost v)
|
||||
:can-view? (:canView v)
|
||||
:hide-if-permissions-not-met? (:hideIfPermissionsNotMet v))
|
||||
(dissoc :canPost :tokenGated :canView :hideIfPermissionsNotMet)
|
||||
(update :members walk/stringify-keys))))
|
||||
{}
|
||||
chats))
|
||||
|
||||
(defn <-categories-rpc
|
||||
[categ]
|
||||
@@ -55,59 +48,49 @@
|
||||
[token-permission]
|
||||
(= (:type token-permission) constants/community-token-permission-become-member))
|
||||
|
||||
(defn- rename-community-key
|
||||
[k]
|
||||
(case k
|
||||
"canRequestAccess" :can-request-access?
|
||||
"canManageUsers" :can-manage-users?
|
||||
"canDeleteMessageForEveryone" :can-delete-message-for-everyone?
|
||||
;; This flag is misleading based on its name alone
|
||||
;; because it should not be used to decide if the user
|
||||
;; is *allowed* to join. Allowance is based on token
|
||||
;; permissions. Still, the flag can be used to know
|
||||
;; whether or not the user will have to wait until an
|
||||
;; admin approves a join request.
|
||||
"canJoin" :can-join?
|
||||
"requestedToJoinAt" :requested-to-join-at
|
||||
"isMember" :is-member?
|
||||
"outroMessage" :outro-message
|
||||
"adminSettings" :admin-settings
|
||||
"tokenPermissions" :token-permissions
|
||||
"communityTokensMetadata" :tokens-metadata
|
||||
"introMessage" :intro-message
|
||||
"muteTill" :muted-till
|
||||
"lastOpenedAt" :last-opened-at
|
||||
"joinedAt" :joined-at
|
||||
(keyword k)))
|
||||
|
||||
(defn <-rpc
|
||||
[c-js]
|
||||
(let [community (transforms/<-js-map
|
||||
c-js
|
||||
{:key-fn rename-community-key
|
||||
:val-fn (fn [k v]
|
||||
(case k
|
||||
"members" v
|
||||
"chats" (<-chats-rpc v)
|
||||
(transforms/js->clj v)))})]
|
||||
(-> community
|
||||
(update :admin-settings
|
||||
set/rename-keys
|
||||
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
|
||||
(update :token-permissions seq)
|
||||
(update :categories <-categories-rpc)
|
||||
(assoc :role-permissions?
|
||||
(->> community
|
||||
:tokenPermissions
|
||||
vals
|
||||
(some role-permission?)))
|
||||
(assoc :membership-permissions?
|
||||
(->> community
|
||||
:tokenPermissions
|
||||
vals
|
||||
(some membership-permission?)))
|
||||
(assoc :token-images
|
||||
(reduce (fn [acc {sym :symbol image :image}]
|
||||
(assoc acc sym image))
|
||||
{}
|
||||
(:communityTokensMetadata community))))))
|
||||
[c]
|
||||
(-> c
|
||||
(set/rename-keys
|
||||
{:canRequestAccess :can-request-access?
|
||||
:canManageUsers :can-manage-users?
|
||||
:canDeleteMessageForEveryone :can-delete-message-for-everyone?
|
||||
;; This flag is misleading based on its name alone
|
||||
;; because it should not be used to decide if the user
|
||||
;; is *allowed* to join. Allowance is based on token
|
||||
;; permissions. Still, the flag can be used to know
|
||||
;; whether or not the user will have to wait until an
|
||||
;; admin approves a join request.
|
||||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?
|
||||
:outroMessage :outro-message
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata
|
||||
:introMessage :intro-message
|
||||
:muteTill :muted-till
|
||||
:lastOpenedAt :last-opened-at
|
||||
:joinedAt :joined-at})
|
||||
(update :admin-settings
|
||||
set/rename-keys
|
||||
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
|
||||
(update :members walk/stringify-keys)
|
||||
(update :chats <-chats-rpc)
|
||||
(update :token-permissions seq)
|
||||
(update :categories <-categories-rpc)
|
||||
(assoc :role-permissions?
|
||||
(->> c
|
||||
:tokenPermissions
|
||||
vals
|
||||
(some role-permission?)))
|
||||
(assoc :membership-permissions?
|
||||
(->> c
|
||||
:tokenPermissions
|
||||
vals
|
||||
(some membership-permission?)))
|
||||
(assoc :token-images
|
||||
(reduce (fn [acc {sym :symbol image :image}]
|
||||
(assoc acc sym image))
|
||||
{}
|
||||
(:communityTokensMetadata c)))))
|
||||
|
||||
@@ -13,18 +13,15 @@
|
||||
(native-module/logout)))
|
||||
|
||||
(rf/defn initialize-app-db
|
||||
[{{:keys [keycard initials-avatar-font-file biometrics]
|
||||
:network/keys [type status]
|
||||
:wallet-connect/keys [web3-wallet]}
|
||||
[{{:keys [keycard initials-avatar-font-file biometrics]
|
||||
:network/keys [type]}
|
||||
:db}]
|
||||
{:db (assoc db/app-db
|
||||
:network/type type
|
||||
:network/status status
|
||||
:initials-avatar-font-file initials-avatar-font-file
|
||||
:keycard (dissoc keycard :secrets :pin :application-info)
|
||||
:biometrics biometrics
|
||||
:syncing nil
|
||||
:wallet-connect/web3-wallet web3-wallet)})
|
||||
:network/type type
|
||||
:initials-avatar-font-file initials-avatar-font-file
|
||||
:keycard (dissoc keycard :secrets :pin :application-info)
|
||||
:biometrics biometrics
|
||||
:syncing nil)})
|
||||
|
||||
(rf/defn logout-method
|
||||
{:events [::logout-method]}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as utils.platform]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[status-im.common.new-device-sheet.view :as new-device-sheet]
|
||||
[status-im.config :as config]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
@@ -220,6 +221,12 @@
|
||||
:name (:name metadata)
|
||||
:device-type (:deviceType metadata))})
|
||||
|
||||
|
||||
(defn should-show-syncing-pop-up?
|
||||
[db installations]
|
||||
(and (:syncing/pairing-process-initiated? db)
|
||||
(first (filter #(not (get-in db [:pairing/installations (:id %)])) installations))))
|
||||
|
||||
(rf/defn handle-installations
|
||||
[{:keys [db]} installations]
|
||||
{:db (update db
|
||||
@@ -228,7 +235,10 @@
|
||||
(fn [acc {:keys [id] :as i}]
|
||||
(update acc id merge (installation<-rpc i)))
|
||||
%
|
||||
installations))})
|
||||
installations))
|
||||
:fx [(when-let [new-installation (should-show-syncing-pop-up? db installations)]
|
||||
[:dispatch
|
||||
[:show-bottom-sheet {:content (fn [] [new-device-sheet/view (:id new-installation)])}]])]})
|
||||
|
||||
(rf/defn load-installations
|
||||
{:events [:pairing.callback/get-our-installations-success]}
|
||||
@@ -243,6 +253,24 @@
|
||||
{}
|
||||
installations))})
|
||||
|
||||
(rf/defn finish-seed-phrase-fallback-syncing
|
||||
{:events [:pairing/finish-seed-phrase-fallback-syncing]}
|
||||
[{:keys [db]}]
|
||||
{:fx [[:dispatch [:show-bottom-sheet {:content (fn [] [new-device-sheet/view-2])}]]
|
||||
[:json-rpc/call
|
||||
[{:method "wakuext_finishPairingThroughSeedPhraseProcess"
|
||||
:params [{:installationId (:syncing/installation-id db)}]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]]]})
|
||||
|
||||
(rf/defn pair-and-sync
|
||||
{:events [:pairing/pair-and-sync]}
|
||||
[cofx installation-id]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_enableAndSyncInstallation"
|
||||
:params [{:installationId installation-id}]
|
||||
:on-success #(log/debug "successfully synced devices")}]]]})
|
||||
|
||||
(rf/defn enable-installation-success
|
||||
{:events [:pairing.callback/enable-installation-success]}
|
||||
[cofx installation-id]
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[legacy.status-im.ui.components.list.views :as list]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf])
|
||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
@@ -21,6 +20,8 @@
|
||||
light-client-enabled?
|
||||
store-confirmations-enabled?
|
||||
current-fleet
|
||||
test-networks-enabled?
|
||||
is-goerli-enabled?
|
||||
peer-syncing-enabled?]}]
|
||||
(keep
|
||||
identity
|
||||
@@ -60,14 +61,14 @@
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :peers-stats])
|
||||
:chevron true}
|
||||
(when (ff/enabled? ::ff/settings.telemetry)
|
||||
{:size :small
|
||||
:title "Telemetry"
|
||||
:accessibility-label :telemetry-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press #(re-frame/dispatch [:profile.settings/toggle-telemetry])
|
||||
:accessory :switch
|
||||
:active telemetry-enabled?})
|
||||
{:size :small
|
||||
:title "Telemetry"
|
||||
:accessibility-label :telemetry-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:profile.settings/toggle-telemetry])
|
||||
:accessory :switch
|
||||
:active telemetry-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/light-client-enabled)
|
||||
:accessibility-label :light-client-enabled
|
||||
@@ -86,6 +87,22 @@
|
||||
[:wakuv2.ui/toggle-store-confirmations (not store-confirmations-enabled?)])
|
||||
:accessory :switch
|
||||
:active store-confirmations-enabled?}
|
||||
{:size :small
|
||||
:title "Testnet mode"
|
||||
:accessibility-label :test-networks-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:profile.settings/toggle-test-networks])
|
||||
:accessory :switch
|
||||
:active test-networks-enabled?}
|
||||
{:size :small
|
||||
:title "Enable Goerli as test network"
|
||||
:accessibility-label :enable-sepolia-as-test-network
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:profile.settings/toggle-goerli-test-network])
|
||||
:accessory :switch
|
||||
:active is-goerli-enabled?}
|
||||
{:size :small
|
||||
:title "Peer syncing"
|
||||
:accessibility-label :peer-syncing
|
||||
@@ -107,7 +124,9 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [light-client-enabled? [:profile/light-client-enabled?]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
is-goerli-enabled? [:profile/is-goerli-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
store-confirmations-enabled? [:profile/store-confirmations-enabled?]
|
||||
telemetry-enabled? [:profile/telemetry-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
@@ -128,6 +147,8 @@
|
||||
:store-confirmations-enabled? store-confirmations-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]]))
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
(when (and can-manage-users? (= constants/community-on-request-access (:access permissions)))
|
||||
[requests-to-join community-id])
|
||||
[rn/flat-list
|
||||
{:data sorted-members
|
||||
{:data (keys sorted-members)
|
||||
:render-data {:community-id community-id
|
||||
:my-public-key my-public-key
|
||||
:can-kick-users? (and can-manage-users?
|
||||
|
||||
@@ -332,9 +332,7 @@
|
||||
(defn set-blank-preview-flag
|
||||
[flag]
|
||||
(log/debug "[native-module] set-blank-preview-flag")
|
||||
;; Sometimes the app crashes during logout because `flag` is nil.
|
||||
(when flag
|
||||
(.setBlankPreviewFlag ^js (encryption) flag)))
|
||||
(.setBlankPreviewFlag ^js (encryption) flag))
|
||||
|
||||
(defn get-device-model-info
|
||||
[]
|
||||
|
||||
@@ -65,8 +65,9 @@
|
||||
:style (style/container loading? theme size)}
|
||||
[loading-view theme]]
|
||||
[linear-gradient/linear-gradient
|
||||
{:style (style/container loading? theme size)
|
||||
:colors (linear-gradient-props theme customization-color)}
|
||||
(assoc {:style (style/container loading? theme size)}
|
||||
:colors
|
||||
(linear-gradient-props theme customization-color))
|
||||
[rn/pressable
|
||||
{:accessibility-label :internal-link-card
|
||||
:on-press on-press}
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
|
||||
(def system-message-base-wrapper
|
||||
{:flex-direction :row
|
||||
:flex 1})
|
||||
:flex 1
|
||||
:align-items :center})
|
||||
|
||||
(def system-message-base-content-wrapper
|
||||
{:align-self :center
|
||||
|
||||
@@ -127,14 +127,6 @@
|
||||
(when incoming? [split-text "sent you a contact request" theme true])
|
||||
[sm-timestamp timestamp theme]]]))
|
||||
|
||||
(defn system-message-group
|
||||
[{:keys [customization-color child]}]
|
||||
[system-message-base
|
||||
{:icon {:icon :i/add-user
|
||||
:color (or customization-color :primary)
|
||||
:opacity 5}}
|
||||
[rn/view child]])
|
||||
|
||||
(defn system-message-pinned
|
||||
[{:keys [pinned-by child customization-color timestamp]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
@@ -191,7 +183,6 @@
|
||||
:contact-request [system-message-contact-request data]
|
||||
:added [system-message-added data]
|
||||
:removed [system-message-removed data]
|
||||
:group [system-message-group data]
|
||||
nil)]))
|
||||
|
||||
(defn system-message
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
(defn main
|
||||
[{:keys [type customization-color]} theme]
|
||||
{:justify-content :flex-start
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:height 32
|
||||
:padding-left 4
|
||||
@@ -16,7 +16,6 @@
|
||||
(defn label
|
||||
[type theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:flex-shrink 1
|
||||
:margin-left (if (= type :address) 6 4)})
|
||||
|
||||
(def collectible-image
|
||||
|
||||
@@ -58,19 +58,16 @@
|
||||
- :emoji - string - emoji used for displaying account avatar
|
||||
- :image-source - resource - image to display on :network, :collectible and :user
|
||||
- :theme - :light / :dark"
|
||||
[{:keys [label customization-color type container-style]
|
||||
[{:keys [label customization-color type]
|
||||
:as props
|
||||
:or {customization-color colors/neutral-80-opa-5}}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:accessibility-label :container
|
||||
:style (merge (style/main (assoc props :customization-color customization-color)
|
||||
theme)
|
||||
container-style)}
|
||||
:style (style/main (assoc props :customization-color customization-color) theme)}
|
||||
[left-view props]
|
||||
[text/text
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:number-of-lines 1
|
||||
:size :heading-1}
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:size :heading-1}
|
||||
label]]))
|
||||
|
||||
@@ -21,8 +21,3 @@
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(def text
|
||||
{:flex 1
|
||||
;; NOTE: assures the ellipses are not cut off when text is too long
|
||||
:padding-right 2})
|
||||
|
||||
@@ -59,9 +59,7 @@
|
||||
[rn/view {:style (merge style/container container-style)}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:number-of-lines 1
|
||||
:weight :semi-bold
|
||||
:style style/text
|
||||
:accessibility-label accessibility-label}
|
||||
title]
|
||||
(case right
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def account-colors
|
||||
[:blue :yellow :purple :turquoise :magenta :sky :orange :army :pink :camel :copper])
|
||||
[:blue :yellow :purple :turquoise :magenta :sky :orange :army :flamingo :camel :copper])
|
||||
|
||||
(defn alpha
|
||||
[value opacity]
|
||||
@@ -44,13 +44,6 @@
|
||||
(alpha light-color light-opacity)
|
||||
(alpha dark-color dark-opacity))))))
|
||||
|
||||
(defn valid-color?
|
||||
[color]
|
||||
(or (keyword? color)
|
||||
(and (string? color)
|
||||
(or (string/starts-with? color "#")
|
||||
(string/starts-with? color "rgb")))))
|
||||
|
||||
|
||||
;;;;Neutral
|
||||
|
||||
@@ -246,7 +239,7 @@
|
||||
60 "#CC6438"}
|
||||
:army {50 "#216266"
|
||||
60 "#1A4E52"}
|
||||
:pink {50 "#F66F8F"
|
||||
:flamingo {50 "#F66F8F"
|
||||
60 "#C55972"}
|
||||
:purple {50 "#7140FD"
|
||||
60 "#5A33CA"}
|
||||
@@ -323,14 +316,13 @@
|
||||
[s]
|
||||
(and (string? s) (string/starts-with? s "#")))
|
||||
|
||||
(def fallback-color (customization :blue))
|
||||
|
||||
(defn- get-from-colors-map
|
||||
[color suffix]
|
||||
(let [color-without-suffix (get colors-map color fallback-color)]
|
||||
(if (hex-string? color-without-suffix)
|
||||
(let [color-without-suffix (get colors-map color)
|
||||
resolved-color? (hex-string? color-without-suffix)]
|
||||
(if resolved-color?
|
||||
color-without-suffix
|
||||
(get color-without-suffix suffix))))
|
||||
(get-in colors-map [color suffix]))))
|
||||
|
||||
(defn- resolve-color*
|
||||
([color theme]
|
||||
@@ -364,15 +356,11 @@
|
||||
([color suffix]
|
||||
(custom-color color suffix nil))
|
||||
([color suffix opacity]
|
||||
(let [resolved-color (cond
|
||||
(not (keyword? color))
|
||||
color
|
||||
|
||||
(hex-string? (get colors-map color))
|
||||
(get colors-map color fallback-color)
|
||||
|
||||
:else
|
||||
(get-in colors-map [color suffix] (get fallback-color suffix)))]
|
||||
(let [hex? (not (keyword? color))
|
||||
resolved-color (cond hex? color
|
||||
(hex-string? (get colors-map color)) (get colors-map color)
|
||||
:else (get-in colors-map
|
||||
[color suffix]))]
|
||||
(if opacity
|
||||
(alpha resolved-color (/ opacity 100))
|
||||
resolved-color))))))
|
||||
|
||||
@@ -4,37 +4,11 @@
|
||||
[oops.core :as oops]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- add-keyboard-listener
|
||||
[listener callback]
|
||||
(oops/ocall rn/keyboard "addListener" listener callback))
|
||||
|
||||
(defn use-keyboard
|
||||
[]
|
||||
(let [[keyboard-height set-keyboard-height] (rn/use-state 0)
|
||||
[did-show? set-did-show] (rn/use-state false)
|
||||
[will-show? set-will-show] (rn/use-state false)]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [will-show-listener (add-keyboard-listener "keyboardWillShow" #(set-will-show true))
|
||||
did-show-listener (add-keyboard-listener "keyboardDidShow"
|
||||
(fn [e]
|
||||
(set-did-show true)
|
||||
(set-keyboard-height
|
||||
(oops/oget e "endCoordinates.height"))))
|
||||
will-hide-listener (add-keyboard-listener "keyboardWillHide" #(set-will-show false))
|
||||
did-hide-listener (add-keyboard-listener "keyboardDidHide"
|
||||
(fn [e]
|
||||
(set-did-show false)
|
||||
(when e
|
||||
(oops/oget e "endCoordinates.height"))))]
|
||||
(fn []
|
||||
(oops/ocall will-show-listener "remove")
|
||||
(oops/ocall did-show-listener "remove")
|
||||
(oops/ocall will-hide-listener "remove")
|
||||
(oops/ocall did-hide-listener "remove")))))
|
||||
{:keyboard-shown did-show?
|
||||
:keyboard-will-show? will-show?
|
||||
:keyboard-height keyboard-height}))
|
||||
(let [kb (.useKeyboard hooks)]
|
||||
{:keyboard-shown (.-keyboardShown ^js kb)
|
||||
:keyboard-height (.-keyboardHeight ^js kb)}))
|
||||
|
||||
(defn use-back-handler
|
||||
[handler]
|
||||
|
||||
@@ -1,39 +1,6 @@
|
||||
(ns react-native.linear-gradient
|
||||
(:require
|
||||
["react-native-linear-gradient" :default LinearGradient]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[taoensso.timbre :as log]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def ^:private linear-gradient* (reagent/adapt-react-class LinearGradient))
|
||||
|
||||
(defn- split-valid-colors
|
||||
[acc idx color]
|
||||
(let [color? (colors/valid-color? color)]
|
||||
(cond-> acc
|
||||
:always (update :safe-colors conj (if color? color "transparent"))
|
||||
(not color?) (update :wrong-colors conj [idx color]))))
|
||||
|
||||
(defn- wrong-colors-str
|
||||
[colors]
|
||||
(reduce-kv (fn [s idx color]
|
||||
(str s "Index: " idx ", color: " (prn-str color)))
|
||||
"Invalid color values in vector passed to Linear Gradient:\n"
|
||||
colors))
|
||||
|
||||
(defn linear-gradient
|
||||
[props & children]
|
||||
(when ^boolean js/goog.DEBUG
|
||||
(assert (vector? (:colors props))))
|
||||
(let [{:keys [wrong-colors safe-colors]} (rn/use-memo
|
||||
(fn []
|
||||
(reduce-kv split-valid-colors
|
||||
{:safe-colors []
|
||||
:wrong-colors {}}
|
||||
(:colors props)))
|
||||
[(:colors props)])]
|
||||
(when (seq wrong-colors)
|
||||
(log/error (wrong-colors-str wrong-colors)))
|
||||
(into [linear-gradient* (assoc props :colors safe-colors)]
|
||||
children)))
|
||||
(def linear-gradient (reagent/adapt-react-class LinearGradient))
|
||||
|
||||
@@ -3,23 +3,21 @@
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn content-container
|
||||
[blur? keyboard-shown? {:keys [padding-vertical padding-horizontal]}]
|
||||
[blur? keyboard-shown?]
|
||||
(let [margin-bottom (if keyboard-shown? 0 (safe-area/get-bottom))]
|
||||
(cond-> {:margin-top :auto
|
||||
:overflow :hidden
|
||||
:margin-bottom margin-bottom
|
||||
:padding-vertical (or padding-vertical 12)
|
||||
:padding-horizontal (or padding-horizontal 20)}
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20}
|
||||
blur? (dissoc :padding-vertical :padding-horizontal))))
|
||||
|
||||
(defn blur-inner-container
|
||||
[{:keys [theme shell-overlay? padding-vertical padding-horizontal background-color]}]
|
||||
{:background-color (or background-color
|
||||
(colors/theme-colors
|
||||
colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme))
|
||||
:padding-vertical (or padding-vertical 12)
|
||||
:padding-horizontal (or padding-horizontal 20)})
|
||||
[theme shell-overlay?]
|
||||
{:background-color (colors/theme-colors colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme)
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20})
|
||||
|
||||
@@ -6,25 +6,20 @@
|
||||
[status-im.common.floating-button-page.floating-container.style :as style]))
|
||||
|
||||
(defn- blur-container
|
||||
[shell-overlay? blur-options child]
|
||||
[child shell-overlay?]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/blur
|
||||
(or blur-options
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent})
|
||||
[rn/view
|
||||
{:style (style/blur-inner-container (assoc
|
||||
blur-options
|
||||
:theme theme
|
||||
:shell-overlay? shell-overlay?))}
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}
|
||||
[rn/view {:style (style/blur-inner-container theme shell-overlay?)}
|
||||
child]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay? blur-options]} child]
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay?]} child]
|
||||
[rn/view
|
||||
{:style (style/content-container blur? keyboard-shown? blur-options)
|
||||
{:style (style/content-container blur? keyboard-shown?)
|
||||
:on-layout on-layout}
|
||||
(if blur?
|
||||
[blur-container shell-overlay? blur-options child]
|
||||
[blur-container child shell-overlay?]
|
||||
child)])
|
||||
|
||||
@@ -13,13 +13,3 @@
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn content-keyboard-avoiding-view
|
||||
[{:keys [top bottom]}]
|
||||
{:position :absolute
|
||||
:top top
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom bottom})
|
||||
|
||||
(def scroll-view-container {:flex 1})
|
||||
|
||||
@@ -30,15 +30,13 @@
|
||||
(reset! ratom height))))
|
||||
|
||||
(defn- init-keyboard-listeners
|
||||
[{:keys [on-did-show on-will-show scroll-view-ref]}]
|
||||
[{:keys [on-did-show scroll-view-ref]}]
|
||||
(let [keyboard-will-show? (reagent/atom false)
|
||||
keyboard-did-show? (reagent/atom false)
|
||||
add-listener (fn [listener callback]
|
||||
(oops/ocall rn/keyboard "addListener" listener callback))
|
||||
will-show-listener (add-listener "keyboardWillShow"
|
||||
(fn [e]
|
||||
(reset! keyboard-will-show? true)
|
||||
(when on-will-show (on-will-show e))))
|
||||
#(reset! keyboard-will-show? true))
|
||||
did-show-listener (add-listener "keyboardDidShow"
|
||||
(fn [e]
|
||||
(reset! keyboard-did-show? true)
|
||||
@@ -60,8 +58,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
||||
blur-options content-avoid-keyboard?]
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?]
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
@@ -72,34 +69,29 @@
|
||||
content-container-height (reagent/atom 0)
|
||||
content-scroll-y (reagent/atom 0)
|
||||
keyboard-height (reagent/atom 0)
|
||||
reset-keyboard-height #(reset! keyboard-height (oops/oget
|
||||
%
|
||||
"endCoordinates.height"))
|
||||
{:keys [keyboard-will-show?
|
||||
keyboard-did-show?
|
||||
remove-listeners]} (init-keyboard-listeners
|
||||
(cond-> {:scroll-view-ref scroll-view-ref}
|
||||
platform/ios?
|
||||
(assoc :on-will-show reset-keyboard-height)
|
||||
(not platform/ios?)
|
||||
(assoc :on-did-show reset-keyboard-height)))
|
||||
{:scroll-view-ref scroll-view-ref
|
||||
:on-did-show
|
||||
(fn [e]
|
||||
(reset! keyboard-height
|
||||
(oops/oget e "endCoordinates.height")))})
|
||||
set-header-height (set-height-on-layout header-height)
|
||||
set-content-container-height (set-height-on-layout content-container-height)
|
||||
set-footer-container-height (set-height-on-layout footer-container-height)
|
||||
set-content-y-scroll (fn [event]
|
||||
(reset! content-scroll-y
|
||||
(oops/oget event "nativeEvent.contentOffset.y")))
|
||||
bottom-safe-area (safe-area/get-bottom)]
|
||||
(oops/oget event "nativeEvent.contentOffset.y")))]
|
||||
(let [keyboard-shown? (if platform/ios? @keyboard-will-show? @keyboard-did-show?)
|
||||
footer-container-padding (+ footer-container-padding (rf/sub [:alert-banners/top-margin]))
|
||||
show-background? (show-background
|
||||
{:window-height window-height
|
||||
:footer-container-height @footer-container-height
|
||||
:keyboard-height @keyboard-height
|
||||
:content-scroll-y @content-scroll-y
|
||||
:content-container-height @content-container-height
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
show-background? (show-background {:window-height window-height
|
||||
:footer-container-height @footer-container-height
|
||||
:keyboard-height @keyboard-height
|
||||
:content-scroll-y @content-scroll-y
|
||||
:content-container-height @content-container-height
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
[:<>
|
||||
(when gradient-cover?
|
||||
[quo/gradient-cover {:customization-color customization-color}])
|
||||
@@ -108,28 +100,20 @@
|
||||
{:on-layout set-header-height
|
||||
:style header-container-style}
|
||||
header]
|
||||
[(if content-avoid-keyboard? rn/keyboard-avoiding-view rn/view)
|
||||
{:style
|
||||
(if content-avoid-keyboard?
|
||||
(style/content-keyboard-avoiding-view
|
||||
{:top @header-height
|
||||
:bottom (if keyboard-shown?
|
||||
@footer-container-height
|
||||
(+ bottom-safe-area @footer-container-height))})
|
||||
style/scroll-view-container)}
|
||||
[gesture/scroll-view
|
||||
{:ref set-scroll-ref
|
||||
:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:automatically-adjust-keyboard-insets true
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps keyboard-should-persist-taps}
|
||||
(into [rn/view
|
||||
{:style content-container-style
|
||||
:on-layout set-content-container-height}]
|
||||
children)]]
|
||||
[gesture/scroll-view
|
||||
{:ref set-scroll-ref
|
||||
:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1
|
||||
:padding-bottom (when @keyboard-did-show?
|
||||
@footer-container-height)}
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps keyboard-should-persist-taps}
|
||||
(into [rn/view
|
||||
{:style content-container-style
|
||||
:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/keyboard-avoiding-view
|
||||
:keyboard-vertical-offset (if platform/ios? footer-container-padding 0)
|
||||
@@ -137,9 +121,8 @@
|
||||
[floating-container/view
|
||||
{:on-layout set-footer-container-height
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:blur-options blur-options
|
||||
:shell-overlay? shell-overlay?
|
||||
:blur? show-background?}
|
||||
:blur? show-background?
|
||||
:shell-overlay? shell-overlay?}
|
||||
footer]]]])
|
||||
(finally
|
||||
(remove-listeners))))
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns status-im.common.new-device-sheet.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def heading
|
||||
{:padding-left 20
|
||||
:padding-bottom 8})
|
||||
|
||||
(def message
|
||||
{:padding-horizontal 20
|
||||
:padding-top 4})
|
||||
|
||||
(def warning
|
||||
{:margin-horizontal 20
|
||||
:margin-top 10})
|
||||
|
||||
(def drawer-container
|
||||
{:padding-horizontal 13
|
||||
:padding-top 16})
|
||||
|
||||
(def settings-subtext
|
||||
{:color colors/white-opa-70
|
||||
:align-self :center
|
||||
:margin-bottom 12})
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
(ns status-im.common.new-device-sheet.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im.common.new-device-sheet.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- dismiss-keyboard
|
||||
[]
|
||||
(rf/dispatch [:dismiss-keyboard]))
|
||||
|
||||
(defn- hide-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
(defn- pair-and-sync
|
||||
[installation-id]
|
||||
(rf/dispatch [:pairing/pair-and-sync installation-id])
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn view
|
||||
[installation-id]
|
||||
(dismiss-keyboard)
|
||||
[:<>
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-sheet-heading
|
||||
:style style/heading}
|
||||
(i18n/label :t/pair-new-device-and-sync)]
|
||||
[quo/text
|
||||
{:weight :regular
|
||||
:size :paragraph-1
|
||||
:accessibility-label :new-device-sheet-message
|
||||
:style style/message}
|
||||
(i18n/label :t/new-device-detected)]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-installation-id
|
||||
:style style/heading}
|
||||
installation-id]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:blur? true
|
||||
:container-style {:margin-top 12}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press hide-bottom-sheet}
|
||||
:button-one-label (i18n/label :t/pair-and-sync)
|
||||
:button-one-props {:on-press #(pair-and-sync installation-id)}}]])
|
||||
|
||||
(defn view-2
|
||||
[]
|
||||
(let [installation-id (rf/sub [:profile/installation-id])]
|
||||
(dismiss-keyboard)
|
||||
[:<>
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-sheet-heading
|
||||
:style style/heading}
|
||||
(i18n/label :t/pair-new-device-and-sync)]
|
||||
[quo/text
|
||||
{:weight :regular
|
||||
:size :paragraph-1
|
||||
:accessibility-label :new-device-sheet-message
|
||||
:style style/message}
|
||||
(i18n/label :t/check-new-device)]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:accessibility-label :new-device-installation-id
|
||||
:style style/heading}
|
||||
installation-id]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:blur? true
|
||||
:container-style {:margin-top 12}
|
||||
:button-one-label (i18n/label :t/close)
|
||||
:button-one-props {:type :grey
|
||||
:on-press hide-bottom-sheet}}]]))
|
||||
@@ -55,7 +55,7 @@
|
||||
{:dispatch (if user-in-sign-in-intro-screen?
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.syncing-progress-intro :screen/onboarding.sign-in-intro]]
|
||||
[:open-modal :screen/onboarding.syncing-progress])}
|
||||
[:navigate-to :screen/onboarding.syncing-progress])}
|
||||
|
||||
(and completed-pairing? sender?)
|
||||
{:dispatch [:syncing/clear-states]}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
(ns status-im.common.raw-data-block.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.raw-data-block.style :as style]))
|
||||
|
||||
(defn view
|
||||
[data]
|
||||
[gesture/scroll-view
|
||||
{:style style/container}
|
||||
[rn/scroll-view
|
||||
{:style style/container
|
||||
:content-container-style style/content}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/content
|
||||
:weight :code}
|
||||
data]])
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
:welcome-illustration (js/require "../resources/images/ui2/welcome_illustration.png")
|
||||
:notifications (js/require "../resources/images/ui2/notifications.png")
|
||||
:nfc-prompt (js/require "../resources/images/ui2/nfc-prompt.png")
|
||||
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")
|
||||
:syncing-devices (js/require "../resources/images/ui2/syncing_devices.png")
|
||||
:syncing-wrong (js/require "../resources/images/ui2/syncing_wrong.png")})
|
||||
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:angry-man
|
||||
|
||||
@@ -38,15 +38,6 @@
|
||||
"wallet"
|
||||
{:fx [[:dispatch [:wallet/signal-received event-js]]]}
|
||||
|
||||
"wallet.sign.transactions"
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-keycard
|
||||
{:on-complete #(rf/dispatch [:keycard/sign-hash %
|
||||
(first (transforms/js->clj event-js))])}]]]}
|
||||
|
||||
"wallet.suggested.routes"
|
||||
{:fx [[:dispatch [:wallet/handle-suggested-routes (transforms/js->clj event-js)]]]}
|
||||
|
||||
"envelope.sent"
|
||||
(messages.transport/update-envelopes-status
|
||||
cofx
|
||||
|
||||
@@ -3,35 +3,21 @@
|
||||
[schema.core :as schema]
|
||||
[status-im.common.standard-authentication.enter-password.view :as enter-password]
|
||||
[status-im.common.standard-authentication.events-schema :as events-schema]
|
||||
[status-im.contexts.keycard.pin.view :as keycard.pin]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-fx :effects.keycard/call-on-auth-success
|
||||
(fn [on-auth-success]
|
||||
(when on-auth-success (on-auth-success ""))))
|
||||
|
||||
(defn authorize
|
||||
[{:keys [db]} [{:keys [on-auth-success keycard-supported?] :as args}]]
|
||||
[{:keys [db]} [args]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
keycard? (get-in db [:profile/profile :keycard-pairing])]
|
||||
{:fx
|
||||
[(if keycard?
|
||||
(if keycard-supported?
|
||||
[:effects.keycard/call-on-auth-success on-auth-success]
|
||||
[:effects.utils/show-popup
|
||||
{:title "This feature is not supported yet "
|
||||
:content
|
||||
"Keycard support is limited to logging in
|
||||
and signing the sending transaction.
|
||||
Use Status Desktop to access all functions."}])
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||
:on-fail #(rf/dispatch [:standard-auth/authorize-with-password args])}])]}))
|
||||
{:fx [[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||
:on-fail (if keycard?
|
||||
#(rf/dispatch [:standard-auth/authorize-with-keycard args])
|
||||
#(rf/dispatch [:standard-auth/authorize-with-password args]))}]]}))
|
||||
|
||||
(schema/=> authorize events-schema/?authorize)
|
||||
(rf/reg-event-fx :standard-auth/authorize authorize)
|
||||
@@ -108,16 +94,6 @@
|
||||
:button-icon-left auth-button-icon-left
|
||||
:button-label auth-button-label}])))
|
||||
|
||||
(defn authorize-with-keycard
|
||||
[_ [{:keys [on-complete]}]]
|
||||
{:fx [[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:hide-on-background-press? false
|
||||
:on-close #(rf/dispatch [:standard-auth/reset-login-password])
|
||||
:content (fn []
|
||||
[keycard.pin/auth {:on-complete on-complete}])}]]]})
|
||||
(rf/reg-event-fx :standard-auth/authorize-with-keycard authorize-with-keycard)
|
||||
|
||||
(defn authorize-with-password
|
||||
[_ [{:keys [on-close theme blur?] :as args}]]
|
||||
{:fx [[:dispatch [:standard-auth/reset-login-password]]
|
||||
@@ -134,9 +110,7 @@
|
||||
(rf/reg-event-fx
|
||||
:standard-auth/reset-login-password
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(update :profile/login dissoc :password :error)
|
||||
(update :keycard dissoc :pin))}))
|
||||
{:db (update db :profile/login dissoc :password :error)}))
|
||||
|
||||
(rf/reg-fx
|
||||
:standard-auth/on-close
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
||||
auth-button-icon-left size blur? container-style disabled? dependencies keycard-supported?]
|
||||
auth-button-icon-left size blur? container-style disabled? dependencies]
|
||||
:or {container-style {:flex 1}}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
auth-method (rf/sub [:auth-method])
|
||||
@@ -21,7 +21,6 @@
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:keycard-supported? keycard-supported?
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
|
||||
@@ -291,7 +291,6 @@
|
||||
(def ^:const wallet-connect-session-delete-event "session_delete")
|
||||
(def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED")
|
||||
(def ^:const wallet-connect-user-disconnected-reason-key "USER_DISCONNECTED")
|
||||
(def ^:const wallet-connect-user-rejected-chains-error-key "USER_REJECTED_CHAINS")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
item])))))
|
||||
|
||||
(defn add-manage-members
|
||||
[{:keys [on-scroll]}]
|
||||
[{:keys [scroll-enabled? on-scroll]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])
|
||||
@@ -71,6 +71,7 @@
|
||||
(i18n/label (if admin? :t/manage-members :t/add-members))]
|
||||
[gesture/section-list
|
||||
{:key-fn :title
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/grouped-by-first-letter])
|
||||
|
||||
@@ -33,7 +33,3 @@
|
||||
(def drawer-message-container
|
||||
{:padding-top 4
|
||||
:padding-bottom 4})
|
||||
|
||||
(def group-member-mention
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
@@ -126,60 +126,14 @@
|
||||
:photo-path photo-path
|
||||
:incoming? (not= public-key from)}]))
|
||||
|
||||
(defn group-member
|
||||
[literal]
|
||||
(let [[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity literal])
|
||||
photo-path (rf/sub [:chats/photo-path literal])]
|
||||
[rn/view {:style style/group-member-mention}
|
||||
[quo/user-avatar
|
||||
{:full-name primary-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? false
|
||||
:size :xxxs
|
||||
:ring? false}]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:style {:margin-left 4}}
|
||||
primary-name]]))
|
||||
|
||||
|
||||
(defn resolve-group-system-message
|
||||
[{:keys [children]}]
|
||||
(reduce (fn [acc {:keys [type literal]}]
|
||||
(if (= type "mention")
|
||||
(conj acc [group-member literal])
|
||||
(conj acc
|
||||
[rn/view
|
||||
[quo/text literal]])))
|
||||
[:<>]
|
||||
children))
|
||||
|
||||
|
||||
(defn render-parsed-text
|
||||
[content]
|
||||
(reduce (fn [acc e]
|
||||
(conj acc (resolve-group-system-message e)))
|
||||
[quo/text]
|
||||
(:parsed-text content)))
|
||||
|
||||
(defn group-system-message
|
||||
[{:keys [chat-id timestamp-str content]} type]
|
||||
(let [{:keys [customization-color]} (rf/sub [:contacts/contact-by-address chat-id])]
|
||||
[quo/system-message
|
||||
{:type type
|
||||
:timestamp timestamp-str
|
||||
:customization-color customization-color
|
||||
:child (render-parsed-text content)}]))
|
||||
|
||||
(defn system-message-content
|
||||
[{:keys [content-type quoted-message] :as message-data}]
|
||||
|
||||
(if quoted-message
|
||||
[pin/pinned-message message-data]
|
||||
(condp = content-type
|
||||
|
||||
constants/content-type-system-text
|
||||
[group-system-message message-data :group]
|
||||
[system.text/text-content message-data]
|
||||
|
||||
constants/content-type-system-pinned-message
|
||||
[system.text/text-content message-data]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.link-preview.events
|
||||
(:require [camel-snake-kebab.core :as csk]
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.collection]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -33,6 +35,17 @@
|
||||
{:fx [[:dispatch
|
||||
[:profile.settings/profile-update :link-preview-request-enabled (boolean enabled?)]]]}))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/link-preview-whitelist-received
|
||||
(fn [{:keys [db]} [whitelist]]
|
||||
{:db (assoc db :link-previews-whitelist whitelist)}))
|
||||
|
||||
(rf/reg-fx :chat.ui/request-link-preview-whitelist
|
||||
(fn []
|
||||
(json-rpc/call {:method "wakuext_getLinkPreviewWhitelist"
|
||||
:params []
|
||||
:on-success [:chat.ui/link-preview-whitelist-received]
|
||||
:on-error #(log/error "Failed to get link preview whitelist")})))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/enable-link-previews
|
||||
(fn [{{:profile/keys [profile]} :db} [site enabled?]]
|
||||
(let [enabled-sites (if enabled?
|
||||
|
||||
@@ -103,11 +103,11 @@
|
||||
(models.contact/process-js-contacts cofx response-js)
|
||||
|
||||
(seq communities)
|
||||
(do
|
||||
(let [communities-clj (types/js->clj communities)]
|
||||
(js-delete response-js "communities")
|
||||
(rf/merge cofx
|
||||
(process-next response-js sync-handler)
|
||||
(communities/handle-communities communities)))
|
||||
(communities/handle-communities communities-clj)))
|
||||
|
||||
(seq bookmarks)
|
||||
(let [bookmarks-clj (types/js->clj bookmarks)]
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"0xD" {:address "0xD"
|
||||
:operable? false
|
||||
:position 3
|
||||
:color :pink
|
||||
:color :flamingo
|
||||
:emoji "🦩"}})
|
||||
|
||||
(def permissioned-accounts
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||
revealed-accounts-count (count revealed-accounts)
|
||||
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts]))
|
||||
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts-without-watched-accounts]))
|
||||
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
|
||||
(i18n/label :t/all-addresses)
|
||||
(i18n/label-pluralize
|
||||
|
||||
@@ -57,24 +57,19 @@
|
||||
:index index})
|
||||
|
||||
(defn- members
|
||||
[community-id chat-id theme]
|
||||
(let [online-members (rf/sub [:communities/chat-members-sorted community-id chat-id :online])
|
||||
offline-members (rf/sub [:communities/chat-members-sorted community-id chat-id :offline])]
|
||||
[rn/section-list
|
||||
{:key-fn :public-key
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:get-item-layout get-item-layout
|
||||
:content-inset-adjustment-behavior :never
|
||||
:sections [{:title (i18n/label :t/online)
|
||||
:data online-members}
|
||||
{:title (i18n/label :t/offline)
|
||||
:data offline-members}]
|
||||
:sticky-section-headers-enabled false
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn footer
|
||||
:render-data {:theme theme}
|
||||
:render-fn contact-item
|
||||
:scroll-event-throttle 32}]))
|
||||
[items theme]
|
||||
[rn/section-list
|
||||
{:key-fn :public-key
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:get-item-layout get-item-layout
|
||||
:content-inset-adjustment-behavior :never
|
||||
:sections items
|
||||
:sticky-section-headers-enabled false
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn footer
|
||||
:render-data {:theme theme}
|
||||
:render-fn contact-item
|
||||
:scroll-event-throttle 32}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
@@ -83,6 +78,8 @@
|
||||
{:keys [description chat-name emoji muted chat-type color]
|
||||
:as chat} (rf/sub [:chats/chat-by-id chat-id])
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])
|
||||
items (rf/sub [:communities/sorted-community-members-section-list
|
||||
community-id chat-id])
|
||||
theme (quo.theme/use-theme)]
|
||||
(rn/use-mount (fn []
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id])))
|
||||
@@ -136,4 +133,4 @@
|
||||
(if muted
|
||||
(home.actions/unmute-chat-action chat-id)
|
||||
(home.actions/mute-chat-action chat-id chat-type muted)))}]}]]]
|
||||
[members community-id chat-id theme]]))
|
||||
[members items theme]]))
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
:as item}]
|
||||
(let [user-selected? (rf/sub [:is-contact-selected? public-key])
|
||||
{:keys [id]} (rf/sub [:get-screen-params])
|
||||
community-members-keys (set (rf/sub [:communities/community-members id]))
|
||||
community-members-keys (set (keys (rf/sub [:communities/community-members id])))
|
||||
community-member? (boolean (community-members-keys public-key))
|
||||
on-toggle (fn []
|
||||
(when-not community-member?
|
||||
|
||||
@@ -39,6 +39,17 @@
|
||||
|
||||
(rf/reg-event-fx :communities/handle-community handle-community)
|
||||
|
||||
(schema/=> handle-community
|
||||
[:=>
|
||||
[:catn
|
||||
[:cofx :schema.re-frame/cofx]
|
||||
[:args
|
||||
[:schema [:catn [:community-js map?]]]]]
|
||||
[:maybe
|
||||
[:map
|
||||
[:db [:map [:communities map?]]]
|
||||
[:fx vector?]]]])
|
||||
|
||||
(rf/defn handle-removed-chats
|
||||
[{:keys [db]} chat-ids]
|
||||
{:db (reduce (fn [db chat-id]
|
||||
@@ -73,9 +84,10 @@
|
||||
|
||||
(rf/defn handle-communities
|
||||
{:events [:community/fetch-success]}
|
||||
[{:keys [db]} communities-js]
|
||||
{:fx (map (fn [c] [:dispatch [:communities/handle-community c]])
|
||||
communities-js)})
|
||||
[{:keys [db]} communities]
|
||||
{:fx
|
||||
(->> communities
|
||||
(map #(vector :dispatch [:communities/handle-community %])))})
|
||||
|
||||
(rf/reg-event-fx :communities/request-to-join-result
|
||||
(fn [{:keys [db]} [community-id request-id response-js]]
|
||||
@@ -124,30 +136,21 @@
|
||||
{}
|
||||
categories))}))
|
||||
|
||||
(rf/reg-event-fx :community/fetch-low-priority
|
||||
(fn []
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_checkAndDeletePendingRequestToJoinCommunity"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success [:sanitize-messages-and-process-response]
|
||||
:on-error #(log/info "failed to fetch communities" %)}
|
||||
{:method "wakuext_collapsedCommunityCategories"
|
||||
:params []
|
||||
:on-success [:communities/fetched-collapsed-categories-success]
|
||||
:on-error #(log/error "failed to fetch collapsed community categories" %)}]]]}))
|
||||
|
||||
(rf/reg-event-fx :community/fetch
|
||||
(fn [_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_serializedCommunities"
|
||||
:params []
|
||||
:on-success [:community/fetch-success]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to fetch communities" %)}]]
|
||||
;; Dispatch a little after 1000ms because other higher-priority events
|
||||
;; after login are being processed at the 1000ms mark.
|
||||
[:dispatch-later [{:ms 1200 :dispatch [:community/fetch-low-priority]}]]]}))
|
||||
{:json-rpc/call [{:method "wakuext_serializedCommunities"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:community/fetch-success %])
|
||||
:on-error #(log/error "failed to fetch communities" %)}
|
||||
{:method "wakuext_checkAndDeletePendingRequestToJoinCommunity"
|
||||
:params []
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/info "failed to fetch communities" %)}
|
||||
{:method "wakuext_collapsedCommunityCategories"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:communities/fetched-collapsed-categories-success %])
|
||||
:on-error #(log/error "failed to fetch collapsed community categories" %)}]}))
|
||||
|
||||
(defn update-previous-permission-addresses
|
||||
[{:keys [db]} [community-id]]
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
(-> effects :json-rpc/call first (select-keys [:method :params]))))))))
|
||||
|
||||
(deftest handle-community-test
|
||||
(let [community #js {:id community-id :clock 2}]
|
||||
(let [community {:id community-id :clock 2}]
|
||||
(testing "given a unjoined community"
|
||||
(let [effects (events/handle-community {} [community])]
|
||||
(is (match? community-id
|
||||
@@ -163,7 +163,7 @@
|
||||
(filter some? (:fx effects))))))
|
||||
|
||||
(testing "given a joined community"
|
||||
(let [community #js {:id community-id :clock 2 :joined true}
|
||||
(let [community (assoc community :joined true)
|
||||
effects (events/handle-community {} [community])]
|
||||
(is (match?
|
||||
[[:dispatch
|
||||
@@ -172,19 +172,16 @@
|
||||
(filter some? (:fx effects))))))
|
||||
|
||||
(testing "given a community with token-permissions-check"
|
||||
(let [community #js
|
||||
{:id community-id :clock 2 :token-permissions-check :fake-token-permissions-check}
|
||||
(let [community (assoc community :token-permissions-check :fake-token-permissions-check)
|
||||
effects (events/handle-community {} [community])]
|
||||
(is (match?
|
||||
[[:dispatch
|
||||
[:communities/check-permissions-to-join-community-with-all-addresses community-id]]]
|
||||
(filter some? (:fx effects))))))
|
||||
|
||||
(testing "given a community with lower clock"
|
||||
(let [effects (events/handle-community {:db {:communities {community-id {:clock 3}}}} [community])]
|
||||
(is (nil? effects))))
|
||||
|
||||
(testing "given a community without clock"
|
||||
(let [community #js {:id community-id}
|
||||
(let [community (dissoc community :clock)
|
||||
effects (events/handle-community {} [community])]
|
||||
(is (nil? effects))))))
|
||||
|
||||
@@ -75,51 +75,46 @@
|
||||
:banner (resources/get-image :discover)
|
||||
:accessibility-label :communities-home-discover-card}})
|
||||
|
||||
(defn on-tab-change
|
||||
[tab]
|
||||
(rf/dispatch [:communities/select-tab tab]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [flat-list-ref (rn/use-ref-atom nil)
|
||||
set-flat-list-ref (rn/use-callback #(reset! flat-list-ref %))
|
||||
theme (quo.theme/use-theme)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
selected-tab (or (rf/sub [:communities/selected-tab]) :joined)
|
||||
{:keys [joined pending opened]} (rf/sub [:communities/grouped-by-status])
|
||||
selected-items (case selected-tab
|
||||
:joined joined
|
||||
:pending pending
|
||||
:opened opened)
|
||||
scroll-shared-value (reanimated/use-shared-value 0)
|
||||
on-scroll (rn/use-callback
|
||||
(fn [event]
|
||||
(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget event
|
||||
"nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})))]
|
||||
[:<>
|
||||
(if (empty? selected-items)
|
||||
[common.empty-state/view
|
||||
{:selected-tab selected-tab
|
||||
:tab->content (empty-state-content theme)}]
|
||||
[reanimated/flat-list
|
||||
{:ref set-flat-list-ref
|
||||
:key-fn :id
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [common.header-spacing/view]
|
||||
:render-fn item-render
|
||||
:style {:margin-top -1}
|
||||
:data selected-items
|
||||
:scroll-event-throttle 8
|
||||
:content-container-style {:padding-bottom
|
||||
jump-to.constants/floating-shell-button-height}
|
||||
:on-scroll on-scroll}])
|
||||
[common.banner/animated-banner
|
||||
{:content banner-data
|
||||
:customization-color customization-color
|
||||
:scroll-ref flat-list-ref
|
||||
:tabs tabs-data
|
||||
:selected-tab selected-tab
|
||||
:on-tab-change on-tab-change
|
||||
:scroll-shared-value scroll-shared-value}]]))
|
||||
(let [flat-list-ref (atom nil)
|
||||
set-flat-list-ref #(reset! flat-list-ref %)]
|
||||
(fn []
|
||||
(let [theme (quo.theme/use-theme)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
selected-tab (or (rf/sub [:communities/selected-tab]) :joined)
|
||||
{:keys [joined pending opened]} (rf/sub [:communities/grouped-by-status])
|
||||
selected-items (case selected-tab
|
||||
:joined joined
|
||||
:pending pending
|
||||
:opened opened)
|
||||
scroll-shared-value (reanimated/use-shared-value 0)]
|
||||
[:<>
|
||||
(if (empty? selected-items)
|
||||
[common.empty-state/view
|
||||
{:selected-tab selected-tab
|
||||
:tab->content (empty-state-content theme)}]
|
||||
[reanimated/flat-list
|
||||
{:ref set-flat-list-ref
|
||||
:key-fn :id
|
||||
:content-inset-adjustment-behavior :never
|
||||
:header [common.header-spacing/view]
|
||||
:render-fn item-render
|
||||
:style {:margin-top -1}
|
||||
:data selected-items
|
||||
:scroll-event-throttle 8
|
||||
:content-container-style {:padding-bottom
|
||||
jump-to.constants/floating-shell-button-height}
|
||||
:on-scroll #(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget
|
||||
%
|
||||
"nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})}])
|
||||
[:f> common.banner/animated-banner
|
||||
{:content banner-data
|
||||
:customization-color customization-color
|
||||
:scroll-ref flat-list-ref
|
||||
:tabs tabs-data
|
||||
:selected-tab selected-tab
|
||||
:on-tab-change (fn [tab] (rf/dispatch [:communities/select-tab tab]))
|
||||
:scroll-shared-value scroll-shared-value}]]))))
|
||||
|
||||
@@ -109,22 +109,3 @@
|
||||
[pairings]
|
||||
(keycard/set-pairings pairings))
|
||||
(rf/reg-fx :effects.keycard/set-pairing-to-keycard set-pairing-to-keycard)
|
||||
|
||||
(defn sign
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] sign")
|
||||
(keycard/sign
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] sign")
|
||||
(when on-success
|
||||
(on-success (transforms/js->clj response))))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] sign"
|
||||
(error-object->map response))
|
||||
(when on-failure
|
||||
(on-failure (error-object->map response)))))))
|
||||
(rf/reg-fx :effects.keycard/sign sign)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
status-im.contexts.keycard.login.events
|
||||
status-im.contexts.keycard.pin.events
|
||||
status-im.contexts.keycard.sheet.events
|
||||
status-im.contexts.keycard.sign.events
|
||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-check-nfc-enabled-success
|
||||
@@ -57,19 +55,3 @@
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
|
||||
(log/debug "[keycard] nfc started success")
|
||||
{:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] on-cancel-event-vector)}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-action-with-pin-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(log/debug "[keycard] get keys error: " error)
|
||||
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
|
||||
pin-retries-count (keycard.utils/pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if (nil? pin-retries-count)
|
||||
{:effects.utils/show-popup {:title "wrong-keycard"}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(update-in [:keycard :pin] assoc :status :error))
|
||||
:fx [[:dispatch [:keycard/hide-connection-sheet]]
|
||||
(when (zero? pin-retries-count)
|
||||
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-keys-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(log/debug "[keycard] get keys error: " error)
|
||||
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
|
||||
pin-retries-count (keycard.utils/pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if (nil? pin-retries-count)
|
||||
{:effects.utils/show-popup {:title "wrong-keycard"}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(update-in [:keycard :pin] assoc :status :error))
|
||||
:fx [[:dispatch [:keycard/hide-connection-sheet]]
|
||||
(when (zero? pin-retries-count)
|
||||
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-keys-success
|
||||
(fn [{:keys [db]} [data]]
|
||||
(let [{:keys [key-uid encryption-public-key
|
||||
@@ -40,25 +56,28 @@
|
||||
:key-uid key-uid}]]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-application-info-success
|
||||
(fn [{:keys [db]} [application-info {:keys [key-uid on-read-fx]}]]
|
||||
(let [error (keycard.utils/validate-application-info key-uid application-info)]
|
||||
(fn [{:keys [db]} [application-info]]
|
||||
(let [profile (get-in db [:profile/profiles-overview (get-in db [:profile/login :key-uid])])
|
||||
pin (get-in db [:keycard :pin :text])
|
||||
error (keycard.utils/validate-application-info profile application-info)]
|
||||
(if error
|
||||
{:effects.utils/show-popup {:title (str error)}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info] application-info)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:fx on-read-fx}))))
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info] application-info)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:effects.keycard/get-keys {:pin pin
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard.login/on-get-keys-error %])}}))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/cancel-reading-card
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] nil)}))
|
||||
|
||||
(rf/reg-event-fx :keycard/read-card
|
||||
(fn [{:keys [db]} [args]]
|
||||
(rf/reg-event-fx :keycard/read-card-and-login
|
||||
(fn [{:keys [db]}]
|
||||
(let [connected? (get-in db [:keycard :card-connected?])
|
||||
event-vector [:keycard/get-application-info
|
||||
{:on-success #(rf/dispatch [:keycard.login/on-get-application-info-success %
|
||||
args])}]]
|
||||
{:on-success #(rf/dispatch [:keycard.login/on-get-application-info-success %])}]]
|
||||
(log/debug "[keycard] proceed-to-login")
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
|
||||
:fx [[:dispatch
|
||||
|
||||
@@ -9,17 +9,13 @@
|
||||
(assoc-in [:keycard :pin :text] (.slice pin 0 -1))
|
||||
(assoc-in [:keycard :pin :status] nil))}))))
|
||||
|
||||
(rf/reg-fx :effects.keycard.pin/dispatch-on-complete
|
||||
(fn [[on-complete new-pin]]
|
||||
(on-complete new-pin)))
|
||||
|
||||
(rf/reg-event-fx :keycard.pin/number-pressed
|
||||
(fn [{:keys [db]} [number max-numbers on-complete]]
|
||||
(fn [{:keys [db]} [number max-numbers on-complete-event]]
|
||||
(let [pin (get-in db [:keycard :pin :text])
|
||||
new-pin (str pin number)]
|
||||
(when (<= (count new-pin) max-numbers)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :text] new-pin)
|
||||
(assoc-in [:keycard :pin :status] nil))
|
||||
:fx [(when (and on-complete (= (dec max-numbers) (count pin)))
|
||||
[:effects.keycard.pin/dispatch-on-complete [on-complete new-pin]])]}))))
|
||||
:fx [(when (= (dec max-numbers) (count pin))
|
||||
[:dispatch [on-complete-event]])]}))))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn auth
|
||||
[{:keys [on-complete]}]
|
||||
[callback-event-key]
|
||||
(let [{:keys [text status]} (rf/sub [:keycard/pin])
|
||||
pin-retry-counter (rf/sub [:keycard/pin-retry-counter])
|
||||
error? (= status :error)]
|
||||
@@ -23,4 +23,4 @@
|
||||
{:delete-key? true
|
||||
:on-delete #(rf/dispatch [:keycard.pin/delete-pressed])
|
||||
:on-press #(rf/dispatch [:keycard.pin/number-pressed % constants/pincode-length
|
||||
on-complete])}]]))
|
||||
callback-event-key])}]]))
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
(ns status-im.contexts.keycard.sign.events
|
||||
(:require [utils.address]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn get-signature-map
|
||||
[tx-hash signature]
|
||||
{tx-hash {:r (subs signature 0 64)
|
||||
:s (subs signature 64 128)
|
||||
:v (str (js/parseInt (subs signature 128 130) 16))}})
|
||||
|
||||
(rf/reg-event-fx :keycard/sign-hash
|
||||
(fn [{:keys [db]} [pin-text tx-hash]]
|
||||
(let [current-address (get-in db [:wallet :current-viewing-account-address])
|
||||
path (get-in db [:wallet :accounts current-address :path])
|
||||
key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/read-card
|
||||
{:key-uid key-uid
|
||||
:on-read-fx [[:effects.keycard/sign
|
||||
{:pin pin-text
|
||||
:path path
|
||||
:hash (utils.address/naked-address tx-hash)
|
||||
:on-success
|
||||
#(do
|
||||
(rf/dispatch [:keycard/hide-connection-sheet])
|
||||
(rf/dispatch
|
||||
[:wallet/proceed-with-transactions-signatures
|
||||
(get-signature-map tx-hash %)]))
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}]]]})))
|
||||
@@ -16,8 +16,8 @@
|
||||
(re-matches #".*NFCError:100.*" error)))
|
||||
|
||||
(defn validate-application-info
|
||||
[profile-key-uid {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
(let [profile-mismatch? (or (nil? profile-key-uid) (not= profile-key-uid key-uid))]
|
||||
[profile {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
(let [profile-mismatch? (or (nil? profile) (not= (:key-uid profile) key-uid))]
|
||||
(log/debug "[keycard] login-with-keycard"
|
||||
"empty application info" (empty? application-info)
|
||||
"no key-uid" (empty? key-uid)
|
||||
|
||||
@@ -17,3 +17,17 @@
|
||||
{:events [:onboarding/overlay-dismiss]}
|
||||
[_]
|
||||
{:onboarding/overlay-dismiss-fx nil})
|
||||
|
||||
(re-frame/reg-fx
|
||||
:onboarding/overlay-show-fx
|
||||
(fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(when-let [push-animation-fn @profiles/push-animation-fn-atom]
|
||||
(push-animation-fn))))
|
||||
|
||||
(rf/defn overlay-show
|
||||
{:events [:onboarding/overlay-show]}
|
||||
[_]
|
||||
{:onboarding/overlay-show-fx nil})
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def flex-fill {:flex 1})
|
||||
|
||||
(def heading {:margin-bottom 20})
|
||||
(def heading-subtitle {:color colors/white})
|
||||
(def heading-title (assoc heading-subtitle :margin-bottom 8))
|
||||
@@ -12,15 +14,23 @@
|
||||
(def space-between-inputs {:height 16})
|
||||
|
||||
(def password-tips
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 20})
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 20})
|
||||
|
||||
(def form-container
|
||||
{:justify-content :space-between
|
||||
:padding-top 12
|
||||
:padding-horizontal 20})
|
||||
(def top-part
|
||||
{:margin-horizontal 20
|
||||
:margin-top 12})
|
||||
|
||||
(def disclaimer-container {:padding-horizontal 20})
|
||||
(def footer-container {:padding-bottom 12})
|
||||
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
||||
(def bottom-part
|
||||
{:flex 1
|
||||
:margin-top 12
|
||||
:justify-content :flex-end})
|
||||
|
||||
(def disclaimer-container
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 4})
|
||||
|
||||
(def button-container
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 12})
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(ns status-im.contexts.onboarding.create-password.view
|
||||
(:require
|
||||
[oops.core :refer [ocall]]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.onboarding.create-password.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -94,7 +94,7 @@
|
||||
[quo/tips {:completed? symbols?}
|
||||
(i18n/label :t/password-creation-tips-4)]]])
|
||||
|
||||
(defn validate-password
|
||||
(defn password-validations
|
||||
[password]
|
||||
(let [validations (juxt utils.string/has-lower-case?
|
||||
utils.string/has-upper-case?
|
||||
@@ -111,25 +111,68 @@
|
||||
(filter true?)
|
||||
count))
|
||||
|
||||
(defn- use-password-checks
|
||||
[password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
(let [{:keys [long-enough?]
|
||||
:as validations} (validate-password password)]
|
||||
{:password-long-enough? long-enough?
|
||||
:password-validations validations
|
||||
:password-strength (calc-password-strength validations)
|
||||
:empty-password? (empty? password)}))
|
||||
[password]))
|
||||
(defn password-form
|
||||
[]
|
||||
(let [password (reagent/atom "")
|
||||
repeat-password (reagent/atom "")
|
||||
accepts-disclaimer? (reagent/atom false)
|
||||
focused-input (reagent/atom nil)
|
||||
show-password-validation? (reagent/atom false)
|
||||
same-password-length? #(and (seq @password)
|
||||
(= (count @password) (count @repeat-password)))]
|
||||
(fn []
|
||||
(let [{user-color :color} (rf/sub [:onboarding/profile])
|
||||
{:keys [long-enough?]
|
||||
:as validations} (password-validations @password)
|
||||
password-strength (calc-password-strength validations)
|
||||
empty-password? (empty? @password)
|
||||
same-passwords? (and (not empty-password?) (= @password @repeat-password))
|
||||
meet-requirements? (and (not empty-password?)
|
||||
(utils.string/at-least-n-chars? @password 10)
|
||||
same-passwords?
|
||||
@accepts-disclaimer?)]
|
||||
[:<>
|
||||
[rn/view {:style style/top-part}
|
||||
[header]
|
||||
[password-inputs
|
||||
{:password-long-enough? long-enough?
|
||||
:passwords-match? same-passwords?
|
||||
:empty-password? empty-password?
|
||||
:show-password-validation? @show-password-validation?
|
||||
:on-input-focus #(reset! focused-input :password)
|
||||
:on-change-password (fn [new-value]
|
||||
(reset! password new-value)
|
||||
(when (same-password-length?)
|
||||
(reset! show-password-validation? true)))
|
||||
:on-change-repeat-password (fn [new-value]
|
||||
(reset! repeat-password new-value)
|
||||
(when (same-password-length?)
|
||||
(reset! show-password-validation? true)))
|
||||
:on-blur-repeat-password #(if empty-password?
|
||||
(reset! show-password-validation? false)
|
||||
(reset! show-password-validation? true))}]]
|
||||
|
||||
(defn- use-repeat-password-checks
|
||||
[password repeat-password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
{:same-password-length? (and (seq password) (= (count password) (count repeat-password)))
|
||||
:same-passwords? (and (seq password) (= password repeat-password))})
|
||||
[password repeat-password]))
|
||||
[rn/view {:style style/bottom-part}
|
||||
(when same-passwords?
|
||||
[rn/view {:style style/disclaimer-container}
|
||||
[quo/disclaimer
|
||||
{:blur? true
|
||||
:on-change #(swap! accepts-disclaimer? not)
|
||||
:checked? @accepts-disclaimer?}
|
||||
(i18n/label :t/password-creation-disclaimer)]])
|
||||
(when (and (= @focused-input :password) (not same-passwords?))
|
||||
[help
|
||||
{:validations validations
|
||||
:password-strength password-strength}])
|
||||
|
||||
[rn/view {:style style/button-container}
|
||||
[quo/button
|
||||
{:disabled? (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding/password-set
|
||||
(security/mask-data @password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]]]))))
|
||||
|
||||
(defn create-password-doc
|
||||
[]
|
||||
@@ -140,108 +183,38 @@
|
||||
[quo/text {:size :paragraph-2}
|
||||
(i18n/label :t/create-profile-password-info-box-description)]]])
|
||||
|
||||
(defn- on-press-info
|
||||
[]
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- page-nav
|
||||
[]
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}]))
|
||||
|
||||
(defn create-password
|
||||
[]
|
||||
(let [[password set-password] (rn/use-state "")
|
||||
[repeat-password set-repeat-password] (rn/use-state "")
|
||||
[accepts-disclaimer? set-accepts-disclaimer?] (rn/use-state false)
|
||||
[focused-input set-focused-input] (rn/use-state nil)
|
||||
[show-password-validation?
|
||||
set-show-password-validation?] (rn/use-state false)
|
||||
{user-color :color} (rf/sub [:onboarding/profile])
|
||||
|
||||
|
||||
{:keys [password-long-enough?
|
||||
password-validations password-strength
|
||||
empty-password?]} (use-password-checks password)
|
||||
|
||||
{:keys [same-password-length? same-passwords?]} (use-repeat-password-checks password
|
||||
repeat-password)
|
||||
|
||||
meet-requirements? (rn/use-memo
|
||||
#(and (not empty-password?)
|
||||
(utils.string/at-least-n-chars? password
|
||||
10)
|
||||
same-passwords?
|
||||
accepts-disclaimer?)
|
||||
[password repeat-password
|
||||
accepts-disclaimer?])]
|
||||
|
||||
[floating-button/view
|
||||
{:header [page-nav]
|
||||
:keyboard-should-persist-taps :handled
|
||||
:content-avoid-keyboard? true
|
||||
:blur-options
|
||||
{:blur-amount 34
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
||||
:padding-vertical 0
|
||||
:padding-horizontal 0}
|
||||
:footer-container-padding 0
|
||||
:footer
|
||||
[rn/view
|
||||
{:style style/footer-container}
|
||||
(when same-passwords?
|
||||
[rn/view {:style style/disclaimer-container}
|
||||
[quo/disclaimer
|
||||
{:blur? true
|
||||
:on-change (partial set-accepts-disclaimer? not)
|
||||
:checked? accepts-disclaimer?}
|
||||
(i18n/label :t/password-creation-disclaimer)]])
|
||||
(when (and (= focused-input :password) (not same-passwords?))
|
||||
[help
|
||||
{:validations password-validations
|
||||
:password-strength password-strength}])
|
||||
[quo/button
|
||||
{:container-style style/footer-button-container
|
||||
:disabled? (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding/password-set
|
||||
(security/mask-data password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]}
|
||||
|
||||
[rn/view {:style style/form-container}
|
||||
[header]
|
||||
[password-inputs
|
||||
{:password-long-enough? password-long-enough?
|
||||
:passwords-match? same-passwords?
|
||||
:empty-password? empty-password?
|
||||
:show-password-validation? show-password-validation?
|
||||
:on-input-focus #(set-focused-input :password)
|
||||
:on-change-password (fn [new-value]
|
||||
(set-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
|
||||
:on-change-repeat-password (fn [new-value]
|
||||
(set-repeat-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
:on-blur-repeat-password #(if empty-password?
|
||||
(set-show-password-validation? false)
|
||||
(set-show-password-validation? true))}]]]))
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
{:keys [top bottom]} (safe-area/get-insets)
|
||||
will-show-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillShow"
|
||||
#(reset! keyboard-shown? true))
|
||||
will-hide-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillHide"
|
||||
#(reset! keyboard-shown? false))
|
||||
on-press-info (fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))]
|
||||
[:<>
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press rn/dismiss-keyboard!
|
||||
:accessible false}
|
||||
[rn/view {:style style/flex-fill}
|
||||
[rn/keyboard-avoiding-view {:style style/flex-fill}
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}]
|
||||
[password-form]
|
||||
[rn/view {:style {:height (if-not @keyboard-shown? bottom 0)}}]]]]]
|
||||
(finally
|
||||
(ocall will-show-listener "remove")
|
||||
(ocall will-hide-listener "remove"))))
|
||||
|
||||
@@ -125,25 +125,31 @@
|
||||
mnemonic key-uid]))
|
||||
on-error]})
|
||||
|
||||
;; TODO: clear syncing data if key-uid does not match
|
||||
(rf/defn seed-phrase-validated
|
||||
{:events [:onboarding/seed-phrase-validated]}
|
||||
[{:keys [db]} seed-phrase key-uid]
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch
|
||||
[:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]}))
|
||||
(let [next-screen (if (and (seq (:syncing/key-uid db))
|
||||
(= (:syncing/key-uid db) key-uid))
|
||||
:screen/onboarding.create-profile-password
|
||||
:screen/onboarding.create-profile)]
|
||||
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/multiaccount-exists-title)
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch
|
||||
[:profile/profile-selected key-uid]))
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[next-screen
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]})))
|
||||
|
||||
(rf/defn navigate-to-create-profile
|
||||
{:events [:onboarding/navigate-to-create-profile]}
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
:padding-bottom 20
|
||||
:background-color (when-not in-onboarding? colors/neutral-80-opa-80-blur)})
|
||||
|
||||
(defn page-illustration
|
||||
[width]
|
||||
{:flex 1
|
||||
:width width
|
||||
:align-items :center
|
||||
:align-self :center
|
||||
:justify-content :center})
|
||||
(def page-illustration
|
||||
{:flex 1
|
||||
:background-color colors/danger-50
|
||||
:align-items :center
|
||||
:margin-horizontal 20
|
||||
:border-radius 20
|
||||
:margin-top 20
|
||||
:justify-content :center})
|
||||
|
||||
(def try-again-button
|
||||
{:margin-top 20
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
[status-im.contexts.onboarding.common.background.view :as background]
|
||||
[status-im.contexts.onboarding.syncing.progress.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -25,40 +26,73 @@
|
||||
:title-accessibility-label :progress-screen-title
|
||||
:description-accessibility-label :progress-screen-sub-title}])
|
||||
|
||||
(defn try-again-button
|
||||
[profile-color]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:syncing/clear-states])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:accessibility-label :try-again-later-button
|
||||
:customization-color profile-color
|
||||
:size 40
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/try-again)])
|
||||
(defn navigate-to-enter-seed-phrase
|
||||
[view-id]
|
||||
(if (= view-id :screen/onboarding.syncing-progress-intro)
|
||||
(do
|
||||
(rf/dispatch [:navigate-back-to :screen/onboarding.sync-or-recover-profile])
|
||||
(debounce/debounce-and-dispatch
|
||||
[:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.sync-or-recover-profile]
|
||||
300))
|
||||
(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/debounce-and-dispatch [:onboarding/overlay-show] 100)
|
||||
(debounce/debounce-and-dispatch [:open-modal :screen/onboarding.new-to-status] 200)
|
||||
(debounce/debounce-and-dispatch
|
||||
[:onboarding/navigate-to-sign-in-by-seed-phrase :screen/onboarding.new-to-status]
|
||||
300))))
|
||||
|
||||
(defn- illustration
|
||||
[pairing-progress?]
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration (:width (rn/get-window)))
|
||||
:source (resources/get-image (if pairing-progress? :syncing-devices :syncing-wrong))}])
|
||||
(defn try-again-button
|
||||
[profile-color in-onboarding? logged-in? view-id]
|
||||
[rn/view
|
||||
(when-not logged-in?
|
||||
[quo/button
|
||||
{:on-press #(navigate-to-enter-seed-phrase view-id)
|
||||
:accessibility-label :try-seed-phrase-button
|
||||
:customization-color profile-color
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/enter-seed-phrase)])
|
||||
|
||||
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:syncing/clear-states])
|
||||
(cond
|
||||
logged-in? (rf/dispatch [:navigate-back])
|
||||
in-onboarding? (rf/dispatch [:navigate-back-to
|
||||
:screen/onboarding.sign-in-intro])
|
||||
:else (do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sign-in]
|
||||
1000))))
|
||||
:accessibility-label :try-again-later-button
|
||||
:customization-color profile-color
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/try-again)]])
|
||||
|
||||
(defn view
|
||||
[in-onboarding?]
|
||||
(let [pairing-status (rf/sub [:pairing/pairing-status])
|
||||
pairing-progress? (pairing-progress pairing-status)
|
||||
profile-color (or (:color (rf/sub [:onboarding/profile]))
|
||||
(rf/sub [:profile/customization-color]))]
|
||||
(let [pairing-status (rf/sub [:pairing/pairing-status])
|
||||
profile-color (:color (rf/sub [:onboarding/profile]))
|
||||
logged-in? (rf/sub [:multiaccount/logged-in?])
|
||||
view-id (rf/sub [:view-id])]
|
||||
[rn/view {:style (style/page-container in-onboarding?)}
|
||||
(when-not in-onboarding?
|
||||
[rn/view {:style style/absolute-fill}
|
||||
[background/view true]])
|
||||
[quo/page-nav {:type :no-title :background :blur}]
|
||||
[page-title pairing-progress?]
|
||||
[illustration pairing-progress?]
|
||||
[page-title (pairing-progress pairing-status)]
|
||||
(if config/show-not-implemented-features?
|
||||
(if (pairing-progress pairing-status)
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text "[Success here]"]]
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text "[Error here]"]])
|
||||
[rn/view {:flex 1}])
|
||||
(when-not (pairing-progress pairing-status)
|
||||
[try-again-button profile-color])]))
|
||||
[try-again-button profile-color in-onboarding? logged-in? view-id])]))
|
||||
|
||||
(defn view-onboarding
|
||||
[]
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
[]
|
||||
(let [state (reagent/atom {:type :default
|
||||
:customization-color :blue
|
||||
:account-color :pink
|
||||
:account-color :flamingo
|
||||
:title "Alisher Yakupov"
|
||||
:address "0x21a...49e"
|
||||
:on-options-press #(js/alert "Options button pressed!")})]
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{:image-source (quo.resources/get-network :ethereum)
|
||||
:label "Mainnet"}
|
||||
:saved-address
|
||||
{:customization-color :pink
|
||||
{:customization-color :flamingo
|
||||
:label "Peter Lambo"}
|
||||
:account
|
||||
{:label "Account"
|
||||
|
||||
@@ -57,15 +57,14 @@
|
||||
[{:method "wakuext_startMessenger"
|
||||
:on-success [:profile.login/messenger-started]
|
||||
:on-error #(log/error "failed to start messenger" %)}]]
|
||||
[:dispatch [:universal-links/generate-profile-url]]
|
||||
[:dispatch [:community/fetch]]
|
||||
|
||||
;; Wallet initialization can be delayed a little bit because we
|
||||
;; need to free the queue for heavier events first, such as
|
||||
;; loading chats and communities. This globally helps alleviate
|
||||
;; stuttering immediately after login.
|
||||
[:dispatch-later [{:ms 500 :dispatch [:wallet/initialize]}]]
|
||||
|
||||
[:push-notifications/load-preferences]
|
||||
[:profile.config/get-node-config]
|
||||
[:logs/set-level log-level]
|
||||
[:activity-center.notifications/fetch-pending-contact-requests-fx]
|
||||
[:activity-center/update-seen-state]
|
||||
[:activity-center.notifications/fetch-unread-count]
|
||||
|
||||
;; Immediately try to open last chat. We can't wait until the
|
||||
;; messenger has started and has processed all chats because
|
||||
@@ -91,45 +90,24 @@
|
||||
;; login phase 2: we want to load and show chats faster, so we split login into 2 phases
|
||||
(rf/reg-event-fx :profile.login/get-chats-callback
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [notifications-enabled? key-uid]} (:profile/profile db)]
|
||||
(let [{:keys [notifications-enabled? key-uid
|
||||
preview-privacy?]} (:profile/profile db)]
|
||||
{:db db
|
||||
:fx [[:effects.profile/enable-local-notifications]
|
||||
[:contacts/initialize-contacts]
|
||||
;; The delay is arbitrary. We just want to give some time for the
|
||||
;; thread to process more important events first, but we can't delay
|
||||
;; too much otherwise the UX may degrade due to stale data.
|
||||
[:dispatch-later [{:ms 1500 :dispatch [:profile.login/non-critical-initialization]}]]
|
||||
[:browser/initialize-browser]
|
||||
[:dispatch [:mobile-network/on-network-status-change]]
|
||||
[:group-chats/get-group-chat-invitations]
|
||||
[:profile.settings/get-profile-picture key-uid]
|
||||
[:profile.settings/blank-preview-flag-changed preview-privacy?]
|
||||
[:chat.ui/request-link-preview-whitelist]
|
||||
[:visibility-status-updates/fetch]
|
||||
[:switcher-cards/fetch]
|
||||
(when (ff/enabled? ::ff/wallet.wallet-connect)
|
||||
[:dispatch [:wallet-connect/init]])
|
||||
(when notifications-enabled?
|
||||
[:effects/push-notifications-enable])]})))
|
||||
|
||||
;; Login phase 3: events at this phase can wait a bit longer to be processed in
|
||||
;; order to leave room for higher-priority or heavy weight events.
|
||||
(rf/reg-event-fx :profile.login/non-critical-initialization
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [preview-privacy?]} (:profile/profile db)]
|
||||
{:fx [[:browser/initialize-browser]
|
||||
[:logging/initialize-web3-client-version]
|
||||
[:group-chats/get-group-chat-invitations]
|
||||
[:profile.settings/blank-preview-flag-changed preview-privacy?]
|
||||
(when (ff/enabled? ::ff/shell.jump-to)
|
||||
[:switcher-cards/fetch])
|
||||
[:visibility-status-updates/fetch]
|
||||
[:dispatch [:universal-links/generate-profile-url]]
|
||||
[:push-notifications/load-preferences]
|
||||
[:profile.config/get-node-config]
|
||||
[:activity-center.notifications/fetch-pending-contact-requests-fx]
|
||||
[:activity-center/update-seen-state]
|
||||
[:activity-center.notifications/fetch-unread-count]
|
||||
[:pairing/get-our-installations]
|
||||
[:json-rpc/call
|
||||
[{:method "admin_nodeInfo"
|
||||
:on-success [:profile.login/node-info-fetched]
|
||||
:on-error #(log/error "node-info: failed error" %)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :profile.login/messenger-started
|
||||
(fn [{:keys [db]} [{:keys [mailservers]}]]
|
||||
(let [new-account? (get db :onboarding/new-account?)]
|
||||
@@ -141,6 +119,13 @@
|
||||
(rf/dispatch [:chats-list/load-success result])
|
||||
(rf/dispatch [:communities/get-user-requests-to-join])
|
||||
(rf/dispatch [:profile.login/get-chats-callback]))}]
|
||||
[:json-rpc/call
|
||||
[{:method "admin_nodeInfo"
|
||||
:on-success [:profile.login/node-info-fetched]
|
||||
:on-error #(log/error "node-info: failed error" %)}]]
|
||||
[:pairing/get-our-installations]
|
||||
(when (:syncing/installation-id db)
|
||||
[:dispatch [:pairing/finish-seed-phrase-fallback-syncing]])
|
||||
(when-not new-account?
|
||||
[:dispatch [:universal-links/process-stored-event]])]})))
|
||||
|
||||
@@ -156,9 +141,11 @@
|
||||
(if error
|
||||
{:db (update db :profile/login #(-> % (dissoc :processing) (assoc :error error)))}
|
||||
{:db (dissoc db :profile/login)
|
||||
:fx [(when (and new-account? (not recovered-account?))
|
||||
[:dispatch-later [{:ms 1000 :dispatch [:wallet-legacy/set-initial-blocks-range]}]])
|
||||
[:dispatch-later [{:ms 2000 :dispatch [:ens/update-usernames ensUsernames]}]]
|
||||
:fx [[:logging/initialize-web3-client-version]
|
||||
(when (and new-account? (not recovered-account?))
|
||||
[:dispatch [:wallet-legacy/set-initial-blocks-range]])
|
||||
[:dispatch [:ens/update-usernames ensUsernames]]
|
||||
[:dispatch [:wallet/initialize]]
|
||||
[:dispatch [:profile.login/login-existing-profile settings account]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
||||
@@ -239,16 +239,7 @@
|
||||
:profile-picture profile-picture
|
||||
:card-style style/login-profile-card}]
|
||||
(if keycard-pairing
|
||||
[keycard.pin/auth
|
||||
{:on-complete
|
||||
(fn [pin-text]
|
||||
(rf/dispatch
|
||||
[:keycard/read-card
|
||||
{:key-uid key-uid
|
||||
:on-read-fx [[:effects.keycard/get-keys
|
||||
{:pin pin-text
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}]))}]
|
||||
[keycard.pin/auth :keycard/read-card-and-login]
|
||||
[password-input])]
|
||||
(when-not keycard-pairing
|
||||
[quo/button
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.config :as profile.config]
|
||||
status-im.contexts.profile.recover.effects
|
||||
[utils.re-frame :as rf]
|
||||
@@ -17,11 +18,11 @@
|
||||
(assoc-in [:syncing :login-sha3-password] login-sha3-password))
|
||||
|
||||
:effects.profile/restore-and-login
|
||||
(merge (profile.config/create)
|
||||
{:displayName display-name
|
||||
:mnemonic (security/safe-unmask-data seed-phrase)
|
||||
:password login-sha3-password
|
||||
:imagePath (profile.config/strip-file-prefix image-path)
|
||||
:customizationColor color
|
||||
:emoji (emoji-picker.utils/random-emoji)
|
||||
:fetchBackup true})}))
|
||||
(assoc (profile.config/create)
|
||||
:displayName display-name
|
||||
:mnemonic (security/safe-unmask-data seed-phrase)
|
||||
:password login-sha3-password
|
||||
:imagePath (profile.config/strip-file-prefix image-path)
|
||||
:customizationColor (or color constants/profile-default-color)
|
||||
:emoji (emoji-picker.utils/random-emoji)
|
||||
:fetchBackup true)}))
|
||||
|
||||
@@ -46,13 +46,29 @@
|
||||
(log/info "[local-pairing] input-connection-string-for-bootstrapping callback"
|
||||
{:response res
|
||||
:event :syncing/input-connection-string-for-bootstrapping})
|
||||
(let [error (when (sync-utils/extract-error res)
|
||||
(str "generic-error: " res))]
|
||||
(when (some? error)
|
||||
(let [response (transforms/json->clj res)
|
||||
installation-id (:installationId response)
|
||||
key-uid (:keyUID response)
|
||||
error (:error response)]
|
||||
(when (seq installation-id)
|
||||
(rf/dispatch [:syncing/set-syncing-installation-id installation-id key-uid]))
|
||||
(when (seq error)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:text error}]))))
|
||||
|
||||
(rf/defn initiate-pairing-process
|
||||
{:events [:syncing/initiate-pairing-process]}
|
||||
[{:keys [db]}]
|
||||
{:db (assoc db :syncing/pairing-process-initiated? true)})
|
||||
|
||||
(rf/defn set-syncing-installation-id
|
||||
{:events [:syncing/set-syncing-installation-id]}
|
||||
[{:keys [db]} installation-id key-uid]
|
||||
{:db (assoc db
|
||||
:syncing/key-uid key-uid
|
||||
:syncing/installation-id installation-id)})
|
||||
|
||||
(rf/defn preflight-outbound-check-for-local-pairing
|
||||
{:events [:syncing/preflight-outbound-check]}
|
||||
[_ set-checks-passed]
|
||||
@@ -96,6 +112,7 @@
|
||||
(when (sync-utils/valid-connection-string? response)
|
||||
(on-valid-connection-string response)
|
||||
(rf/dispatch [:syncing/update-role constants/local-pairing-role-sender])
|
||||
(rf/dispatch [:syncing/initiate-pairing-process])
|
||||
(rf/dispatch [:hide-bottom-sheet])))]
|
||||
(when-not (and error (string/blank? error))
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
[]
|
||||
(let [compressed-key (rf/sub [:profile/compressed-key])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
keypairs (rf/sub [:wallet/fully-operable-keypairs-list])
|
||||
keypairs (rf/sub [:wallet/keypairs-list])
|
||||
selected-keypair (rf/sub [:wallet/selected-keypair-uid])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
[selected-key-uid set-selected-key-uid] (rn/use-state selected-keypair)]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/stop-get-suggested-routes]))
|
||||
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-routes-calculation]))
|
||||
[rn/view {:style style/bridge-send-wrapper}
|
||||
[input-amount/view
|
||||
{:current-screen-id :screen/wallet.bridge-input-amount
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
(not watch-only?))
|
||||
{:icon-name :i/dapps
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
|
||||
|
||||
{:content-type :account-switcher
|
||||
:customization-color color
|
||||
:on-press #(on-dapps-press switcher-type)
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
(ns status-im.contexts.wallet.common.activity-tab.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
|
||||
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -82,10 +80,6 @@
|
||||
; :network-logo network-logo}
|
||||
; :blur? false}])
|
||||
|
||||
(defn- section-header
|
||||
[{:keys [title]}]
|
||||
[quo/divider-date title])
|
||||
|
||||
(defn activity-item
|
||||
[{:keys [transaction] :as activity}]
|
||||
(case transaction
|
||||
@@ -94,63 +88,20 @@
|
||||
;; :mint [mint-activity activity]
|
||||
nil))
|
||||
|
||||
(defn- pressable-text
|
||||
[{:keys [on-press text]}]
|
||||
[rn/text
|
||||
{:style {:text-decoration-line :underline}
|
||||
:on-press on-press}
|
||||
text])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
address (rf/sub [:wallet/current-viewing-account-address])
|
||||
activity-list (rf/sub [:wallet/activities-for-current-viewing-account])
|
||||
open-eth-chain-explorer (rn/use-callback
|
||||
#(rf/dispatch [:wallet/navigate-to-chain-explorer
|
||||
{:address address
|
||||
:network constants/mainnet-network-name}])
|
||||
[address])
|
||||
open-oeth-chain-explorer (rn/use-callback
|
||||
#(rf/dispatch [:wallet/navigate-to-chain-explorer
|
||||
{:address address
|
||||
:network constants/optimism-network-name}])
|
||||
[address])
|
||||
open-arb-chain-explorer (rn/use-callback
|
||||
#(rf/dispatch [:wallet/navigate-to-chain-explorer
|
||||
{:address address
|
||||
:network constants/arbitrum-network-name}])
|
||||
[address])]
|
||||
[:<>
|
||||
[quo/information-box
|
||||
{:type :informative
|
||||
:icon :i/info
|
||||
:closable? false
|
||||
:style {:margin-horizontal 20 :margin-vertical 8}}
|
||||
[:<>
|
||||
(str (i18n/label :t/wallet-activity-beta-message) " ")
|
||||
[pressable-text
|
||||
{:on-press open-eth-chain-explorer
|
||||
:text (i18n/label :t/etherscan)}]
|
||||
", "
|
||||
[pressable-text
|
||||
{:on-press open-oeth-chain-explorer
|
||||
:text (i18n/label :t/op-explorer)}]
|
||||
(str ", " (string/lower-case (i18n/label :t/or)) " ")
|
||||
[pressable-text
|
||||
{:on-press open-arb-chain-explorer
|
||||
:text (i18n/label :t/arbiscan)}]
|
||||
"."]]
|
||||
(if (empty? activity-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:image (resources/get-themed-image :no-activity theme)}]
|
||||
[rn/section-list
|
||||
{:sections activity-list
|
||||
:sticky-section-headers-enabled false
|
||||
:style {:flex 1
|
||||
:padding-horizontal 8}
|
||||
:content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height}
|
||||
:render-fn activity-item
|
||||
:render-section-header-fn section-header}])]))
|
||||
(let [theme (quo.theme/use-theme)
|
||||
activity-list (rf/sub [:wallet/activities-for-current-viewing-account])]
|
||||
(if (empty? activity-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:image (resources/get-themed-image :no-activity theme)}]
|
||||
[rn/section-list
|
||||
{:sections activity-list
|
||||
:sticky-section-headers-enabled false
|
||||
:style {:flex 1
|
||||
:padding-horizontal 8}
|
||||
:content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height}
|
||||
:render-fn activity-item
|
||||
:render-section-header-fn (fn [{:keys [title]}] [quo/divider-date title])}])))
|
||||
|
||||
@@ -84,10 +84,10 @@
|
||||
[]
|
||||
(let [{:keys [bottom]} (safe-area/get-insets)
|
||||
{:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
sessions (rf/sub
|
||||
[:wallet-connect/sessions-for-current-account-and-networks])
|
||||
theme (quo.theme/use-theme)]
|
||||
[:wallet-connect/sessions-for-current-account])
|
||||
theme (quo.theme/use-theme)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[rn/view {:flex 1}
|
||||
[header
|
||||
{:title (i18n/label :t/connected-dapps)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils.money :as money]
|
||||
[utils.number :as utils.number]
|
||||
@@ -189,77 +188,3 @@
|
||||
:removed-account-addresses removed-account-addresses
|
||||
:updated-keypairs-by-id updated-keypairs-by-id
|
||||
:updated-accounts-by-address updated-accounts-by-address}))
|
||||
|
||||
(defn- rename-keys-to-kebab-case
|
||||
[m]
|
||||
(set/rename-keys m (zipmap (keys m) (map transforms/->kebab-case-keyword (keys m)))))
|
||||
|
||||
(defn rpc->suggested-routes
|
||||
[suggested-routes]
|
||||
(cond
|
||||
(map? suggested-routes)
|
||||
(into {}
|
||||
(for [[k v] (rename-keys-to-kebab-case suggested-routes)]
|
||||
[k (rpc->suggested-routes v)]))
|
||||
|
||||
(vector? suggested-routes)
|
||||
(map rpc->suggested-routes suggested-routes)
|
||||
|
||||
:else suggested-routes))
|
||||
|
||||
(def ^:private precision 6)
|
||||
|
||||
(defn new->old-route-path
|
||||
[new-path]
|
||||
(let [bonder-fees (:tx-bonder-fees new-path)
|
||||
token-fees (+ (money/wei->ether bonder-fees)
|
||||
(money/wei->ether
|
||||
(:tx-token-fees new-path)))]
|
||||
{:from (:from-chain new-path)
|
||||
:amount-in-locked (:amount-in-locked new-path)
|
||||
:amount-in (:amount-in new-path)
|
||||
:max-amount-in "0x0"
|
||||
:gas-fees {:gas-price "0"
|
||||
:base-fee (send-utils/convert-to-gwei (:tx-base-fee
|
||||
new-path)
|
||||
precision)
|
||||
:max-priority-fee-per-gas (send-utils/convert-to-gwei (:tx-priority-fee
|
||||
new-path)
|
||||
precision)
|
||||
:max-fee-per-gas-low (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:low])
|
||||
precision)
|
||||
:max-fee-per-gas-medium (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:medium])
|
||||
precision)
|
||||
:max-fee-per-gas-high (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:high])
|
||||
precision)
|
||||
:l-1-gas-fee (send-utils/convert-to-gwei (:tx-l-1-fee
|
||||
new-path)
|
||||
precision)
|
||||
:eip-1559-enabled true}
|
||||
:bridge-name (:processor-name new-path)
|
||||
:amount-out (:amount-out new-path)
|
||||
:approval-contract-address (:approval-contract-address new-path)
|
||||
:approval-required (:approval-required new-path)
|
||||
:estimated-time (:estimated-time new-path)
|
||||
:approval-gas-fees (* (money/wei->ether (get-in new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:medium]))
|
||||
(:approval-gas-amount new-path))
|
||||
:to (:to-chain new-path)
|
||||
:bonder-fees bonder-fees
|
||||
:approval-amount-required (:approval-amount-required new-path)
|
||||
;; :cost () ;; tbd not used on desktop
|
||||
:token-fees token-fees
|
||||
:gas-amount (:tx-gas-amount new-path)}))
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
(ns status-im.contexts.wallet.send.events
|
||||
(:require
|
||||
[camel-snake-kebab.extras :as cske]
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible.utils]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.money :as money]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-send-data
|
||||
(fn [{:keys [db]}]
|
||||
@@ -23,82 +24,86 @@
|
||||
{:db (assoc-in db [:wallet :ui :send :select-address-tab] tab)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-success
|
||||
(fn [{:keys [db]} [suggested-routes-data]]
|
||||
(let [chosen-route (:best suggested-routes-data)
|
||||
{:keys [token collectible token-display-name
|
||||
receiver-networks
|
||||
receiver-network-values
|
||||
sender-network-values tx-type
|
||||
disabled-from-chain-ids
|
||||
from-locked-amounts]} (get-in db [:wallet :ui :send])
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks
|
||||
(map #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain
|
||||
{:route chosen-route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:receiver? false})
|
||||
from-network-values-for-ui (send-utils/network-values-for-ui
|
||||
from-network-amounts-by-chain)
|
||||
to-network-amounts-by-chain (send-utils/network-amounts-by-chain
|
||||
{:route chosen-route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:receiver? true})
|
||||
to-network-values-for-ui (send-utils/network-values-for-ui
|
||||
to-network-amounts-by-chain)
|
||||
sender-possible-chain-ids (map :chain-id sender-network-values)
|
||||
sender-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values
|
||||
(if (= tx-type :tx/bridge)
|
||||
from-network-values-for-ui
|
||||
(send-utils/add-zero-values-to-network-values
|
||||
from-network-values-for-ui
|
||||
sender-possible-chain-ids))
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:from-locked-amounts from-locked-amounts
|
||||
:tx-type tx-type
|
||||
:receiver? false})
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
sender-network-values))
|
||||
receiver-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values to-network-values-for-ui
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:receiver? true})
|
||||
(->
|
||||
(fn [{:keys [db]} [suggested-routes timestamp]]
|
||||
(when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp)
|
||||
(let [suggested-routes-data (cske/transform-keys transforms/->kebab-case-keyword
|
||||
suggested-routes)
|
||||
chosen-route (:best suggested-routes-data)
|
||||
token (get-in db [:wallet :ui :send :token])
|
||||
collectible (get-in db [:wallet :ui :send :collectible])
|
||||
token-display-name (get-in db [:wallet :ui :send :token-display-name])
|
||||
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 (get-in db [:wallet :ui :send :disabled-from-chain-ids] [])
|
||||
from-locked-amounts (get-in db [:wallet :ui :send :from-locked-amounts] {})
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks (mapv #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:receiver? false})
|
||||
from-network-values-for-ui (send-utils/network-values-for-ui from-network-amounts-by-chain)
|
||||
to-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:receiver? true})
|
||||
to-network-values-for-ui (send-utils/network-values-for-ui to-network-amounts-by-chain)
|
||||
sender-possible-chain-ids (mapv :chain-id sender-network-values)
|
||||
sender-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values
|
||||
(if (= tx-type :tx/bridge)
|
||||
from-network-values-for-ui
|
||||
(send-utils/add-zero-values-to-network-values
|
||||
from-network-values-for-ui
|
||||
sender-possible-chain-ids))
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:from-locked-amounts from-locked-amounts
|
||||
:tx-type tx-type
|
||||
:receiver? false})
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
receiver-network-values)
|
||||
vec
|
||||
(conj {:type :edit})))
|
||||
network-links (when routes-available?
|
||||
(send-utils/network-links chosen-route
|
||||
sender-network-values
|
||||
receiver-network-values))]
|
||||
{:db (update-in db
|
||||
[:wallet :ui :send]
|
||||
assoc
|
||||
:suggested-routes suggested-routes-data
|
||||
:route chosen-route
|
||||
:from-values-by-chain from-network-values-for-ui
|
||||
:to-values-by-chain to-network-values-for-ui
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values
|
||||
:network-links network-links
|
||||
:loading-suggested-routes? false)})))
|
||||
sender-network-values))
|
||||
receiver-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values to-network-values-for-ui
|
||||
: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-loading-network-amounts-to-zero
|
||||
receiver-network-values)
|
||||
vec
|
||||
(conj {:type :edit})))
|
||||
|
||||
network-links (when routes-available?
|
||||
(send-utils/network-links chosen-route
|
||||
sender-network-values
|
||||
receiver-network-values))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :suggested-routes] suggested-routes-data)
|
||||
(assoc-in [:wallet :ui :send :route] chosen-route)
|
||||
(assoc-in [:wallet :ui :send :from-values-by-chain] from-network-values-for-ui)
|
||||
(assoc-in [:wallet :ui :send :to-values-by-chain] to-network-values-for-ui)
|
||||
(assoc-in [:wallet :ui :send :sender-network-values] sender-network-values)
|
||||
(assoc-in [:wallet :ui :send :receiver-network-values] receiver-network-values)
|
||||
(assoc-in [:wallet :ui :send :network-links] network-links)
|
||||
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))}))))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-error
|
||||
(fn [{:keys [db]} [error-message]]
|
||||
(fn [{:keys [db]} [error]]
|
||||
(let [cleaned-sender-network-values (-> (get-in db [:wallet :ui :send :sender-network-values])
|
||||
(send-utils/reset-loading-network-amounts-to-zero))
|
||||
cleaned-receiver-network-values (-> (get-in db [:wallet :ui :send :receiver-network-values])
|
||||
@@ -115,7 +120,7 @@
|
||||
[:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text error-message}]]]})))
|
||||
:text (:message error)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-suggested-routes
|
||||
(fn [{:keys [db]}]
|
||||
@@ -130,7 +135,8 @@
|
||||
:sender-network-values
|
||||
:receiver-network-values
|
||||
:network-links
|
||||
:loading-suggested-routes?)}))
|
||||
:loading-suggested-routes?
|
||||
:suggested-routes-call-timestamp)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-send-address
|
||||
(fn [{:keys [db]}]
|
||||
@@ -171,7 +177,7 @@
|
||||
(assoc-in [:wallet :ui :send :receiver-preferred-networks] receiver-networks)
|
||||
(assoc-in [:wallet :ui :send :receiver-networks] receiver-networks))
|
||||
:fx [(when (and collectible-tx? one-collectible?)
|
||||
[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]])
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
@@ -183,7 +189,7 @@
|
||||
(fn [{:keys [db]} [selected-networks]]
|
||||
(let [amount (get-in db [:wallet :ui :send :amount])]
|
||||
{:db (assoc-in db [:wallet :ui :send :receiver-networks] selected-networks)
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount amount}]]]})))
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-to-send
|
||||
@@ -294,7 +300,7 @@
|
||||
one-collectible?
|
||||
(assoc-in [:wallet :ui :send :amount] 1))
|
||||
:fx [(when (and one-collectible? recipient-set?)
|
||||
[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]])
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen current-screen
|
||||
@@ -305,7 +311,7 @@
|
||||
:wallet/set-collectible-amount-to-send
|
||||
(fn [{db :db} [{:keys [stack-id amount]}]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount amount}]]
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
@@ -341,7 +347,7 @@
|
||||
(fn [{:keys [db]}]
|
||||
(let [keys-to-remove [:to-values-by-chain :network-links :sender-network-values :route
|
||||
:receiver-network-values :suggested-routes :from-values-by-chain
|
||||
:loading-suggested-routes?]]
|
||||
:loading-suggested-routes? :suggested-routes-call-timestamp]]
|
||||
{:db (update-in db [:wallet :ui :send] #(apply dissoc % keys-to-remove))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/disable-from-networks
|
||||
@@ -376,67 +382,74 @@
|
||||
(when (empty? sender-network-values) :sender-network-values)
|
||||
(when (empty? receiver-network-values) :receiver-network-values)))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/start-get-suggested-routes
|
||||
(fn [{:keys [db]} [{:keys [amount amount-out updated-token] :as args :or {amount-out "0"}}]]
|
||||
(rf/reg-event-fx :wallet/get-suggested-routes
|
||||
(fn [{:keys [db now]} [{:keys [amount updated-token]}]]
|
||||
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
||||
{:keys [token tx-type collectible to-address
|
||||
receiver-networks disabled-from-chain-ids
|
||||
from-locked-amounts bridge-to-chain-id]
|
||||
:or {token updated-token}} (get-in db [:wallet :ui :send])
|
||||
token (or updated-token (get-in db [:wallet :ui :send :token]))
|
||||
transaction-type (get-in db [:wallet :ui :send :tx-type])
|
||||
collectible (get-in db [:wallet :ui :send :collectible])
|
||||
to-address (get-in db [:wallet :ui :send :to-address])
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
disabled-from-chain-ids (or (get-in db [:wallet :ui :send :disabled-from-chain-ids]) [])
|
||||
from-locked-amounts (or (get-in db [:wallet :ui :send :from-locked-amounts]) {})
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
networks ((if test-networks-enabled? :test :prod)
|
||||
(get-in db [:wallet :networks]))
|
||||
network-chain-ids (map :chain-id networks)
|
||||
bridge-to-chain-id (get-in db [:wallet :ui :send :bridge-to-chain-id])
|
||||
token-decimal (when token (:decimals token))
|
||||
token-id (utils/format-token-id token collectible)
|
||||
to-token-id ""
|
||||
network-preferences (if token [] [(get-in collectible [:id :contract-id :chain-id])])
|
||||
gas-rates constants/gas-rate-medium
|
||||
to-hex (fn [v] (send-utils/amount-in-hex v (if token token-decimal 0)))
|
||||
amount-in (to-hex amount)
|
||||
amount-out (to-hex amount-out)
|
||||
from-address wallet-address
|
||||
disabled-to-chain-ids (if (= tx-type :tx/bridge)
|
||||
disabled-from-chain-ids disabled-from-chain-ids
|
||||
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 %)
|
||||
receiver-networks)))
|
||||
network-chain-ids))
|
||||
from-locked-amount (update-vals from-locked-amounts to-hex)
|
||||
transaction-type (case tx-type
|
||||
: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)
|
||||
transaction-type-param (case transaction-type
|
||||
: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))
|
||||
sender-token-available-networks-for-suggested-routes
|
||||
(when token
|
||||
(send-utils/token-available-networks-for-suggested-routes
|
||||
{:balances-per-chain balances-per-chain
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:only-with-balance? true}))
|
||||
(send-utils/token-available-networks-for-suggested-routes {:balances-per-chain
|
||||
balances-per-chain
|
||||
:disabled-chain-ids
|
||||
disabled-from-chain-ids
|
||||
:only-with-balance? true}))
|
||||
receiver-token-available-networks-for-suggested-routes
|
||||
(when token
|
||||
(send-utils/token-available-networks-for-suggested-routes
|
||||
{:balances-per-chain balances-per-chain
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:only-with-balance? false}))
|
||||
token-networks-ids (when token (map #(:chain-id %) (:networks token)))
|
||||
(send-utils/token-available-networks-for-suggested-routes {:balances-per-chain
|
||||
balances-per-chain
|
||||
:disabled-chain-ids
|
||||
disabled-from-chain-ids
|
||||
:only-with-balance? false}))
|
||||
token-networks-ids (when token (mapv #(:chain-id %) (:networks token)))
|
||||
sender-network-values (when sender-token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
{:valid-networks
|
||||
(if (= tx-type :tx/bridge)
|
||||
(if (= transaction-type :tx/bridge)
|
||||
(remove #(= bridge-to-chain-id %)
|
||||
sender-token-available-networks-for-suggested-routes)
|
||||
sender-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 tx-type
|
||||
:tx-type transaction-type
|
||||
:receiver? false}))
|
||||
receiver-network-values (when receiver-token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
{:valid-networks
|
||||
(if (= tx-type :tx/bridge)
|
||||
(if (= transaction-type :tx/bridge)
|
||||
(filter
|
||||
#(= bridge-to-chain-id %)
|
||||
receiver-token-available-networks-for-suggested-routes)
|
||||
@@ -444,70 +457,40 @@
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:tx-type transaction-type
|
||||
:receiver? true}))
|
||||
params [{:uuid (str (random-uuid))
|
||||
:sendType transaction-type
|
||||
:addrFrom from-address
|
||||
:addrTo to-address
|
||||
:amountIn amount-in
|
||||
:amountOut amount-out
|
||||
:tokenID token-id
|
||||
:toTokenID to-token-id
|
||||
:disabledFromChainIDs disabled-from-chain-ids
|
||||
:disabledToChainIDs disabled-to-chain-ids
|
||||
:gasFeeMode gas-rates
|
||||
:fromLockedAmount from-locked-amount
|
||||
:username (:username args)
|
||||
:publicKey (:publicKey args)
|
||||
:packID (:packID args)}]]
|
||||
(when (and to-address from-address amount-in token-id)
|
||||
{:db (update-in db
|
||||
[:wallet :ui :send]
|
||||
#(-> %
|
||||
(assoc :amount amount
|
||||
:loading-suggested-routes? true
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values)
|
||||
(dissoc :network-links)
|
||||
(cond-> token (assoc :token token))))
|
||||
:json-rpc/call [{:method "wallet_getSuggestedRoutesV2Async"
|
||||
:params params
|
||||
:on-error (fn [error]
|
||||
request-params [transaction-type-param
|
||||
from-address
|
||||
to-address
|
||||
amount-in
|
||||
token-id
|
||||
to-token-id
|
||||
disabled-from-chain-ids
|
||||
disabled-to-chain-ids
|
||||
network-preferences
|
||||
gas-rates
|
||||
from-locked-amount]]
|
||||
{:db (cond-> db
|
||||
:always (assoc-in [:wallet :ui :send :amount] amount)
|
||||
:always (assoc-in [:wallet :ui :send :loading-suggested-routes?] true)
|
||||
:always (assoc-in [:wallet :ui :send :sender-network-values]
|
||||
sender-network-values)
|
||||
:always (assoc-in [:wallet :ui :send :receiver-network-values]
|
||||
receiver-network-values)
|
||||
:always (assoc-in [:wallet :ui :send :suggested-routes-call-timestamp] now)
|
||||
:always (update-in [:wallet :ui :send] dissoc :network-links)
|
||||
token (assoc-in [:wallet :ui :send :token] token))
|
||||
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
|
||||
:params request-params
|
||||
:on-success (fn [suggested-routes]
|
||||
(rf/dispatch [:wallet/suggested-routes-success suggested-routes
|
||||
now]))
|
||||
:on-error (fn [error]
|
||||
(rf/dispatch [:wallet/suggested-routes-error error])
|
||||
(log/error "failed to get suggested routes (async)"
|
||||
{:event :wallet/start-get-suggested-routes
|
||||
:error (:message error)
|
||||
:params params}))}]}))))
|
||||
|
||||
(rf/reg-event-fx :wallet/stop-get-suggested-routes
|
||||
(fn []
|
||||
{:fx [[:dispatch [:wallet/clean-routes-calculation]]]
|
||||
:json-rpc/call [{:method "wallet_stopSuggestedRoutesV2AsyncCalcualtion"
|
||||
:params []
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to stop suggested routes calculation"
|
||||
{:event :wallet/stop-get-suggested-routes
|
||||
:error error}))}]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/handle-suggested-routes
|
||||
(fn [_ data]
|
||||
(if-let [error (some-> data
|
||||
first
|
||||
:ErrorResponse
|
||||
(#(if (= (:code %) "0") "An error occurred" (:details %))))]
|
||||
(do
|
||||
(log/error "failed to get suggested routes (async)"
|
||||
{:event :wallet/handle-suggested-routes
|
||||
:error error})
|
||||
{:fx [[:dispatch [:wallet/suggested-routes-error error]]]})
|
||||
(let [suggested-routes-new-data (data-store/rpc->suggested-routes data)
|
||||
suggested-routes (-> suggested-routes-new-data
|
||||
first
|
||||
(update :best #(map data-store/new->old-route-path %))
|
||||
(update :candidates #(map data-store/new->old-route-path %)))]
|
||||
{:fx [[:dispatch
|
||||
[:wallet/suggested-routes-success suggested-routes]]]}))))
|
||||
(log/error "failed to get suggested routes"
|
||||
{:event :wallet/get-suggested-routes
|
||||
:error error
|
||||
:params request-params}))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/add-authorized-transaction
|
||||
(fn [{:keys [db]} [transaction]]
|
||||
@@ -694,13 +677,11 @@
|
||||
:transfer-type transaction-type-param})
|
||||
transaction-paths
|
||||
sha3-pwd]]
|
||||
(log/info "multi transaction called")
|
||||
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||
:params request-params
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send transaction"
|
||||
{:event :wallet/send-transaction
|
||||
@@ -711,23 +692,6 @@
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/proceed-with-transactions-signatures
|
||||
(fn [_ [signatures]]
|
||||
{:json-rpc/call [{:method "wallet_proceedWithTransactionsSignatures"
|
||||
:params [signatures]
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to proceed-with-transactions-signatures"
|
||||
{:event :wallet/proceed-with-transactions-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/select-from-account
|
||||
(fn [{db :db} [{:keys [address stack-id network-details start-flow?]}]]
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
(h/deftest-event :wallet/set-collectible-amount-to-send
|
||||
[event-id dispatch]
|
||||
(let [initial-db {:wallet {:ui {:send nil}}}
|
||||
expected-fx [[:dispatch [:wallet/start-get-suggested-routes {:amount 10}]]
|
||||
expected-fx [[:dispatch [:wallet/get-suggested-routes {:amount 10}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen nil :flow-id :wallet-send-flow}]]]
|
||||
@@ -273,18 +273,19 @@
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send
|
||||
{:other-props :value
|
||||
:suggested-routes ["1" "2"]
|
||||
:route "1"
|
||||
:amount 10
|
||||
: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}]
|
||||
:sender-network-values [:eth :arb1]
|
||||
:receiver-network-values [:eth :arb1]
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]
|
||||
:loading-suggested-routes? false}}}})
|
||||
{:other-props :value
|
||||
:suggested-routes ["1" "2"]
|
||||
:route "1"
|
||||
:amount 10
|
||||
: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}]
|
||||
:sender-network-values [:eth :arb1]
|
||||
:receiver-network-values [:eth :arb1]
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]
|
||||
:loading-suggested-routes? false
|
||||
:suggested-routes-call-timestamp ["1" "2"]}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :suggested-routes)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :route)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
|
||||
@@ -295,6 +296,8 @@
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :network-links)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:loading-suggested-routes?)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:suggested-routes-call-timestamp)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/suggested-routes-error
|
||||
@@ -321,7 +324,7 @@
|
||||
:receiver-network-values receiver-network-amounts
|
||||
:route :values
|
||||
:loading-suggested-routes? true}}}})
|
||||
(is (match? expected-result (dispatch [event-id "error"])))))
|
||||
(is (match? expected-result (dispatch [event-id {:message "error"}])))))
|
||||
|
||||
(h/deftest-event :wallet/reset-network-amounts-to-zero
|
||||
[event-id dispatch]
|
||||
@@ -435,7 +438,7 @@
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]]
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount 1}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
[{:keys [amount bounce-duration-ms token valid-input?]}]
|
||||
(if valid-input?
|
||||
(debounce/debounce-and-dispatch
|
||||
[:wallet/start-get-suggested-routes
|
||||
[:wallet/get-suggested-routes
|
||||
{:amount amount
|
||||
:updated-token token}]
|
||||
bounce-duration-ms)
|
||||
@@ -396,7 +396,7 @@
|
||||
(and (not should-try-again?) confirm-disabled?))
|
||||
:on-press (cond
|
||||
should-try-again?
|
||||
#(rf/dispatch [:wallet/start-get-suggested-routes
|
||||
#(rf/dispatch [:wallet/get-suggested-routes
|
||||
{:amount amount-in-crypto
|
||||
:updated-token token-by-symbol}])
|
||||
sending-to-unpreferred-networks?
|
||||
|
||||
@@ -257,8 +257,7 @@
|
||||
:transaction-type transaction-type}]
|
||||
(when (and (not loading-suggested-routes?) route (seq route))
|
||||
[standard-auth/slide-button
|
||||
{:keycard-supported? true
|
||||
:size :size-48
|
||||
{:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
@@ -266,7 +265,8 @@
|
||||
:customization-color account-color
|
||||
:on-auth-success #(rf/dispatch
|
||||
[:wallet/send-transaction
|
||||
(security/safe-unmask-data %)])
|
||||
(security/safe-unmask-data
|
||||
%)])
|
||||
:auth-button-label (i18n/label :t/confirm)}])]
|
||||
:gradient-cover? true
|
||||
:customization-color (:color account)}
|
||||
|
||||
@@ -242,10 +242,3 @@
|
||||
(defn tx-type-collectible?
|
||||
[tx-type]
|
||||
(contains? collectible-tx-set tx-type))
|
||||
|
||||
(defn convert-to-gwei
|
||||
[n precision]
|
||||
(-> n
|
||||
money/wei->gwei
|
||||
(money/with-precision precision)
|
||||
(str)))
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
:iconUrl (get-in session [:peer :metadata :icons 0])
|
||||
:url (get-in session [:peer :metadata :url])
|
||||
:accounts (get-in session [:namespaces :eip155 :accounts])
|
||||
:chains (get-in session [:namespaces :eip155 :chains])
|
||||
:disconnected false})
|
||||
|
||||
(defn filter-operable-accounts
|
||||
|
||||
@@ -14,20 +14,17 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/init
|
||||
(fn [{:keys [db]}]
|
||||
(let [network-status (:network/status db)
|
||||
web3-wallet-missing? (-> db :wallet-connect/web3-wallet boolean not)]
|
||||
(if (and (= network-status :online) web3-wallet-missing?)
|
||||
(do (log/info "Initialising WalletConnect SDK")
|
||||
{:fx [[:effects.wallet-connect/init
|
||||
{:on-success #(rf/dispatch [:wallet-connect/on-init-success %])
|
||||
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]})
|
||||
(let [network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:fx [[:effects.wallet-connect/init
|
||||
{:on-success #(rf/dispatch [:wallet-connect/on-init-success %])
|
||||
:on-fail #(rf/dispatch [:wallet-connect/on-init-fail %])}]]}
|
||||
;; NOTE: when offline, fetching persistent sessions only
|
||||
{:fx [[:dispatch [:wallet-connect/fetch-persisted-sessions]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-init-success
|
||||
(fn [{:keys [db]} [web3-wallet]]
|
||||
(log/info "WalletConnect SDK initialisation successful")
|
||||
{:db (assoc db :wallet-connect/web3-wallet web3-wallet)
|
||||
:fx [[:dispatch [:wallet-connect/register-event-listeners]]
|
||||
[:dispatch [:wallet-connect/fetch-persisted-sessions]]]}))
|
||||
@@ -35,9 +32,9 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reload-on-network-change
|
||||
(fn [{:keys [db]} [is-connected?]]
|
||||
(let [logged-in? (-> db :profile/profile boolean)]
|
||||
(when (and is-connected? logged-in?)
|
||||
(log/info "Re-Initialising WalletConnect SDK due to network change")
|
||||
(let [logged-in? (-> db :profile/profile boolean)
|
||||
web3-wallet-missing? (-> db :wallet-connect/web3-wallet boolean not)]
|
||||
(when (and is-connected? logged-in? web3-wallet-missing?)
|
||||
{:fx [[:dispatch [:wallet-connect/init]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
@@ -88,30 +85,23 @@
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet-connect/show-session-networks-unsupported-toast proposal]]
|
||||
[:dispatch
|
||||
[:wallet-connect/reject-session-proposal proposal]]]}))))
|
||||
[:wallet-connect/session-networks-unsupported proposal]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/show-session-networks-unsupported-toast
|
||||
:wallet-connect/session-networks-unsupported
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [{:keys [name url]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
(let [{:keys [name]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported
|
||||
{:dapp (wallet-connect-core/compute-dapp-name name url)})}]]]})))
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported {:dapp name})}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-request
|
||||
(fn [{:keys [db]} [event]]
|
||||
(if (wallet-connect-core/event-should-be-handled? db event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet-connect/send-response
|
||||
{:error (wallet-connect/get-sdk-error
|
||||
constants/wallet-connect-user-rejected-chains-error-key)}]]]})))
|
||||
(when (wallet-connect-core/event-should-be-handled? db event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-delete
|
||||
@@ -174,32 +164,23 @@
|
||||
current-address (get-in db [:wallet-connect/current-proposal :address])
|
||||
accounts (-> (partial wallet-connect-core/format-eip155-address current-address)
|
||||
(map session-networks))
|
||||
network-status (:network/status db)
|
||||
expiry (get-in current-proposal [:params :expiryTimestamp])]
|
||||
network-status (:network/status db)]
|
||||
(if (= network-status :online)
|
||||
{:db (assoc-in db [:wallet-connect/current-proposal :response-sent?] true)
|
||||
:fx [(if (wc-utils/timestamp-expired? expiry)
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :wallet-connect-proposal-expired
|
||||
:type :negative
|
||||
:text (i18n/label :t/wallet-connect-proposal-expired)}]]
|
||||
[:effects.wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal current-proposal
|
||||
:networks session-networks
|
||||
:accounts accounts
|
||||
:on-success (fn [approved-session]
|
||||
(log/info "Wallet Connect session approved")
|
||||
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
|
||||
(rf/dispatch [:wallet-connect/persist-session
|
||||
approved-session]))
|
||||
:on-fail (fn [error]
|
||||
(log/error "Wallet Connect session approval failed"
|
||||
{:error error
|
||||
:event :wallet-connect/approve-session})
|
||||
(rf/dispatch
|
||||
[:wallet-connect/reset-current-session-proposal]))}])
|
||||
{:fx [[:effects.wallet-connect/approve-session
|
||||
{:web3-wallet web3-wallet
|
||||
:proposal current-proposal
|
||||
:networks session-networks
|
||||
:accounts accounts
|
||||
:on-success (fn [approved-session]
|
||||
(log/info "Wallet Connect session approved")
|
||||
(rf/dispatch [:wallet-connect/reset-current-session-proposal])
|
||||
(rf/dispatch [:wallet-connect/persist-session approved-session]))
|
||||
:on-fail (fn [error]
|
||||
(log/error "Wallet Connect session approval failed"
|
||||
{:error error
|
||||
:event :wallet-connect/approve-session})
|
||||
(rf/dispatch
|
||||
[:wallet-connect/reset-current-session-proposal]))}]
|
||||
[:dispatch [:dismiss-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch [:wallet-connect/no-internet-toast]]]}))))
|
||||
|
||||
@@ -233,10 +214,7 @@
|
||||
|
||||
(not version-supported?)
|
||||
(i18n/label :t/wallet-connect-version-not-supported
|
||||
{:version version})
|
||||
|
||||
:else
|
||||
(i18n/label :t/something-went-wrong))}]]]}
|
||||
{:version version}))}]]]}
|
||||
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
|
||||
|
||||
;; We first load sessions from database, then we initiate a call to Wallet Connect SDK and
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.modals.common.header.style
|
||||
(:require [quo.foundations.typography :as typography]))
|
||||
|
||||
(def ^:private line-height (:line-height typography/heading-1))
|
||||
(ns status-im.contexts.wallet.wallet-connect.modals.common.header.style)
|
||||
|
||||
(def header-container
|
||||
{:padding-vertical 12
|
||||
:justify-content :flex-start
|
||||
:align-items :center
|
||||
:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:row-gap 2})
|
||||
{:padding-vertical 12})
|
||||
|
||||
(def word-container
|
||||
{:height line-height
|
||||
:justify-content :center})
|
||||
(def header-dapp-name
|
||||
{:margin-top -4})
|
||||
|
||||
(def dapp-container
|
||||
{:margin-top 0
|
||||
:height line-height})
|
||||
|
||||
(def account-container
|
||||
{:height line-height})
|
||||
(def header-account-name
|
||||
{:padding-top 4})
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.modals.common.header.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as core]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style]))
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as core]
|
||||
[status-im.contexts.wallet.wallet-connect.modals.common.header.style :as style]
|
||||
[utils.string]))
|
||||
|
||||
(defn view
|
||||
[{:keys [label dapp account]}]
|
||||
[rn/view {:style style/header-container}
|
||||
(let [{:keys [name iconUrl url]} dapp
|
||||
image-source (core/compute-dapp-icon-path iconUrl url)]
|
||||
[rn/view {:style style/dapp-container}
|
||||
[quo/summary-tag
|
||||
{:type :dapp
|
||||
:label name
|
||||
:image-source image-source}]])
|
||||
(for [word (string/split label #" ")]
|
||||
^{:key word}
|
||||
[rn/view {:style style/word-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold}
|
||||
(str " " word)]])
|
||||
(let [{:keys [emoji customization-color name]} account]
|
||||
[rn/view {:style style/account-container}
|
||||
[quo/summary-tag
|
||||
{:type :account
|
||||
:emoji emoji
|
||||
:label name
|
||||
:customization-color customization-color}]])])
|
||||
[rn/view
|
||||
{:style style/header-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold}
|
||||
(let [{:keys [name iconUrl url]} dapp
|
||||
image-source (core/compute-dapp-icon-path iconUrl url)]
|
||||
[rn/view {:style style/header-dapp-name}
|
||||
[quo/summary-tag
|
||||
{:type :dapp
|
||||
:label name
|
||||
:image-source image-source}]])
|
||||
(str " " label " ")
|
||||
(let [{:keys [emoji customization-color name]} account]
|
||||
[rn/view {:style style/header-account-name}
|
||||
[quo/summary-tag
|
||||
{:type :account
|
||||
:emoji emoji
|
||||
:label name
|
||||
:customization-color customization-color}]])]])
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:background :blur
|
||||
:on-press #(rf/dispatch [:wallet-connect/dismiss-request-modal])
|
||||
:on-press #(do (rf/dispatch [:wallet-connect/dismiss-request-modal])
|
||||
(rf/dispatch [:wallet-connect/reject-session-request]))
|
||||
:accessibility-label accessibility-label}])
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
network (rf/sub [:wallet-connect/current-request-network])
|
||||
{:keys [max-fees-fiat-formatted
|
||||
error-state]} (rf/sub [:wallet-connect/current-request-transaction-information])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet-connect/on-request-modal-dismissed]))
|
||||
[rn/view {:style (style/container bottom)}
|
||||
[quo/gradient-cover {:customization-color customization-color}]
|
||||
[page-nav/view
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
{:keys [customization-color]
|
||||
:as account} (rf/sub [:wallet-connect/current-request-account-details])
|
||||
dapp (rf/sub [:wallet-connect/current-request-dapp])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet-connect/on-request-modal-dismissed]))
|
||||
[rn/view {:style (style/container bottom)}
|
||||
[quo/gradient-cover {:customization-color customization-color}]
|
||||
[page-nav/view
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
network (rf/sub [:wallet-connect/current-request-network])
|
||||
{:keys [max-fees-fiat-formatted
|
||||
error-state]} (rf/sub [:wallet-connect/current-request-transaction-information])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet-connect/on-request-modal-dismissed]))
|
||||
[rn/view {:style (style/container bottom)}
|
||||
[quo/gradient-cover {:customization-color customization-color}]
|
||||
[page-nav/view
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user