Compare commits

..
Author SHA1 Message Date
Ulises M eb129b97f3 Rende11's changes 2023-11-21 12:42:53 -06:00
371 changed files with 5251 additions and 7125 deletions
+1
View File
@@ -95,6 +95,7 @@ react-native.fs/unlink
react-native.fs/file-exists?
status-im.ui.components.colors/white
status-im.ui.components.colors/black
status-im.transport.core-test/messages
status-im.ui.components.core/animated-header
status-im.ui.components.core/safe-area-provider
status-im.ui.components.core/safe-area-consumer
@@ -1,4 +0,0 @@
{:linters
{:unresolved-symbol
{:exclude [(cljs.test/is [match? thrown-match?])
(clojure.test/is [match? thrown-match?])]}}}
-1
View File
@@ -32,7 +32,6 @@
"letsubs" :binding
"with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body
"deftest-sub" :arg1-body
"wait-for" :arg1-body
@@ -27,23 +27,18 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
X509Certificate cert = null;
HandshakeCertificates clientCertificates;
String certPem = "";
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = getCertificatePem();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
if (certPem.isEmpty()) {
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
return null;
}
// Convert PEM certificate string to X509Certificate object
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = StatusPackage.getImageTLSCert();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
// Convert PEM certificate string to X509Certificate object
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
@@ -79,17 +74,4 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
return null;
}
}
private String getCertificatePem() {
try {
String certPem = StatusPackage.getImageTLSCert();
if (certPem == null || certPem.trim().isEmpty()) {
Log.e(TAG, "Certificate PEM string is null or empty");
return "";
}
return certPem;
} catch (Exception e) {
Log.e(TAG, "Could not getImageTLSCert", e);
return "";
}
}
}
+1
View File
@@ -77,6 +77,7 @@ pipeline {
}
}
stage('Upload') {
when { expression { !utils.isReleaseBuild() } }
steps { script {
env.DIAWI_URL = ios.uploadToDiawi()
env.PKG_URL = env.DIAWI_URL
+1 -21
View File
@@ -641,26 +641,6 @@ keywords and concatenating them into a single string.
```
### Tests
#### Prefer `match?` over `=` when comparing data structures
Prefer the `match?` directive over `=` when comparing data structures, otherwise
when the check fails the output can be too difficult to read. `match?` is
defined by library https://github.com/nubank/matcher-combinators.
```clojure
;; bad
(deftest some-test
(let [expected {...}
actual {...}]
(is (= expected actual))))
;; good
(deftest some-test
(let [expected {...}
actual {...}]
(is (match? expected actual))))
```
#### Subscription tests
Test [layer-3 subscriptions](https://day8.github.io/re-frame/subscriptions/) by
@@ -736,7 +716,7 @@ src
- `src/js`: Raw Javascript files, e.g. React Native Reanimated worklets.
- `src/mocks`: Plumbing configuration to be able to run tests.
- `src/quo/`: The component library for Status Mobile. [Read more...](../src/quo/README.md)
- `src/quo/`: The component library for Status Mobile.
- `src/react_native/`: Contains only low-level constructs to help React Native
work in tandem with Clojure(Script).
- `src/status_im2/`: Directory where we try to be as strict as possible about
-18
View File
@@ -602,15 +602,6 @@
}
},
{
"path": "nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "4c94bd510f0c18a20191e46dd6becedebc640bbd",
"sha256": "0wpla2hx0s4mda58ndyd8938zmnz1gyhgfr6pzfphy27xfbvsssl"
}
},
{
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
"host": "https://repo1.maven.org/maven2",
@@ -755,15 +746,6 @@
}
},
{
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "aa95d25ea98bfe1152ea540f6e58a303c8cacc86",
"sha256": "0qvdsr5ryjmrpz622ivpyq5aayn42y4bk531vbasyj2yj7gcg35h"
}
},
{
"path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218",
"host": "https://repo1.maven.org/maven2",
-2
View File
@@ -65,7 +65,6 @@ net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar
nrepl/bencode/1.1.0/bencode-1.1.0.jar
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
org/babashka/sci/0.7.38/sci-0.7.38.jar
@@ -82,7 +81,6 @@ org/clojure/data.json/2.4.0/data.json-2.4.0.jar
org/clojure/data.priority-map/1.1.0/data.priority-map-1.1.0.jar
org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar
org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541.jar
org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0.jar
org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
org/clojure/test.check/1.1.1/test.check-1.1.1.jar
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.jar
-9
View File
@@ -14,7 +14,6 @@ stdenv.mkDerivation {
"patchJavaPhase"
"patchReactNativePhase"
"patchPodPhase"
"patchGlogPhase"
"installPhase"
];
@@ -99,14 +98,6 @@ stdenv.mkDerivation {
'[RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];'
'';
# Fix pod issue after upgrading to MacOS Sonoma and Xcode 15
# https://github.com/status-im/status-mobile/issues/17682
patchGlogPhase = ''
substituteInPlace ./node_modules/react-native/scripts/ios-configure-glog.sh \
--replace 'export CC="' '#export CC="' \
--replace 'export CXX="' '#export CXX="'
'';
# The ELF types are incompatible with the host platform, so let's not even try
# TODO: Use Android NDK to strip binaries manually
dontPatchELF = true;
-1
View File
@@ -73,7 +73,6 @@ in {
allowHigher = true;
};
go = super.go_1_19;
clang = super.clang_15;
buildGoPackage = super.buildGo119Package;
buildGoModule = super.buildGo119Module;
gomobile = (super.gomobile.overrideAttrs (old: {
+1 -1
View File
@@ -94,7 +94,7 @@
"process": "0.11.10",
"react-test-renderer": "18.0.0",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
"shadow-cljs": "2.26.2"
"shadow-cljs": "2.25.0"
},
"binary": {
"module_name": "status_nodejs_addon",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

+2 -4
View File
@@ -12,12 +12,10 @@
[metosin/malli "0.13.0"]
;; Dev dependencies
[refactor-nrepl "3.9.1"]
[cider/cider-nrepl "0.31.0"]
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
[cider/piggieback "0.4.1"]
[org.slf4j/slf4j-nop "2.0.9"]
[re-frisk-remote "1.6.0"]
[nubank/matcher-combinators "3.8.8"]
;; Use the same version specified in the Nix dependency.
[clj-kondo/clj-kondo "2023.09.07"]
+12 -1
View File
@@ -49,7 +49,6 @@
:Text {}
:StatusBar {}
:ScrollView {}
:SafeAreaView {}
:KeyboardAvoidingView {}
:TextInput {}
:Image {}
@@ -368,6 +367,17 @@
:LineChart #js {}
:LineChartBicolor #js {}})
(def wallet-connect-client
#js
{:default #js {}
:CLIENT_EVENTS #js
{:session #js
{:request nil
:created nil
:deleted nil
:proposal nil
:updated nil}}})
(def worklet-factory
#js {:applyAnimationsToStyle (fn [])})
@@ -436,6 +446,7 @@
"../src/js/worklets/parallax.js" #js {}
"../src/js/worklets/identifiers_highlighting.js" #js {}
"./fleets.js" default-fleets
"@walletconnect/client" wallet-connect-client
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
"../translations/de.json" (js/JSON.parse (slurp "./translations/de.json"))
"../translations/en.json" (js/JSON.parse (slurp "./translations/en.json"))
-11
View File
@@ -116,17 +116,6 @@ rendered. We use [React Native Testing Library](https://callstack.github.io/reac
There are dozens of examples in the repository, so use them as a reference. A
good and complete example is [quo.components.avatars.user-avatar.component-spec](/src/quo/components/avatars/user_avatar/component_spec.cljs)
### No-props test
When writing tests for the component that has props, please add one test that covers situation when props aren't passed. Because even if component not showing anything meaningful without props, it shouldn't crash.
```clojure
(h/describe "Transaction Progress"
(h/test "component renders without props"
(h/render [quo/transaction-progress {}])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
```
## Do not couple the library with re-frame
Don't use re-frame inside this library (e.g. dispatch & subscribe). If a
@@ -30,6 +30,6 @@
{:accessibility-label :account-emoji
:adjusts-font-size-to-fit true
:style {:font-size emoji-size}}
(when emoji (string/trim emoji))]]))
(string/trim emoji)]]))
(def view (quo.theme/with-theme view-internal))
@@ -67,7 +67,7 @@
[rn/text
{:style (style/emoji-size size)
:accessibility-label :emoji}
(when emoji (string/trim emoji))])
(string/trim emoji)])
[lock locked? size theme]])
(def view (quo.theme/with-theme view-internal))
@@ -2,30 +2,26 @@
(:require [quo.foundations.colors :as colors]))
(defn- circle-color
[customization-color neutral? theme]
(if neutral?
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
(colors/custom-color customization-color 50 20)))
[customization-color]
(colors/custom-color customization-color 50 20))
(defn- text-color
[customization-color neutral? theme]
(if neutral?
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
(colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)))
[customization-color theme]
(colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))
(defn container
[circle-size customization-color neutral? theme]
[circle-size customization-color]
{:width circle-size
:height circle-size
:border-radius circle-size
:text-align :center
:justify-content :center
:align-items :center
:background-color (circle-color customization-color neutral? theme)})
:background-color (circle-color customization-color)})
(defn text
[customization-color neutral? theme]
{:color (text-color customization-color neutral? theme)})
[customization-color theme]
{:color (text-color customization-color theme)})
@@ -1,6 +1,5 @@
(ns quo.components.avatars.wallet-user-avatar.view
(:require [clojure.string :as string]
[quo.components.avatars.wallet-user-avatar.style :as style]
(:require [quo.components.avatars.wallet-user-avatar.style :as style]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
[react-native.core :as rn]
@@ -41,21 +40,18 @@
:customization-color - keyword (default: nil) - color of the avatar
:size - keyword (default: last element of properties object) - size of the
avatar
:monospace? - boolean (default: false) - use monospace font
:lowercase? - boolean (default: false) - lowercase text
:neutral? - boolean (default: false) - use neutral colors variant"
[{:keys [full-name customization-color size theme monospace? lowercase? neutral?]
:monospace? - boolean (default: false) - use monospace font"
[{:keys [full-name customization-color size theme monospace?]
:or {size biggest-possible}}]
(let [circle-size (:size (size properties))
small? (check-if-size-small size)
initials (utils.string/get-initials full-name (if small? 1 2))]
small? (check-if-size-small size)]
[rn/view
{:style (style/container circle-size customization-color neutral? theme)}
{:style (style/container circle-size customization-color)}
[text/text
{:accessibility-label :wallet-user-avatar
:size (:font-size (size properties))
:weight (if monospace? :monospace (:font-weight (size properties)))
:style (style/text customization-color neutral? theme)}
(if (and initials lowercase?) (string/lower-case initials) initials)]]))
:style (style/text customization-color theme)}
(utils.string/get-initials full-name (if small? 1 2))]]))
(def wallet-user-avatar (quo.theme/with-theme view-internal))
+29 -25
View File
@@ -10,36 +10,40 @@
(defn token-requirement-list-row
[tokens padding?]
[rn/view {:style (style/token-row padding?)}
(map-indexed (fn [token-index token]
(let [{:keys [amount sufficient? purchasable?]} token]
^{:key token-index}
[rn/view {:style style/token-tag-spacing}
[token-tag/view
{:token-symbol (:symbol token)
:token-value amount
:size :size-24
:options (cond
sufficient? :hold
purchasable? :add)}]]))
tokens)])
[rn/view
{:style (style/token-row padding?)}
(doall
(map-indexed (fn [token-index token]
(let [{:keys [img-src amount sufficient? purchasable?]} token]
^{:key token-index}
[rn/view {:style style/token-tag-spacing}
[token-tag/view
{:token-symbol (:symbol token)
:token-value amount
:size :size-24
:options (cond
sufficient? :hold
purchasable? :add)
:token-img-src img-src}]]))
tokens))])
(defn- internal-view
[{:keys [tokens padding? theme]}]
[:<>
(if (> (count tokens) 1)
(map-indexed
(fn [token-requirement-index tokens]
^{:key token-requirement-index}
[rn/view {:margin-bottom 12}
(when-not (= token-requirement-index 0)
[rn/view {:style (style/token-row-or-border theme)}])
(when-not (= token-requirement-index 0)
[text/text
{:style (style/token-row-or-text padding? theme)
:size :label} (string/lower-case (i18n/label :t/or))])
[token-requirement-list-row tokens padding?]])
tokens)
(doall
(map-indexed
(fn [token-requirement-index tokens]
^{:key token-requirement-index}
[rn/view {:margin-bottom 12}
(when-not (= token-requirement-index 0)
[rn/view {:style (style/token-row-or-border theme)}])
(when-not (= token-requirement-index 0)
[text/text
{:style (style/token-row-or-text padding? theme)
:size :label} (string/lower-case (i18n/label :t/or))])
[token-requirement-list-row tokens padding?]])
tokens))
[token-requirement-list-row (first tokens) padding?])])
(def token-requirement-list (quo.theme/with-theme internal-view))
@@ -1,56 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.component-spec
(:require
[quo.components.dropdowns.dropdown-input.view :as dropdown-input]
[test-helpers.component :as h]))
(h/describe "Dropdown Input"
(h/test "default render"
(let [header-label "Label"
label "Dropdown"]
(h/render [dropdown-input/view
{:label? true
:header-label
header-label} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-text header-label))
(h/is-truthy (h/get-by-text label))))
(h/test "render with icon"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:icon? true
:icon-name
:i/wallet
:label? true}
label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-label-text :left-icon))
(h/is-truthy (h/get-by-text label))))
(h/test "render in active state"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:state :active
:label?
true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-label-text :right-icon "Expecting active state icon"))))
(h/test "render in disabled state"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:state :disabled
:label? true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-disabled (h/get-by-text label "Dropdown should be disabled in disabled state"))))
(h/test "on-press"
(let [event (h/mock-fn)
label "Dropdown"]
(h/render [dropdown-input/view
{:on-press event
:label?
true} label])
(h/fire-event :press (h/get-by-text label))
(h/was-called event))))
@@ -1,49 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.properties
(:require
[quo.foundations.colors :as colors]))
(def icon-size 20)
(defn- grey-blur
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-80-opa-20
colors/white-opa-40
theme)
(colors/theme-colors colors/neutral-80-opa-10
colors/white-opa-10
theme))})
(defn- outline
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
(defn- grey
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-20
colors/neutral-60
theme))})
(defn get-colors
[{:keys [theme state blur?]}]
(let [active? (= state :active)]
(cond
blur? (grey-blur theme active?)
(= theme :dark) (outline theme active?)
(= theme :light) (grey theme active?))))
@@ -1,62 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.style
(:require
[quo.foundations.colors :as colors]))
(def gap 8)
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(def left-icon
{:margin-right gap})
(defn right-icon
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
:margin-right gap})
(defn header-label
[theme blur?]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40
colors/white-opa-70
theme)
(colors/theme-colors colors/neutral-50
colors/neutral-40
theme))
:margin-bottom gap})
(def root-container
{:width "100%"
:height 40})
(defn container
[{:keys [background-color border-color]}
{:keys [icon? state]}]
(cond-> {:align-items :center
:justify-content :space-between
:flex-direction :row
:padding-vertical 9
:padding-left 16
:padding-right 12
:overflow :hidden
:background-color background-color
:border-radius 12}
icon?
(assoc :padding-left 12)
border-color
(assoc :border-color border-color
:border-width 1)
(= state :disabled)
(assoc :opacity 0.3)))
(def right-half-container
{:flex-direction :row
:align-items :center})
@@ -1,68 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.view
(:require
[quo.components.dropdowns.dropdown-input.properties :as properties]
[quo.components.dropdowns.dropdown-input.style :as style]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.theme :as theme]
[react-native.core :as rn]))
(defn- view-internal
[{:keys [state theme on-press icon?
label? blur?
accessibility-label header-label]
:or {state :default
icon? true
label? true
blur? false
header-label "Label"}
:as props}
label]
(let [{:keys [left-icon-color right-icon-color right-icon-color-2]
:as colors} (properties/get-colors props)
right-icon (if (= state :active) :i/pullup :i/dropdown)]
[rn/view
{:style style/root-container}
(when label?
[text/text
{:size :paragraph-2
:weight :medium
:align :left
:style (style/header-label theme blur?)} header-label])
[rn/pressable
{:accessibility-label (or accessibility-label :dropdown)
:disabled (= state :disabled)
:on-press on-press
:style (style/container colors props)}
[rn/view
{:style style/right-half-container}
(when icon?
[icon/icon
:i/placeholder
{:accessibility-label :left-icon
:color left-icon-color
:size properties/icon-size
:container-style style/left-icon}])
[text/text
{:size :paragraph-1
:weight :regular
:number-of-lines 1
:style (style/right-icon theme)}
label]]
[icon/icon
right-icon
{:size properties/icon-size
:accessibility-label :right-icon
:color right-icon-color
:color-2 right-icon-color-2}]]]))
(def view
"Props:
- state: :default (default) | :active | :disabled
- label: string
- header-label: string
- icon?: boolean
- label?: boolean
- blur?: boolean
- on-press: function"
(theme/with-theme view-internal))
+5 -6
View File
@@ -9,10 +9,9 @@
(defn- valid-color?
[color]
(and color
(or (keyword? color)
(and (string? color)
(not (string/blank? color))))))
(or (keyword? color)
(and (string? color)
(not (string/blank? color)))))
(defn- image-icon-style
[{:keys [color no-color size container-style theme]}]
@@ -38,8 +37,8 @@
(cond-> {:size size
:accessibility-label accessibility-label
:style container-style}
(valid-color? color) (assoc :color color)
(valid-color? color-2) (assoc :color-2 color-2))]
(and color (valid-color? color)) (assoc :color color)
(and color-2 (valid-color? color-2)) (assoc :color-2 color-2))]
[rn/image
{:style (image-icon-style (assoc props :size size))
:accessibility-label accessibility-label
+6 -54
View File
@@ -118,61 +118,13 @@
"M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z"
:fill color-2}]])
(defn- contact-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 10
:cy 10
:r 7.5
:fill color}]
[svg/path
{:d
"M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z"
:fill color-2}]])
(defn- verified-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z"
:fill color}]
[svg/path
{:d "M7.25 10.75L9.25 12.25L12.75 7.75"
:stroke color-2
:stroke-width "1.2"}]])
(defn- untrustworthy-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z"
:fill color}]
[svg/path
{:d
"M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z"
:fill color-2}]])
(def ^:private icons
{:i/clear-20 clear-20
:i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12
:i/contact-12 contact-12
:i/contact-20 contact-20
:i/verified-20 verified-20
:i/untrustworthy-20 untrustworthy-20})
{:i/clear-20 clear-20
:i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12
:i/contact-12 contact-12})
(defn- append-to-keyword
[k & xs]
@@ -11,7 +11,6 @@
(case k
:success (colors/resolve-color :success theme)
:error (colors/resolve-color :danger theme)
:warning (colors/resolve-color :warning theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn view-internal
@@ -61,10 +61,14 @@
value (reagent/atom "")
focused? (atom false)]
(fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan on-detect-ens
on-detect-address address-regex valid-ens-or-address?]}]
on-detect-address
ens-regex address-regex
valid-ens-or-address?]}]
(let [on-change (fn [text]
(when (not= @value text)
(let [address? (when address-regex
(let [ens? (when ens-regex
(boolean (re-matches ens-regex text)))
address? (when address-regex
(boolean (re-matches address-regex text)))]
(if (> (count text) 0)
(reset! status :typing)
@@ -72,9 +76,9 @@
(reset! value text)
(when on-change-text
(on-change-text text))
(when (and on-detect-ens (> (count text) 0))
(when (and ens? on-detect-ens)
(reset! status :loading)
(on-detect-ens text #(reset! status :typing)))
(on-detect-ens text))
(when (and address? on-detect-address)
(reset! status :loading)
(on-detect-address text)))))
@@ -1,17 +0,0 @@
(ns quo.components.ios.drawer-bar.style
(:require
[quo.foundations.colors :as colors]
[quo.theme :as theme]))
(def handle-container
{:padding-vertical 8
:height 20
:align-items :center})
(defn handle
[{:keys [theme]}]
{:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:opacity (theme/theme-value 0.05 0.1 theme)
:border-radius 100})
@@ -1,12 +0,0 @@
(ns quo.components.ios.drawer-bar.view
(:require
[quo.components.ios.drawer-bar.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
[props]
[rn/view {:style style/handle-container}
[rn/view {:style (style/handle props)}]])
(def view (quo.theme/with-theme view-internal))
@@ -13,7 +13,7 @@
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-in changes state to :pressed with blur? enabled"
(h/render [account/view {:blur? true}])
@@ -21,26 +21,31 @@
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-5})))
(h/test "render with state :active"
(h/render [account/view {:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 10)}))
(h/test "on-press-out changes state to :active"
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "render with state :active and blur? enabled"
(h/render [account/view
{:blur? true
:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10}))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [account/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10})))
(h/test "render with state :selected"
(h/render [account/view {:state :selected}])
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "on-press-out changes state to :selected"
(h/render [account/view {:selectable? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/is-truthy (h/query-by-label-text :check-icon))))
(h/test "calls on-press"
(h/test "on-press-out calls on-press"
(let [on-press (h/mock-fn)]
(h/render [account/view {:on-press on-press}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "renders token props if type :tag"
@@ -3,12 +3,12 @@
[quo.foundations.colors :as colors]))
(defn- background-color
[{:keys [state pressed? blur? customization-color]}]
(cond (or pressed? (= state :selected))
(if blur? colors/white-opa-5 (colors/resolve-color customization-color :light 5))
[{:keys [state blur? customization-color]}]
(cond (or (= state :pressed) (= state :selected))
(if blur? colors/white-opa-5 (colors/custom-color customization-color 50 5))
(= state :active)
(if blur? colors/white-opa-10 (colors/resolve-color customization-color :light 10))
(and pressed? blur?) colors/white-opa-10
(if blur? colors/white-opa-10 (colors/custom-color customization-color 50 10))
(and (= state :pressed) blur?) colors/white-opa-10
:else :transparent))
(defn container
+51 -31
View File
@@ -94,42 +94,62 @@
[icon/icon :i/check
{:color (if blur?
colors/white
(colors/resolve-color customization-color theme))}]])
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))}]])
(defn- internal-view
[_]
(let [pressed? (reagent/atom false)
on-press-in #(reset! pressed? true)
on-press-out #(reset! pressed? false)]
(fn [{:keys [type state blur? customization-color on-press]
(defn- f-internal-view
[]
(let [state (reagent/atom :default)
active-or-selected? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [type selectable? blur? customization-color on-press]
:or {customization-color :blue
type :default
state :default
blur? false}
:as props}]
[rn/pressable
{:style (style/container
{:state state
:blur? blur?
:customization-color customization-color
:pressed? @pressed?})
:on-press-in on-press-in
:on-press on-press
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(cond
(#{:balance-neutral :balance-negative :balance-positive} type)
[balance-view props]
(let [on-press-out (fn []
(let [new-state (if @active-or-selected?
:default
(if (and (= type :default) selectable?)
:selected
:active))]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active-or-selected? (or (= new-state :active)
(= new-state :selected)))
(reset! state new-state)
(when on-press
(on-press))))]
(rn/use-effect
#(cond (and selectable? (= type :default) (= @state :active)) (reset! state :selected)
(and (not selectable?) (= type :default) (= @state :selected)) (reset! state :active))
[selectable?])
[rn/pressable
{:style (style/container
{:state @state :blur? blur? :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(when (or (= type :balance-neutral)
(= type :balance-negative)
(= type :balance-positive))
[balance-view props])
(when (= type :tag)
[token-tag props])
(when (= type :action)
[options-button props])
(when (and (= type :default)
(= @state :selected))
[check-icon props])]]))))
(= type :tag)
[token-tag props]
(= type :action)
[options-button props]
(and (= type :default) (= state :selected))
[check-icon props])]])))
(defn- internal-view
[props]
[:f> f-internal-view props])
(def view (quo.theme/with-theme internal-view))
@@ -13,11 +13,11 @@
[{:keys [theme address networks blur?]}]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :size-32
:full-name "0 x"
{:size :medium
:f-name "0"
:l-name "x"
:monospace? true
:lowercase? true
:neutral? true}]
:uppercase? false}]
[rn/view {:style style/account-container}
[text/text {:size :paragraph-1}
(map (fn [network]
@@ -25,8 +25,8 @@
[text/text
{:size :paragraph-1
:weight :semi-bold
:style {:color (colors/resolve-color (:network-name network) theme)}}
(str (:short-name network) ":")])
:style {:color (colors/resolve-color network theme)}}
(str (subs (name network) 0 3) ":")])
networks)
[text/text
{:size :paragraph-1
@@ -4,7 +4,6 @@
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.list-items.preview-list.properties :as properties]
[quo.components.tags.number-tag.view :as number-tag]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
@@ -32,12 +31,7 @@
:height size
:border-radius border-radius}}]
:tokens [token/view
{:token item
:size size
:style {:border-radius border-radius}}]
(:network :dapps) [fast-image/fast-image
(:tokens :network :dapps) [fast-image/fast-image
{:source (or (:source item) item)
:style {:width size
:height size
@@ -1,5 +1,6 @@
(ns quo.components.list-items.saved-address.view
(:require
[clojure.string :as string]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.icon :as icon]
[quo.components.list-items.saved-address.style :as style]
@@ -12,23 +13,27 @@
(defn- left-container
[{:keys [blur? theme name ens address customization-color]}]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :size-32
:full-name name
:customization-color customization-color}]
[rn/view {:style style/account-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style style/name-text}
name]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
(or ens (address/get-shortened-key address))]]]])
(let [names (remove string/blank? (string/split name " "))
first-name (if (> (count names) 0) (first names) "")
last-name (if (> (count names) 1) (last names) "")]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :medium
:f-name first-name
:l-name last-name
:customization-color customization-color}]
[rn/view {:style style/account-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style style/name-text}
name]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
(or ens (address/get-shortened-key address))]]]]))
(defn- internal-view
[]
@@ -5,7 +5,7 @@
[test-helpers.component :as h]))
(def props
{:token :snt
{:token (resources/get-token :snt)
:state :default
:label "Status"
:networks [(resources/get-network :ethereum)]
@@ -26,23 +26,21 @@
(def info
{:flex-direction :row
:align-items :center
:width "70%"})
:align-items :center})
(def token-info
{:height 40
:flex 1})
{:height 40})
(def token-image
{:border-width 1
:border-radius 16
:border-color colors/neutral-80-opa-5
:margin-right 8
:background-color colors/neutral-80-opa-5})
{:width 32
:height 32
:border-width 1
:border-radius 16
:border-color colors/neutral-80-opa-5
:margin-right 8})
(def values-container
{:align-items :flex-end
:max-width "30%"})
{:align-items :flex-end})
(defn fiat-value
[theme]
@@ -4,7 +4,6 @@
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.list-items.token-network.style :as style]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
@@ -12,20 +11,15 @@
(defn- info
[{:keys [token label networks]}]
[rn/view {:style style/info}
(when token
[token/view
{:style style/token-image
:size :size-32
:token token}])
[rn/image
{:source (or (:source token) token)
:style style/token-image}]
[rn/view {:style style/token-info}
[text/text
{:weight :semi-bold
:number-of-lines 1}
(if-not (empty? label) label "-")]
[text/text {:weight :semi-bold} label]
[preview-list/view
{:type :network
:size :size-14
:number (count networks)}
:number 3}
networks]]])
(defn- values
@@ -36,14 +30,12 @@
:accessibility-label :check-icon}]
[rn/view {:style style/values-container}
[text/text
{:weight :medium
:size :paragraph-2
:number-of-lines 1}
{:weight :medium
:size :paragraph-2}
token-value]
[text/text
{:style (style/fiat-value theme)
:size :paragraph-2
:number-of-lines 1}
{:style (style/fiat-value theme)
:size :paragraph-2}
fiat-value]]))
(defn- view-internal
@@ -1,10 +1,12 @@
(ns quo.components.list-items.token-value.view
(:require
[clojure.string :as string]
[quo.components.icon :as icon]
[quo.components.list-items.token-value.style :as style]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
@@ -12,8 +14,7 @@
(defn- internal-view
[]
(let [state (reagent/atom :default)]
(fn [{:keys [theme customization-color status token metrics? values on-press
on-long-press]}]
(fn [{:keys [theme customization-color status token metrics? values on-press on-long-press]}]
(let [bg-opacity (case @state
:active 10
:pressed 5
@@ -33,13 +34,16 @@
{:style {:flex-direction :row
:align-items :center
:flex 1}}
[token/view {:token (:symbol token) :size :size-32}]
[rn/image
{:source (resources/get-token token)
:style {:width 32
:height 32}}]
[rn/view {:style {:margin-left 8}}
[text/text {:weight :semi-bold} (:name token)]
[text/text {:weight :semi-bold} (common/token-label token)]
[text/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(str crypto-value " " (:symbol token))]]]
(str crypto-value " " (if token (string/upper-case (clj->js token)) ""))]]]
[rn/view
{:style {:align-items :flex-end
:justify-content :space-between}}
@@ -36,7 +36,7 @@
:blur? false
:type :digit} 1])
(h/is-truthy (h/query-by-label-text :text-label))
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key))
(h/was-called on-press)))
(h/test "Is not pressable when disabled is true"
@@ -47,5 +47,5 @@
:blur? false
:type :digit} 1])
(h/is-truthy (h/query-by-label-text :text-label))
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key))
(h/was-not-called on-press))))
@@ -1,7 +1,7 @@
(ns quo.components.numbered-keyboard.numbered-keyboard.style)
(def container
{:display :flex
{:flex 1
:padding-top 8
:padding-horizontal 48})
@@ -17,12 +17,10 @@
(defn- view-internal
[]
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete
container-style]
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete]
:or {left-action :none}}]
[rn/view
{:style (merge style/container
container-style)}
{:style style/container}
(for [row-index (range 1 4)]
^{:key row-index}
[rn/view {:style style/row-container}
@@ -62,7 +60,7 @@
:theme theme}]
(if delete-key?
[keyboard-item
{:item :i/backspace
{:item :i/delete
:type :key
:disabled? disabled?
:on-press on-delete
-22
View File
@@ -1,22 +0,0 @@
(ns quo.components.overlay.style
(:require [quo.foundations.colors :as colors]))
(defn overlay-background
[type]
(let [background-color (case type
:shell colors/neutral-80-opa-80-blur
:drawer colors/neutral-100-opa-70-blur
nil)]
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0
:background-color background-color}))
(def container
{:flex 1})
(def blur-container
{:flex 1
:background-color :transparent})
-20
View File
@@ -1,20 +0,0 @@
(ns quo.components.overlay.view
(:require
[quo.components.overlay.style :as style]
[react-native.blur :as blur]
[react-native.core :as rn]))
(defn view
[{:keys [type]} & children]
[rn/view {:style (style/overlay-background type)}
(if (= type :shell)
[blur/view
{:blur-amount 20
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent
:style style/container}
[rn/view {:style style/blur-container}
children]]
[rn/view {:style style/container}
children])])
@@ -1,7 +1,6 @@
(ns quo.components.settings.data-item.component-spec
(:require
[quo.core :as quo]
[quo.foundations.resources :as quo.resources]
[test-helpers.component :as h]))
(h/describe
@@ -10,14 +9,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -27,14 +26,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? false
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -45,14 +44,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :small
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -63,14 +62,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -81,31 +80,31 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/get-by-text "Subtitle")))
(h/is-truthy (h/get-by-text "Description")))
(h/test "right icon is not visible when icon-right? is false"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -115,6 +114,7 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -122,17 +122,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :icon-right)))
(h/test "icon is visible when subtitle type is icon"
(h/test "description icon is visible when description is icon"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :icon
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -140,17 +140,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :icon
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :subtitle-type-icon)))
(h/is-truthy (h/query-by-label-text :description-icon)))
(h/test "image is visible when subtitle type is network"
(h/test "description image is visible when description is network"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :network
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -158,18 +158,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :network
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow
:network-image (quo.resources/get-network :ethereum)}])
(h/is-truthy (h/query-by-label-text :subtitle-type-image)))
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :description-image)))
(h/test "emoji is visible when subtitle type is account"
(h/test "description emoji is visible when description is account"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -177,8 +176,7 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -37,8 +37,8 @@
:align-items :center})
(defn subtitle-icon-container
[subtitle-type]
{:margin-right (when (not= :default subtitle-type) 4)
[description]
{:margin-right (when (not= :default description) 4)
:justify-content :center})
(defn title
+13 -14
View File
@@ -7,6 +7,7 @@
[quo.components.markdown.text :as text]
[quo.components.settings.data-item.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.resources :as quo.resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]))
@@ -16,15 +17,13 @@
[rn/view {:style (style/loading-container size blur? theme)}])
(defn- left-subtitle
[{:keys [theme size subtitle-type icon icon-color blur? subtitle customization-color emoji
network-image]
:or {subtitle-type :default}}]
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji]}]
[rn/view {:style style/subtitle-container}
(when (not= :small size)
[rn/view {:style (style/subtitle-icon-container subtitle-type)}
(case subtitle-type
[rn/view {:style (style/subtitle-icon-container description)}
(case description
:icon [icons/icon icon
{:accessibility-label :subtitle-type-icon
{:accessibility-label :description-icon
:size 16
:color icon-color}]
:account [account-avatar/view
@@ -33,8 +32,8 @@
:emoji emoji
:type :default}]
:network [rn/image
{:accessibility-label :subtitle-type-image
:source network-image
{:accessibility-label :description-image
:source (quo.resources/tokens :eth)
:style style/image}]
nil)])
[text/text
@@ -59,9 +58,10 @@
(i18n/label :t/days)])])
(defn- left-side
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
[{:keys [theme title status size blur? custom-subtitle icon subtitle subtitle-type label icon-color
customization-color network-image emoji]
"The description can either be given as a string `description` or a component `custom-subtitle`"
[{:keys [theme title status size blur? description custom-subtitle icon subtitle label icon-color
customization-color
emoji]
:as props}]
[rn/view {:style style/left-side}
[left-title
@@ -79,14 +79,13 @@
[left-subtitle
{:theme theme
:size size
:subtitle-type subtitle-type
:description description
:icon icon
:icon-color icon-color
:blur? blur?
:subtitle subtitle
:customization-color customization-color
:emoji emoji
:network-image network-image}]))])
:emoji emoji}]))])
(defn- right-side
[{:keys [label icon-right? right-icon icon-color communities-list]}]
+27 -18
View File
@@ -17,21 +17,30 @@
{:width size})))
(defn base-tag
[{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label type labelled?]
:or {size 32}}
children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]])
[_]
(fn
[{:keys [id
size
disabled?
border-color
border-width
background-color
on-press
accessibility-label
type
labelled?]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]]))
@@ -59,10 +59,6 @@
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
(defn token-logo
[size]
{:border-radius (if (= size 24) 10 14)})
(defn circle-logo
[size]
(if (= size 24)
@@ -7,7 +7,6 @@
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
@@ -74,7 +73,7 @@
(defn- view-internal
[{:keys [theme type size state blur? customization-color profile-picture full-name users
group-name amount token network-logo network-name networks
group-name token-logo amount token-name network-logo network-name networks
account-name emoji collectible collectible-name collectible-number duration container-style]
:or {customization-color :blue
type :default
@@ -124,11 +123,8 @@
[communities-tag (assoc props :channel? (= type :channel))]
:token
[tag-skeleton {:theme theme :size size :text (str amount " " token)}
[token/view
{:style (style/token-logo size)
:token token
:size (if (= size 24) :size-20 :size-28)}]]
[tag-skeleton {:theme theme :size size :text (str amount " " token-name)}
[rn/image {:style (style/circle-logo size) :source token-logo}]]
:network
[tag-skeleton {:theme theme :size size :text network-name}
@@ -186,8 +182,9 @@
- `:token`
- size
- token-logo (valid rn/image :source value)
- amount
- token
- token-name
- `:network`
- size
@@ -47,7 +47,7 @@
(h/test "Token view render"
(h/render [summary-tag/view
{:type :token
:label "1,000 SNT"
:token :eth}])
{:type :token
:label "1,000 SNT"
:image-source "path/to/token-image.png"}])
(h/is-truthy (h/get-by-text "1,000 SNT"))))
@@ -24,4 +24,6 @@
:border-radius 10})
(def token-image
{:border-radius 12})
{:width 24
:height 24
:border-radius 12})
@@ -5,13 +5,12 @@
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.markdown.text :as text]
[quo.components.tags.summary-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- left-view
[{:keys [label type customization-color emoji image-source token]}]
[{:keys [label type customization-color emoji image-source]}]
(case type
:account
[account-avatar/view
@@ -39,10 +38,9 @@
:profile-picture image-source
:customization-color customization-color}]
:token
[token/view
{:token token
:size :size-24
:style style/token-image}]
[rn/image
{:source image-source
:style style/token-image}]
nil))
(defn- view-internal
@@ -52,7 +50,7 @@
should vary based on a custom color.
- :type - :token / :user / :collectible / :saved-address / :network / :account
- :emoji - string - emoji used for displaying account avatar
- :image-source - resource - image to display on :network, :collectible and :user
- :image-source - resource - image to display on :network, :collectible :user and :token
- :theme - :light / :dark"
[{:keys [label customization-color type theme]
:as props
@@ -64,7 +62,6 @@
[text/text
{:style (style/label type theme)
:weight :semi-bold
:size :heading-1}
label]])
:size :heading-1} label]])
(def view (quo.theme/with-theme view-internal))
+39 -30
View File
@@ -4,7 +4,7 @@
[quo.components.markdown.text :as text]
[quo.components.tags.base-tag :as base-tag]
[quo.foundations.colors :as colors]
[quo.theme]
[quo.theme :as theme]
[react-native.core :as rn]))
(def themes
@@ -66,45 +66,54 @@
text-color)
label])])
(defn tag-internal
(defn tag
"opts
{:type :icon/:emoji/:label
:label string
:size 32/24
:on-press fn
:blurred? true/false
:blurred? true/false
:resource icon/image
:labelled? true/false
:disabled? true/false}
opts
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[{:keys [id on-press disabled? size active accessibility-label label resource type
labelled? blurred? icon-color theme]
:or {size 32}}]
(let [state (cond
disabled? :disabled
active :active
:else :default)
{:keys [border-color
blurred-border-color
text-color]} (get-in themes [theme state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]]))
(def tag (quo.theme/with-theme tag-internal))
[_ _]
(fn
[{:keys [id
on-press
disabled?
size
active
accessibility-label
label
resource
type
labelled?
blurred?
icon-color
override-theme]
:or {size 32}}]
(let [state (cond disabled? :disabled
active :active
:else :default)
{:keys [border-color blurred-border-color text-color]}
(get-in themes [(or override-theme (theme/get-theme)) state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]])))
+7 -3
View File
@@ -34,10 +34,14 @@
(defn token-img
[size]
(case size
:size-24 {:margin-right 6
(condp = size
:size-24 {:width 20
:height 20
:margin-right 6
:border-radius 10}
:size-32 {:margin-right 8
:size-32 {:width 28
:height 28
:margin-right 8
:border-radius 14}))
(defn label
+12 -16
View File
@@ -4,7 +4,6 @@
[quo.components.icon :as icons]
[quo.components.markdown.text :as text]
[quo.components.tags.token-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
@@ -15,12 +14,13 @@
- :options - false / :add / :hold (default false)
- :size - :size-24 / :size-32 (default :size-24)
- :blur? - boolean (default false)
- :theme - :light / :dark
- :theme - :light / :dark
- :token-img-src - token image source
- :token-value - string - token value
- :token-symbol - string"
[]
(let [container-width (reagent/atom 0)]
(fn [{:keys [options size blur? theme token-value token-symbol]
(fn [{:keys [options size blur? theme token-img-src token-value token-symbol]
:or {size :size-24}}]
[rn/view
{:on-layout #(reset! container-width
@@ -28,25 +28,21 @@
[hole-view/hole-view
{:holes (if options
[{:x (- @container-width
(case size
(condp = size
:size-24 10
:size-32 12
nil))
:y (case size
:size-32 12))
:y (condp = size
:size-24 -6
:size-32 -4
nil)
:size-32 -4)
:width 16
:height 16
:borderRadius 8}]
[])}
[rn/view {:style (style/container size options blur? theme)}
[token/view
{:style (style/token-img size)
:token token-symbol
:size (case size
:size-24 :size-20
:size-32 :size-28)}]
[rn/view
{:style (style/container size options blur? theme)}
[rn/image
{:style (style/token-img size)
:source token-img-src}]
[text/text
{:size :paragraph-2
:weight :medium
@@ -1,28 +0,0 @@
(ns quo.components.text-combinations.channel-name.component-spec
(:require [quo.components.text-combinations.channel-name.view :as channel-name]
[test-helpers.component :as h]))
(h/describe "Channel name"
(h/test "Renders Default"
(h/render [channel-name/view {:channel-name "Test channel"}])
(h/is-truthy (h/get-by-text "# Test channel")))
(h/test "Renders unlocked icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:unlocked? true}])
(h/is-truthy (h/get-by-label-text :channel-name-unlocked-icon)))
(h/test "Renders muted icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:muted? true}])
(h/is-truthy (h/get-by-label-text :channel-name-muted-icon)))
(h/test "Renders muted and unlocked icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:muted? true
:unlocked? true}])
(h/is-truthy (h/get-by-label-text :channel-name-unlocked-icon))
(h/is-truthy (h/get-by-label-text :channel-name-muted-icon))))
@@ -1,30 +0,0 @@
(ns quo.components.text-combinations.channel-name.style
(:require [quo.foundations.colors :as colors]))
(def container {:flex-direction :row})
(def icons-container
{:flex-direction :row
:padding-top 8
:padding-bottom 4
:margin-left 6})
(def icon {:width 20 :height 20})
(def icons-gap {:width 4})
(defn- blur-icon-color
[theme]
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme))
(defn unlocked-icon-color
[theme blur?]
(if blur?
(blur-icon-color theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn muted-icon-color
[theme blur?]
(if blur?
(blur-icon-color theme)
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)))
@@ -1,40 +0,0 @@
(ns quo.components.text-combinations.channel-name.view
(:require [quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.text-combinations.channel-name.style :as style]
[quo.theme]
[react-native.core :as rn]))
(defn icons
[{:keys [theme unlocked? muted? blur?]}]
[rn/view {:style style/icons-container}
(when unlocked?
[rn/view
{:style style/icon
:accessibility-label :channel-name-unlocked-icon}
[icon/icon :i/unlocked
{:color (style/unlocked-icon-color theme blur?)
:size 20}]])
(when (and unlocked? muted?)
[rn/view {:style style/icons-gap}])
(when muted?
[rn/view
{:style style/icon
:accessibility-label :channel-name-muted-icon}
[icon/icon :i/muted
{:color (style/muted-icon-color theme blur?)
:size 20}]])])
(defn- view-internal
[{:keys [unlocked? muted? channel-name] :as props}]
[rn/view {:style style/container}
[text/text
{:size :heading-1
:weight :semi-bold}
(str "# " channel-name)]
(when (or unlocked? muted?)
[icons props])])
(def view (quo.theme/with-theme view-internal))
@@ -1,51 +0,0 @@
(ns quo.components.text-combinations.standard-title.component-spec
(:require [quo.components.text-combinations.standard-title.view :as standard-title]
[test-helpers.component :as h]))
(h/describe "Text combinations - Standard title"
(h/test "Default render"
(h/render [standard-title/view {:title "This is a title"}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Counter variant"
(h/render [standard-title/view
{:title "This is a title"
:right :counter
:counter-left 50
:counter-right 100}])
(h/is-truthy (h/get-by-text "50/100")))
(h/describe "Action variant"
(h/test "Default render"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/is-truthy (h/get-by-text "This is a title"))))
(h/test "Action fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-action))
(h/was-called-times on-press-fn 1))))
(h/describe "Tag variant"
(h/test "Default render"
(h/render [standard-title/view
{:title "This is a title"
:right :tag}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Tag callback fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :tag
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-tag))
(h/was-called-times on-press-fn 1)))))
@@ -1,24 +0,0 @@
(ns quo.components.text-combinations.standard-title.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:justify-content :space-between})
(def right-container {:margin-left 20})
(def right-counter
{:padding-top 12
:padding-bottom 2})
(defn right-counter-text
[blur? theme]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))})
(defn right-tag-icon-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
@@ -1,68 +0,0 @@
(ns quo.components.text-combinations.standard-title.view
(:require [clojure.string :as string]
[quo.components.buttons.button.view :as button]
[quo.components.markdown.text :as text]
[quo.components.tags.tag :as tag]
[quo.components.text-combinations.standard-title.style :as style]
[quo.theme]
[react-native.core :as rn]
[utils.number]))
(defn- get-counter-number
[n]
(let [parsed-number (utils.number/parse-int n)]
(if (< n 10)
(str "0" parsed-number)
parsed-number)))
(defn- right-counter
[{:keys [blur? theme counter-left counter-right]}]
[rn/view {:style style/right-counter}
[text/text
{:size :paragraph-2
:weight :regular
:style (style/right-counter-text blur? theme)}
(str (get-counter-number counter-left)
"/"
(get-counter-number counter-right))]])
(defn- right-action
[{:keys [customization-color on-press icon]
:or {icon :i/placeholder}}]
[button/button
{:accessibility-label :standard-title-action
:size 32
:icon-only? true
:customization-color customization-color
:on-press on-press}
icon])
(defn- right-tag
[{:keys [theme blur? on-press icon label]
:or {icon :i/placeholder}}]
(let [labelled? (not (string/blank? label))]
[tag/tag
{:accessibility-label :standard-title-tag
:size 32
:type :icon
:resource icon
:on-press on-press
:labelled? labelled?
:label (when labelled? label)
:blurred? blur?
:icon-color (style/right-tag-icon-color blur? theme)}]))
(defn- view-internal
[{:keys [title right] :as props}]
[rn/view {:style style/container}
[text/text {:size :heading-1 :weight :semi-bold}
title]
(when right
[rn/view {:style style/right-container}
(case right
:counter [right-counter props]
:action [right-action props]
:tag [right-tag props]
nil)])])
(def view (quo.theme/with-theme view-internal))
@@ -9,8 +9,3 @@
(def description-description-text
{:margin-top 8})
(def emoji-hash
{:margin-top 8
:letter-spacing 0.5
:line-height 20.5})
@@ -1,68 +0,0 @@
(ns quo.components.text-combinations.username.component-spec
(:require [quo.components.text-combinations.username.view :as username]
[test-helpers.component :as h]))
(defn test-all-status
[component-to-render component-props]
(h/test "Verified status"
(h/render [component-to-render (assoc component-props :status :verified)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Contact status"
(h/render [component-to-render (assoc component-props :status :contact)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy status"
(h/render [component-to-render (assoc component-props :status :untrustworthy)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy contact status"
(h/render [component-to-render (assoc component-props :status :untrustworthy-contact)])
(let [icons (h/get-all-by-label-text :username-status-icon)]
(h/is-truthy (aget icons 0))
(h/is-truthy (aget icons 1))))
(h/test "Blocked status"
(h/render [component-to-render (assoc component-props :status :blocked)])
(h/is-truthy (h/get-by-label-text :username-status-icon))))
(h/describe "Text combinations - Username"
(h/test "Renders default"
(h/render [username/view {:username "Test username"}])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "Render different :name-type values"
(h/describe "default"
(let [props {:name-type :default
:username "Test username"}]
(h/test "default render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "ens"
(let [props {:name-type :ens
:username "test-username.eth"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "test-username.eth")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "nickname"
(let [props {:name-type :nickname
:username "Nickname"
:name "Real name"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Nickname"))
(h/is-truthy (h/get-by-text "Real name")))
(h/describe "All status are rendered"
(test-all-status username/view props))))))
@@ -1,30 +0,0 @@
(ns quo.components.text-combinations.username.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:height 32})
(def username-text-container
{:flex-direction :row
:align-items :flex-end})
(defn real-name-text
[theme blur?]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-60 colors/neutral-40 theme))})
(defn real-name-dot
[theme blur?]
(assoc (real-name-text theme blur?) :margin-horizontal 6))
(defn status-icon-container
[name-type status]
(cond-> {:flex-direction :row
:margin-left 4}
(#{:default :ens} name-type) (assoc :margin-top 8
:margin-bottom 4)
(= :nickname name-type) (assoc :margin-top 10
:margin-bottom 2)
(= status :untrustworthy-contact) (assoc :margin-right 2)))
@@ -1,57 +0,0 @@
(ns quo.components.text-combinations.username.view
(:require [quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.text-combinations.username.style :as style]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]))
(defn- username-text
[{:keys [theme name-type username blur?]
real-name :name}]
[rn/view {:style style/username-text-container}
[text/text
{:size :heading-1
:weight :semi-bold}
username]
(when (= name-type :nickname)
[:<>
[text/text
{:style (style/real-name-dot theme blur?)
:size :paragraph-1
:weight :medium}
"∙"]
[text/text
{:style (style/real-name-text theme blur?)
:size :paragraph-1
:weight :medium}
real-name]])])
(defn- icon-20
[icon-name theme color]
[icon/icon icon-name
{:accessibility-label :username-status-icon
:size 20
:color (colors/resolve-color color theme)}])
(defn status-icon
[{:keys [theme name-type status]
:or {name-type :default}}]
[rn/view {:style (style/status-icon-container name-type status)}
(case status
:verified [icon-20 :i/verified theme :success]
:contact [icon-20 :i/contact theme :blue]
:untrustworthy [icon-20 :i/untrustworthy theme :danger]
:blocked [icon-20 :i/block theme :danger]
:untrustworthy-contact [:<>
[icon-20 :i/untrustworthy theme :danger]
[icon-20 :i/contact theme :blue]]
nil)])
(defn view-internal
[props]
[rn/view {:style style/container}
[username-text props]
[status-icon props]])
(def view (quo.theme/with-theme view-internal))
@@ -27,8 +27,7 @@
description-accessibility-label
button-icon
button-on-press
customization-color
emoji-hash]}]
customization-color]}]
[rn/view {:style container-style}
[rn/view
{:style {:flex-direction :row
@@ -56,11 +55,6 @@
:weight :regular
:size :paragraph-1
:style style/description-description-text}
description])
(when emoji-hash
[text/text
{:number-of-lines 1
:style style/emoji-hash}
emoji-hash])])
description])])
(def view (theme/with-theme view-internal))
@@ -1,34 +0,0 @@
(ns quo.components.utilities.token.loader
(:require [clojure.java.io :as io]
[clojure.string :as string]))
(def ^:private token-path "./resources/images/tokens/mainnet/")
(defn- clean-filename
"Return a (string) filename without the .png extension and @<number>x suffix."
[file]
(first (string/split (str file) #"@|\.png")))
(defn- get-js-require
[filename]
(let [require-path (str "." filename ".png")]
`(js/require ~require-path)))
(defn- get-file-key
[filename]
(-> filename
(string/split #"\/")
(peek)
(string/lower-case)))
(defn get-tokens
[]
(let [files (file-seq (io/file token-path))
png-filenames (keep (fn [file]
(when (string/ends-with? file "png")
(clean-filename file)))
files)]
(zipmap (map get-file-key png-filenames)
(map get-js-require png-filenames))))
(defmacro resolve-tokens [] (get-tokens))
@@ -1,14 +0,0 @@
(ns quo.components.utilities.token.loader
(:require-macros [quo.components.utilities.token.loader :as loader])
(:require [clojure.string :as string]))
(def ^:private tokens (loader/resolve-tokens))
(defn- get-token-image*
[token]
(let [token-symbol (cond-> token
(keyword? token) name
:always string/lower-case)]
(get tokens token-symbol)))
(def get-token-image (memoize get-token-image*))
@@ -1,58 +0,0 @@
(ns quo.components.utilities.token.view
(:require [quo.components.utilities.token.loader :as token-loader]
[react-native.core :as rn]
[schema.core :as schema]
[utils.number]))
(def ?schema
[:=>
[:cat
[:map {:closed true}
[:size {:optional true :default 32} [:or keyword? pos-int?]]
[:token {:optional true} [:or keyword? string?]]
[:style {:optional true} map?]
;; Ignores `token` and uses this as parameter to `rn/image`'s source.
[:image-source {:optional true} [:or string? map?]]
;; If true, adds `data:image/png;base64,` as prefix to the string passed as `image-source`
[:add-b64-prefix? {:optional true} boolean?]]]
:any])
(defn- size->number
"Remove `size-` prefix in size keywords and returns a number useful for styling."
[size]
(-> size name (subs 5) utils.number/parse-int))
(defn- token-style
[style size]
(let [size-number (if (keyword? size)
(size->number size)
size)]
(assoc style
:width size-number
:height size-number)))
(def ^:private b64-png-image-prefix "data:image/png;base64,")
(defn view-internal
"Render a token image.
Props:
- style: extra styles to apply to the `rn/image` component.
- size: `:size-nn` or just `nn`, being `nn` any number. Defaults to 32.
- token: string or keyword, it can contain upper case letters or not.
E.g. all of these are valid and resolve to the same:
:token/snt | :snt | :SNT | \"SNT\" | \"snt\".
- image-source: Ignores `token` and uses this as parameter to `rn/image`'s source.
- add-b64-prefix?: If true, adds `data:image/png;base64,` as prefix to the string
passed as `image-source`.
"
[{:keys [token size style image-source add-b64-prefix?]
:or {size 32}}]
(let [b64-string (if (and image-source add-b64-prefix?)
(str b64-png-image-prefix image-source)
image-source)
source (or b64-string (token-loader/get-token-image token))]
[rn/image
{:style (token-style style size)
:source source}]))
(def view (schema/instrument #'view-internal ?schema))
@@ -93,7 +93,7 @@
:end {:x 1 :y 0}}])
(defn- user-account
[_]
[]
(let [pressed? (reagent/atom false)
on-press-in #(reset! pressed? true)
on-press-out #(reset! pressed? false)]
@@ -147,7 +147,7 @@
[gradient-overview theme customization-color])])))))
(defn- add-account-view
[_]
[]
(let [pressed? (reagent/atom false)]
(fn [{:keys [on-press customization-color theme metrics?]}]
[rn/pressable
@@ -20,13 +20,12 @@
(i18n/label :t/trip-accounts))])
(defn- row-icon
[customization-color profile-picture type secondary-color]
[profile-picture type secondary-color]
(case type
:default-keypair [user-avatar/user-avatar
{:size :xxs
:ring? false
:customization-color customization-color
:profile-picture profile-picture}]
{:size :xxs
:ring? false
:profile-picture profile-picture}]
:recovery-phrase [icons/icon
:i/seed
{:accessibility-label :recovery-phrase-icon
@@ -42,11 +41,10 @@
nil))
(defn- row-view
[{:keys [type theme secondary-color customization-color profile-picture title stored subtitle
on-press]}]
[{:keys [type theme secondary-color profile-picture title stored subtitle on-press]}]
[rn/view {:style (style/row-container type theme)}
[rn/view {:style style/icon-container}
[row-icon customization-color profile-picture type secondary-color]]
[row-icon profile-picture type secondary-color]]
[rn/view
{:style style/row-content-container}
[row-title type title]
@@ -70,19 +68,18 @@
{:color secondary-color}]])])
(defn- list-view
[{:keys [type stored customization-color profile-picture user-name theme secondary-color]}]
[{:keys [type stored profile-picture user-name theme secondary-color]}]
(let [stored-name (if (= :on-device stored)
(i18n/label :t/on-device)
(i18n/label :t/on-keycard))]
[row-view
{:type type
:stored stored
:customization-color customization-color
:profile-picture profile-picture
:title user-name
:subtitle stored-name
:theme theme
:secondary-color secondary-color}]))
{:type type
:stored stored
:profile-picture profile-picture
:title user-name
:subtitle stored-name
:theme theme
:secondary-color secondary-color}]))
(defn- card-view
[theme derivation-path secondary-color on-press]
@@ -108,13 +105,12 @@
(def view
"Create an account-origin UI component.
| key | values |
| ----------------------|------------------------------------------------|
| :type | :default-keypair :recovery-phrase :private-key
| :stored | :on-device :on-keycard
| :profile-picture | image source
| :customization-color | profile color
| :derivation-path | string
| :user-name | string
| :on-press | function"
| key | values |
| ------------------|------------------------------------------------|
| :type | :default-keypair :recovery-phrase :private-key
| :stored | :on-device :on-keycard
| :profile-picture | image source
| :derivation-path | string
| :user-name | string
| :on-press | function"
(quo.theme/with-theme view-internal))
@@ -133,7 +133,7 @@
| key | description |
| -------------|-------------|
| `:account-name` | A value representing the account name (default `nil`)
| `:account` | A value that represents if the account is a `:watched-address` or a `:default` account. (default `nil`)
| `:account` | A value that represents if the account is a `:watched-account` or a `:default` account. (default `nil`)
| `:time-frame` | A value that represents the type of the timeframe, Can be from a preset of time frames. `[:1-week :1-month :3-months :1-year :custom]` (default `nil`) if custom is set, We expect a start time and if there's a space between two times that are in `time-frame-string` we'll split them with an arrow to the right icon
| `:loading?` | A value that indicates that component is loading data. (default `nil`)
| `:metrics` | A value that indicates if the account value have increased can be `:positive` or `:negative` (default `nil`)
@@ -1,99 +0,0 @@
(ns quo.components.wallet.confirmation-progress.component-spec
(:require [quo.core :as quo]
[reagent.core :as reagent]
[test-helpers.component :as h]))
(defn- get-test-data
[{:keys [state network]
:or {state :pending network :mainnet}}]
{:counter (reagent/atom 0)
:total-box 85
:progress-value "10"
:network network
:state state
:customization-color :blue})
(h/describe "Confirmation Progress"
(h/test "component renders when state is sending and network is optimism"
(h/render [quo/confirmation-propgress
(get-test-data {:state :sending
:network :optimism})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is confirmed and network is optimism"
(h/render [quo/confirmation-propgress
(get-test-data {:state :confirmed
:network :optimism})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is finalising and network is optimism"
(h/render [quo/confirmation-propgress
(get-test-data {:state :finalising
:network :optimism})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is finalized and network is optimism"
(h/render [quo/confirmation-propgress
(get-test-data {:state :finalized
:network :optimism})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is error and network is optimism"
(h/render [quo/confirmation-propgress
(get-test-data {:state :error
:network :optimism})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is sending and network is arbitrum"
(h/render [quo/confirmation-propgress
(get-test-data {:state :sending
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is confirmed and network is arbitrum"
(h/render [quo/confirmation-propgress
(get-test-data {:state :confirmed
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is finalising and network is arbitrum"
(h/render [quo/confirmation-propgress
(get-test-data {:state :finalising
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is finalized and network is arbitrum"
(h/render [quo/confirmation-propgress
(get-test-data {:state :finalized
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is error and network is arbitrum"
(h/render [quo/confirmation-propgress
(get-test-data {:state :error
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :progress-box)))
(h/test "component renders when state is pending and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "component renders when state is sending and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {:state :sending})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "component renders when state is confirmed and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {:state :confirmed})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "component renders when state is finalising and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {:state :finalising})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "component renders when state is finalized and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {:state :finalized})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "component renders when state is error and network is mainnet"
(h/render [quo/confirmation-propgress (get-test-data {:state :error})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box))))
@@ -1,9 +0,0 @@
(ns quo.components.wallet.confirmation-progress.style)
(def progress-box-container
{:flex-direction :row
:align-items :center
:padding-horizontal 12
:padding-bottom 10
:padding-top 4
:flex-wrap :wrap})
@@ -1,69 +0,0 @@
(ns quo.components.wallet.confirmation-progress.view
(:require [quo.components.wallet.confirmation-progress.style :as style]
[quo.components.wallet.progress-bar.view :as progress-box]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(def ^:private max-progress 100)
(def ^:private min-progress 0)
(defn- calculate-box-state
[state counter index]
(cond
(and (= state :sending) (>= counter index) (< index 3)) :confirmed
(and (= state :confirmed) (>= counter index) (< index 5)) :confirmed
(and (= state :finalising) (>= counter index) (< index 5)) :confirmed
(and (= state :finalising) (>= counter index) (> index 4) (< index 20)) :finalized
(and (= state :finalized) (>= counter index) (< index 5)) :confirmed
(and (= state :finalized) (>= counter index) (> index 4)) :finalized
(and (= state :error) (>= counter index) (< index 2)) :error
:else :pending))
(defn- calculate-box-state-sidenet
[state]
(case state
:error :error
(:confirmed :finalising :finalized) :finalized
:pending))
(defn- calculate-progressed-value
[state progress-value]
(case state
:finalising progress-value
:finalized max-progress
min-progress))
(defn- progress-boxes-mainnet
[{:keys [state counter total-box]}]
[rn/view
{:accessibility-label :mainnet-progress-box
:style style/progress-box-container}
(let [numbers (range 1 total-box)]
(doall (for [n numbers]
[progress-box/view
{:state (calculate-box-state state counter n)
:customization-color :blue
:key n}])))])
(defn- progress-boxes-sidenet
[{:keys [state progress-value]}]
[rn/view
{:accessibility-label :progress-box
:style style/progress-box-container}
[progress-box/view
{:state (calculate-box-state-sidenet state)
:customization-color :success}]
[progress-box/view
{:state (calculate-box-state-sidenet state)
:full-width? true
:progressed-value (calculate-progressed-value state progress-value)
:customization-color :blue}]])
(defn- view-internal
[{:keys [network] :as props}]
(case network
:mainnet [progress-boxes-mainnet props]
(:arbitrum :optimism) [progress-boxes-sidenet props]
nil))
(def view (quo.theme/with-theme view-internal))
@@ -28,9 +28,3 @@
{:flex-direction :row
:align-items :center
:justify-content :space-between})
(defn subtitle
[blur? theme]
{:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
+13 -15
View File
@@ -11,7 +11,6 @@
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.platform :as platform]
[reagent.core :as reagent]
[utils.i18n :as i18n]))
@@ -20,6 +19,11 @@
(let [first-name (first (string/split full-name #" "))]
(i18n/label :t/keypair-title {:name first-name})))
(defn details-string
[address stored]
(str (when address (str address " ∙ "))
(if (= stored :on-device) (i18n/label :t/on-device) (i18n/label :t/on-keycard))))
(defn avatar
[{{:keys [full-name]} :details
avatar-type :type
@@ -63,21 +67,15 @@
[{:keys [details stored blur? theme]}]
(let [{:keys [address]} details]
[rn/view
{:style {:flex-direction :row
:align-items :center}
:accessibility-label :details}
{:style {:flex-direction :row
:align-items :center}}
[text/text
{:size :paragraph-2
:style (style/subtitle blur? theme)}
address]
[text/text
{:size :paragraph-2
:style (merge (style/subtitle blur? theme) {:bottom (if platform/ios? 2 -2)})}
" ∙ "]
[text/text
{:size :paragraph-2
:style (style/subtitle blur? theme)}
(if (= stored :on-device) (i18n/label :t/on-device) (i18n/label :t/on-keycard))]
{:size :paragraph-2
:accessibility-label :details
:style {:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}}
(details-string address stored)]
(when (= stored :on-keycard)
[rn/view {:style {:margin-left 4}}
[icon/icon :i/keycard-card
@@ -2,15 +2,17 @@
(:require
[clojure.string :as string]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.network-amount.style :as style]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
[{:keys [amount token theme]}]
[rn/view {:style style/container}
[token/view {:token token :size :size-12}]
[rn/image
{:source (resources/get-token token)
:style {:width 12 :height 12}}]
[text/text
{:weight :medium
:size :paragraph-2
@@ -39,7 +39,7 @@
:width 8
:borderRadius 3
:borderColor colors/neutral-80-opa-5
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
:backgroundColor (colors/custom-color (:customization-color props) 50)})))
(h/test "finalized state with customtization-color blue in dark mode"
(let [theme :dark
@@ -51,7 +51,7 @@
:width 8
:borderRadius 3
:borderColor colors/neutral-80-opa-5
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
:backgroundColor (colors/custom-color (:customization-color props) 60)})))
(h/test "finalized state with customtization-color army in light mode"
(let [theme :light
@@ -63,7 +63,7 @@
:width 8
:borderRadius 3
:borderColor colors/neutral-80-opa-5
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
:backgroundColor (colors/custom-color (:customization-color props) 50)})))
(h/test "confirmed state in light mode"
(let [theme :light
@@ -75,7 +75,7 @@
:width 8
:borderRadius 3
:borderColor colors/neutral-80-opa-5
:backgroundColor (colors/resolve-color :success theme)})))
:backgroundColor colors/success-50})))
(h/test "confirmed state in dark mode"
(let [theme :dark
@@ -99,7 +99,7 @@
:width 8
:borderRadius 3
:borderColor colors/neutral-80-opa-5
:backgroundColor (colors/resolve-color :danger theme)})))
:backgroundColor colors/danger-50})))
(h/test "error state in dark mode"
(let [theme :dark
@@ -111,4 +111,4 @@
:width 8
:borderRadius 3
:borderColor colors/white-opa-5
:backgroundColor (colors/resolve-color :danger theme)}))))
:backgroundColor colors/danger-60}))))
@@ -3,48 +3,31 @@
[quo.foundations.colors :as colors]))
(defn- border-and-background-color
[customization-color theme]
[customization-color]
{:light {:pending {:border-color colors/neutral-80-opa-5
:background-color colors/neutral-5}
:confirmed {:border-color colors/neutral-80-opa-5
:background-color (colors/resolve-color :success theme)}
:background-color (colors/custom-color :success 50)}
:finalized {:border-color colors/neutral-80-opa-5
:background-color (colors/resolve-color customization-color theme)}
:background-color (colors/custom-color customization-color 50)}
:error {:border-color colors/neutral-80-opa-5
:background-color (colors/resolve-color :danger theme)}}
:background-color (colors/custom-color :danger 50)}}
:dark {:pending {:border-color colors/neutral-70
:background-color colors/neutral-80}
:confirmed {:border-color colors/white-opa-5
:background-color (colors/resolve-color :success theme)}
:background-color (colors/custom-color :success 60)}
:finalized {:border-color colors/neutral-80-opa-5
:background-color (colors/resolve-color customization-color theme)}
:background-color (colors/custom-color customization-color 60)}
:error {:border-color colors/white-opa-5
:background-color (colors/resolve-color :danger theme)}}})
(def max-value 100)
:background-color (colors/custom-color :danger 60)}}})
(defn root-container
[{:keys [customization-color state theme full-width?]}]
(let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color
theme)
[theme (if full-width? :pending state)])]
{:height 12
:flex (when full-width? 1)
:width (when (not full-width?) 8)
:border-radius 3
:border-width 1
:border-color border-color
:background-color background-color
:margin-horizontal 1
:margin-vertical 2}))
(defn progressed-bar
[{:keys [customization-color state theme progressed-value]}]
(let [{:keys [background-color]} (get-in (border-and-background-color customization-color theme)
[theme state])
progress (if (> progressed-value max-value) max-value progressed-value)]
[{:keys [customization-color state theme]}]
(let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color)
[theme state])]
{:height 12
:margin-top -1
:width (str progress "%")
:width 8
:border-radius 3
:border-width 1
:border-color border-color
:background-color background-color}))
@@ -5,11 +5,9 @@
[react-native.core :as rn]))
(defn- view-internal
[{:keys [full-width?] :as props}]
[props]
[rn/view
{:accessibility-label :progress-bar
:style (style/root-container props)}
(when full-width?
[rn/view {:style (style/progressed-bar props)}])])
:style (style/root-container props)}])
(def view (quo.theme/with-theme view-internal))
@@ -4,7 +4,7 @@
(defn container
[networks? theme]
{:width "100%"
{:width 335
:height (if networks? 90 56)
:border-radius 16
:border-width 1
@@ -16,6 +16,10 @@
:flex-direction :row
:justify-content :space-between})
(def token
{:width 32
:height 32})
(defn text-input
[theme]
(merge typography/heading-1
+53 -56
View File
@@ -1,17 +1,17 @@
(ns quo.components.wallet.token-input.view
(:require
[clojure.string :as string]
[quo.components.buttons.button.view :as button]
[quo.components.dividers.divider-line.view :as divider-line]
[quo.components.markdown.text :as text]
[quo.components.tags.network-tags.view :as network-tag]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
[clojure.string :as string]
[quo.components.buttons.button.view :as button]
[quo.components.dividers.divider-line.view :as divider-line]
[quo.components.markdown.text :as text]
[quo.components.tags.network-tags.view :as network-tag]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn calc-value
[crypto? currency token value conversion]
@@ -21,14 +21,13 @@
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
(defn- view-internal
[{external-value :value}]
(let [width (:width (rn/get-window))
value (reagent/atom nil)
crypto? (reagent/atom true)
input-ref (atom nil)
controlled-input? (some? external-value)]
[]
(let [width (:width (rn/get-window))
value (reagent/atom nil)
crypto? (reagent/atom true)
input-ref (atom nil)]
(fn [{:keys [theme token currency conversion networks title customization-color
on-change-text on-swap container-style show-keyboard?]
on-swap container-style show-keyboard?]
:or {show-keyboard? true}
external-value :value}]
[rn/view
@@ -41,44 +40,42 @@
:style {:flex-direction :row
:flex-grow 1
:align-items :flex-end}}
[token/view {:token token :size :size-32}]
[rn/image
{:style style/token
:source (resources/get-token token)}]
[rn/text-input
(cond-> {:auto-focus true
:ref #(reset! input-ref %)
:placeholder "0"
:placeholder-text-color (colors/theme-colors colors/neutral-40
colors/neutral-50
theme)
:keyboard-type :numeric
:max-length 12
:on-change-text (fn [v]
(when-not controlled-input?
(reset! value v))
(when on-change-text
(on-change-text v)))
:style (style/text-input theme)
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?}
controlled-input? (assoc :value external-value)
(not controlled-input?) (assoc :default-value @value))]
[text/text
{:size :paragraph-2
:weight :semi-bold
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 8
:padding-bottom 2}}
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press (fn []
(swap! crypto? not)
(when on-swap
(on-swap @crypto?)))
:type :outline
:accessibility-label :reorder}
:i/reorder]]
{:ref #(do (reset! input-ref %)
(when %
(.focus ^js %)))
:placeholder "0"
:placeholder-text-color (colors/theme-colors colors/neutral-40
colors/neutral-50
theme)
:default-value (or external-value @value)
:keyboard-type :numeric
:max-length 12
:on-change-text #(reset! value %)
:style (style/text-input theme)
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?}]]
[text/text
{:size :paragraph-2
:weight :semi-bold
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 8
:padding-bottom 2}}
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press (fn []
(swap! crypto? not)
(when on-swap
(on-swap @crypto?)))
:type :outline
:accessibility-label :reorder}
:i/reorder]
[divider-line/view {:container-style {:margin-vertical 8}}]
[rn/view {:style style/data-container}
[network-tag/view {:networks networks :title title}]
@@ -1,200 +0,0 @@
(ns quo.components.wallet.transaction-progress.component-spec
(:require [quo.core :as quo]
[reagent.core :as reagent]
[test-helpers.component :as h]))
(defn- get-test-data
[{:keys [state network]
:or {state :pending network :mainnet}}]
{:title "Title"
:tag-name "Doodle"
:tag-number "120"
:network network
:customization-color :blue
:networks [{:network :mainnet
:state state
:counter (reagent/atom 0)
:total-box 85
:progress 30
:epoch-number "123"}
{:network :optimism
:state state
:progress "50"
:epoch-number "123"}
{:network :arbitrum
:state state
:progress "30"
:epoch-number "123"}]
:on-press (fn []
(js/alert "Transaction progress item pressed"))})
(h/describe "Transaction Progress"
(h/test "component renders without props"
(h/render [quo/transaction-progress])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is pending and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is sending and network is optimism-arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :sending
:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is confirmed and network is optimism-arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :confirmed
:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalising and network is optimism-arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :finalising
:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalized and network is optimism-arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :finalized
:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is error and network is optimism-arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :error
:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is sending and network is optimism"
(h/render [quo/transaction-progress
(get-test-data {:state :sending
:network :optimism})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is confirmed and network is optimism"
(h/render [quo/transaction-progress
(get-test-data {:state :confirmed
:network :optimism})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalising and network is optimism"
(h/render [quo/transaction-progress
(get-test-data {:state :finalising
:network :optimism})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalized and network is optimism"
(h/render [quo/transaction-progress
(get-test-data {:state :finalized
:network :optimism})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is error and network is optimism"
(h/render [quo/transaction-progress
(get-test-data {:state :error
:network :optimism})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is sending and network is arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :sending
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is confirmed and network is arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :confirmed
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalising and network is arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :finalising
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalized and network is arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :finalized
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is error and network is arbitrum"
(h/render [quo/transaction-progress
(get-test-data {:state :error
:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is pending and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is sending and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:state :sending})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is confirmed and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:state :confirmed})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalising and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:state :finalising})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is finalized and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:state :finalized})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "component renders when state is error and network is mainnet"
(h/render [quo/transaction-progress (get-test-data {:state :error})])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
(h/test "mainnet progress box is visible network is mainnet"
(h/render [quo/transaction-progress (get-test-data {})])
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
(h/test "arbitrum-optimism progress box is visible network is optimism-arbitrum"
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
(h/is-truthy (h/get-all-by-label-text :progress-box)))
(h/test "arbitrum progress box is visible network is arbitrum"
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
(h/is-truthy (h/get-all-by-label-text :progress-box)))
(h/test "optimism progress box is visible network is optimism"
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
(h/is-truthy (h/get-all-by-label-text :progress-box)))
(h/test "title is visible network is optimism-arbitrum"
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-text "Title")))
(h/test "title is visible network is mainnet"
(h/render [quo/transaction-progress (get-test-data {})])
(h/is-truthy (h/get-by-text "Title")))
(h/test "title is visible network is optimism"
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
(h/is-truthy (h/get-by-text "Title")))
(h/test "title is visible network is arbitrum"
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
(h/is-truthy (h/get-by-text "Title")))
(h/test "context tag is visible network is optimism-arbitrum"
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
(h/is-truthy (h/get-by-label-text :context-tag)))
(h/test "context tag is visible network is mainnet"
(h/render [quo/transaction-progress (get-test-data {})])
(h/is-truthy (h/get-by-label-text :context-tag)))
(h/test "context tag is visible network is optimism"
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
(h/is-truthy (h/get-by-label-text :context-tag)))
(h/test "context tag is visible network is optimism"
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
(h/is-truthy (h/get-by-label-text :context-tag))))
@@ -1,38 +0,0 @@
(ns quo.components.wallet.transaction-progress.style
(:require [quo.foundations.colors :as colors]))
(def title-text-container
{:flex 1})
(def icon
{:margin-right 4})
(defn box-style
[theme]
{:border-radius 16
:border-width 1
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)})
(def title-container
{:align-items :center
:flex-direction :row
:padding-left 12
:padding-top 8
:padding-right 8
:padding-bottom 4})
(def status-row-container
{:flex-direction :row
:align-items :center
:flex 1
:padding-horizontal 12
:padding-top 8
:padding-bottom 4})
(defn context-tag-container
[theme]
{:padding-horizontal 12
:padding-bottom 8
:flex-direction :row
:border-bottom-width 1
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)})
@@ -1,187 +0,0 @@
(ns quo.components.wallet.transaction-progress.view
(:require [quo.components.buttons.button.view :as button]
[quo.components.icon :as icons]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.view :as context-tag]
[quo.components.wallet.confirmation-progress.view :as confirmation-progress]
[quo.components.wallet.transaction-progress.style :as style]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]))
(def ^:private max-mainnet-verifications 4)
(def ^:private max-sidenet-verifications 1)
(defn- icon-internal
([icon]
(icon-internal icon nil 20))
([icon color]
(icon-internal icon color 20))
([icon color size]
[rn/view {:style style/icon}
[icons/icon
icon
{:color color
:size size
:no-color (when (not color) true)}]]))
(defn- text-internal
[{:keys [weight size accessibility-label color]
:or {weight :semi-bold
size :paragraph-1}}
title]
[text/text
{:accessibility-label accessibility-label
:ellipsize-mode :tail
:number-of-lines 1
:weight weight
:size size
:style {:color color}}
title])
(defn- network-type-text
[state]
(case state
(:sending :pending) (i18n/label :t/pending-on)
(:confirmed :finalising) (i18n/label :t/confirmed-on)
:finalized (i18n/label :t/finalized-on)
:error (i18n/label :t/failed-on)
nil))
(defn- calculate-counter
[counter]
(if (< counter 4) counter max-mainnet-verifications))
(defn mainnet-label
[counter]
(str counter "/" max-mainnet-verifications))
(defn subnet-label
[counter]
(str counter "/" max-sidenet-verifications))
(defn- text-steps
[network state epoch-number counter]
(let [steps (case network
:mainnet
{:pending (mainnet-label 0)
:sending (mainnet-label (calculate-counter counter))
:confirmed (mainnet-label (calculate-counter counter))
:finalising (mainnet-label (calculate-counter counter))
:finalized (i18n/label :t/epoch-number {:number epoch-number})
:error (mainnet-label 0)}
(or :optimism :arbitrum)
{:pending (subnet-label 0)
:sending (subnet-label 0)
:confirmed (subnet-label 0)
:finalising (subnet-label 1)
:finalized (i18n/label :t/epoch-number {:number epoch-number})
:error (subnet-label 0)}
nil)]
(get steps state)))
(defn- get-status-icon
[theme state]
(case state
(:pending :sending) {:icon :i/pending-state
:color (colors/theme-colors colors/neutral-50
colors/neutral-40
theme)}
(:confirmed :finalising) {:icon :i/positive-state
:color (colors/resolve-color :success theme)}
:finalized {:icon :i/diamond}
:error {:icon :i/negative-state
:color (colors/resolve-color :danger theme)}
nil))
(defn- get-network
[networks network]
(some #(when (= (:network %) network) %)
networks))
(defn- calculate-error-state
[networks]
(some #(= (:state %) :error) networks))
(defn- title-internal
[{:keys [title theme networks]}]
[rn/view {:style style/title-container}
[icon-internal :i/placeholder (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)]
[rn/view {:style style/title-text-container}
[text-internal nil title]]
(when (calculate-error-state networks)
[button/button
{:size 24
:icon-left :i/refresh}
(i18n/label :t/retry)])])
(defn- tag-internal
[tag-photo tag-name tag-number theme]
[rn/view {:style (style/context-tag-container theme)}
[context-tag/view
{:size 24
:collectible tag-photo
:collectible-name tag-name
:collectible-number tag-number
:type :collectible}]])
(defn- get-network-text
[network]
(case network
:arbitrum (i18n/label :t/arbitrum)
:mainnet (i18n/label :t/mainnet)
:optimism (i18n/label :t/optimism)
nil))
(defn- status-row
[{:keys [theme state network epoch-number counter]}]
(let [{:keys [icon color]} (get-status-icon theme state)]
[rn/view {:style style/status-row-container}
[icon-internal icon color 16]
[rn/view {:style style/title-text-container}
[text-internal
{:weight :regular
:size :paragraph-2}
(str (network-type-text state) " " (get-network-text network))]]
[rn/view
[text-internal
{:weight :regular
:size :paragraph-2
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}
(text-steps network state epoch-number counter)]]]))
(defn- view-network
[{:keys [theme state epoch-number counter total-box progress network]}]
[:<>
[status-row
{:theme theme
:state state
:network network
:epoch-number epoch-number
:counter counter}]
[confirmation-progress/view
{:state state
:network network
:counter counter
:total-box total-box
:progress-value progress}]])
(defn- view-internal
[{:keys [title on-press accessibility-label theme tag-photo tag-name tag-number networks]
:or {accessibility-label :transaction-progress}}]
[rn/touchable-without-feedback
{:on-press on-press
:accessibility-label accessibility-label}
[rn/view {:style (style/box-style theme)}
[title-internal
{:title title
:theme theme
:networks networks}]
[tag-internal tag-photo tag-name tag-number theme]
(for [network networks]
^{:key (:network network)}
(let [assoc-props #(get-network networks %)]
[view-network (assoc-props (:network network))]))]])
(def view (quo.theme/with-theme view-internal))

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