Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52fa1d56fd | ||
|
|
5033b68045 | ||
|
|
5b1ea1e59a |
@@ -143,10 +143,6 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_17
|
||||
}
|
||||
// Disable default lint checks to remove redundant lintVitalReportRelease task
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
|
||||
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
|
||||
externalNativeBuild {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.17'
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
|
||||
/* 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.17'
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.17'
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.17'
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
|
||||
/* 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.17'
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Fallback versions for each dependency
|
||||
readonly FOOJAY_FALLBACK="0.5.0"
|
||||
readonly KOTLIN_FALLBACK="1.8.0"
|
||||
readonly TOOLS_FALLBACK="3.5.4"
|
||||
readonly HERMES_FALLBACK="0.73.5"
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
cd "${GIT_ROOT}"
|
||||
|
||||
get_version() {
|
||||
local file="$1"
|
||||
local pattern="$2"
|
||||
local fallback="$3"
|
||||
local version
|
||||
|
||||
if [[ ! -f "$file" ]]; then
|
||||
echo "$fallback"
|
||||
return 0
|
||||
fi
|
||||
|
||||
version=$(grep "$pattern" "$file" 2>/dev/null | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.*[0-9]*" | tail -n1 || echo "$fallback")
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
foojay_version=$(get_version "./node_modules/@react-native/gradle-plugin/settings.gradle.kts" "foojay.*version" "$FOOJAY_FALLBACK")
|
||||
kotlin_version=$(get_version "./node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml" "kotlin =" "$KOTLIN_FALLBACK")
|
||||
tools_version=$(get_version "./patches/BlurView-build.gradle.patch" "gradle:" "$TOOLS_FALLBACK")
|
||||
hermes_version=$(get_version "./node_modules/react-native/ReactAndroid/gradle.properties" "VERSION_NAME" "$HERMES_FALLBACK")
|
||||
|
||||
|
||||
cat << EOF
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:$foojay_version
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:$kotlin_version
|
||||
com.android.tools.build:gradle:$tools_version
|
||||
com.facebook.react:hermes-android:$hermes_version
|
||||
EOF
|
||||
@@ -38,10 +38,16 @@ function gen_deps_list() {
|
||||
echo -e "${CLR}Found ${GRN}$(wc -l < "${DEPS_LIST}")${RST} direct dependencies..."
|
||||
}
|
||||
|
||||
# FIXME: Fix for missing packages.
|
||||
# FIXME: Temporary fix for missing packages.
|
||||
# https://github.com/status-im/status-mobile/issues/15447
|
||||
function add_deps_hack() {
|
||||
"${CUR_DIR}/deps_versions.sh" >> "${DEPS_LIST}"
|
||||
echo -n \
|
||||
'org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
|
||||
com.android.tools.build:gradle:3.5.4
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
com.facebook.react:hermes-android:0.73.5' \
|
||||
>> "${DEPS_LIST}"
|
||||
}
|
||||
|
||||
# Find download URLs for each dependency.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script generates a list of dependencies for the main project and its
|
||||
# sub-projects defined using Gradle config files. It uses github-dependency-graph-gradle-plugin:
|
||||
# https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#using-the-plugin-to-generate-dependency-reports
|
||||
# sub-projects defined using Gradle config files. It parses Gradle output of
|
||||
# 'dependencies' and 'buildEnvironment` tasks using AWK.
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ let
|
||||
repo = "status-go";
|
||||
rev = "unknown";
|
||||
shortRev = rev;
|
||||
version = "unknown";
|
||||
cleanVersion = version;
|
||||
rawVersion = "develop";
|
||||
cleanVersion = rawVersion;
|
||||
goPackagePath = "github.com/${owner}/${repo}";
|
||||
# We use builtins.path so that we can name the resulting derivation,
|
||||
# Normally the name would not be deterministic, taken from the checkout directory.
|
||||
@@ -43,6 +43,7 @@ let
|
||||
inherit (versionJSON) owner repo version;
|
||||
rev = versionJSON.commit-sha1;
|
||||
shortRev = strings.substring 0 7 rev;
|
||||
rawVersion = versionJSON.version;
|
||||
cleanVersion = lib.sanitizeVersion versionJSON.version;
|
||||
# Need to pretend this is from status-im to let Go build it.
|
||||
goPackagePath = "github.com/status-im/${repo}";
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 278 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
@@ -10,10 +10,11 @@
|
||||
([{:keys [style]} child]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:style [style
|
||||
{:pointer-events :box-none
|
||||
:background-color (or (:background-color style)
|
||||
(colors/theme-colors colors/white colors/neutral-80 theme))}]}
|
||||
{:style (assoc style
|
||||
:pointer-events :box-none
|
||||
:background-color
|
||||
(or (:background-color style)
|
||||
(colors/theme-colors colors/white colors/neutral-80 theme)))}
|
||||
child])))
|
||||
|
||||
(def view (if platform/ios? blur/view view-android))
|
||||
|
||||
@@ -56,63 +56,62 @@
|
||||
24 8
|
||||
12))})
|
||||
|
||||
(defn container-styles
|
||||
(defn style-container
|
||||
[{:keys [size disabled? border-radius background-color border-color icon-only? icon-top
|
||||
icon-left icon-right inner-style]}]
|
||||
[{:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if icon-top :column :row)
|
||||
:padding-horizontal (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 (if border-color 10 11)
|
||||
40 16
|
||||
32 12
|
||||
24 7
|
||||
16))
|
||||
:padding-left (when-not (or icon-only? icon-left)
|
||||
(case size
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
24 8
|
||||
16))
|
||||
:padding-right (when-not (or icon-only? icon-right)
|
||||
(case size
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
24 8
|
||||
16))
|
||||
:padding-top (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 (if border-color 8 9)
|
||||
32 (if border-color 4 5)
|
||||
24 0
|
||||
(if border-color 8 9)))
|
||||
:padding-bottom (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
24 0
|
||||
9))
|
||||
:overflow :hidden
|
||||
:background-color (if disabled? (colors/alpha background-color 0.3) background-color)
|
||||
:border-radius (if border-radius
|
||||
border-radius
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8
|
||||
12))
|
||||
:border-color border-color
|
||||
:border-width (when border-color 1)}
|
||||
(when icon-only?
|
||||
{:width size})
|
||||
(when border-color
|
||||
{:border-color border-color
|
||||
:border-width 1})
|
||||
inner-style])
|
||||
icon-left icon-right]}]
|
||||
(merge {:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if icon-top :column :row)
|
||||
:padding-horizontal (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 (if border-color 10 11)
|
||||
40 16
|
||||
32 12
|
||||
24 7
|
||||
16))
|
||||
:padding-left (when-not (or icon-only? icon-left)
|
||||
(case size
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
24 8
|
||||
16))
|
||||
:padding-right (when-not (or icon-only? icon-right)
|
||||
(case size
|
||||
56 nil
|
||||
40 16
|
||||
32 12
|
||||
24 8
|
||||
16))
|
||||
:padding-top (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 (if border-color 8 9)
|
||||
32 (if border-color 4 5)
|
||||
24 0
|
||||
(if border-color 8 9)))
|
||||
:padding-bottom (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
24 0
|
||||
9))
|
||||
:overflow :hidden
|
||||
:background-color (if disabled? (colors/alpha background-color 0.3) background-color)
|
||||
:border-radius (if border-radius
|
||||
border-radius
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8
|
||||
12))
|
||||
:border-color border-color
|
||||
:border-width (when border-color 1)}
|
||||
(when icon-only?
|
||||
{:width size})
|
||||
(when border-color
|
||||
{:border-color border-color
|
||||
:border-width 1})))
|
||||
|
||||
@@ -62,9 +62,12 @@
|
||||
:on-press on-press
|
||||
:allow-multiple-presses? allow-multiple-presses?
|
||||
:on-long-press on-long-press
|
||||
:style [(style/shape-style-container size border-radius) container-style]}
|
||||
:style (merge
|
||||
(style/shape-style-container size border-radius)
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (style/container-styles {:size size
|
||||
{:style (merge
|
||||
(style/style-container {:size size
|
||||
:disabled? disabled?
|
||||
:border-radius border-radius
|
||||
:background-color background-color
|
||||
@@ -72,8 +75,8 @@
|
||||
:icon-only? icon-only?
|
||||
:icon-top icon-top
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right
|
||||
:inner-style inner-style})}
|
||||
:icon-right icon-right})
|
||||
inner-style)}
|
||||
(when overlay-customization-color
|
||||
[customization-colors/overlay
|
||||
{:customization-color overlay-customization-color
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
:error
|
||||
[info-message/view
|
||||
{:icon :i/alert
|
||||
{:icon :i/info
|
||||
:size :default
|
||||
:status :error}
|
||||
text]
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
(def content
|
||||
{:align-items :flex-start
|
||||
:margin-top 8
|
||||
:margin-bottom (+ (safe-area/get-bottom) 12)})
|
||||
|
||||
(defn title
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
theme)
|
||||
:margin-bottom 8})
|
||||
{:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
theme)})
|
||||
|
||||
@@ -24,13 +24,12 @@
|
||||
:always-bounce-vertical false
|
||||
:content-inset-adjustment-behavior :never}
|
||||
[rn/view {:style style/container}
|
||||
(when title
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:accessibility-label :documentation-drawer-title
|
||||
:style (style/title theme)
|
||||
:weight :semi-bold}
|
||||
title])
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:accessibility-label :documentation-drawer-title
|
||||
:style (style/title theme)
|
||||
:weight :semi-bold}
|
||||
title]
|
||||
[rn/view {:style style/content :accessibility-label :documentation-drawer-content}
|
||||
content
|
||||
(when show-button?
|
||||
|
||||
@@ -57,10 +57,17 @@
|
||||
:container-style style/keycard-icon}])])
|
||||
|
||||
(defn- account-subtitle
|
||||
[{:keys [description]}]
|
||||
[address-text/view
|
||||
{:address description
|
||||
:format :short}])
|
||||
[{:keys [networks theme blur? description]}]
|
||||
(if networks
|
||||
[address-text/view
|
||||
{:networks networks
|
||||
:address description
|
||||
:format :short}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style (style/description theme blur?)}
|
||||
description]))
|
||||
|
||||
(defn- default-keypair-subtitle
|
||||
[{:keys [description theme blur?]}]
|
||||
@@ -102,7 +109,7 @@
|
||||
description])
|
||||
|
||||
(defn- subtitle
|
||||
[{:keys [type theme blur? stored description community-name community-logo
|
||||
[{:keys [type theme blur? stored networks description community-name community-logo
|
||||
context-tag-type account-name emoji customization-color full-name profile-picture context
|
||||
icon]}]
|
||||
(cond
|
||||
@@ -114,7 +121,8 @@
|
||||
|
||||
(= :account type)
|
||||
[account-subtitle
|
||||
{:theme theme
|
||||
{:networks networks
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:description description}]
|
||||
|
||||
@@ -197,11 +205,11 @@
|
||||
(defn view
|
||||
[{:keys [title title-icon type description blur? community-name community-logo button-icon
|
||||
account-name emoji context-tag-type button-type container-style
|
||||
on-button-press on-button-long-press profile-picture stored label full-name
|
||||
on-button-press on-button-long-press profile-picture stored networks label full-name
|
||||
button-disabled? account-avatar-emoji account-avatar-type customization-color icon-avatar
|
||||
context icon]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style [style/container container-style]}
|
||||
[rn/view {:style (merge style/container container-style)}
|
||||
(when (left-image-supported-types type)
|
||||
[rn/view {:style style/left-container}
|
||||
[left-image
|
||||
@@ -225,6 +233,7 @@
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:stored stored
|
||||
:networks networks
|
||||
:description description
|
||||
:community-name community-name
|
||||
:community-logo community-logo
|
||||
|
||||
@@ -35,4 +35,4 @@
|
||||
(def image-placeholder
|
||||
{:width 80
|
||||
:height 80
|
||||
:background-color colors/danger-50})
|
||||
:background-color colors/danger})
|
||||
|
||||
@@ -18,5 +18,5 @@
|
||||
:colors [color-top color-bottom]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 0 :y 1}
|
||||
:style [(style/root-container opacity height)
|
||||
container-style]}])))
|
||||
:style (merge (style/root-container opacity height)
|
||||
container-style)}])))
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)))
|
||||
|
||||
(defn address-input
|
||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan on-paste
|
||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||
valid-ens-or-address? container-style]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
@@ -82,13 +82,12 @@
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
on-paste (rn/use-callback #(if (fn? on-paste)
|
||||
(on-paste on-change)
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(on-change clipboard)))))
|
||||
[on-paste])
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(on-change clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(on-change "")
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color colors/danger-50-opa-40
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
@@ -48,7 +48,7 @@
|
||||
:placeholder (colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color colors/danger-50-opa-40
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
:char-limit char-limit
|
||||
:theme theme}])
|
||||
[rn/view
|
||||
{:style [(style/input-container colors-by-status small? disabled?) input-container-style]}
|
||||
{:style (merge (style/input-container colors-by-status small? disabled?) input-container-style)}
|
||||
(when-let [{:keys [icon-name]} left-icon]
|
||||
[left-accessory
|
||||
{:variant-colors variant-colors
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "keycard component"
|
||||
(let [holder-name "Alisha"]
|
||||
(h/test "Render of keycard component when: holder-name prop is set"
|
||||
(h/test "Render of keycard component when: holder-name prop is not set"
|
||||
(h/render [keycard/keycard])
|
||||
(h/is-truthy (h/get-by-translation-text :t/empty-keycard)))
|
||||
|
||||
(h/test "Render of keycard component when: holder-name prop is set"
|
||||
(let [holder-name "Alisha"]
|
||||
(h/render [keycard/keycard {:holder-name holder-name}])
|
||||
(h/is-truthy (h/get-by-translation-text :t/user-keycard {:name holder-name})))))
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
(def keycard-chip-height 28)
|
||||
|
||||
(defn card-container
|
||||
[locked? theme blur?]
|
||||
[locked? theme]
|
||||
{:overflow :hidden
|
||||
:height keycard-height
|
||||
:align-items :flex-start
|
||||
:justify-content :space-between
|
||||
:border-width 1
|
||||
:border-color (if (or locked? blur?)
|
||||
:border-color (if locked?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme))
|
||||
:border-style :solid
|
||||
:border-radius 16
|
||||
:padding 16
|
||||
:background-color (if locked?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-50-opa-40 theme)
|
||||
colors/keycard-color)})
|
||||
(colors/theme-colors colors/danger colors/danger-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))})
|
||||
|
||||
(defn keycard-logo
|
||||
[locked? theme]
|
||||
@@ -28,6 +28,18 @@
|
||||
colors/white
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
(defn keycard-watermark
|
||||
[locked? theme]
|
||||
{:position :absolute
|
||||
:tint-color (if locked?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))
|
||||
:align-self :center
|
||||
:height 280.48
|
||||
:transform [{:rotate "-30deg"} {:translateY -30}]
|
||||
:opacity (when-not locked? 0.02)
|
||||
:z-index 1})
|
||||
|
||||
(def keycard-chip
|
||||
{:height keycard-chip-height
|
||||
:position :absolute
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns quo.components.keycard.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.keycard.style :as style]
|
||||
[quo.components.tags.tag :as tag]
|
||||
[quo.foundations.colors :as colors]
|
||||
@@ -15,9 +14,12 @@
|
||||
- :locked? - Boolean to specify whether the keycard is locked or not
|
||||
- :theme :light/:dark
|
||||
"
|
||||
[{:keys [holder-name locked? blur?]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style (style/card-container locked? theme blur?)}
|
||||
[{:keys [holder-name locked?]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
label (if holder-name
|
||||
(i18n/label :t/user-keycard {:name holder-name})
|
||||
(i18n/label :t/empty-keycard))]
|
||||
[rn/view {:style (style/card-container locked? theme)}
|
||||
[rn/image
|
||||
{:source (resources/get-image :keycard-logo)
|
||||
:style (style/keycard-logo locked? theme)}]
|
||||
@@ -25,14 +27,16 @@
|
||||
{:source (resources/get-image
|
||||
(if (or locked? (= :dark theme)) :keycard-chip-dark :keycard-chip-light))
|
||||
:style style/keycard-chip}]
|
||||
(when-not (string/blank? holder-name)
|
||||
[tag/tag
|
||||
{:size 32
|
||||
:type (when locked? :icon)
|
||||
:label (i18n/label :t/user-keycard {:name holder-name})
|
||||
:labelled? true
|
||||
:blurred? true
|
||||
:resource (when locked? :i/locked)
|
||||
:accessibility-label :holder-name
|
||||
:icon-color colors/white-70-blur
|
||||
:override-theme (when locked? :dark)}])]))
|
||||
[rn/image
|
||||
{:source (resources/get-image :keycard-watermark)
|
||||
:style (style/keycard-watermark locked? theme)}]
|
||||
[tag/tag
|
||||
{:size 32
|
||||
:type (when locked? :icon)
|
||||
:label label
|
||||
:labelled? true
|
||||
:blurred? true
|
||||
:resource (when locked? :i/locked)
|
||||
:accessibility-label :holder-name
|
||||
:icon-color colors/white-70-blur
|
||||
:override-theme (when locked? :dark)}]]))
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
(h/test "Test icon renders for ':action :icon'"
|
||||
(h/render-with-theme-provider [account-list-card/view
|
||||
{:account-props account-props
|
||||
:network :ethereum
|
||||
:action :icon
|
||||
:on-options-press (fn [])}])
|
||||
(h/is-truthy (h/get-by-label-text :icon))))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- internal-view
|
||||
[{:keys [action blur? account-props on-press on-options-press]}]
|
||||
[{:keys [action blur? account-props networks on-press on-options-press]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[state set-state] (rn/use-state :default)
|
||||
on-press-in (rn/use-callback #(set-state :pressed))
|
||||
@@ -31,9 +31,10 @@
|
||||
:size :paragraph-2}
|
||||
(:name account-props)]
|
||||
[address-text/view
|
||||
{:blur? blur?
|
||||
:address (:address account-props)
|
||||
:format :short}]]]
|
||||
{:blur? blur?
|
||||
:networks networks
|
||||
:address (:address account-props)
|
||||
:format :short}]]]
|
||||
(when (= action :icon)
|
||||
[rn/pressable {:on-press on-options-press}
|
||||
[icon/icon :i/options
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
:margin-left -4}
|
||||
(if (= type :top)
|
||||
{:top 0}
|
||||
{:transform [{:rotate-z "180deg"}]
|
||||
{:transform [{:rotateZ "180deg"}]
|
||||
:bottom 0})
|
||||
style)}]))
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
subtitle]]])
|
||||
|
||||
(defn- main-variant
|
||||
[{:keys [title subtitle button-label image max-height accessibility-label on-press button-props]}]
|
||||
[{:keys [title subtitle button-label image max-height accessibility-label on-press button-type]}]
|
||||
[rn/view {:style style/main-variant}
|
||||
[rn/view {:style style/main-variant-text-container}
|
||||
[text/text
|
||||
@@ -56,20 +56,18 @@
|
||||
:resize-mode :contain
|
||||
:source image}]
|
||||
[button/button
|
||||
(merge
|
||||
{:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:type :grey
|
||||
:size 40
|
||||
:container-style style/main-button
|
||||
:theme :dark
|
||||
:background :blur}
|
||||
button-props)
|
||||
{:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:type (or button-type :grey)
|
||||
:size 40
|
||||
:container-style style/main-button
|
||||
:theme :dark
|
||||
:background :blur}
|
||||
button-label]])
|
||||
|
||||
(defn small-option-card
|
||||
[{:keys [variant title subtitle button-label image max-height on-press accessibility-label
|
||||
button-props container-style]
|
||||
button-type container-style]
|
||||
:or {variant :main accessibility-label :small-option-card}}]
|
||||
(let [main-variant? (= variant :main)
|
||||
card-component (if main-variant? main-variant icon-variant)
|
||||
@@ -86,4 +84,4 @@
|
||||
:accessibility-label accessibility-label
|
||||
:image image
|
||||
:max-height max-height
|
||||
:button-props button-props}]]))
|
||||
:button-type button-type}]]))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
[{:keys [label data container-style blur?]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
last-item (rn/use-memo #(last data) [data])]
|
||||
[rn/view {:style [(style/container label) container-style]}
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
(when label
|
||||
[text/text
|
||||
{:weight :medium
|
||||
@@ -29,3 +29,4 @@
|
||||
[data-item/view data-item-props]
|
||||
(when-not (= item last-item)
|
||||
[rn/view {:style (style/settings-separator blur? theme)}])])]]))
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
separator (rn/use-memo (fn [] [rn/view
|
||||
{:style (style/reorder-separator blur? theme)}])
|
||||
[blur? theme])]
|
||||
[rn/view {:style [(style/container label) container-style]}
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
(let [theme (quo.theme/use-theme)
|
||||
settings-items (remove nil? data)
|
||||
last-index (dec (count settings-items))]
|
||||
[rn/view {:style [(style/container label) container-style]}
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
(when label
|
||||
[text/text
|
||||
{:weight :medium
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
{:flex 1}))
|
||||
|
||||
(def avatar-overlay
|
||||
{:justify-content :center
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:bottom 0
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(defn qr-image
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
(defn- avatar-image
|
||||
[{avatar-type :avatar
|
||||
:as props}]
|
||||
[rn/view {:style [rn/stylesheet-absolute-fill style/avatar-overlay]}
|
||||
[rn/view {:style style/avatar-overlay}
|
||||
[rn/view
|
||||
{:style (case avatar-type
|
||||
:wallet-account style/avatar-container-rounded
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
{:type :profile
|
||||
:profile-picture 123})
|
||||
|
||||
(def wallet-props {:networks '(:ethereum)})
|
||||
|
||||
(def text-press-event
|
||||
{:test-name "Text pressed"
|
||||
:accessibility-label :share-qr-code-info-text
|
||||
@@ -31,6 +33,24 @@
|
||||
:event-name :press
|
||||
:callback-prop-key :on-share-press})
|
||||
|
||||
(def multichain-press-event
|
||||
{:test-name "Multichain tab pressed"
|
||||
:accessibility-label :share-qr-code-multichain-tab
|
||||
:event-name :press
|
||||
:callback-prop-key :on-multichain-press})
|
||||
|
||||
(def legacy-press-event
|
||||
{:test-name "Legacy tab pressed"
|
||||
:accessibility-label :share-qr-code-legacy-tab
|
||||
:event-name :press
|
||||
:callback-prop-key :on-legacy-press})
|
||||
|
||||
(def settings-press-event
|
||||
{:test-name "Settings pressed"
|
||||
:accessibility-label :share-qr-code-settings
|
||||
:event-name :press
|
||||
:callback-prop-key :on-settings-press})
|
||||
|
||||
(defn render-share-qr-code
|
||||
[props]
|
||||
;; NOTE: rendering the profile type first, so that the re-render is triggered.
|
||||
@@ -54,22 +74,45 @@
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Wallet Legacy"
|
||||
(render-share-qr-code (assoc default-props
|
||||
:type
|
||||
:wallet))
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :wallet
|
||||
:address :legacy}))
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Saved address"
|
||||
(render-share-qr-code (assoc default-props
|
||||
:type
|
||||
:saved-address))
|
||||
(h/test "Wallet multichain"
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :wallet
|
||||
:address :multichain}))
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Saved address legacy"
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :saved-address
|
||||
:address :legacy}))
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Watched address"
|
||||
(render-share-qr-code (assoc default-props
|
||||
:type
|
||||
:watched-address))
|
||||
(h/test "Saved address multichain"
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :saved-address
|
||||
:address :multichain}))
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Watched address legacy"
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :watched-address
|
||||
:address :legacy}))
|
||||
(h/is-truthy (h/get-by-text qr-label)))
|
||||
|
||||
(h/test "Watched address multichain"
|
||||
(render-share-qr-code (merge default-props
|
||||
wallet-props
|
||||
{:type :watched-address
|
||||
:address :multichain}))
|
||||
(h/is-truthy (h/get-by-text qr-label))))
|
||||
|
||||
(h/describe "Fires all events for all types"
|
||||
@@ -93,27 +136,78 @@
|
||||
|
||||
(h/describe "Wallet Legacy"
|
||||
(test-fire-events
|
||||
(assoc default-props
|
||||
:type :wallet
|
||||
:emoji "👻")
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :wallet
|
||||
:address :legacy
|
||||
:emoji "👻"})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event]))
|
||||
share-press-event
|
||||
multichain-press-event
|
||||
legacy-press-event]))
|
||||
|
||||
(h/describe "Saved Address"
|
||||
(h/describe "Wallet Multichain"
|
||||
(test-fire-events
|
||||
(assoc default-props
|
||||
:type
|
||||
:saved-address)
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :wallet
|
||||
:address :multichain
|
||||
:emoji "👻"})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event]))
|
||||
share-press-event
|
||||
legacy-press-event
|
||||
multichain-press-event
|
||||
settings-press-event]))
|
||||
|
||||
(h/describe "Watched Address"
|
||||
(h/describe "Saved Address Legacy"
|
||||
(test-fire-events
|
||||
(assoc default-props
|
||||
:type :watched-address
|
||||
:emoji "👽")
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :saved-address
|
||||
:address :legacy})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event])))))
|
||||
share-press-event
|
||||
legacy-press-event
|
||||
multichain-press-event]))
|
||||
|
||||
(h/describe "Saved Address Multichain"
|
||||
(test-fire-events
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :saved-address :address :multichain})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event
|
||||
legacy-press-event
|
||||
multichain-press-event
|
||||
settings-press-event]))
|
||||
|
||||
(h/describe "Watched Address Legacy"
|
||||
(test-fire-events
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :watched-address
|
||||
:address :legacy
|
||||
:emoji "👽"})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event
|
||||
legacy-press-event
|
||||
multichain-press-event]))
|
||||
|
||||
(h/describe "Watched Address Multichain"
|
||||
(test-fire-events
|
||||
(merge default-props
|
||||
wallet-props
|
||||
{:type :watched-address
|
||||
:address :multichain
|
||||
:emoji "👽"})
|
||||
[text-press-event
|
||||
text-long-press-event
|
||||
share-press-event
|
||||
legacy-press-event
|
||||
multichain-press-event
|
||||
settings-press-event])))))
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
(ns quo.components.share.share-qr-code.schema)
|
||||
(ns quo.components.share.share-qr-code.schema
|
||||
(:require
|
||||
[quo.foundations.resources :as resources]))
|
||||
|
||||
(defn- valid-network?
|
||||
[network]
|
||||
(-> network resources/get-network boolean))
|
||||
|
||||
(def ?base
|
||||
[:map
|
||||
@@ -29,9 +35,25 @@
|
||||
[:type [:= :wallet]]
|
||||
[:emoji {:optional true} [:maybe ?emoji]]])
|
||||
|
||||
(def ?address-multichain
|
||||
[:map
|
||||
[:address [:= :multichain]]
|
||||
[:on-settings-press {:optional true} fn?]])
|
||||
|
||||
(def ?address-base
|
||||
[:merge
|
||||
[:map
|
||||
[:networks [:sequential [:fn valid-network?]]]
|
||||
[:on-legacy-press {:optional true} [:maybe fn?]]
|
||||
[:on-multichain-press {:optional true} [:maybe fn?]]
|
||||
[:address [:enum :legacy :multichain]]]
|
||||
[:multi {:dispatch :address}
|
||||
[:multichain ?address-multichain]]])
|
||||
|
||||
(def ?saved-address
|
||||
[:map
|
||||
[:type [:= :saved-address]]])
|
||||
[:type [:= :saved-address]]
|
||||
[:on-settings-press {:optional true} fn?]])
|
||||
|
||||
(def ?watched-address
|
||||
[:map
|
||||
@@ -45,8 +67,8 @@
|
||||
[:multi {:dispatch :type}
|
||||
[:channel [:merge ?base ?channel]]
|
||||
[:profile [:merge ?base ?profile]]
|
||||
[:wallet [:merge ?base ?wallet]]
|
||||
[:saved-address [:merge ?base ?saved-address]]
|
||||
[:watched-address [:merge ?base ?watched-address]]]]]
|
||||
[:wallet [:merge ?base ?address-base ?wallet]]
|
||||
[:saved-address [:merge ?base ?address-base ?saved-address]]
|
||||
[:watched-address [:merge ?base ?address-base ?watched-address]]]]]
|
||||
:any])
|
||||
|
||||
|
||||
@@ -12,12 +12,37 @@
|
||||
[quo.components.share.qr-code.view :as qr-code]
|
||||
[quo.components.share.share-qr-code.schema :as component-schema]
|
||||
[quo.components.share.share-qr-code.style :as style]
|
||||
[quo.components.tabs.tab.view :as tab]
|
||||
[quo.components.wallet.address-text.view :as address-text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- header
|
||||
[{:keys [on-legacy-press on-multichain-press address]}]
|
||||
[rn/view {:style style/header-container}
|
||||
[tab/view
|
||||
{:accessibility-label :share-qr-code-multichain-tab
|
||||
:id :wallet-multichain-tab
|
||||
:active-item-container-style style/header-tab-active
|
||||
:item-container-style style/header-tab-inactive
|
||||
:size 24
|
||||
:active (= :multichain address)
|
||||
:on-press on-multichain-press}
|
||||
(i18n/label :t/multichain)]
|
||||
[rn/view {:style style/space-between-tabs}]
|
||||
[tab/view
|
||||
{:accessibility-label :share-qr-code-legacy-tab
|
||||
:id :wallet-legacy-tab
|
||||
:active-item-container-style style/header-tab-active
|
||||
:item-container-style style/header-tab-inactive
|
||||
:size 24
|
||||
:active (= :legacy address)
|
||||
:on-press on-legacy-press}
|
||||
(i18n/label :t/legacy)]])
|
||||
|
||||
(defn- info-label
|
||||
[share-qr-code-type]
|
||||
[text/text {:size :paragraph-2 :weight :medium :style style/title}
|
||||
@@ -61,7 +86,7 @@
|
||||
:on-long-press on-text-long-press}
|
||||
qr-data]])
|
||||
|
||||
(defn- wallet-bottom
|
||||
(defn- wallet-legacy-bottom
|
||||
[{:keys [component-width qr-data on-text-press on-text-long-press]}]
|
||||
[info-text
|
||||
{:width component-width
|
||||
@@ -69,6 +94,28 @@
|
||||
:on-long-press on-text-long-press}
|
||||
qr-data])
|
||||
|
||||
(defn wallet-multichain-bottom
|
||||
[{:keys [component-width qr-data on-text-press on-text-long-press on-settings-press]}]
|
||||
[rn/view
|
||||
{:style style/wallet-multichain-container}
|
||||
[info-text
|
||||
{:width component-width
|
||||
:on-press on-text-press
|
||||
:on-long-press on-text-long-press}
|
||||
[address-text/view
|
||||
{:address qr-data
|
||||
:full-address? true
|
||||
:weight :regular
|
||||
:size :paragraph-1}]]
|
||||
[button/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :share-qr-code-settings
|
||||
:on-press on-settings-press}
|
||||
:i/advanced]])
|
||||
|
||||
(defn- header-icon
|
||||
[{:keys [share-qr-type customization-color emoji profile-picture full-name]}]
|
||||
(case share-qr-type
|
||||
@@ -93,9 +140,17 @@
|
||||
:full-name full-name}]
|
||||
nil))
|
||||
|
||||
(defn- has-header?
|
||||
[share-qr-type]
|
||||
(case share-qr-type
|
||||
(:wallet
|
||||
:watched-address
|
||||
:saved-address) true
|
||||
false))
|
||||
|
||||
(defn- share-qr-code
|
||||
[{:keys [share-qr-type qr-image-uri component-width customization-color full-name
|
||||
profile-picture emoji on-share-press]
|
||||
profile-picture emoji on-share-press address]
|
||||
:as props}]
|
||||
[:<>
|
||||
[gradient-cover/view {:customization-color customization-color :height 463}]
|
||||
@@ -113,6 +168,8 @@
|
||||
{:color colors/white-opa-40
|
||||
:container-style style/watched-account-icon}])]
|
||||
[share-button {:on-press on-share-press}]]
|
||||
(when (has-header? share-qr-type)
|
||||
[header props])
|
||||
[quo.theme/provider :light
|
||||
[qr-code/view
|
||||
{:qr-image-uri qr-image-uri
|
||||
@@ -128,12 +185,12 @@
|
||||
:profile-picture profile-picture
|
||||
:emoji emoji}]]
|
||||
[rn/view {:style style/bottom-container}
|
||||
(case share-qr-type
|
||||
:profile
|
||||
(if (= share-qr-type :profile)
|
||||
[profile-bottom props]
|
||||
(:wallet :watched-address :saved-address)
|
||||
[wallet-bottom props]
|
||||
nil)]]])
|
||||
(case address
|
||||
:legacy [wallet-legacy-bottom props]
|
||||
:multichain [wallet-multichain-bottom props]
|
||||
nil))]]])
|
||||
|
||||
(defn- view-internal
|
||||
[{provided-width :width :as props}]
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
theme (quo.theme/use-theme)}
|
||||
:as props}]
|
||||
(let [[image-error? set-image-error] (rn/use-state false)]
|
||||
[rn/view {:style [{:align-items :flex-start} container-style]}
|
||||
[rn/view {:style (merge {:align-items :flex-start} container-style)}
|
||||
[rn/view
|
||||
{:style (style/container {:theme theme
|
||||
:type type
|
||||
|
||||
@@ -6,28 +6,17 @@
|
||||
[{:keys [status theme blur?]}]
|
||||
{:flex-direction :row
|
||||
:align-self :flex-start
|
||||
:background-color (cond (= status :error)
|
||||
(colors/theme-colors
|
||||
(colors/override-color :danger 10 50)
|
||||
(colors/override-color :danger 10 60)
|
||||
theme)
|
||||
(= status :warning)
|
||||
(colors/theme-colors
|
||||
(colors/override-color :warning 10 50)
|
||||
(colors/override-color :warning 10 60)
|
||||
theme))
|
||||
:background-color (when (= status :error)
|
||||
(colors/theme-colors
|
||||
(colors/override-color :danger 10 50)
|
||||
(colors/override-color :danger 10 60)
|
||||
theme))
|
||||
:border-width 1
|
||||
:border-color (cond (= status :error)
|
||||
(colors/theme-colors
|
||||
(colors/override-color :danger 20 50)
|
||||
(colors/override-color :danger 20 60)
|
||||
theme)
|
||||
|
||||
(= status :warning)
|
||||
(colors/theme-colors
|
||||
(colors/override-color :warning 20 50)
|
||||
(colors/override-color :warning 20 60)
|
||||
theme)
|
||||
(and blur? (= status :default)) (colors/theme-colors
|
||||
colors/neutral-80-opa-5
|
||||
colors/white-opa-5
|
||||
@@ -46,7 +35,5 @@
|
||||
[{:keys [status theme networks-shown?]}]
|
||||
{:padding-left (if networks-shown? 4 0)
|
||||
:margin-top -1
|
||||
:color (cond (= status :error)
|
||||
(colors/resolve-color :danger theme)
|
||||
(= status :warning)
|
||||
(colors/resolve-color :warning theme))})
|
||||
:color (when (= status :error)
|
||||
(colors/resolve-color :danger theme))})
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
(defn network-bridge-add
|
||||
[{:keys [network state theme container-style on-press]}]
|
||||
[rn/pressable
|
||||
{:style [(style/container network state theme)
|
||||
(style/add-container theme)
|
||||
container-style]
|
||||
{:style (merge (style/container network state theme)
|
||||
(style/add-container theme)
|
||||
container-style)
|
||||
:on-press on-press}
|
||||
[icon/icon :i/edit
|
||||
{:size 12
|
||||
@@ -36,7 +36,7 @@
|
||||
(if (= status :edit)
|
||||
[network-bridge-add (assoc args :theme theme)]
|
||||
[rn/pressable
|
||||
{:style [(style/container network status theme) container-style]
|
||||
{:style (merge (style/container network status theme) container-style)
|
||||
:accessible true
|
||||
:accessibility-label :container
|
||||
:on-press on-press
|
||||
|
||||
@@ -195,12 +195,17 @@
|
||||
(def success-60-opa-30 (alpha success-60 0.3))
|
||||
(def success-60-opa-40 (alpha success-60 0.4))
|
||||
|
||||
;;;;Danger
|
||||
(def danger "#E95460")
|
||||
|
||||
;; Danger with transparency
|
||||
(def danger-opa-40 (alpha danger 0.4))
|
||||
|
||||
;;Solid
|
||||
(def danger-50 "#E95460")
|
||||
(def danger-60 "#BA434D")
|
||||
|
||||
(def system-yellow "#FFD60A")
|
||||
(def keycard-color "#FF6400")
|
||||
|
||||
;;50 with transparency
|
||||
(def danger-50-opa-0 (alpha danger-50 0))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{:keycard-logo (js/require "../resources/images/ui2/keycard-logo.png")
|
||||
:keycard-chip-light (js/require "../resources/images/ui2/keycard-chip-light.png")
|
||||
:keycard-chip-dark (js/require "../resources/images/ui2/keycard-chip-dark.png")
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:bored-ape (js/require "../resources/images/mock2/bored-ape.png")})
|
||||
|
||||
(def ui-themed
|
||||
|
||||
@@ -211,5 +211,3 @@
|
||||
(def linking (.-Linking react-native))
|
||||
|
||||
(defn open-url [link] (.openURL ^js linking link))
|
||||
|
||||
(def stylesheet-absolute-fill ^js (.. react-native -StyleSheet -absoluteFill))
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
["react-native-redash" :refer (withPause)]
|
||||
[react-native.flat-list :as rn-flat-list]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.utils :as rn.utils]
|
||||
[reagent.core :as reagent]
|
||||
[utils.transforms :as transforms]
|
||||
[utils.worklets.core :as worklets.core]))
|
||||
|
||||
(def ^:const default-duration 300)
|
||||
@@ -34,7 +36,13 @@
|
||||
;; Animated Components
|
||||
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View reanimated)))
|
||||
(def ^:private view* (reagent/adapt-react-class (.-View reanimated)))
|
||||
|
||||
(defn view
|
||||
[& argv]
|
||||
(let [[reagent-props children] (rn.utils/get-props-and-children argv)
|
||||
updated-props (update reagent-props :style transforms/styles-with-vectors)]
|
||||
(into [view* updated-props] children)))
|
||||
|
||||
(def scroll-view (reagent/adapt-react-class (.-ScrollView reanimated)))
|
||||
(def image (reagent/adapt-react-class (.-Image reanimated)))
|
||||
@@ -178,3 +186,4 @@
|
||||
(with-timing value
|
||||
(clj->js {:duration duration
|
||||
:easing (default-easing)})))))
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
(ns react-native.utils-test
|
||||
(:require
|
||||
[cljs.test :refer [deftest is testing]]
|
||||
[utils.reagent :as sut]))
|
||||
|
||||
(sut/set-convert-props-in-vectors!)
|
||||
|
||||
(deftest convert-prop-value-test
|
||||
;; `test-fn` transforms the result to be easily compared during testing
|
||||
(let [test-fn (comp js->clj sut/convert-prop-value)]
|
||||
(testing "camelCase keys are kept as is"
|
||||
(let [props {:foo nil
|
||||
:bar nil}]
|
||||
(is (= (update-keys props name)
|
||||
(test-fn props)))))
|
||||
|
||||
(testing "kebab-case keys are transformed"
|
||||
(let [props {:foo nil
|
||||
:bar nil}]
|
||||
(is (= {"foo" nil
|
||||
"bar" nil}
|
||||
(test-fn props)))))
|
||||
|
||||
(testing "kebab-case keys are transformed when passed inside a vector"
|
||||
(let [props-in-vector [{:foo nil
|
||||
:bar nil}]]
|
||||
(is (= [{"foo" nil
|
||||
"bar" nil}]
|
||||
(test-fn props-in-vector)))))
|
||||
|
||||
(testing "kebab-case keys are transformed recursively when the structure has vectors"
|
||||
(let [props-with-vectors {:foo [{:foo-bar nil
|
||||
:foo-baz nil}]
|
||||
:bar [{:bar-baz nil}
|
||||
{:bar-qux nil}]}]
|
||||
(is (= {"foo" [{"fooBar" nil
|
||||
"fooBaz" nil}]
|
||||
"bar" [{"barBaz" nil} {"barQux" nil}]}
|
||||
(test-fn props-with-vectors))))
|
||||
(testing "Complex example"
|
||||
(let [complex-props {:foo [{:foo-bar nil :foo-baz nil}]
|
||||
:bar [{:bar-baz nil} {:bar-qux nil}]
|
||||
:qux {:foo-qux :bar-qux}
|
||||
:foo-bar-qux {:foo [{:bar :qux}
|
||||
{:bar-qux nil}]
|
||||
:foo-bar :qux
|
||||
:foo-bar-qux [:foo :bar :qux {:foo-bar :foo-bar}]}}]
|
||||
(is (= {"foo" [{"fooBar" nil "fooBaz" nil}]
|
||||
"bar" [{"barBaz" nil} {"barQux" nil}]
|
||||
"qux" {"fooQux" "bar-qux"}
|
||||
"fooBarQux" {"foo" [{"bar" "qux"} {"barQux" nil}]
|
||||
"fooBar" "qux"
|
||||
"fooBarQux" ["foo" "bar" "qux" {"fooBar" "foo-bar"}]}}
|
||||
(test-fn complex-props))))))))
|
||||
@@ -18,13 +18,13 @@
|
||||
:podcasts (js/require "../resources/images/ui2/podcasts.png")
|
||||
:generate-keys (js/require "../resources/images/ui2/generate-keys.png")
|
||||
:add-key-to-keycard (js/require "../resources/images/ui2/add-key-to-keycard.png")
|
||||
:import-key-to-keycard (js/require "../resources/images/ui2/import-key-to-keycard.png")
|
||||
:ethereum-address (js/require "../resources/images/ui2/ethereum-address.png")
|
||||
:use-keycard (js/require "../resources/images/ui2/keycard.png")
|
||||
:use-recovery-phrase (js/require "../resources/images/ui2/recovery-phrase.png")
|
||||
:check-your-keycard (js/require "../resources/images/ui2/check-your-keycard.png")
|
||||
:qr-code (js/require "../resources/images/ui2/qr-code.png")
|
||||
:keycard-logo (js/require "../resources/images/ui2/keycard-logo.png")
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:keycard-buy (js/require "../resources/images/ui2/keycard-buy.png")
|
||||
:keycard-migration (js/require "../resources/images/ui2/keycard-migration.png")
|
||||
:keycard-migration-failed (js/require "../resources/images/ui2/keycard-migration-failed.png")
|
||||
|
||||
@@ -15,7 +15,16 @@
|
||||
|
||||
(def flex-spacer {:flex 1})
|
||||
|
||||
(def hole {:z-index 2 :opacity 0.95})
|
||||
(def absolute-fill
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(def hole
|
||||
(merge absolute-fill
|
||||
{:z-index 2 :opacity 0.95}))
|
||||
|
||||
(defn root-container
|
||||
[padding-top]
|
||||
|
||||
@@ -174,10 +174,10 @@
|
||||
:on-success-scan set-qr-code-succeeded
|
||||
:on-failed-scan set-rescan-timeout}))}]]
|
||||
[hole-view/hole-view
|
||||
{:style [rn/stylesheet-absolute-fill style/hole]
|
||||
:holes [(assoc qr-view-finder :border-radius 16)]}
|
||||
{:style style/hole
|
||||
:holes [(assoc qr-view-finder :borderRadius 16)]}
|
||||
[quo/blur
|
||||
{:style rn/stylesheet-absolute-fill
|
||||
{:style style/absolute-fill
|
||||
:blur-amount 10
|
||||
:blur-type :transparent
|
||||
:overlay-color colors/neutral-80-opa-80-blur
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
(def mainnet-chain-explorer-link "https://etherscan.io/address/")
|
||||
(def optimism-mainnet-chain-explorer-link "https://optimistic.etherscan.io/address/")
|
||||
(def arbitrum-mainnet-chain-explorer-link "https://arbiscan.io/address/")
|
||||
(def base-mainnet-chain-explorer-link "https://basescan.org/address/")
|
||||
(def base-sepolia-chain-explorer-link "https://sepolia.basescan.org/address/")
|
||||
(def sepolia-chain-explorer-link "https://sepolia.etherscan.io/address/")
|
||||
(def optimism-sepolia-chain-explorer-link "https://sepolia-optimistic.etherscan.io/address/")
|
||||
(def arbitrum-sepolia-chain-explorer-link "https://sepolia.arbiscan.io/address/")
|
||||
|
||||
@@ -443,10 +443,7 @@
|
||||
(def ^:const wallet-account-name-max-length 20)
|
||||
|
||||
|
||||
(def ^:const gas-rate-low 0)
|
||||
(def ^:const gas-rate-medium 1)
|
||||
(def ^:const gas-rate-high 2)
|
||||
(def ^:const gas-rate-custom 3)
|
||||
(def ^:const send-type-transfer 0)
|
||||
(def ^:const send-type-bridge 5)
|
||||
(def ^:const send-type-erc-721-transfer 6)
|
||||
|
||||
@@ -95,10 +95,10 @@
|
||||
|
||||
(defn get-actions
|
||||
[{:keys [outgoing content pinned-by outgoing-status deleted? deleted-for-me? content-type
|
||||
bridge-message message-id]
|
||||
bridge-message]
|
||||
:as message-data}
|
||||
{:keys [able-to-send-message? community? community-member? can-delete-message-for-everyone?
|
||||
message-pin-enabled group-chat group-admin? debug-log-level?]}]
|
||||
message-pin-enabled group-chat group-admin?]}]
|
||||
(let [edit-message? (and (or community-member? (not community?))
|
||||
outgoing
|
||||
(not (or deleted? deleted-for-me?))
|
||||
@@ -153,14 +153,6 @@
|
||||
:icon :i/copy
|
||||
:id :copy})
|
||||
|
||||
debug-log-level?
|
||||
(conj {:type :main
|
||||
:on-press #(clipboard/set-string message-id)
|
||||
:label (i18n/label :t/copy-message-id)
|
||||
:accessibility-label :copy-message-id
|
||||
:icon :i/copy
|
||||
:id :copy-message-id})
|
||||
|
||||
pin-message?
|
||||
(conj {:type :main
|
||||
:on-press #(pin-message message-data)
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
(ns status-im.contexts.keycard.backup.events
|
||||
(:require [utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.generate-and-load-key
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [masked-phrase pin]} (get-in db [:keycard :backup])]
|
||||
{:fx [[:effects.keycard/generate-and-load-key
|
||||
{:mnemonic (security/safe-unmask-data masked-phrase)
|
||||
:pin pin
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :screen/keycard.backup.success]))
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]})))
|
||||
|
||||
(defn- ready-to-add-not-empty
|
||||
[error]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if (= error :keycard/error.not-keycard)
|
||||
(rf/dispatch [:keycard/on-application-info-error error])
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.backup.not-empty
|
||||
{:on-press #(rf/dispatch [:keycard/backup.ready-to-add-connect])}]))))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.ready-to-add-connect
|
||||
(fn [_]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(rf/dispatch [:keycard/backup.generate-and-load-key])
|
||||
(ready-to-add-not-empty error)))}]]]}))
|
||||
|
||||
(defn- scan-empty-card-not-empty
|
||||
[error]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if (= error :keycard/error.not-keycard)
|
||||
(rf/dispatch [:keycard/on-application-info-error error])
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.backup.not-empty
|
||||
{:on-press #(rf/dispatch [:keycard/backup.scan-empty-card])}]))))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.scan-empty-card
|
||||
(fn [_]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:keycard/backup.create-or-enter-pin]))
|
||||
(scan-empty-card-not-empty error)))}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.save-pin
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:db (assoc-in db [:keycard :backup :pin] pin)}))
|
||||
|
||||
(defn- save-pin-and-navigate-to-phrase
|
||||
[pin]
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/backup.save-pin pin])
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/use-recovery-phrase-dark
|
||||
{:on-success #(rf/dispatch [:keycard/backup.phrase-entered %])}]))
|
||||
|
||||
(defn- verify-entered-pin-and-continue
|
||||
[pin]
|
||||
(rf/dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(rf/dispatch
|
||||
[:keycard/verify-pin
|
||||
{:pin pin
|
||||
:on-success #(save-pin-and-navigate-to-phrase pin)
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}])
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]))
|
||||
|
||||
(declare init-card-not-empty)
|
||||
|
||||
(defn- init-card-with-pin-and-continue
|
||||
[pin]
|
||||
(rf/dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(rf/dispatch
|
||||
[:keycard/init-card
|
||||
{:pin pin
|
||||
:on-success #(rf/dispatch
|
||||
[:keycard/get-application-info
|
||||
{:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(save-pin-and-navigate-to-phrase pin)
|
||||
(init-card-not-empty pin error)))}])}])
|
||||
(init-card-not-empty pin error)))}]))
|
||||
|
||||
(defn- init-card-not-empty
|
||||
[pin error]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if (= error :keycard/error.not-keycard)
|
||||
(rf/dispatch [:keycard/on-application-info-error error])
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.backup.not-empty
|
||||
{:on-press #(init-card-with-pin-and-continue pin)}]))))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.create-or-enter-pin
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [initialized?]} (get-in db [:keycard :application-info])]
|
||||
{:fx [[:dispatch [:navigate-back]]
|
||||
(if initialized?
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.pin.enter
|
||||
{:on-complete verify-entered-pin-and-continue}]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.pin.create
|
||||
{:on-complete init-card-with-pin-and-continue}]])]})))
|
||||
|
||||
(rf/reg-event-fx :keycard/backup.phrase-entered
|
||||
(fn [{:keys [db]} [{:keys [phrase]}]]
|
||||
{:db (assoc-in db [:keycard :backup :masked-phrase] phrase)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch [:open-modal :screen/keycard.backup.ready-to-add]]]}))
|
||||
@@ -1,96 +0,0 @@
|
||||
(ns status-im.contexts.keycard.backup.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn ready-to-add
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/ready-add-keypair-keycard)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration)}]]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/backup.ready-to-add-connect])}}]])
|
||||
|
||||
(defn success-view
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/backup-keycard-created)}]
|
||||
[rn/view {:style {:flex 1}}]
|
||||
[rn/view {:style {:padding-horizontal 20}}
|
||||
[quo/button {:on-press events-helper/navigate-back}
|
||||
(i18n/label :t/done)]]])
|
||||
|
||||
(defn not-empty-view
|
||||
[]
|
||||
(let [{:keys [on-press]} (rf/sub [:get-screen-params])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard-not-empty)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/scan-empty-keycard)}]
|
||||
[rn/view {:style {:flex 1}}]
|
||||
[common.view/tips]
|
||||
[rn/view {:style {:padding-horizontal 20}}
|
||||
[quo/button {:on-press on-press}
|
||||
(i18n/label :t/try-again)]]]))
|
||||
|
||||
(defn scan-empty
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/scan-empty-keycard)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/backup-empty-keycard-only)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :check-your-keycard)}]]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/ready-to-scan)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/backup.scan-empty-card])}}]])
|
||||
|
||||
(defn sheet
|
||||
[{:keys [on-continue]}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/drawer-top {:title (i18n/label :t/create-backup-keycard)}]
|
||||
[quo/text
|
||||
{:style {:padding-horizontal 20
|
||||
:padding-vertical 8}}
|
||||
(i18n/label :t/backup-keycard-instructions)]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:button-one-label (i18n/label :t/continue)
|
||||
:button-one-props {:customization-color customization-color
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(on-continue))}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||
@@ -1,73 +0,0 @@
|
||||
(ns status-im.contexts.keycard.change-pin.events
|
||||
(:require [status-im.contexts.keycard.utils :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin.enter-current-pin
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update db :keycard dissoc :change-pin)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.pin.enter
|
||||
{:title (i18n/label :t/enter-current-keycard-pin)
|
||||
:on-complete (fn [current-pin]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/change-pin.save-current-pin current-pin])
|
||||
(rf/dispatch [:keycard/change-pin.enter-new-pin]))}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin.save-current-pin
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:db (assoc-in db [:keycard :change-pin :current-pin] (security/mask-data pin))}))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin.enter-new-pin
|
||||
(fn [_]
|
||||
{:fx [[:dispatch
|
||||
[:open-modal :screen/keycard.pin.create
|
||||
{:title (i18n/label :t/create-new-keycard-pin)
|
||||
:repeat-stage-title (i18n/label :t/repeat-new-keycard-pin)
|
||||
:on-complete (fn [new-pin]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/change-pin.save-new-pin new-pin])
|
||||
(rf/dispatch [:open-modal :screen/keycard.ready-to-change-pin]))}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin.save-new-pin
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:db (assoc-in db [:keycard :change-pin :new-pin] (security/mask-data pin))}))
|
||||
|
||||
(defn- change-pin-and-continue
|
||||
[current-pin new-pin]
|
||||
(rf/dispatch [:keycard/change-pin
|
||||
{:on-success (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.pin-change-success]))
|
||||
:on-failure (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.pin-change-failed]))
|
||||
:current-pin current-pin
|
||||
:new-pin new-pin}]))
|
||||
|
||||
(defn- verify-pin-and-continue
|
||||
[current-pin new-pin]
|
||||
(rf/dispatch
|
||||
[:keycard/verify-pin
|
||||
{:pin current-pin
|
||||
:on-success #(change-pin-and-continue current-pin new-pin)
|
||||
:on-failure (fn [error]
|
||||
(when-not (utils/tag-lost? (:error error))
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:keycard/on-action-with-pin-error error])
|
||||
(rf/dispatch [:keycard/change-pin.enter-current-pin])))}]))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin.verify-current-pin-and-continue
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [current-pin new-pin]} (get-in db [:keycard :change-pin])
|
||||
unmasked-current-pin (security/safe-unmask-data current-pin)
|
||||
unmasked-new-pin (security/safe-unmask-data new-pin)]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:on-success #(verify-pin-and-continue unmasked-current-pin unmasked-new-pin)}]]]})))
|
||||
@@ -1,82 +0,0 @@
|
||||
(ns status-im.contexts.keycard.change-pin.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn change-pin-confirmation-sheet
|
||||
[]
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/change-pin-keycard)
|
||||
:shell? true}
|
||||
[rn/view
|
||||
[quo/text {:size :paragraph-2}
|
||||
(i18n/label :t/change-pin-keycard-message)]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:container-style {:margin-horizontal -20}
|
||||
:blur? true
|
||||
:button-one-label (i18n/label :t/continue)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/change-pin.enter-current-pin])}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:on-press events-helper/hide-bottom-sheet
|
||||
:type :grey}}]]])
|
||||
|
||||
(defn ready-to-change-pin
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/ready-to-change-pin)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain}]]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch
|
||||
[:keycard/change-pin.verify-current-pin-and-continue])}}]])
|
||||
|
||||
(defn pin-change-success
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard-pin-changed)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/keycard-pin-changed-description)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain}]]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/done)
|
||||
:button-one-props {:on-press events-helper/navigate-back}}]])
|
||||
|
||||
(defn pin-change-failed
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard-pin-change-failed)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/keycard-pin-change-failed-description)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain}]]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/try-again)
|
||||
:button-one-props {:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :screen/keycard.ready-to-change-pin]))}}]])
|
||||
@@ -1,26 +0,0 @@
|
||||
(ns status-im.contexts.keycard.check.events
|
||||
(:require [utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :keycard/check-empty-card
|
||||
(fn [{:keys [db]}]
|
||||
(let [keycard-profile? (not (nil? (get-in db [:profile/profile :keycard-pairing])))]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:theme :dark
|
||||
:on-success
|
||||
(fn []
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if keycard-profile?
|
||||
(rf/dispatch [:open-modal :screen/keycard.manage.profile-keys])
|
||||
(rf/dispatch [:open-modal :screen/keycard.migrate.profile-keys])))
|
||||
:on-error
|
||||
(fn [error]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if (and (= error :keycard/error.keycard-empty)
|
||||
(not keycard-profile?))
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.empty]))
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]]]})))
|
||||
@@ -4,7 +4,6 @@
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -36,7 +35,6 @@
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content keycard-documentation
|
||||
:theme :dark
|
||||
:shell? true}])}]}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/check-keycard)
|
||||
@@ -46,7 +44,9 @@
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :check-your-keycard)}]]
|
||||
[common.view/tips]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/ready-to-scan)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
(ns status-im.contexts.keycard.common.view
|
||||
(:require [quo.core :as quo]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn tips
|
||||
[]
|
||||
[:<>
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]])
|
||||
@@ -1,7 +1,5 @@
|
||||
(ns status-im.contexts.keycard.create.events
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.common.resources :as resources]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
@@ -9,10 +7,9 @@
|
||||
(fn [_]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
{:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.empty-create]))
|
||||
@@ -21,17 +18,8 @@
|
||||
(defn- backup-recovery-phrase-success
|
||||
[masked-seed-phrase]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :screen/confirm-backup-dark
|
||||
(rf/dispatch [:open-modal :screen/confirm-backup
|
||||
{:masked-seed-phrase masked-seed-phrase
|
||||
:theme :dark
|
||||
:shell? true
|
||||
:on-try-again #(rf/dispatch [:open-modal :screen/backup-recovery-phrase-dark
|
||||
{:on-success backup-recovery-phrase-success
|
||||
:masked-seed-phrase (->> masked-seed-phrase
|
||||
security/safe-unmask-data
|
||||
(string/join " ")
|
||||
security/mask-data)
|
||||
:revealed? true}])
|
||||
:on-success #(rf/dispatch [:keycard/create.phrase-backed-up
|
||||
masked-seed-phrase])}]))
|
||||
|
||||
@@ -51,13 +39,10 @@
|
||||
security/safe-unmask-data
|
||||
(string/join " ")
|
||||
security/mask-data))
|
||||
:fx [[:dispatch
|
||||
[:keycard/create.create-or-enter-pin
|
||||
{:ready-to-add-screen-title (i18n/label :t/ready-add-keypair-keycard)
|
||||
:ready-to-add-screen-image (resources/get-image :add-key-to-keycard)}]]]}))
|
||||
:fx [[:dispatch [:keycard/create.create-or-enter-pin]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/create.create-or-enter-pin
|
||||
(fn [{:keys [db]} [{:keys [ready-to-add-screen-title ready-to-add-screen-image]}]]
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [initialized?]} (get-in db [:keycard :application-info])]
|
||||
{:fx [[:dispatch [:navigate-back]]
|
||||
(if initialized?
|
||||
@@ -71,9 +56,7 @@
|
||||
{:on-complete (fn [new-pin]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/create.save-pin new-pin])
|
||||
(rf/dispatch [:open-modal :screen/keycard.create.ready-to-add
|
||||
{:title ready-to-add-screen-title
|
||||
:image ready-to-add-screen-image}]))}]])]})))
|
||||
(rf/dispatch [:open-modal :screen/keycard.create.ready-to-add]))}]])]})))
|
||||
|
||||
(rf/reg-event-fx :keycard/create.save-pin
|
||||
(fn [{:keys [db]} [pin]]
|
||||
@@ -81,7 +64,7 @@
|
||||
|
||||
(rf/reg-event-fx :keycard/create.on-application-info-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(if (or (= error :keycard/error.keycard-empty)
|
||||
(if (or (= error :keycard/error.keycard-blank)
|
||||
(and (get-in db [:keycard :application-info :initialized?])
|
||||
(= error :keycard/error.keycard-wrong-profile)))
|
||||
(rf/dispatch [:keycard/create.continue])
|
||||
@@ -91,8 +74,7 @@
|
||||
(fn [_]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error #(rf/dispatch [:keycard/create.on-application-info-error %])}]]]}))
|
||||
{:on-error #(rf/dispatch [:keycard/create.on-application-info-error %])}]]]}))
|
||||
|
||||
(defn get-application-info-and-continue
|
||||
[]
|
||||
@@ -108,7 +90,7 @@
|
||||
(cond
|
||||
|
||||
(not initialized?)
|
||||
{:fx [[:effects.keycard/init-card
|
||||
{:fx [[:keycard/init-card
|
||||
{:pin pin
|
||||
:on-success get-application-info-and-continue}]]}
|
||||
|
||||
@@ -130,7 +112,4 @@
|
||||
(if (contains? (:profile/profiles-overview db) key-uid)
|
||||
{:fx [[:dispatch [:onboarding/multiaccount-already-exists key-uid]]]}
|
||||
{:db (assoc-in db [:keycard :create :masked-phrase] masked-seed-phrase)
|
||||
:fx [[:dispatch
|
||||
[:keycard/create.create-or-enter-pin
|
||||
{:ready-to-add-screen-title (i18n/label :t/ready-to-import-keypair-keycard)
|
||||
:ready-to-add-screen-image (resources/get-image :import-key-to-keycard)}]]]})))
|
||||
:fx [[:dispatch [:keycard/create.create-or-enter-pin]]]})))
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -24,7 +25,6 @@
|
||||
:title (i18n/label :t/check-keycard)
|
||||
:subtitle (i18n/label :t/see-keycard-ready)
|
||||
:button-label (i18n/label :t/scan-keycard)
|
||||
:button-props {:type :primary :icon-left :i/keycard}
|
||||
:accessibility-label :get-keycard
|
||||
:image (resources/get-image :check-your-keycard)
|
||||
:on-press #(rf/dispatch [:keycard/create.check-empty-card])}]
|
||||
@@ -37,35 +37,31 @@
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press #(rf/dispatch [:browser.ui/open-url constants/get-keycard-url])}]]
|
||||
[rn/view {:style {:flex 1}}]
|
||||
[common.view/tips]])
|
||||
|
||||
(defn- ready-to-add-documentation
|
||||
[]
|
||||
[quo/documentation-drawers
|
||||
{:shell? true}
|
||||
[quo/text {:size :paragraph-2}
|
||||
(i18n/label :t/ready-add-keypair-keycard-documentation)]])
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]])
|
||||
|
||||
(defn ready-to-add
|
||||
[]
|
||||
(let [{:keys [title image]} (rf/sub [:get-screen-params])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content ready-to-add-documentation
|
||||
:theme :dark
|
||||
:shell? true}])}]}]
|
||||
[quo/page-top
|
||||
{:title title}]
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style {:flex 1 :align-self :center :margin-vertical 37}
|
||||
:source image}]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/create.start])}}]]))
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back
|
||||
:right-side [(when config/show-not-implemented-features?
|
||||
{:icon-name :i/info
|
||||
:on-press not-implemented/alert})]}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/ready-add-keypair-keycard)
|
||||
:description :text
|
||||
:description-text ""}]
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style {:flex 1 :align-self :center :margin-vertical 37}
|
||||
:source (resources/get-image :add-key-to-keycard)}]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/create.start])}}]])
|
||||
|
||||
@@ -56,14 +56,6 @@
|
||||
(fn [args]
|
||||
(keycard/factory-reset (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/verify-pin
|
||||
(fn [args]
|
||||
(keycard/verify-pin (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/change-pin
|
||||
(fn [args]
|
||||
(keycard/change-pin (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/sign
|
||||
(fn [args]
|
||||
(-> (keycard/sign args)
|
||||
@@ -83,7 +75,7 @@
|
||||
(promesa/then on-success)
|
||||
(promesa/catch (keycard.utils/get-on-failure args)))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/init-card
|
||||
(rf/reg-fx :keycard/init-card
|
||||
(fn [args]
|
||||
(keycard/init-card (keycard.utils/wrap-handlers args))))
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
:accessibility-label :create-new-profile-keycard
|
||||
:container-style {:margin-horizontal 20 :margin-top 8}
|
||||
:image (resources/get-image :keycard-buy)
|
||||
:button-props {:type :primary}
|
||||
:button-type :primary
|
||||
:on-press #(rf/dispatch [:keycard/create.get-phrase])}]
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
|
||||
@@ -2,22 +2,20 @@
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.contexts.keycard.backup.view :as backup.view]
|
||||
[status-im.contexts.keycard.factory-reset.view :as factory-reset]
|
||||
[status-im.contexts.keycard.unblock.view :as keycard.unblock]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def titles
|
||||
{:keycard/error.keycard-empty {:title (i18n/label :t/keycard-empty)
|
||||
{:keycard/error.keycard-blank {:title (i18n/label :t/keycard-empty)
|
||||
:description (i18n/label :t/no-key-pair-keycard)}
|
||||
:keycard/error.keycard-wrong-profile {:title (i18n/label :t/keycard-not-empty)
|
||||
:description (i18n/label :t/cant-store-new-keys)}
|
||||
:keycard/error.keycard-unpaired {:title (i18n/label :t/keycard-full)
|
||||
:description (i18n/label :t/pairing-slots-occupied)}
|
||||
:keycard/error.keycard-frozen {:title (i18n/label :t/keycard-blocked)
|
||||
:keycard/error.keycard-frozen {:title (i18n/label :t/keycard-locked)
|
||||
:description (i18n/label :t/cant-use-right-now)}
|
||||
:keycard/error.keycard-locked {:title (i18n/label :t/keycard-blocked)
|
||||
:keycard/error.keycard-locked {:title (i18n/label :t/keycard-locked)
|
||||
:description (i18n/label :t/cant-use-right-now)}})
|
||||
|
||||
(defn view
|
||||
@@ -33,38 +31,11 @@
|
||||
:description :text
|
||||
:description-text description}]
|
||||
[rn/view {:style {:margin-horizontal 20}}
|
||||
[quo/keycard {:blur? true}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/use-backup-keycard)
|
||||
:image :icon
|
||||
:image-props :i/placeholder
|
||||
:action :arrow
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/create-backup-profile-keycard)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[backup.view/sheet
|
||||
{:on-continue
|
||||
(rf/dispatch
|
||||
[:keycard/backup.create-or-enter-pin])}])}]))}]
|
||||
[quo/keycard {:holder-name ""}]
|
||||
(when (not= :keycard/error.keycard-blank error)
|
||||
[:<>
|
||||
(when (or (= error :keycard/error.keycard-frozen)
|
||||
(= error :keycard/error.keycard-locked))
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/unblock-keycard)
|
||||
:image :icon
|
||||
:image-props :i/placeholder
|
||||
:action :arrow
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/with-recovery-phrase)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content keycard.unblock/sheet}]))}])
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/factory-reset)
|
||||
:image :icon
|
||||
@@ -74,6 +45,4 @@
|
||||
:description-props {:text (i18n/label :t/remove-keycard-content)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content factory-reset/sheet}]))}]])]]))
|
||||
{:content factory-reset/sheet}]))}]])]]))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
(ns status-im.contexts.keycard.events
|
||||
(:require [re-frame.core :as rf]
|
||||
status-im.contexts.keycard.backup.events
|
||||
status-im.contexts.keycard.check.events
|
||||
status-im.contexts.keycard.create.events
|
||||
status-im.contexts.keycard.login.events
|
||||
status-im.contexts.keycard.migrate.events
|
||||
@@ -10,7 +8,6 @@
|
||||
status-im.contexts.keycard.nfc.sheets.events
|
||||
status-im.contexts.keycard.pin.events
|
||||
status-im.contexts.keycard.sign.events
|
||||
status-im.contexts.keycard.unblock.events
|
||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||
[utils.address :as address]
|
||||
utils.datetime
|
||||
@@ -59,10 +56,6 @@
|
||||
[:keycard/on-application-info-error
|
||||
:keycard/error.keycard-locked]])]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard/init-card
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/init-card data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/get-keys
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/get-keys data}))
|
||||
@@ -79,20 +72,11 @@
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/factory-reset data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/verify-pin
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/verify-pin data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/change-pin
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/change-pin data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/connect-derive-address-and-add-account
|
||||
(fn [_ [{:keys [pin derivation-path key-uid account-preferences]}]]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:key-uid key-uid
|
||||
{:key-uid key-uid
|
||||
:on-success
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
@@ -161,26 +145,17 @@
|
||||
(rf/dispatch [:keycard/on-application-info-error
|
||||
:keycard/error.not-keycard]))))}}))
|
||||
|
||||
(rf/reg-event-fx :keycard/connect.next-stage
|
||||
(fn [{:keys [db]} [{:keys [key-uid on-success on-error]}]]
|
||||
(let [event-vector [:keycard/get-application-info
|
||||
{:key-uid key-uid
|
||||
:on-success on-success
|
||||
:on-error on-error}]]
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
|
||||
:fx [(when (get-in db [:keycard :card-connected?])
|
||||
[:dispatch event-vector])]})))
|
||||
|
||||
(rf/reg-event-fx :keycard/connect
|
||||
(fn [{:keys [db]} [{:keys [key-uid on-success on-error theme]}]]
|
||||
(let [event-vector [:keycard/get-application-info
|
||||
{:key-uid key-uid
|
||||
:on-success on-success
|
||||
:on-error on-error}]]
|
||||
(fn [{:keys [db]} [{:keys [key-uid on-success on-error on-connect-event-vector]}]]
|
||||
(let [event-vector
|
||||
(or on-connect-event-vector
|
||||
[:keycard/get-application-info
|
||||
{:key-uid key-uid
|
||||
:on-success on-success
|
||||
:on-error on-error}])]
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
|
||||
:fx [[:dispatch
|
||||
[:keycard/show-connection-sheet
|
||||
{:on-cancel-event-vector [:keycard/cancel-connection]
|
||||
:theme theme}]]
|
||||
{:on-cancel-event-vector [:keycard/cancel-connection]}]]
|
||||
(when (get-in db [:keycard :card-connected?])
|
||||
[:dispatch event-vector])]})))
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
[key-uid]
|
||||
(rf/dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:key-uid key-uid
|
||||
{:key-uid key-uid
|
||||
:on-success reset-card
|
||||
:on-error (fn [error]
|
||||
(if (or (= error :keycard/error.keycard-frozen)
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
(fn []
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:on-error
|
||||
{:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-wrong-profile)
|
||||
(do
|
||||
@@ -58,8 +57,7 @@
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:theme :dark
|
||||
:key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
{:key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
:on-success (fn []
|
||||
(rf/dispatch
|
||||
[:keycard/get-more-keys
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
(ns status-im.contexts.keycard.manage.profile-keys.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.contexts.keycard.backup.view :as backup.view]
|
||||
[status-im.contexts.keycard.change-pin.view :as change-pin.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- backup-sheet
|
||||
[]
|
||||
[backup.view/sheet
|
||||
{:on-continue
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/keycard.backup.scan-empty]))}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title profile-name}]
|
||||
[rn/view {:style {:margin-horizontal 20}}
|
||||
[rn/view {:style {:padding-top 8 :padding-bottom 20}}
|
||||
[quo/keycard {:blur? true}]]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/change-pin-keycard)
|
||||
:image :icon
|
||||
:blur? true
|
||||
:image-props :i/keycard
|
||||
:action :arrow
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/change-pin-keycard-description)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content change-pin.view/change-pin-confirmation-sheet}]))}]
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/backup-keycard)
|
||||
:image :icon
|
||||
:blur? true
|
||||
:image-props :i/keycard
|
||||
:action :arrow
|
||||
:description :text
|
||||
:description-props {:text (i18n/label :t/create-backup-profile-keycard)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content backup-sheet}]))}]]]))
|
||||
@@ -3,6 +3,23 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.check-empty-card
|
||||
(fn [{:keys [db]}]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:on-success
|
||||
(fn []
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.profile-keys]))
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.empty]))
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
|
||||
|
||||
(defn get-application-info-and-continue
|
||||
[key-uid]
|
||||
(rf/dispatch [:keycard/get-application-info
|
||||
@@ -10,7 +27,7 @@
|
||||
:on-success #(rf/dispatch [:keycard/migration.continue])
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(rf/dispatch [:keycard/migration.continue])
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]))
|
||||
|
||||
@@ -23,7 +40,7 @@
|
||||
(cond
|
||||
|
||||
(not initialized?)
|
||||
{:fx [[:effects.keycard/init-card
|
||||
{:fx [[:keycard/init-card
|
||||
{:pin pin
|
||||
:on-success #(get-application-info-and-continue key-uid)}]]}
|
||||
|
||||
@@ -46,27 +63,17 @@
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:on-success #(rf/dispatch [:keycard/migration.continue])
|
||||
:theme :dark
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(rf/dispatch [:keycard/migration.continue])
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
|
||||
|
||||
(defn- backup-recovery-phrase-success
|
||||
[masked-seed-phrase]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :screen/confirm-backup-dark
|
||||
(rf/dispatch [:open-modal :screen/confirm-backup
|
||||
{:masked-seed-phrase masked-seed-phrase
|
||||
:theme :dark
|
||||
:shell? true
|
||||
:on-try-again #(rf/dispatch [:open-modal :screen/backup-recovery-phrase-dark
|
||||
{:on-success backup-recovery-phrase-success
|
||||
:masked-seed-phrase (->> masked-seed-phrase
|
||||
security/safe-unmask-data
|
||||
(string/join " ")
|
||||
security/mask-data)
|
||||
:revealed? true}])
|
||||
:on-success #(rf/dispatch [:keycard/migration.phrase-backed-up])}]))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.get-phrase
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
:description-text (i18n/label :t/finalise-migration-instructions)}]
|
||||
[rn/view {:style {:margin-horizontal 20}}
|
||||
[rn/view {:style {:padding-top 8 :padding-bottom 20}}
|
||||
[quo/keycard {:blur? true}]]
|
||||
[quo/keycard {:holder-name ""}]]
|
||||
[quo/section-label {:section (i18n/label :t/what-you-can-do) :container-style {:padding-vertical 8}}]
|
||||
[quo/settings-item
|
||||
{:title (i18n/label :t/finalise-migration)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -27,7 +26,9 @@
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration)}]]
|
||||
[common.view/tips]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (if initialized? (i18n/label :t/enter-keycard-pin) (i18n/label :t/scan-keycard))
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(rf/reg-event-fx :keycard/show-connection-sheet
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector theme]} :as args]]
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]} :as args]]
|
||||
(if platform/android?
|
||||
{:db (assoc-in db
|
||||
[:keycard :connection-sheet-opts]
|
||||
{:on-close #(rf/dispatch on-cancel-event-vector)
|
||||
:theme theme})
|
||||
{:on-close #(rf/dispatch on-cancel-event-vector)})
|
||||
:fx [[:effects.keycard.ios/start-nfc nil]
|
||||
[:dismiss-keyboard true]
|
||||
[:show-nfc-sheet nil]]}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
(defn connect-keycard
|
||||
[]
|
||||
(let [connected? (rf/sub [:keycard/connected?])
|
||||
{:keys [on-close theme]} (rf/sub [:keycard/connection-sheet-opts])
|
||||
theme (or theme (quo.theme/use-theme))]
|
||||
(let [connected? (rf/sub [:keycard/connected?])
|
||||
{:keys [on-close]} (rf/sub [:keycard/connection-sheet-opts])
|
||||
theme (quo.theme/use-theme)]
|
||||
[rn/view {:flex 1}
|
||||
[rn/view {:flex 1}]
|
||||
[rn/view
|
||||
|
||||
@@ -9,47 +9,45 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [on-complete title repeat-stage-title]} (rf/sub [:get-screen-params])
|
||||
[pin set-pin] (rn/use-state "")
|
||||
[first-pin set-first-pin] (rn/use-state "")
|
||||
[error? set-error] (rn/use-state false)
|
||||
[stage set-stage] (rn/use-state :create)
|
||||
pin-empty? (string/blank? pin)
|
||||
on-delete (rn/use-callback
|
||||
(fn []
|
||||
(set-error false)
|
||||
(if (= (count pin) 1)
|
||||
(do
|
||||
(set-pin "")
|
||||
(set-stage :create))
|
||||
(when (and pin (pos? (count pin)))
|
||||
(set-pin (.slice pin 0 -1)))))
|
||||
[pin])
|
||||
on-press (rn/use-callback
|
||||
(fn [new-symbol]
|
||||
(let [new-pin (str pin new-symbol)]
|
||||
(when (<= (count new-pin)
|
||||
constants/pincode-length)
|
||||
(set-pin new-pin)
|
||||
(when (= constants/pincode-length
|
||||
(count new-pin))
|
||||
(if (= :repeat stage)
|
||||
(if (= first-pin new-pin)
|
||||
(on-complete new-pin)
|
||||
(set-error true))
|
||||
(do
|
||||
(set-pin "")
|
||||
(set-first-pin new-pin)
|
||||
(set-stage :repeat)))))))
|
||||
[pin stage first-pin])]
|
||||
(let [{:keys [on-complete]} (rf/sub [:get-screen-params])
|
||||
[pin set-pin] (rn/use-state "")
|
||||
[first-pin set-first-pin] (rn/use-state "")
|
||||
[error? set-error] (rn/use-state false)
|
||||
[stage set-stage] (rn/use-state :create)
|
||||
pin-empty? (string/blank? pin)
|
||||
on-delete (rn/use-callback
|
||||
(fn []
|
||||
(set-error false)
|
||||
(if (= (count pin) 1)
|
||||
(do
|
||||
(set-pin "")
|
||||
(set-stage :create))
|
||||
(when (and pin (pos? (count pin)))
|
||||
(set-pin (.slice pin 0 -1)))))
|
||||
[pin])
|
||||
on-press (rn/use-callback
|
||||
(fn [new-symbol]
|
||||
(let [new-pin (str pin new-symbol)]
|
||||
(when (<= (count new-pin) constants/pincode-length)
|
||||
(set-pin new-pin)
|
||||
(when (= constants/pincode-length (count new-pin))
|
||||
(if (= :repeat stage)
|
||||
(if (= first-pin new-pin)
|
||||
(on-complete new-pin)
|
||||
(set-error true))
|
||||
(do
|
||||
(set-pin "")
|
||||
(set-first-pin new-pin)
|
||||
(set-stage :repeat)))))))
|
||||
[pin stage first-pin])]
|
||||
[rn/view {:style {:padding-bottom 12 :flex 1}}
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (if (= :create stage)
|
||||
(or title (i18n/label :t/create-keycard-pin))
|
||||
(or repeat-stage-title (i18n/label :t/repeat-keycard-pin)))
|
||||
(i18n/label :t/create-keycard-pin)
|
||||
(i18n/label :t/repeat-keycard-pin))
|
||||
:description :text
|
||||
:description-text (i18n/label :t/pin-needed-login-sign)}]
|
||||
[rn/view {:style {:flex 1 :justify-content :center :align-items :center :padding-vertical 34}}
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [on-complete title]} (rf/sub [:get-screen-params])]
|
||||
(let [{:keys [on-complete]} (rf/sub [:get-screen-params])]
|
||||
[rn/view {:style {:padding-bottom 12 :flex 1}}
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top {:title (or title (i18n/label :t/enter-keycard-pin))}]
|
||||
[quo/page-top {:title (i18n/label :t/enter-keycard-pin)}]
|
||||
[keycard.pin/auth {:on-complete on-complete}]]))
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
(ns status-im.contexts.keycard.unblock.events
|
||||
(:require [utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/unblock.pin-created
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:db (assoc-in db [:keycard :unblock :pin] pin)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch [:open-modal :screen/keycard.unblock.ready-to-unblock]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/unblock.phrase-entered
|
||||
(fn [{:keys [db]} [{:keys [phrase]}]]
|
||||
{:db (assoc-in db [:keycard :unblock :masked-phrase] phrase)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.pin.create
|
||||
{:on-complete #(rf/dispatch [:keycard/unblock.pin-created %])}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/unblock.generate-and-load-key
|
||||
(fn [{:keys [db]}]
|
||||
(let [{:keys [masked-phrase pin]} (get-in db [:keycard :unblock])]
|
||||
{:fx [[:effects.keycard/generate-and-load-key
|
||||
{:mnemonic (security/safe-unmask-data masked-phrase)
|
||||
:pin pin
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :screen/keycard.unblock.success]))}]]})))
|
||||
|
||||
;; third stage, import keys
|
||||
(rf/reg-event-fx :keycard/unblock.import-keys
|
||||
(fn []
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect.next-stage
|
||||
{:on-error (fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(rf/dispatch [:keycard/unblock.generate-and-load-key])
|
||||
(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/on-application-info-error error]))))}]]]}))
|
||||
|
||||
;; second stage, check if card initialized
|
||||
(rf/reg-event-fx :keycard/unblock.init-card-or-import-keys
|
||||
(fn [{:keys [db]}]
|
||||
(let [pin (get-in db [:keycard :unblock :pin])
|
||||
{:keys [initialized?]} (get-in db [:keycard :application-info])]
|
||||
{:fx [(if initialized?
|
||||
[:dispatch [:keycard/unblock.import-keys]]
|
||||
[:effects.keycard/init-card
|
||||
{:pin pin
|
||||
:on-success #(rf/dispatch [:keycard/unblock.import-keys])}])]})))
|
||||
|
||||
;; second stage, init card with pin
|
||||
(defn init-with-pin
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:keycard/connect.next-stage
|
||||
{:on-error (fn [error]
|
||||
(if (= error :keycard/error.keycard-empty)
|
||||
(rf/dispatch [:keycard/unblock.init-card-or-import-keys])
|
||||
(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/on-application-info-error error]))))}]))
|
||||
|
||||
;; first stage, reset card
|
||||
(rf/reg-event-fx :keycard/unblock
|
||||
(fn [{:keys [db]}]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:keycard :application-info :key-uid])
|
||||
:on-error (fn [error]
|
||||
(cond
|
||||
(or (= error :keycard/error.keycard-frozen)
|
||||
(= error :keycard/error.keycard-locked))
|
||||
(rf/dispatch [:keycard/factory-reset {:on-success init-with-pin}])
|
||||
|
||||
(= error :keycard/error.keycard-empty)
|
||||
(init-with-pin)
|
||||
|
||||
:else
|
||||
(do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(if (= error :keycard/error.keycard-wrong-profile)
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.different-card]))
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))))}]]]}))
|
||||
@@ -1,60 +0,0 @@
|
||||
(ns status-im.contexts.keycard.unblock.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.contexts.keycard.common.view :as common.view]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn success-view
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard-unblocked)}]
|
||||
[rn/view {:style {:flex 1}}]
|
||||
[rn/view {:style {:padding-horizontal 20}}
|
||||
[quo/button {:on-press events-helper/navigate-back}
|
||||
(i18n/label :t/done)]]])
|
||||
|
||||
(defn ready-to-unblock
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/ready-to-unblock-keycard)}]
|
||||
[rn/view {:style {:flex 1}}]
|
||||
[common.view/tips]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/unblock])}}]])
|
||||
|
||||
(defn sheet
|
||||
[]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/drawer-top {:title (i18n/label :t/unblock-keycard-recovery)}]
|
||||
[quo/text
|
||||
{:style {:padding-horizontal 20
|
||||
:padding-vertical 8}}
|
||||
(i18n/label :t/unblock-keycard-instructions)]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:button-one-label (i18n/label :t/continue)
|
||||
:button-one-props {:customization-color
|
||||
customization-color
|
||||
:on-press
|
||||
(fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/use-recovery-phrase-dark
|
||||
{:on-success #(rf/dispatch [:keycard/unblock.phrase-entered %])}]))}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||
@@ -28,7 +28,7 @@
|
||||
:keycard/error.not-keycard
|
||||
|
||||
(not has-master-key?)
|
||||
:keycard/error.keycard-empty
|
||||
:keycard/error.keycard-blank
|
||||
|
||||
(and (zero? pin-retry-counter)
|
||||
(or (nil? puk-retry-counter)
|
||||
@@ -84,9 +84,8 @@
|
||||
(->> (:accounts kp)
|
||||
(map :address)
|
||||
set))]
|
||||
(when-not (nil? address)
|
||||
(-> keypairs
|
||||
vals
|
||||
find-keycard-keypair
|
||||
keypair-addresses
|
||||
(contains? (string/lower-case address))))))
|
||||
(-> keypairs
|
||||
vals
|
||||
find-keycard-keypair
|
||||
keypair-addresses
|
||||
(contains? (string/lower-case address)))))
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...78b"}
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "oeth"}]
|
||||
:action :none
|
||||
:on-press (fn [] (js/alert "Item pressed"))
|
||||
:on-options-press (fn [] (js/alert "Options pressed"))
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
[{:type :select
|
||||
:key :status
|
||||
:options [{:key :error}
|
||||
{:key :warning}
|
||||
{:key :default}]}
|
||||
{:type :text
|
||||
:key :title}
|
||||
|
||||
@@ -44,23 +44,22 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [step-labels [:t/backup-step-1 :t/backup-step-2 :t/backup-step-3
|
||||
:t/backup-step-4]
|
||||
checked? (reagent/atom
|
||||
{:0 false
|
||||
:1 false
|
||||
:2 false
|
||||
:3 false})
|
||||
{:keys [on-success masked-seed-phrase
|
||||
revealed?]} (rf/sub [:get-screen-params])
|
||||
revealed? (reagent/atom revealed?)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
seed-phrase (reagent/atom (if masked-seed-phrase
|
||||
(->
|
||||
(security/safe-unmask-data
|
||||
masked-seed-phrase)
|
||||
(string/split #"\s"))
|
||||
[]))]
|
||||
(let [step-labels [:t/backup-step-1 :t/backup-step-2 :t/backup-step-3
|
||||
:t/backup-step-4]
|
||||
checked? (reagent/atom
|
||||
{:0 false
|
||||
:1 false
|
||||
:2 false
|
||||
:3 false})
|
||||
revealed? (reagent/atom false)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
{:keys [on-success masked-seed-phrase]} (rf/sub [:get-screen-params])
|
||||
seed-phrase (reagent/atom (if masked-seed-phrase
|
||||
(->
|
||||
(security/safe-unmask-data
|
||||
masked-seed-phrase)
|
||||
(string/split #"\s"))
|
||||
[]))]
|
||||
(fn []
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
(rn/use-mount
|
||||
@@ -109,7 +108,8 @@
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/i-have-written)
|
||||
:button-one-props {:customization-color customization-color
|
||||
:button-one-props {:disabled? (some false? (vals @checked?))
|
||||
:customization-color customization-color
|
||||
:on-press #(on-success (security/mask-data @seed-phrase))}}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[]
|
||||
{;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is resolved
|
||||
:wakuV2Nameserver "8.8.8.8"
|
||||
:kdfIterations 3200
|
||||
:statusProxyEnabled config/status-proxy-enabled?
|
||||
:statusProxyStageName config/status-proxy-stage-name
|
||||
:statusProxyMarketUser config/STATUS_BUILD_PROXY_USER
|
||||
|
||||
@@ -5,42 +5,95 @@
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.settings.keycard.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn registered-keycard
|
||||
[{:keys [profile-name profile-image customization-color]}]
|
||||
[rn/view {:style style/keycard-row}
|
||||
[quo/icon :i/keycard-card
|
||||
{:size 20
|
||||
:color colors/white-70-blur}]
|
||||
[rn/view
|
||||
[quo/text profile-name]
|
||||
[rn/view {:style style/keycard-owner}
|
||||
[quo/user-avatar
|
||||
{:full-name profile-name
|
||||
:profile-picture profile-image
|
||||
:customization-color customization-color
|
||||
:status-indicator false
|
||||
:ring? false
|
||||
:size :xxxs}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/keycard-owner-name}
|
||||
profile-name]]]])
|
||||
|
||||
(defn registered-keycards
|
||||
[]
|
||||
(let [keycards (rf/sub [:keycard/registered-keycards])]
|
||||
[:<>
|
||||
[rn/view {:style {:flex 1}}
|
||||
[quo/divider-label
|
||||
{:counter? false
|
||||
:tight? true
|
||||
:blur? true}
|
||||
(i18n/label :t/registered-keycards)]
|
||||
[rn/view {:style style/registered-keycards-container}
|
||||
(for [keycard keycards]
|
||||
^{:key (:keycard-uid keycard)}
|
||||
[registered-keycard keycard])]]
|
||||
[quo/text
|
||||
{:size :heading-2
|
||||
:weight :semi-bold
|
||||
:style {:margin-left 20}}
|
||||
(i18n/label :t/scan-keycard-actions)]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/ready-to-scan)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/connect])}}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard)}]
|
||||
[rn/view {:style {:padding-horizontal 28 :padding-top 20}}
|
||||
[quo/small-option-card
|
||||
{:variant :main
|
||||
:title (i18n/label :t/get-keycard)
|
||||
:subtitle (i18n/label :t/secure-wallet-card)
|
||||
:button-label (i18n/label :t/buy-keycard)
|
||||
:accessibility-label :get-keycard
|
||||
:image (resources/get-image :keycard-buy)
|
||||
:on-press #(rf/dispatch [:browser.ui/open-url constants/get-keycard-url])}]
|
||||
[rn/view {:style {:margin-top 24}}
|
||||
[quo/text
|
||||
{:style {:margin-bottom 1
|
||||
:color colors/white-opa-70}
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/own-keycard)]]
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/manage-keycard)
|
||||
:subtitle (i18n/label :t/setup-keycard-description)
|
||||
:accessibility-label :setup-keycard
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:open-modal :screen/keycard.check
|
||||
{:on-press
|
||||
#(rf/dispatch [:keycard/check-empty-card])}]))}]]])
|
||||
(let [keycard-profile? (rf/sub [:keycard/keycard-profile?])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard)}]
|
||||
(if keycard-profile?
|
||||
[registered-keycards]
|
||||
[rn/view {:style {:padding-horizontal 28 :padding-top 20}}
|
||||
[quo/small-option-card
|
||||
{:variant :main
|
||||
:title (i18n/label :t/get-keycard)
|
||||
:subtitle (i18n/label :t/secure-wallet-card)
|
||||
:button-label (i18n/label :t/buy-keycard)
|
||||
:accessibility-label :get-keycard
|
||||
:image (resources/get-image :keycard-buy)
|
||||
:on-press #(rf/dispatch [:browser.ui/open-url constants/get-keycard-url])}]
|
||||
[rn/view {:style {:margin-top 24}}
|
||||
[quo/text
|
||||
{:style {:margin-bottom 1
|
||||
:color colors/white-opa-70}
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/own-keycard)]]
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/setup-keycard)
|
||||
:subtitle (i18n/label :t/ready-keycard)
|
||||
:accessibility-label :setup-keycard
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:open-modal :screen/keycard.check
|
||||
{:on-press
|
||||
#(rf/dispatch
|
||||
[:keycard/migration.check-empty-card])}]))}]])]))
|
||||
|
||||
+8
-11
@@ -7,6 +7,7 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.validation :as validation]
|
||||
[utils.address :as utils-address]
|
||||
[utils.debounce :as debounce]
|
||||
@@ -19,7 +20,7 @@
|
||||
|
||||
(defn- validate-input
|
||||
[account-addresses saved-addresses user-input]
|
||||
(let [address-without-prefix (utils-address/extract-address-without-chains-info user-input)]
|
||||
(let [[_ address-without-prefix] (utils/split-prefix-and-address user-input)]
|
||||
(cond
|
||||
(string/blank? user-input)
|
||||
nil
|
||||
@@ -95,8 +96,8 @@
|
||||
|
||||
(defn- existing-saved-address
|
||||
[{:keys [address]}]
|
||||
(let [address-without-prefix (utils-address/extract-address-without-chains-info address)
|
||||
{:keys [name customization-color ens ens?]}
|
||||
(let [[_ address-without-prefix] (utils/split-prefix-and-address address)
|
||||
{:keys [name customization-color chain-short-names ens ens?]}
|
||||
(rf/sub [:wallet/saved-address-by-address address-without-prefix])]
|
||||
[rn/view {:style style/existing-saved-address-container}
|
||||
[quo/text
|
||||
@@ -108,7 +109,7 @@
|
||||
{:blur? true
|
||||
:active-state? true
|
||||
:user-props {:name name
|
||||
:address address-without-prefix
|
||||
:address (str chain-short-names address-without-prefix)
|
||||
:ens (when ens? ens)
|
||||
:customization-color customization-color
|
||||
:blur? true}
|
||||
@@ -154,13 +155,9 @@
|
||||
:on-success on-ens-resolve
|
||||
:on-error #(set-error :ens-not-registered)}]
|
||||
300)))))
|
||||
paste-into-input (rn/use-callback
|
||||
#(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(when-not (string/blank? clipboard-text)
|
||||
(-> clipboard-text
|
||||
utils-address/extract-address-without-chains-info
|
||||
on-change-text)))))
|
||||
paste-into-input (rn/use-callback #(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(on-change-text clipboard-text))))
|
||||
on-press-continue (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
|
||||
(defn save-address
|
||||
[{:keys [db]}
|
||||
[{:keys [address name customization-color on-success on-error ens]}]]
|
||||
[{:keys [address name customization-color on-success on-error chain-short-names ens]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?}]
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?
|
||||
:chainShortNames chain-short-names}]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_upsertSavedAddress"
|
||||
:params [address-to-save]
|
||||
|
||||
@@ -174,21 +174,24 @@
|
||||
address "0x3"
|
||||
ens "bobby.eth"
|
||||
customization-color :yellow
|
||||
chain-short-names "eth:arb1:oeth:"
|
||||
args {:on-success on-success
|
||||
:on-error on-error
|
||||
:name name
|
||||
:address address
|
||||
:customization-color customization-color
|
||||
:ens ens}
|
||||
:ens ens
|
||||
:chain-short-names chain-short-names}
|
||||
effects (events/save-address cofx [args])
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:json-rpc/call
|
||||
[{:method "wakuext_upsertSavedAddress"
|
||||
:params [{:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?}]
|
||||
:params [{:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?
|
||||
:chainShortNames chain-short-names}]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.save-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -15,22 +18,58 @@
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- network-preferences-sheet
|
||||
[{:keys [address color selected-networks set-selected-networks]}]
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:title (i18n/label :t/add-network-preferences)
|
||||
:description (i18n/label :t/saved-address-network-preference-selection-description)
|
||||
:button-label (i18n/label :t/add-preferences)
|
||||
:blur? true
|
||||
:selected-networks (set selected-networks)
|
||||
:account {:address address
|
||||
:color color}
|
||||
:on-save (fn [chain-ids]
|
||||
(set-selected-networks (map network-utils/id->network chain-ids))
|
||||
(rf/dispatch [:hide-bottom-sheet]))}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [edit?]} (rf/sub [:get-screen-params])
|
||||
{:keys [address name customization-color ens ens?]}
|
||||
{:keys [address name customization-color ens ens? network-preferences-names]}
|
||||
(rf/sub [:wallet/saved-address])
|
||||
[network-prefixes address-without-prefix] (utils/split-prefix-and-address address)
|
||||
[address-label set-address-label] (rn/use-state (or name ""))
|
||||
[address-color set-address-color] (rn/use-state (or customization-color
|
||||
(rand-nth colors/account-colors)))
|
||||
[selected-networks set-selected-networks]
|
||||
(rn/use-state (or network-preferences-names
|
||||
(network-utils/network-preference-prefix->network-names network-prefixes)))
|
||||
chain-short-names (rn/use-memo
|
||||
#(network-utils/network-names->network-preference-prefix
|
||||
selected-networks)
|
||||
[selected-networks])
|
||||
placeholder (i18n/label :t/address-name)
|
||||
address-text (rn/use-callback
|
||||
(fn []
|
||||
[quo/address-text
|
||||
{:full-address? true
|
||||
:address address
|
||||
:address (str chain-short-names address-without-prefix)
|
||||
:format :long}])
|
||||
[address])
|
||||
[address-without-prefix chain-short-names])
|
||||
open-network-preferences (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (network-preferences-sheet
|
||||
{:address address-without-prefix
|
||||
:color address-color
|
||||
:selected-networks selected-networks
|
||||
:set-selected-networks
|
||||
set-selected-networks})}]))
|
||||
[address selected-networks address-color])
|
||||
on-press-save (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/save-address
|
||||
@@ -43,9 +82,10 @@
|
||||
[:wallet/add-saved-address-failed]
|
||||
:name address-label
|
||||
:ens (when ens? ens)
|
||||
:address address
|
||||
:customization-color address-color}]))
|
||||
[address address-label
|
||||
:address address-without-prefix
|
||||
:customization-color address-color
|
||||
:chain-short-names chain-short-names}]))
|
||||
[address-without-prefix chain-short-names address-label
|
||||
address-color])
|
||||
data-item-props (rn/use-memo
|
||||
#(cond-> {:status :default
|
||||
@@ -53,14 +93,16 @@
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? true
|
||||
:right-icon (when-not ens? :i/advanced)
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:subtitle ens
|
||||
:custom-subtitle address-text
|
||||
:on-press (when-not ens? open-network-preferences)
|
||||
:container-style style/data-item}
|
||||
ens?
|
||||
(dissoc :custom-subtitle))
|
||||
[ens ens? address-text])]
|
||||
[ens ens? open-network-preferences address-text])]
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0)
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.share-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.image-server :as image-server]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -29,18 +32,54 @@
|
||||
:message address
|
||||
:isNewTask true})}]))
|
||||
|
||||
(defn- open-preferences
|
||||
[{:keys [address color selected-networks set-selected-networks]}]
|
||||
(let [on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(set-selected-networks (map network-utils/id->network chain-ids)))
|
||||
sheet-content (fn []
|
||||
[network-preferences/view
|
||||
{:description (i18n/label
|
||||
:t/saved-address-network-preference-selection-description)
|
||||
:button-label (i18n/label :t/display)
|
||||
:blur? true
|
||||
:selected-networks (set selected-networks)
|
||||
:account {:address address
|
||||
:color color}
|
||||
:on-save on-save}])]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content sheet-content}])))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [name address customization-color]} (rf/sub [:get-screen-params])
|
||||
share-title (str name " " (i18n/label :t/address))
|
||||
qr-url address
|
||||
qr-media-server-uri (rn/use-memo
|
||||
#(image-server/get-qr-image-uri-for-any-url
|
||||
{:url qr-url
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
:qr-size qr-size
|
||||
:error-level :highest})
|
||||
[qr-url])]
|
||||
(let [{:keys [name address customization-color
|
||||
network-preferences-names]} (rf/sub [:get-screen-params])
|
||||
[wallet-type set-wallet-type] (rn/use-state :legacy)
|
||||
[selected-networks set-selected-networks] (rn/use-state network-preferences-names)
|
||||
on-settings-press (rn/use-callback
|
||||
#(open-preferences
|
||||
{:selected-networks selected-networks
|
||||
:set-selected-networks set-selected-networks
|
||||
:address address
|
||||
:color customization-color})
|
||||
[address customization-color selected-networks])
|
||||
on-legacy-press (rn/use-callback #(set-wallet-type :legacy))
|
||||
on-multichain-press (rn/use-callback #(set-wallet-type :multichain))
|
||||
share-title (str name " " (i18n/label :t/address))
|
||||
qr-url (rn/use-memo #(utils/get-wallet-qr
|
||||
{:wallet-type wallet-type
|
||||
:selected-networks selected-networks
|
||||
:address address})
|
||||
[wallet-type selected-networks address])
|
||||
qr-media-server-uri (rn/use-memo
|
||||
#(image-server/get-qr-image-uri-for-any-url
|
||||
{:url qr-url
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
:qr-size qr-size
|
||||
:error-level :highest})
|
||||
[qr-url])]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:top-inset? true}
|
||||
@@ -56,8 +95,13 @@
|
||||
[rn/view {:style style/qr-wrapper}
|
||||
[quo/share-qr-code
|
||||
{:type :saved-address
|
||||
:address wallet-type
|
||||
:qr-image-uri qr-media-server-uri
|
||||
:qr-data qr-url
|
||||
:networks selected-networks
|
||||
:on-share-press #(share-action qr-url share-title)
|
||||
:full-name name
|
||||
:customization-color customization-color}]]]]))
|
||||
:customization-color customization-color
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-multichain-press on-multichain-press
|
||||
:on-settings-press on-settings-press}]]]]))
|
||||
|
||||
+24
-32
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.sheets.address-options.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
@@ -9,18 +10,18 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [name address customization-color] :as opts}]
|
||||
[{:keys [name full-address chain-short-names address customization-color] :as opts}]
|
||||
(let [open-send-flow (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/init-send-flow-for-address
|
||||
{:address address
|
||||
{:address full-address
|
||||
:recipient
|
||||
{:label name
|
||||
:customization-color
|
||||
customization-color
|
||||
:recipient-type :saved-address}
|
||||
:stack-id :screen/settings.saved-addresses}]))
|
||||
[name customization-color])
|
||||
[full-address name customization-color])
|
||||
open-eth-chain-explorer (rn/use-callback
|
||||
#(rf/dispatch [:wallet/navigate-to-chain-explorer
|
||||
{:address address
|
||||
@@ -36,26 +37,21 @@
|
||||
{:address address
|
||||
:network constants/optimism-network-name}])
|
||||
[address])
|
||||
open-base-chain-explorer (rn/use-callback
|
||||
#(rf/dispatch [:wallet/navigate-to-chain-explorer
|
||||
{:address address
|
||||
:network constants/base-network-name}])
|
||||
[address])
|
||||
open-share (rn/use-callback
|
||||
#(rf/dispatch
|
||||
[:open-share
|
||||
{:options (if platform/ios?
|
||||
{:activityItemSources
|
||||
[{:placeholderItem {:type :text
|
||||
:content address}
|
||||
:content full-address}
|
||||
:item {:default {:type :text
|
||||
:content
|
||||
address}}
|
||||
:linkMetadata {:title address}}]}
|
||||
{:title address
|
||||
:message address
|
||||
full-address}}
|
||||
:linkMetadata {:title full-address}}]}
|
||||
{:title full-address
|
||||
:message full-address
|
||||
:isNewTask true})}])
|
||||
[address])
|
||||
[full-address])
|
||||
open-remove-confirmation-sheet (rn/use-callback
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
@@ -87,24 +83,20 @@
|
||||
:blur? true
|
||||
:on-press open-eth-chain-explorer
|
||||
:accessibility-label :view-address-on-etherscan}
|
||||
{:icon :i/link
|
||||
:right-icon :i/external
|
||||
:label (i18n/label :t/view-address-on-optimistic)
|
||||
:blur? true
|
||||
:on-press open-oeth-chain-explorer
|
||||
:accessibility-label :view-address-on-optimistic}
|
||||
{:icon :i/link
|
||||
:right-icon :i/external
|
||||
:label (i18n/label :t/view-address-on-arbiscan)
|
||||
:blur? true
|
||||
:on-press open-arb-chain-explorer
|
||||
:accessibility-label :view-address-on-arbiscan}
|
||||
{:icon :i/link
|
||||
:right-icon :i/external
|
||||
:label (i18n/label :t/view-address-on-basescan)
|
||||
:blur? true
|
||||
:on-press open-base-chain-explorer
|
||||
:accessibility-label :view-address-on-basescan}
|
||||
(when (string/includes? chain-short-names constants/optimism-short-name)
|
||||
{:icon :i/link
|
||||
:right-icon :i/external
|
||||
:label (i18n/label :t/view-address-on-optimistic)
|
||||
:blur? true
|
||||
:on-press open-oeth-chain-explorer
|
||||
:accessibility-label :view-address-on-optimistic})
|
||||
(when (string/includes? chain-short-names constants/arbitrum-short-name)
|
||||
{:icon :i/link
|
||||
:right-icon :i/external
|
||||
:label (i18n/label :t/view-address-on-arbiscan)
|
||||
:blur? true
|
||||
:on-press open-arb-chain-explorer
|
||||
:accessibility-label :view-address-on-arbiscan})
|
||||
{:icon :i/share
|
||||
:on-press open-share
|
||||
:label (i18n/label :t/share-address)
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
:container-style style/empty-container-style}]))
|
||||
|
||||
(defn- saved-address
|
||||
[{:keys [name address customization-color ens? ens]}]
|
||||
(let [on-press-saved-address (rn/use-callback
|
||||
[{:keys [name address chain-short-names customization-color ens? ens network-preferences-names]}]
|
||||
(let [full-address (str chain-short-names address)
|
||||
on-press-saved-address (rn/use-callback
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
@@ -42,16 +43,20 @@
|
||||
:blur-background colors/bottom-sheet-background-blur
|
||||
:content (fn []
|
||||
[address-options/view
|
||||
{:address address
|
||||
:ens? ens?
|
||||
:ens ens
|
||||
:name name
|
||||
{:address address
|
||||
:chain-short-names chain-short-names
|
||||
:full-address full-address
|
||||
:ens? ens?
|
||||
:ens ens
|
||||
:name name
|
||||
:network-preferences-names
|
||||
network-preferences-names
|
||||
:customization-color customization-color}])}])
|
||||
[address name customization-color])]
|
||||
[address chain-short-names full-address name customization-color])]
|
||||
[quo/saved-address
|
||||
{:blur? true
|
||||
:user-props {:name name
|
||||
:address address
|
||||
:address full-address
|
||||
:ens (when ens? ens)
|
||||
:customization-color customization-color
|
||||
:blur? true}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[quo.core :as quo]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -16,12 +17,13 @@
|
||||
|
||||
(defn- send-to-address
|
||||
[address]
|
||||
(rf/dispatch
|
||||
[:wallet/init-send-flow-for-address
|
||||
{:address address
|
||||
:recipient {:recipient-type :address
|
||||
:label (utils/get-shortened-address address)}
|
||||
:stack-id :wallet-select-address}]))
|
||||
(let [[_ split-address] (network-utils/split-network-full-address address)]
|
||||
(rf/dispatch
|
||||
[:wallet/init-send-flow-for-address
|
||||
{:address address
|
||||
:recipient {:recipient-type :address
|
||||
:label (utils/get-shortened-address split-address)}
|
||||
:stack-id :wallet-select-address}])))
|
||||
|
||||
(defn view
|
||||
[address]
|
||||
|
||||
@@ -11,61 +11,56 @@
|
||||
|
||||
(defn- header
|
||||
[]
|
||||
(let [{:keys [status]} (rf/sub [:get-screen-params])]
|
||||
[:<>
|
||||
[rn/view {:style style/header-row}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :close-shell-share-tab
|
||||
:container-style style/header-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:i/close]
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :shell-scan-button
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :shell-qr-reader]))}
|
||||
:i/scan]]
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style style/header-heading}
|
||||
(if (= :receive status)
|
||||
(i18n/label :t/receive)
|
||||
(i18n/label :t/share))]]))
|
||||
[:<>
|
||||
[rn/view {:style style/header-row}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :close-shell-share-tab
|
||||
:container-style style/header-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
:i/close]
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :grey
|
||||
:background :blur
|
||||
:size 32
|
||||
:accessibility-label :shell-scan-button
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :shell-qr-reader]))}
|
||||
:i/scan]]
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style style/header-heading}
|
||||
(i18n/label :t/share)]])
|
||||
|
||||
(defn- tab-content
|
||||
[]
|
||||
(let [{:keys [initial-tab hide-tab-selector?]
|
||||
:or {initial-tab :profile
|
||||
hide-tab-selector? false}} (rf/sub [:get-screen-params])
|
||||
[selected-tab set-selected-tab] (rn/use-state initial-tab)]
|
||||
[initial-tab]
|
||||
(let [[selected-tab set-selected-tab] (rn/use-state initial-tab)]
|
||||
[rn/view {:style {:padding-top (safe-area/get-top)}}
|
||||
[header]
|
||||
(when-not hide-tab-selector?
|
||||
[rn/view {:style style/tabs-container}
|
||||
[quo/segmented-control
|
||||
{:size 28
|
||||
:blur? true
|
||||
:on-change set-selected-tab
|
||||
:default-active selected-tab
|
||||
:data [{:id :profile
|
||||
:label (i18n/label :t/profile)}
|
||||
{:id :wallet
|
||||
:label (i18n/label :t/wallet)}]}]])
|
||||
[rn/view {:style style/tabs-container}
|
||||
[quo/segmented-control
|
||||
{:size 28
|
||||
:blur? true
|
||||
:on-change set-selected-tab
|
||||
:default-active selected-tab
|
||||
:data [{:id :profile
|
||||
:label (i18n/label :t/profile)}
|
||||
{:id :wallet
|
||||
:label (i18n/label :t/wallet)}]}]]
|
||||
(if (= selected-tab :wallet)
|
||||
[wallet-view/wallet-tab]
|
||||
[profile-view/profile-tab])]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view {:key :share}
|
||||
[tab-content]]])
|
||||
(let [{:keys [initial-tab] :or {initial-tab :profile}} (rf/sub [:get-screen-params])]
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view
|
||||
{:key :share}
|
||||
[tab-content initial-tab]]]))
|
||||
|
||||
@@ -11,20 +11,45 @@
|
||||
share-qr-code (h/get-by-label-text :share-qr-code)]
|
||||
;; Fires on-layout since it's needed to render the content
|
||||
(h/fire-event :layout share-qr-code #js {:nativeEvent #js {:layout #js {:width 500}}})
|
||||
(rerender-fn [wallet-view/wallet-tab])))
|
||||
(rerender-fn [wallet-view/wallet-tab])
|
||||
(h/fire-event :press (h/get-by-label-text :share-qr-code-legacy-tab))))
|
||||
|
||||
(h/describe "share wallet addresses"
|
||||
(h/setup-restorable-re-frame)
|
||||
(h/before-each
|
||||
(fn []
|
||||
(h/setup-subs {:dimensions/window-width 500
|
||||
:mediaserver/port 200
|
||||
:wallet/accounts [{:address "0x707f635951193ddafbb40971a0fcaab8a6415160"
|
||||
:name "Wallet One"
|
||||
:emoji "😆"
|
||||
:color :blue}]})))
|
||||
:mediaserver/port 200
|
||||
:wallet/accounts [{:address "0x707f635951193ddafbb40971a0fcaab8a6415160"
|
||||
:name "Wallet One"
|
||||
:emoji "😆"
|
||||
:color :blue}]
|
||||
:wallet/preferred-chain-names-for-address #{:eth :oeth :arb1}})))
|
||||
|
||||
(h/test "should display the wallet tab"
|
||||
(render-wallet-view)
|
||||
(h/is-truthy (h/query-by-text "Wallet One"))
|
||||
(h/is-truthy (h/query-by-text "0x707f635951193ddafbb40971a0fcaab8a6415160"))))
|
||||
(-> (h/expect (h/query-by-text "Wallet One"))
|
||||
(h/is-truthy)))
|
||||
|
||||
(h/test "should display the legacy account"
|
||||
(render-wallet-view)
|
||||
(-> (h/wait-for #(h/get-by-label-text :share-qr-code-legacy-tab))
|
||||
(.then (fn []
|
||||
(h/is-truthy (h/query-by-text "0x707f635951193ddafbb40971a0fcaab8a6415160"))
|
||||
(h/is-falsy (h/query-by-text "eth:"))))))
|
||||
|
||||
;; NOTE: Fails with error below possibly due to Infura outage:
|
||||
;; FAIL ./status_im.contexts.shell.share.wallet.component_spec.js
|
||||
;; ● share wallet addresses › should display the multichain account
|
||||
;;
|
||||
;; No protocol method IDeref.-deref defined for type undefined
|
||||
(h/test-skip "should display the multichain account"
|
||||
(render-wallet-view)
|
||||
(-> (h/wait-for #(h/get-by-label-text :share-qr-code-multichain-tab))
|
||||
(.then (fn []
|
||||
(h/fire-event :press (h/get-by-label-text :share-qr-code-multichain-tab))
|
||||
(-> (h/wait-for #(h/get-by-label-text :share-qr-code-settings))
|
||||
(.then (fn []
|
||||
(h/is-truthy (h/get-by-text "eth:"))
|
||||
(h/is-truthy (h/get-by-text "oeth:"))
|
||||
(h/is-truthy (h/get-by-text "arb1:"))))))))))
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.shell.share.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.image-server :as image-server]
|
||||
[utils.number]
|
||||
@@ -28,12 +31,36 @@
|
||||
:message address
|
||||
:isNewTask true})}]))
|
||||
|
||||
(defn- open-preferences
|
||||
[selected-networks account]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[network-preferences/view
|
||||
{:blur? true
|
||||
:selected-networks (set @selected-networks)
|
||||
:account account
|
||||
:button-label (i18n/label :t/display)
|
||||
:on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map #(get network-utils/id->network %)
|
||||
chain-ids)))}])}]))
|
||||
|
||||
(defn- wallet-qr-code-item
|
||||
[{:keys [account index]}]
|
||||
(let [{window-width :width} (rn/get-window)]
|
||||
[{:keys [account index preferred-chains]}]
|
||||
(let [{window-width :width} (rn/get-window)
|
||||
selected-networks (reagent/atom preferred-chains)
|
||||
wallet-type (reagent/atom :multichain)
|
||||
on-settings-press #(open-preferences selected-networks account)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
(fn []
|
||||
(let [share-title (str (:name account) " " (i18n/label :t/address))
|
||||
qr-url (:address account)
|
||||
qr-url (utils/get-wallet-qr {:wallet-type @wallet-type
|
||||
:selected-networks @selected-networks
|
||||
:address (:address account)})
|
||||
qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
|
||||
{:url qr-url
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
@@ -44,19 +71,25 @@
|
||||
[quo/share-qr-code
|
||||
{:type :wallet
|
||||
:width (- window-width (* style/screen-padding 2))
|
||||
:address @wallet-type
|
||||
:qr-image-uri qr-media-server-uri
|
||||
:qr-data qr-url
|
||||
:networks @selected-networks
|
||||
:on-share-press #(share-action qr-url share-title)
|
||||
:profile-picture nil
|
||||
:full-name (:name account)
|
||||
:customization-color (:color account)
|
||||
:emoji (:emoji account)}]]]))))
|
||||
:emoji (:emoji account)
|
||||
:on-multichain-press on-multichain-press
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-settings-press on-settings-press}]]]))))
|
||||
|
||||
(defn render-item
|
||||
[{:keys [position] :as account}]
|
||||
[{:keys [address] :as account}]
|
||||
[wallet-qr-code-item
|
||||
{:account account
|
||||
:index position}])
|
||||
{:account account
|
||||
:index (:position account)
|
||||
:preferred-chains (rf/sub [:wallet/preferred-chain-names-for-address address])}])
|
||||
|
||||
(defn- qr-code-visualized-index
|
||||
[offset qr-code-size num-qr-codes]
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
[status-im.contexts.wallet.common.screen-base.create-or-edit-account.view
|
||||
:as create-or-edit-account]
|
||||
[status-im.contexts.wallet.common.utils :as common.utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[status-im.contexts.wallet.sheets.remove-account.view :as remove-account]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -53,10 +55,15 @@
|
||||
:updated-key :name
|
||||
:new-value @edited-account-name}))]
|
||||
(fn []
|
||||
(let [{:keys [name emoji address color default-account?]
|
||||
(let [{:keys [name emoji address color watch-only? default-account?]
|
||||
:as account} (rf/sub [:wallet/current-viewing-account])
|
||||
network-details (rf/sub [:wallet/network-preference-details])
|
||||
test-networks-enabled? (rf/sub [:profile/test-networks-enabled?])
|
||||
other-account-names (rf/sub [:wallet/accounts-names-without-current-account])
|
||||
other-emojis-and-colors (rf/sub [:wallet/accounts-emojis-and-colors-without-current-account])
|
||||
network-preferences-key (if test-networks-enabled?
|
||||
:test-preferred-chain-ids
|
||||
:prod-preferred-chain-ids)
|
||||
account-name (or @edited-account-name name)
|
||||
input-error (or @emoji-color-error @name-error)
|
||||
button-disabled? (or (string/blank? @edited-account-name)
|
||||
@@ -101,9 +108,23 @@
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:blur? false
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (fn [] [quo/address-text
|
||||
{:address address
|
||||
:format :long}])
|
||||
{:networks network-details
|
||||
:address address
|
||||
:format :long}])
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(save-account
|
||||
{:account account
|
||||
:updated-key network-preferences-key
|
||||
:new-value chain-ids}))
|
||||
:watch-only? watch-only?}])}]))
|
||||
:container-style style/data-item}]]))))
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.account.share-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.image-server :as image-server]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -26,14 +31,38 @@
|
||||
:message address
|
||||
:isNewTask true})}]))
|
||||
|
||||
(defn- open-preferences
|
||||
[selected-networks]
|
||||
(let [on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map network-utils/id->network chain-ids)))
|
||||
sheet-content (fn []
|
||||
[network-preferences/view
|
||||
{:blur? true
|
||||
:selected-networks (set @selected-networks)
|
||||
:on-save on-save
|
||||
:button-label (i18n/label :t/display)}])]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content sheet-content}])))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [padding-top (:top (safe-area/get-insets))]
|
||||
(let [padding-top (:top (safe-area/get-insets))
|
||||
wallet-type (reagent/atom :multichain)
|
||||
selected-networks (reagent/atom constants/default-network-names)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
(fn []
|
||||
(let [{:keys [address color emoji watch-only?]
|
||||
:as account} (rf/sub [:wallet/current-viewing-account])
|
||||
preferred-networks (rf/sub [:wallet/preferred-chain-names-for-address address])
|
||||
share-title (str (:name account) " " (i18n/label :t/address))
|
||||
qr-url address
|
||||
qr-url (utils/get-wallet-qr {:wallet-type @wallet-type
|
||||
:selected-networks @selected-networks
|
||||
:address address})
|
||||
qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
|
||||
{:url qr-url
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
@@ -45,6 +74,8 @@
|
||||
:receive (i18n/label :t/receive)
|
||||
nil)]
|
||||
|
||||
(rn/use-mount #(reset! selected-networks preferred-networks))
|
||||
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view
|
||||
{:flex 1
|
||||
@@ -64,10 +95,15 @@
|
||||
[rn/view {:style {:padding-horizontal 20}}
|
||||
[quo/share-qr-code
|
||||
{:type (if watch-only? :watched-address :wallet)
|
||||
:address @wallet-type
|
||||
:qr-image-uri qr-media-server-uri
|
||||
:qr-data qr-url
|
||||
:networks @selected-networks
|
||||
:on-share-press #(share-action qr-url share-title)
|
||||
:profile-picture nil
|
||||
:full-name (:name account)
|
||||
:customization-color color
|
||||
:emoji emoji}]]]]))))
|
||||
:emoji emoji
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-multichain-press on-multichain-press
|
||||
:on-settings-press on-settings-press}]]]]))))
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
[status-im.contexts.shell.constants :as constants]
|
||||
[status-im.contexts.wallet.account.tabs.about.style :as style]
|
||||
[status-im.contexts.wallet.add-account.create-account.utils :as create-account.utils]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn about-options
|
||||
[]
|
||||
(let [{:keys [address] :as account} (rf/sub [:wallet/current-viewing-account])
|
||||
share-title (str (:name account) " " (i18n/label :t/address))]
|
||||
networks (rf/sub [:wallet/network-preference-details])
|
||||
share-title (str (:name account) " " (i18n/label :t/address))
|
||||
multichain-address (utils/get-multichain-address networks address)]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/link
|
||||
:accessibility-label :view-on-eth
|
||||
@@ -40,19 +43,11 @@
|
||||
[:wallet/navigate-to-chain-explorer-from-bottom-sheet
|
||||
config/arbitrum-mainnet-chain-explorer-link
|
||||
address])}
|
||||
{:icon :i/link
|
||||
:accessibility-label :view-on-base
|
||||
:label (i18n/label :t/view-on-base)
|
||||
:right-icon :i/external
|
||||
:on-press #(rf/dispatch
|
||||
[:wallet/navigate-to-chain-explorer-from-bottom-sheet
|
||||
config/base-mainnet-chain-explorer-link
|
||||
address])}
|
||||
{:icon :i/copy
|
||||
:accessibility-label :copy-address
|
||||
:label (i18n/label :t/copy-address)
|
||||
:on-press (fn []
|
||||
(clipboard/set-string address)
|
||||
(clipboard/set-string multichain-address)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:text (i18n/label :t/address-copied)}]))}
|
||||
@@ -67,7 +62,7 @@
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(js/setTimeout
|
||||
#(rf/dispatch [:wallet/share-account
|
||||
{:title share-title :content address}])
|
||||
{:title share-title :content multichain-address}])
|
||||
600))}]]]))
|
||||
|
||||
(defn view
|
||||
@@ -78,6 +73,7 @@
|
||||
keypair-type :type
|
||||
keycards :keycards} (rf/sub [:wallet/current-viewing-account-keypair])
|
||||
keypair-keycard? (boolean (seq keycards))
|
||||
networks (rf/sub [:wallet/network-preference-details])
|
||||
origin-type (case keypair-type
|
||||
:seed
|
||||
:recovery-phrase
|
||||
@@ -97,8 +93,9 @@
|
||||
:size :default
|
||||
:title (if watch-only? (i18n/label :t/watched-address) (i18n/label :t/address))
|
||||
:custom-subtitle (fn [] [quo/address-text
|
||||
{:address address
|
||||
:format :long}])
|
||||
{:networks networks
|
||||
:address address
|
||||
:format :long}])
|
||||
:container-style {:margin-bottom 12}
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content about-options}])}]
|
||||
(when (not watch-only?)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user