Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb129b97f3 |
@@ -77,6 +77,7 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
|
||||
@@ -716,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
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -49,7 +49,6 @@
|
||||
:Text {}
|
||||
:StatusBar {}
|
||||
:ScrollView {}
|
||||
:SafeAreaView {}
|
||||
:KeyboardAvoidingView {}
|
||||
:TextInput {}
|
||||
:Image {}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
[]
|
||||
|
||||
@@ -26,25 +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
|
||||
{:width 32
|
||||
:height 32
|
||||
: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]
|
||||
|
||||
@@ -15,14 +15,11 @@
|
||||
{: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
|
||||
@@ -33,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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})
|
||||
@@ -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
|
||||
|
||||
@@ -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]}]
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
(ns quo.components.status-link-previews.community.component-spec
|
||||
(:require
|
||||
[quo.components.status-link-previews.community.view :as view]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(def props
|
||||
{:title "Some title"
|
||||
:description "Some description"
|
||||
:link "status.im"
|
||||
:logo "data:image/png,logo-x"
|
||||
:thumbnail "data:image/png,whatever"
|
||||
:member-count 20
|
||||
:active-members-count 20})
|
||||
|
||||
(h/describe "Status link previews - Community"
|
||||
(h/test "default render"
|
||||
(h/render [view/view])
|
||||
(h/is-truthy (h/query-by-label-text :link-preview))
|
||||
(h/is-null (h/query-by-label-text :button-enable-preview)))
|
||||
|
||||
(h/test "renders with most common props"
|
||||
(h/render [view/view props])
|
||||
(h/is-truthy (h/query-by-text (:title props)))
|
||||
(h/is-truthy (h/query-by-text (:description props)))
|
||||
(h/is-truthy (h/query-by-text (:link props)))
|
||||
(h/is-truthy (h/query-by-label-text :logo))
|
||||
(h/is-truthy (h/query-by-label-text :thumbnail)))
|
||||
|
||||
(h/test "does not render thumbnail if prop is not present"
|
||||
(h/render [view/view (dissoc props :thumbnail)])
|
||||
(h/is-null (h/query-by-label-text :thumbnail)))
|
||||
|
||||
(h/test "does not render logo if prop is not present"
|
||||
(h/render [view/view (dissoc props :logo)])
|
||||
(h/is-null (h/query-by-label-text :logo))))
|
||||
@@ -1,51 +0,0 @@
|
||||
(ns quo.components.status-link-previews.community.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(defn loading-circle
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
|
||||
:margin-right 4
|
||||
:width 16
|
||||
:height 16
|
||||
:border-radius 16})
|
||||
|
||||
(defn loading-stat
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
|
||||
:margin-right 4
|
||||
:width 32
|
||||
:height 8
|
||||
:border-radius 16})
|
||||
|
||||
(def loading-stat-container {:flex-direction :row :align-items :center :margin-right 12})
|
||||
|
||||
(defn loading-first-line-bar
|
||||
[theme]
|
||||
{:style {:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
|
||||
:width 145
|
||||
:height 16
|
||||
:border-radius 6}})
|
||||
|
||||
(defn loading-second-line-bar
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
|
||||
:width 112
|
||||
:height 8
|
||||
:border-radius 6
|
||||
:margin-bottom 17})
|
||||
|
||||
(defn loading-thumbnail-box
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)
|
||||
:margin-right 4
|
||||
:width 271
|
||||
:height 139
|
||||
:border-radius 16})
|
||||
|
||||
(def thumbnail
|
||||
{:width "100%"
|
||||
:height 139
|
||||
:margin-top 8
|
||||
:border-radius 12})
|
||||
|
||||
(def row-spacing {:flex-direction :row :margin-bottom 12})
|
||||
@@ -1,101 +0,0 @@
|
||||
(ns quo.components.status-link-previews.community.view
|
||||
(:require
|
||||
[quo.components.community.community-stat.view :as community-stat]
|
||||
[quo.components.links.link-preview.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.status-link-previews.community.style :as status-link-previews-style]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- description-comp
|
||||
[description members-count active-members-count]
|
||||
[rn/view
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:number-of-lines 3
|
||||
:accessibility-label :description} description]
|
||||
[rn/view {:flex-direction :row :margin-top 12}
|
||||
[community-stat/view
|
||||
{:value members-count
|
||||
:icon :i/members
|
||||
:accessibility-label :members-count
|
||||
:style {:margin-right 12}}]
|
||||
[community-stat/view
|
||||
{:value (or active-members-count 0)
|
||||
:icon :i/active-members
|
||||
:accessibility-label :active-members-count}]]])
|
||||
|
||||
(defn- title-comp
|
||||
[title]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:number-of-lines 1
|
||||
:weight :semi-bold
|
||||
:style style/title
|
||||
:accessibility-label :title}
|
||||
title])
|
||||
|
||||
(defn- thumbnail-comp
|
||||
[thumbnail]
|
||||
[rn/image
|
||||
{:style status-link-previews-style/thumbnail
|
||||
:source (if (string? thumbnail)
|
||||
{:uri thumbnail}
|
||||
thumbnail)
|
||||
:accessibility-label :thumbnail}])
|
||||
|
||||
(defn- logo-comp
|
||||
[logo]
|
||||
[rn/image
|
||||
{:accessibility-label :logo
|
||||
:source (if (string? logo)
|
||||
{:uri logo}
|
||||
logo)
|
||||
:style style/logo}])
|
||||
|
||||
(defn- stat-loading
|
||||
[theme]
|
||||
[rn/view {:style status-link-previews-style/loading-stat-container}
|
||||
[rn/view {:style (status-link-previews-style/loading-circle theme)}]
|
||||
[rn/view {:style (status-link-previews-style/loading-stat theme)}]])
|
||||
|
||||
(defn- loading-view
|
||||
[theme]
|
||||
[rn/view
|
||||
{:accessibility-label :loading}
|
||||
[rn/view {:style status-link-previews-style/row-spacing}
|
||||
[rn/view (status-link-previews-style/loading-circle theme)]
|
||||
[rn/view (status-link-previews-style/loading-first-line-bar theme)]]
|
||||
[rn/view {:style (status-link-previews-style/loading-second-line-bar theme)}]
|
||||
[rn/view status-link-previews-style/row-spacing
|
||||
[stat-loading theme]
|
||||
[stat-loading theme]]
|
||||
[rn/view {:style (status-link-previews-style/loading-thumbnail-box theme)}]])
|
||||
|
||||
(defn f-internal-view
|
||||
[{:keys [title description loading? thumbnail-size icon banner members-count active-members-count
|
||||
theme on-press]
|
||||
:or {loading? false}}]
|
||||
[rn/touchable-opacity
|
||||
{:style (merge (style/container (not loading?))
|
||||
{:width 295
|
||||
:height 245})
|
||||
:accessibility-label :link-preview
|
||||
:on-press on-press}
|
||||
(if loading?
|
||||
[loading-view theme]
|
||||
[:<>
|
||||
[rn/view {:style style/header-container}
|
||||
(when icon
|
||||
[logo-comp icon])
|
||||
[title-comp title]]
|
||||
(when description
|
||||
[description-comp description members-count active-members-count])
|
||||
(when banner
|
||||
[thumbnail-comp banner thumbnail-size])])])
|
||||
|
||||
(defn- internal-view
|
||||
[props]
|
||||
[:f> f-internal-view props])
|
||||
|
||||
(def view (theme/with-theme internal-view))
|
||||
@@ -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]]))
|
||||
|
||||
@@ -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,44 +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?]]]))
|
||||
[_ _]
|
||||
(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?]]])))
|
||||
|
||||
(def tag (quo.theme/with-theme tag-internal))
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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))})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.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]))
|
||||
[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
|
||||
@@ -45,42 +44,38 @@
|
||||
{: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}]
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
quo.components.drawers.drawer-buttons.view
|
||||
quo.components.drawers.drawer-top.view
|
||||
quo.components.drawers.permission-context.view
|
||||
quo.components.dropdowns.dropdown-input.view
|
||||
quo.components.dropdowns.dropdown.view
|
||||
quo.components.dropdowns.network-dropdown.view
|
||||
quo.components.empty-state.empty-state.view
|
||||
@@ -66,7 +65,6 @@
|
||||
quo.components.inputs.recovery-phrase.view
|
||||
quo.components.inputs.search-input.view
|
||||
quo.components.inputs.title-input.view
|
||||
quo.components.ios.drawer-bar.view
|
||||
quo.components.keycard.view
|
||||
quo.components.links.link-preview.view
|
||||
quo.components.links.url-preview-list.view
|
||||
@@ -102,7 +100,6 @@
|
||||
quo.components.numbered-keyboard.keyboard-key.view
|
||||
quo.components.numbered-keyboard.numbered-keyboard.view
|
||||
quo.components.onboarding.small-option-card.view
|
||||
quo.components.overlay.view
|
||||
quo.components.password.tips.view
|
||||
quo.components.profile.collectible.view
|
||||
quo.components.profile.profile-card.view
|
||||
@@ -125,7 +122,6 @@
|
||||
quo.components.settings.settings-item.view
|
||||
quo.components.share.qr-code.view
|
||||
quo.components.share.share-qr-code.view
|
||||
quo.components.status-link-previews.community.view
|
||||
quo.components.switchers.group-messaging-card.view
|
||||
quo.components.tabs.account-selector
|
||||
quo.components.tabs.segmented-tab
|
||||
@@ -140,8 +136,6 @@
|
||||
quo.components.tags.tags
|
||||
quo.components.tags.tiny-tag.view
|
||||
quo.components.tags.token-tag.view
|
||||
quo.components.text-combinations.channel-name.view
|
||||
quo.components.text-combinations.standard-title.view
|
||||
quo.components.text-combinations.view
|
||||
quo.components.wallet.account-card.view
|
||||
quo.components.wallet.account-origin.view
|
||||
@@ -237,7 +231,6 @@
|
||||
|
||||
;;;; Dropdowns
|
||||
(def dropdown quo.components.dropdowns.dropdown.view/view)
|
||||
(def dropdown-input quo.components.dropdowns.dropdown-input.view/view)
|
||||
(def network-dropdown quo.components.dropdowns.network-dropdown.view/view)
|
||||
|
||||
;;;; Empty State
|
||||
@@ -270,9 +263,6 @@
|
||||
(def search-input quo.components.inputs.search-input.view/search-input)
|
||||
(def title-input quo.components.inputs.title-input.view/view)
|
||||
|
||||
;;;; iOS
|
||||
(def drawer-bar quo.components.ios.drawer-bar.view/view)
|
||||
|
||||
;;;; Numbered Keyboard
|
||||
(def keyboard-key quo.components.numbered-keyboard.keyboard-key.view/view)
|
||||
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
|
||||
@@ -282,9 +272,6 @@
|
||||
(def url-preview quo.components.links.url-preview.view/view)
|
||||
(def url-preview-list quo.components.links.url-preview-list.view/view)
|
||||
|
||||
;;;; Status links
|
||||
(def status-link-preview-community quo.components.status-link-previews.community.view/view)
|
||||
|
||||
;;;; List items
|
||||
(def account-item quo.components.list-items.account.view/view)
|
||||
(def account-list-card quo.components.list-items.account-list-card.view/view)
|
||||
@@ -326,9 +313,6 @@
|
||||
(def notification quo.components.notifications.notification.view/notification)
|
||||
(def toast quo.components.notifications.toast.view/toast)
|
||||
|
||||
;;;; Overlay
|
||||
(def overlay quo.components.overlay.view/view)
|
||||
|
||||
;;;; Password
|
||||
(def tips quo.components.password.tips.view/view)
|
||||
|
||||
@@ -384,8 +368,6 @@
|
||||
(def token-tag quo.components.tags.token-tag.view/view)
|
||||
|
||||
;;;; Text combinations
|
||||
(def channel-name quo.components.text-combinations.channel-name.view/view)
|
||||
(def standard-title quo.components.text-combinations.standard-title.view/view)
|
||||
(def text-combinations quo.components.text-combinations.view/view)
|
||||
|
||||
;;;; Wallet
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
[quo.components.drawers.drawer-buttons.component-spec]
|
||||
[quo.components.drawers.drawer-top.component-spec]
|
||||
[quo.components.drawers.permission-context.component-spec]
|
||||
[quo.components.dropdowns.dropdown-input.component-spec]
|
||||
[quo.components.dropdowns.dropdown.component-spec]
|
||||
[quo.components.dropdowns.network-dropdown.component-spec]
|
||||
[quo.components.gradient.gradient-cover.component-spec]
|
||||
@@ -76,7 +75,6 @@
|
||||
[quo.components.tags.status-tags-component-spec]
|
||||
[quo.components.tags.summary-tag.component-spec]
|
||||
[quo.components.tags.tiny-tag.component-spec]
|
||||
[quo.components.text-combinations.channel-name.component-spec]
|
||||
[quo.components.wallet.account-card.component-spec]
|
||||
[quo.components.wallet.account-origin.component-spec]
|
||||
[quo.components.wallet.account-overview.component-spec]
|
||||
|
||||
@@ -148,9 +148,7 @@
|
||||
(def black-opa-30 (alpha black 0.3))
|
||||
(def black-opa-60 (alpha black 0.6))
|
||||
(def onboarding-header-black "#000716")
|
||||
(def border-avatar-light
|
||||
"Simulates a blurred, transparent border for avatars in light mode"
|
||||
"#475060")
|
||||
|
||||
;;;;Primary
|
||||
|
||||
;;Solid
|
||||
@@ -203,16 +201,6 @@
|
||||
(def danger-50-opa-30 (alpha danger-50 0.3))
|
||||
(def danger-50-opa-40 (alpha danger-50 0.4))
|
||||
|
||||
;;;;Warning
|
||||
(def warning-50 "#FF7D46")
|
||||
(def warning-60 "#CC6438")
|
||||
|
||||
;;50 with transparency
|
||||
(def warning-50-opa-5 (alpha warning-50 0.05))
|
||||
(def warning-50-opa-10 (alpha warning-50 0.1))
|
||||
(def warning-50-opa-20 (alpha warning-50 0.2))
|
||||
(def warning-50-opa-30 (alpha warning-50 0.3))
|
||||
(def warning-50-opa-40 (alpha warning-50 0.4))
|
||||
|
||||
;; Colors for customizing users account
|
||||
(def customization
|
||||
@@ -266,9 +254,7 @@
|
||||
:danger {50 danger-50
|
||||
60 danger-60}
|
||||
:success {50 success-50
|
||||
60 success-60}
|
||||
:warning {50 warning-50
|
||||
60 warning-60}}
|
||||
60 success-60}}
|
||||
customization
|
||||
networks))
|
||||
|
||||
|
||||
@@ -33,191 +33,14 @@
|
||||
(get dapps k))
|
||||
|
||||
(def tokens
|
||||
{:0-native (js/require "../resources/images/tokens/mainnet/0-native.png")
|
||||
:0xbtc (js/require "../resources/images/tokens/mainnet/0XBTC.png")
|
||||
:1st (js/require "../resources/images/tokens/mainnet/1ST.png")
|
||||
:abt (js/require "../resources/images/tokens/mainnet/ABT.png")
|
||||
:abyss (js/require "../resources/images/tokens/mainnet/ABYSS.png")
|
||||
:ae (js/require "../resources/images/tokens/mainnet/AE.png")
|
||||
:agld (js/require "../resources/images/tokens/mainnet/AGLD.png")
|
||||
:akro (js/require "../resources/images/tokens/mainnet/AKRO.png")
|
||||
:amb (js/require "../resources/images/tokens/mainnet/AMB.png")
|
||||
:ampl (js/require "../resources/images/tokens/mainnet/AMPL.png")
|
||||
:ant (js/require "../resources/images/tokens/mainnet/ANT.png")
|
||||
:appc (js/require "../resources/images/tokens/mainnet/APPC.png")
|
||||
:ast (js/require "../resources/images/tokens/mainnet/AST.png")
|
||||
:atmchain (js/require "../resources/images/tokens/mainnet/ATMChain.png")
|
||||
:ausdc (js/require "../resources/images/tokens/mainnet/aUSDC.png")
|
||||
:bal (js/require "../resources/images/tokens/mainnet/BAL.png")
|
||||
:bam (js/require "../resources/images/tokens/mainnet/BAM.png")
|
||||
:band (js/require "../resources/images/tokens/mainnet/BAND.png")
|
||||
:bat (js/require "../resources/images/tokens/mainnet/BAT.png")
|
||||
:blt (js/require "../resources/images/tokens/mainnet/BLT.png")
|
||||
:blz (js/require "../resources/images/tokens/mainnet/BLZ.png")
|
||||
:bnb (js/require "../resources/images/tokens/mainnet/BNB.png")
|
||||
:bnt (js/require "../resources/images/tokens/mainnet/BNT.png")
|
||||
:brln (js/require "../resources/images/tokens/mainnet/BRLN.png")
|
||||
:btm (js/require "../resources/images/tokens/mainnet/BTM.png")
|
||||
:btu (js/require "../resources/images/tokens/mainnet/BTU.png")
|
||||
:cdai (js/require "../resources/images/tokens/mainnet/cDAI.png")
|
||||
:cdt (js/require "../resources/images/tokens/mainnet/CDT.png")
|
||||
:centra (js/require "../resources/images/tokens/mainnet/Centra.png")
|
||||
:cfi (js/require "../resources/images/tokens/mainnet/CFI.png")
|
||||
:ck (js/require "../resources/images/tokens/mainnet/CK.png")
|
||||
:cnd (js/require "../resources/images/tokens/mainnet/CND.png")
|
||||
:cob (js/require "../resources/images/tokens/mainnet/COB.png")
|
||||
:comp (js/require "../resources/images/tokens/mainnet/COMP.png")
|
||||
:crv (js/require "../resources/images/tokens/mainnet/CRV.png")
|
||||
:cvc (js/require "../resources/images/tokens/mainnet/CVC.png")
|
||||
:dai (js/require "../resources/images/tokens/mainnet/DAI.png")
|
||||
:dat (js/require "../resources/images/tokens/mainnet/DAT.png")
|
||||
:data (js/require "../resources/images/tokens/mainnet/DATA.png")
|
||||
:dcn (js/require "../resources/images/tokens/mainnet/DCN.png")
|
||||
:dgd (js/require "../resources/images/tokens/mainnet/DGD.png")
|
||||
:dgx (js/require "../resources/images/tokens/mainnet/DGX.png")
|
||||
:dlt (js/require "../resources/images/tokens/mainnet/DLT.png")
|
||||
:dnt (js/require "../resources/images/tokens/mainnet/DNT.png")
|
||||
:dpy (js/require "../resources/images/tokens/mainnet/DPY.png")
|
||||
:drt (js/require "../resources/images/tokens/mainnet/DRT.png")
|
||||
:dta (js/require "../resources/images/tokens/mainnet/DTA.png")
|
||||
:edg (js/require "../resources/images/tokens/mainnet/EDG.png")
|
||||
:edo (js/require "../resources/images/tokens/mainnet/EDO.png")
|
||||
:ekg (js/require "../resources/images/tokens/mainnet/EKG.png")
|
||||
:eko (js/require "../resources/images/tokens/mainnet/EKO.png")
|
||||
:elf (js/require "../resources/images/tokens/mainnet/ELF.png")
|
||||
:emona (js/require "../resources/images/tokens/mainnet/EMONA.png")
|
||||
:eng (js/require "../resources/images/tokens/mainnet/ENG.png")
|
||||
:enj (js/require "../resources/images/tokens/mainnet/ENJ.png")
|
||||
:ens (js/require "../resources/images/tokens/mainnet/ENS.png")
|
||||
:eos (js/require "../resources/images/tokens/mainnet/EOS.png")
|
||||
:equad (js/require "../resources/images/tokens/mainnet/EQUAD.png")
|
||||
:eth (js/require "../resources/images/tokens/mainnet/ETH-token.png")
|
||||
:eth2x-fli (js/require "../resources/images/tokens/mainnet/ETH2x-FLI.png")
|
||||
:ethos (js/require "../resources/images/tokens/mainnet/ETHOS.png")
|
||||
:evx (js/require "../resources/images/tokens/mainnet/EVX.png")
|
||||
:fuel (js/require "../resources/images/tokens/mainnet/FUEL.png")
|
||||
:fun (js/require "../resources/images/tokens/mainnet/FUN.png")
|
||||
:fxc (js/require "../resources/images/tokens/mainnet/FXC.png")
|
||||
:gdc (js/require "../resources/images/tokens/mainnet/GDC.png")
|
||||
:gen (js/require "../resources/images/tokens/mainnet/GEN.png")
|
||||
:glm (js/require "../resources/images/tokens/mainnet/GLM.png")
|
||||
:gno (js/require "../resources/images/tokens/mainnet/GNO.png")
|
||||
:gnt (js/require "../resources/images/tokens/mainnet/GNT.png")
|
||||
:grid (js/require "../resources/images/tokens/mainnet/GRID.png")
|
||||
:grt (js/require "../resources/images/tokens/mainnet/GRT.png")
|
||||
:hez (js/require "../resources/images/tokens/mainnet/HEZ.png")
|
||||
:hst (js/require "../resources/images/tokens/mainnet/HST.png")
|
||||
:ht (js/require "../resources/images/tokens/mainnet/HT.png")
|
||||
:icn (js/require "../resources/images/tokens/mainnet/ICN.png")
|
||||
:icos (js/require "../resources/images/tokens/mainnet/ICOS.png")
|
||||
:iost (js/require "../resources/images/tokens/mainnet/IOST.png")
|
||||
:kdo (js/require "../resources/images/tokens/mainnet/KDO.png")
|
||||
:kin (js/require "../resources/images/tokens/mainnet/KIN.png")
|
||||
:knc (js/require "../resources/images/tokens/mainnet/KNC.png")
|
||||
:kudos (js/require "../resources/images/tokens/mainnet/Kudos.png")
|
||||
:lend (js/require "../resources/images/tokens/mainnet/LEND.png")
|
||||
:link (js/require "../resources/images/tokens/mainnet/LINK.png")
|
||||
:lisk (js/require "../resources/images/tokens/mainnet/LISK.png")
|
||||
:loom (js/require "../resources/images/tokens/mainnet/LOOM.png")
|
||||
:lpt (js/require "../resources/images/tokens/mainnet/LPT.png")
|
||||
:lrc (js/require "../resources/images/tokens/mainnet/LRC.png")
|
||||
:mana (js/require "../resources/images/tokens/mainnet/MANA.png")
|
||||
:mco (js/require "../resources/images/tokens/mainnet/MCO.png")
|
||||
:mda (js/require "../resources/images/tokens/mainnet/MDA.png")
|
||||
:met (js/require "../resources/images/tokens/mainnet/MET.png")
|
||||
:mfg (js/require "../resources/images/tokens/mainnet/MFG.png")
|
||||
:mgo (js/require "../resources/images/tokens/mainnet/MGO.png")
|
||||
:mkr (js/require "../resources/images/tokens/mainnet/MKR.png")
|
||||
:mln (js/require "../resources/images/tokens/mainnet/MLN.png")
|
||||
:moc (js/require "../resources/images/tokens/mainnet/MOC.png")
|
||||
:mod (js/require "../resources/images/tokens/mainnet/MOD.png")
|
||||
:mth (js/require "../resources/images/tokens/mainnet/MTH.png")
|
||||
:mtl (js/require "../resources/images/tokens/mainnet/MTL.png")
|
||||
:myb (js/require "../resources/images/tokens/mainnet/MYB.png")
|
||||
:nexo (js/require "../resources/images/tokens/mainnet/NEXO.png")
|
||||
:nexxo (js/require "../resources/images/tokens/mainnet/NEXXO.png")
|
||||
:nmr (js/require "../resources/images/tokens/mainnet/NMR.png")
|
||||
:npxs (js/require "../resources/images/tokens/mainnet/NPXS.png")
|
||||
:ogn (js/require "../resources/images/tokens/mainnet/OGN.png")
|
||||
:omg (js/require "../resources/images/tokens/mainnet/OMG.png")
|
||||
:otn (js/require "../resources/images/tokens/mainnet/OTN.png")
|
||||
:oxt (js/require "../resources/images/tokens/mainnet/OXT.png")
|
||||
:pax (js/require "../resources/images/tokens/mainnet/PAX.png")
|
||||
:paxg (js/require "../resources/images/tokens/mainnet/PAXG.png")
|
||||
:pay (js/require "../resources/images/tokens/mainnet/PAY.png")
|
||||
:pbtc (js/require "../resources/images/tokens/mainnet/PBTC.png")
|
||||
:plr (js/require "../resources/images/tokens/mainnet/PLR.png")
|
||||
:poe (js/require "../resources/images/tokens/mainnet/POE.png")
|
||||
:poly (js/require "../resources/images/tokens/mainnet/POLY.png")
|
||||
:powr (js/require "../resources/images/tokens/mainnet/POWR.png")
|
||||
:ppp (js/require "../resources/images/tokens/mainnet/PPP.png")
|
||||
:ppt (js/require "../resources/images/tokens/mainnet/PPT.png")
|
||||
:pt (js/require "../resources/images/tokens/mainnet/PT.png")
|
||||
:qkc (js/require "../resources/images/tokens/mainnet/QKC.png")
|
||||
:qrl (js/require "../resources/images/tokens/mainnet/QRL.png")
|
||||
:qsp (js/require "../resources/images/tokens/mainnet/QSP.png")
|
||||
:r (js/require "../resources/images/tokens/mainnet/R.png")
|
||||
:rae (js/require "../resources/images/tokens/mainnet/RAE.png")
|
||||
:rare (js/require "../resources/images/tokens/mainnet/RARE.png")
|
||||
:rcn (js/require "../resources/images/tokens/mainnet/RCN.png")
|
||||
:rdn (js/require "../resources/images/tokens/mainnet/RDN.png")
|
||||
:ren (js/require "../resources/images/tokens/mainnet/REN.png")
|
||||
:rep (js/require "../resources/images/tokens/mainnet/REP.png")
|
||||
:req (js/require "../resources/images/tokens/mainnet/REQ.png")
|
||||
:rhoc (js/require "../resources/images/tokens/mainnet/RHOC.png")
|
||||
:rlc (js/require "../resources/images/tokens/mainnet/RLC.png")
|
||||
:rol (js/require "../resources/images/tokens/mainnet/ROL.png")
|
||||
:sai (js/require "../resources/images/tokens/mainnet/SAI.png")
|
||||
:salt (js/require "../resources/images/tokens/mainnet/SALT.png")
|
||||
:san (js/require "../resources/images/tokens/mainnet/SAN.png")
|
||||
:sngls (js/require "../resources/images/tokens/mainnet/SNGLS.png")
|
||||
:snm (js/require "../resources/images/tokens/mainnet/SNM.png")
|
||||
:snt (js/require "../resources/images/tokens/mainnet/SNT.png")
|
||||
:snx (js/require "../resources/images/tokens/mainnet/SNX.png")
|
||||
:socks (js/require "../resources/images/tokens/mainnet/SOCKS.png")
|
||||
:spank (js/require "../resources/images/tokens/mainnet/SPANK.png")
|
||||
:spike (js/require "../resources/images/tokens/mainnet/SPIKE.png")
|
||||
:spn (js/require "../resources/images/tokens/mainnet/SPN.png")
|
||||
:st (js/require "../resources/images/tokens/mainnet/ST.png")
|
||||
:storj (js/require "../resources/images/tokens/mainnet/STORJ.png")
|
||||
:storm (js/require "../resources/images/tokens/mainnet/STORM.png")
|
||||
:strk (js/require "../resources/images/tokens/mainnet/STRK.png")
|
||||
:stx (js/require "../resources/images/tokens/mainnet/STX.png")
|
||||
:sub (js/require "../resources/images/tokens/mainnet/SUB.png")
|
||||
:supr (js/require "../resources/images/tokens/mainnet/SUPR.png")
|
||||
:susd (js/require "../resources/images/tokens/mainnet/sUSD.png")
|
||||
:taas (js/require "../resources/images/tokens/mainnet/TAAS.png")
|
||||
:taud (js/require "../resources/images/tokens/mainnet/TAUD.png")
|
||||
:tcad (js/require "../resources/images/tokens/mainnet/TCAD.png")
|
||||
:tgbp (js/require "../resources/images/tokens/mainnet/TGBP.png")
|
||||
:tkn (js/require "../resources/images/tokens/mainnet/TKN.png")
|
||||
:tkx (js/require "../resources/images/tokens/mainnet/TKX.png")
|
||||
:tnt (js/require "../resources/images/tokens/mainnet/TNT.png")
|
||||
:trst (js/require "../resources/images/tokens/mainnet/TRST.png")
|
||||
:trx (js/require "../resources/images/tokens/mainnet/TRX.png")
|
||||
:tusd (js/require "../resources/images/tokens/mainnet/TUSD.png")
|
||||
:ubi (js/require "../resources/images/tokens/mainnet/UBI.png")
|
||||
:ubt (js/require "../resources/images/tokens/mainnet/UBT.png")
|
||||
:ukg (js/require "../resources/images/tokens/mainnet/UKG.png")
|
||||
:uni (js/require "../resources/images/tokens/mainnet/UNI.png")
|
||||
:upp (js/require "../resources/images/tokens/mainnet/UPP.png")
|
||||
:usdc (js/require "../resources/images/tokens/mainnet/USDC.png")
|
||||
:usds (js/require "../resources/images/tokens/mainnet/USDS.png")
|
||||
:usdt (js/require "../resources/images/tokens/mainnet/USDT.png")
|
||||
:veri (js/require "../resources/images/tokens/mainnet/VERI.png")
|
||||
:vgx (js/require "../resources/images/tokens/mainnet/VGX.png")
|
||||
:vib (js/require "../resources/images/tokens/mainnet/VIB.png")
|
||||
:wabi (js/require "../resources/images/tokens/mainnet/WaBi.png")
|
||||
:wbtc (js/require "../resources/images/tokens/mainnet/WBTC.png")
|
||||
:weth (js/require "../resources/images/tokens/mainnet/WETH.png")
|
||||
:wings (js/require "../resources/images/tokens/mainnet/WINGS.png")
|
||||
:wtc (js/require "../resources/images/tokens/mainnet/WTC.png")
|
||||
:xaur (js/require "../resources/images/tokens/mainnet/XAUR.png")
|
||||
:xpa (js/require "../resources/images/tokens/mainnet/XPA.png")
|
||||
:xrl (js/require "../resources/images/tokens/mainnet/XRL.png")
|
||||
:xuc (js/require "../resources/images/tokens/mainnet/XUC.png")
|
||||
:zrx (js/require "../resources/images/tokens/mainnet/ZRX.png")
|
||||
:zsc (js/require "../resources/images/tokens/mainnet/ZSC.png")})
|
||||
{:eth (js/require "../resources/images/tokens/mainnet/ETH-token.png")
|
||||
:knc (js/require "../resources/images/tokens/mainnet/KNC.png")
|
||||
:mana (js/require "../resources/images/tokens/mainnet/MANA.png")
|
||||
:rare (js/require "../resources/images/tokens/mainnet/RARE.png")
|
||||
:dai (js/require "../resources/images/tokens/mainnet/DAI.png")
|
||||
:fxc (js/require "../resources/images/tokens/mainnet/FXC.png")
|
||||
:usdt (js/require "../resources/images/tokens/mainnet/USDT.png")
|
||||
:snt (js/require "../resources/images/tokens/mainnet/SNT.png")})
|
||||
|
||||
(defn get-token
|
||||
[k]
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
(def view (reagent/adapt-react-class (.-View ^js react-native)))
|
||||
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
|
||||
(def safe-area-view (reagent/adapt-react-class (.-SafeAreaView ^js react-native)))
|
||||
|
||||
(def ^:private image-native
|
||||
(reagent/adapt-react-class (.-Image ^js react-native)))
|
||||
|
||||
@@ -58,16 +58,14 @@
|
||||
|
||||
(defn save-credentials
|
||||
"Stores the credentials for the address to the Keychain"
|
||||
([server username password]
|
||||
(save-credentials server username password identity))
|
||||
([server username password callback]
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback))))
|
||||
[server username password callback]
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback)))
|
||||
|
||||
(defn get-credentials
|
||||
"Gets the credentials for a specified server from the Keychain"
|
||||
|
||||
@@ -147,48 +147,15 @@
|
||||
preferred-name (get-in db [:profile/profile :preferred-name])
|
||||
emoji? (message-content/emoji-only-content? {:text input-text
|
||||
:response-to message-id})]
|
||||
{:chat-id current-chat-id
|
||||
:content-type (if emoji?
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:text input-text
|
||||
:response-to message-id
|
||||
:ens-name preferred-name
|
||||
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
|
||||
(get-in db [:chat/link-previews :unfurled]))
|
||||
:status-link-previews (map (fn [item]
|
||||
{:url (:url item)
|
||||
:community
|
||||
{:community-id (get-in item [:community :community-id])
|
||||
:color (get-in item
|
||||
[:community :color])
|
||||
:description (get-in item
|
||||
[:community :description])
|
||||
:display-name (get-in item
|
||||
[:community :display-name])
|
||||
:members-count (get-in item
|
||||
[:community :members-count])
|
||||
:active-members-count (get-in item
|
||||
[:community :active-members-count])
|
||||
:icon {:data-uri (get-in item
|
||||
[:community :icon
|
||||
:data-uri])
|
||||
:width (get-in item
|
||||
[:community :icon
|
||||
:width])
|
||||
:height (get-in item
|
||||
[:community :icon
|
||||
:height])}
|
||||
:banner {:data-uri (get-in item
|
||||
[:community :banner
|
||||
:data-uri])
|
||||
:width (get-in item
|
||||
[:community :banner
|
||||
:width])
|
||||
:height (get-in item
|
||||
[:community :banner
|
||||
:height])}}})
|
||||
(get-in db [:chat/status-link-previews :unfurled]))})))
|
||||
{:chat-id current-chat-id
|
||||
:content-type (if emoji?
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:text input-text
|
||||
:response-to message-id
|
||||
:ens-name preferred-name
|
||||
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
|
||||
(get-in db [:chat/link-previews :unfurled]))})))
|
||||
|
||||
(defn build-image-messages
|
||||
[{db :db} chat-id input-text]
|
||||
@@ -226,7 +193,6 @@
|
||||
(rf/merge cofx
|
||||
(clean-input current-chat-id)
|
||||
(link-preview/reset-unfurled)
|
||||
(link-preview/clear-status-link-previews)
|
||||
(mentions/clear-mentions))))
|
||||
|
||||
(rf/defn send-messages
|
||||
@@ -239,7 +205,6 @@
|
||||
(rf/merge cofx
|
||||
(clean-input (:current-chat-id db))
|
||||
(link-preview/reset-unfurled)
|
||||
(link-preview/clear-status-link-previews)
|
||||
(chat.message/send-messages messages)))))
|
||||
|
||||
(rf/defn send-audio-message
|
||||
@@ -274,30 +239,25 @@
|
||||
:as cofx} text {:keys [message-id quoted-message chat-id]}]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_editMessage"
|
||||
:params [{:id message-id
|
||||
:text text
|
||||
:content-type (if (message-content/emoji-only-content?
|
||||
{:text text
|
||||
:response-to quoted-message})
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:linkPreviews (map #(-> %
|
||||
(select-keys [:url :title :description
|
||||
:thumbnail])
|
||||
data-store-messages/->link-preview-rpc)
|
||||
(get-in db [:chat/link-previews :unfurled]))
|
||||
:statusLinkPreviews (map
|
||||
data-store-messages/<-status-link-previews-rpc
|
||||
(get-in db [:chat/status-link-previews :unfurled]))}]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to edit message " %)
|
||||
:on-success (fn [result]
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response
|
||||
result]))}]}
|
||||
{:json-rpc/call [{:method "wakuext_editMessage"
|
||||
:params [{:id message-id
|
||||
:text text
|
||||
:content-type (if (message-content/emoji-only-content?
|
||||
{:text text
|
||||
:response-to quoted-message})
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:linkPreviews (map #(-> %
|
||||
(select-keys [:url :title :description
|
||||
:thumbnail])
|
||||
data-store-messages/->link-preview-rpc)
|
||||
(get-in db [:chat/link-previews :unfurled]))}]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to edit message " %)
|
||||
:on-success (fn [result]
|
||||
(re-frame/dispatch [:sanitize-messages-and-process-response
|
||||
result]))}]}
|
||||
(link-preview/reset-unfurled)
|
||||
(link-preview/clear-status-link-previews)
|
||||
(cancel-message-edit)))
|
||||
|
||||
(rf/defn send-current-message
|
||||
|
||||
@@ -76,9 +76,9 @@
|
||||
|
||||
(rf/defn handle-mark-all-read-in-community-successful
|
||||
{:events [::mark-all-read-in-community-successful]}
|
||||
[{:keys [db] :as cofx} {:keys [chats] :as _messenger-response}]
|
||||
[{:keys [db] :as cofx} chat-ids]
|
||||
(rf/merge cofx
|
||||
{:db (reduce mark-chat-all-read db (map :id chats))
|
||||
{:db (reduce mark-chat-all-read db chat-ids)
|
||||
:dispatch [:activity-center.notifications/fetch-unread-count]}))
|
||||
|
||||
(rf/defn handle-mark-all-read
|
||||
|
||||
@@ -326,7 +326,7 @@
|
||||
(conj contacts user-pk)
|
||||
contacts)]
|
||||
(when (seq pks)
|
||||
{:json-rpc/call [{:method "wakuext_shareCommunityV2"
|
||||
{:json-rpc/call [{:method "wakuext_shareCommunity"
|
||||
:params [{:communityId community-id
|
||||
:users pks}]
|
||||
:js-response true
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn ->rpc
|
||||
[{:keys [content]
|
||||
:as message}]
|
||||
[{:keys [content] :as message}]
|
||||
(cond-> message
|
||||
content
|
||||
(assoc :text (:text content)
|
||||
@@ -17,18 +16,6 @@
|
||||
:community-id :communityId
|
||||
:clock-value :clock})))
|
||||
|
||||
(defn- <-status-link-previews-rpc
|
||||
[preview]
|
||||
(-> preview
|
||||
(update :community
|
||||
set/rename-keys
|
||||
{:communityId :community-id
|
||||
:displayName :display-name
|
||||
:membersCount :members-count
|
||||
:activeMembersCount :active-members-count})
|
||||
(update-in [:community :banner] set/rename-keys {:dataUri :data-uri})
|
||||
(update-in [:community :icon] set/rename-keys {:dataUri :data-uri})))
|
||||
|
||||
(defn- <-link-preview-rpc
|
||||
[preview]
|
||||
(update preview :thumbnail set/rename-keys {:dataUri :data-uri}))
|
||||
@@ -66,10 +53,8 @@
|
||||
:new :new?
|
||||
:albumImagesCount :album-images-count
|
||||
:displayName :display-name
|
||||
:linkPreviews :link-previews
|
||||
:statusLinkPreviews :status-link-previews})
|
||||
:linkPreviews :link-previews})
|
||||
(update :link-previews #(map <-link-preview-rpc %))
|
||||
(update :status-link-previews #(map <-status-link-previews-rpc %))
|
||||
(update :quoted-message
|
||||
set/rename-keys
|
||||
{:parsedText :parsed-text
|
||||
|
||||
@@ -82,7 +82,4 @@
|
||||
"wallet-owned-collectibles-filtering-done" {:fx [[:dispatch
|
||||
[:wallet/owned-collectibles-filtering-done
|
||||
event]]]}
|
||||
"wallet-get-collectibles-details-done" {:fx [[:dispatch
|
||||
[:wallet/get-collectible-details-done
|
||||
event]]]}
|
||||
(log/warn ::unknown-wallet-event :type type :event event)))
|
||||
|
||||
@@ -74,8 +74,7 @@
|
||||
:Nameserver "8.8.8.8"
|
||||
:PeerExchange true
|
||||
:Port 0
|
||||
:UDPPort 0
|
||||
:LightClient true})
|
||||
:UDPPort 0})
|
||||
|
||||
(def login-node-config
|
||||
{:WalletConfig (cond-> {:Enabled true}
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
;;; Link previews
|
||||
(reg-root-key-sub :link-previews-whitelist :link-previews-whitelist)
|
||||
(reg-root-key-sub :chat/link-previews :chat/link-previews)
|
||||
(reg-root-key-sub :chat/status-link-previews :chat/status-link-previews)
|
||||
|
||||
;;commands
|
||||
(reg-root-key-sub :commands/select-account :commands/select-account)
|
||||
|
||||
@@ -5,49 +5,32 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- image->rpc [image] (set/rename-keys image {:data-uri :dataUri}))
|
||||
|
||||
(defn- link-preview->rpc
|
||||
[preview]
|
||||
(update preview
|
||||
:thumbnail
|
||||
(fn [thumbnail]
|
||||
(image->rpc thumbnail))))
|
||||
|
||||
(defn- status-link-preview->rpc
|
||||
[preview]
|
||||
(update preview
|
||||
:community
|
||||
(fn [community]
|
||||
(-> community
|
||||
(set/rename-keys {:community-id :communityId
|
||||
:display-name :displayName
|
||||
:members-count :membersCount
|
||||
:active-members-count :activeMembersCount})
|
||||
(update :banner image->rpc)
|
||||
(update :icon image->rpc)))))
|
||||
(set/rename-keys thumbnail {:data-uri :dataUri}))))
|
||||
|
||||
(defn build-message
|
||||
[msg]
|
||||
(-> msg
|
||||
(update :link-previews #(map link-preview->rpc %))
|
||||
(update :status-link-previews #(set (map status-link-preview->rpc %)))
|
||||
(set/rename-keys
|
||||
{:album-id :albumId
|
||||
:audio-duration-ms :audioDurationMs
|
||||
:audio-path :audioPath
|
||||
:chat-id :chatId
|
||||
:community-id :communityId
|
||||
:content-type :contentType
|
||||
:ens-name :ensName
|
||||
:image-height :imageHeight
|
||||
:image-path :imagePath
|
||||
:image-width :imageWidth
|
||||
:link-previews :linkPreviews
|
||||
:status-link-previews :statusLinkPreviews
|
||||
:response-to :responseTo
|
||||
:sticker :sticker
|
||||
:text :text})))
|
||||
{:album-id :albumId
|
||||
:audio-duration-ms :audioDurationMs
|
||||
:audio-path :audioPath
|
||||
:chat-id :chatId
|
||||
:community-id :communityId
|
||||
:content-type :contentType
|
||||
:ens-name :ensName
|
||||
:image-height :imageHeight
|
||||
:image-path :imagePath
|
||||
:image-width :imageWidth
|
||||
:link-previews :linkPreviews
|
||||
:response-to :responseTo
|
||||
:sticker :sticker
|
||||
:text :text})))
|
||||
|
||||
(rf/defn send-chat-messages
|
||||
[_ messages]
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
(vector
|
||||
action-button
|
||||
dismiss-button)
|
||||
(vector dismiss-button))
|
||||
dismiss-button)
|
||||
(when on-dismiss
|
||||
{:cancelable false})))))
|
||||
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.touch-id :as touch-id]
|
||||
[status-im2.common.keychain.events :as keychain]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -43,60 +41,16 @@
|
||||
{:db (assoc db :biometric/supported-type supported-type)})
|
||||
|
||||
(rf/defn show-message
|
||||
{:events [:biometric/show-message]}
|
||||
[_ code]
|
||||
(let [handle-error? (and code
|
||||
(not (contains? #{"USER_CANCELED" "USER_FALLBACK"} code)))
|
||||
content (if (#{"NOT_AVAILABLE" "NOT_ENROLLED"} code)
|
||||
(i18n/label :t/grant-face-id-permissions)
|
||||
(i18n/label :t/biometric-auth-error {:code code}))]
|
||||
(when handle-error?
|
||||
(let [content (if (#{"NOT_AVAILABLE" "NOT_ENROLLED"} code)
|
||||
(i18n/label :t/grant-face-id-permissions)
|
||||
(when-not (or (= code "USER_CANCELED") (= code "USER_FALLBACK"))
|
||||
(i18n/label :t/biometric-auth-error {:code code})))]
|
||||
(when content
|
||||
{:utils/show-popup
|
||||
{:title (i18n/label :t/biometric-auth-login-error-title)
|
||||
:content content}})))
|
||||
|
||||
(defn- supress-biometry-error-key
|
||||
[key-uid]
|
||||
(keyword (str "biometric/supress-not-enrolled-error-" key-uid)))
|
||||
|
||||
;; NOTE: if the account had biometrics registered, but it's not enrolled at the moment,
|
||||
;; we should show the error message only once and supress further "NOT_ENROLLED" errors
|
||||
;; until biometry is enrolled again. Note that we can only know that when :biometric/authenticate
|
||||
;; is dispatched and fails with "NOT_ENROLLED", since :biometric/get-supported-biometric-type
|
||||
;; only tells us what kind of biometric is available on the device, but it doesn't know of its
|
||||
;; enrollment status.
|
||||
(re-frame/reg-fx
|
||||
:biometric/supress-not-enrolled-error
|
||||
(fn [[key-uid dispatch-event]]
|
||||
(let [storage-key (supress-biometry-error-key key-uid)]
|
||||
(-> (async-storage/get-item storage-key identity)
|
||||
(.then (fn [item]
|
||||
(when (not item)
|
||||
(rf/dispatch dispatch-event)
|
||||
(async-storage/set-item! storage-key true))))
|
||||
(.catch (fn [err]
|
||||
(log/error "Couldn't supress biometry NOT_ENROLLED error"
|
||||
{:key-uid key-uid
|
||||
:event :biometric/supress-not-enrolled-error
|
||||
:error err})))))))
|
||||
|
||||
;; NOTE: when biometrics is re-enrolled, we erase the flag in async-storage to assure
|
||||
;; the "NOT_ENROLLED" error message will be shown again if biometrics is un-enrolled
|
||||
;; in the future.
|
||||
(re-frame/reg-fx
|
||||
:biometric/reset-not-enrolled-error
|
||||
(fn [key-uid]
|
||||
(let [storage-key (supress-biometry-error-key key-uid)]
|
||||
(-> (async-storage/get-item storage-key identity)
|
||||
(.then (fn [supress?]
|
||||
(when supress?
|
||||
(async-storage/set-item! storage-key nil))))
|
||||
(.catch (fn [err]
|
||||
(log/error "Couldn't reset supressing biometry NOT_ENROLLED error"
|
||||
{:key-uid key-uid
|
||||
:event :biometric/reset-not-enrolled-error
|
||||
:error err})))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:biometric/authenticate
|
||||
(fn [options]
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
(ns status-im2.common.bottom-sheet.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn handle
|
||||
[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
|
||||
:align-self :center
|
||||
:margin-vertical 8})
|
||||
|
||||
(defn sheet
|
||||
[{:keys [top]} window-height selected-item]
|
||||
{:position :absolute
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
item-height (reagent/atom 0)]
|
||||
(fn [{:keys [hide? insets theme]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle?]
|
||||
gradient-cover? customization-color]
|
||||
:or {border-radius 12}}]
|
||||
(let [{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
@@ -117,13 +117,12 @@
|
||||
[rn/view
|
||||
{:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin)
|
||||
:on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))}
|
||||
(when (and gradient-cover? customization-color)
|
||||
(when gradient-cover?
|
||||
[rn/view {:style style/gradient-bg}
|
||||
[quo/gradient-cover
|
||||
{:customization-color customization-color
|
||||
:opacity 0.4}]])
|
||||
(when-not hide-handle?
|
||||
[quo/drawer-bar])
|
||||
[rn/view {:style (style/handle theme)}]
|
||||
[content]]]]]))))
|
||||
|
||||
(defn- internal-view
|
||||
|
||||
@@ -49,15 +49,16 @@
|
||||
|
||||
(defn save-auth-method!
|
||||
[key-uid method]
|
||||
(-> (keychain/save-credentials
|
||||
(str key-uid "-auth")
|
||||
key-uid
|
||||
method)
|
||||
(.catch (fn [err]
|
||||
(log/error "Failed to save auth method in the keychain"
|
||||
{:error err
|
||||
:key-uid key-uid
|
||||
:auth-method method})))))
|
||||
(keychain/save-credentials
|
||||
(str key-uid "-auth")
|
||||
key-uid
|
||||
method
|
||||
#(when-not %
|
||||
(log/error
|
||||
(str "Error while saving auth method."
|
||||
" "
|
||||
"The app will continue to work normally, "
|
||||
"but you will have to login again next time you launch it.")))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/save-auth-method
|
||||
@@ -78,59 +79,27 @@
|
||||
(if can-save?
|
||||
(keychain/get-credentials
|
||||
(str key-uid "-auth")
|
||||
(fn [value]
|
||||
(callback (if value (oops/oget value "password") auth-method-none))))
|
||||
#(callback (if % (oops/oget % "password") auth-method-none)))
|
||||
(callback nil))))))
|
||||
|
||||
(defn save-user-password!
|
||||
[key-uid password]
|
||||
(keychain/save-credentials key-uid key-uid (security/safe-unmask-data password) #()))
|
||||
|
||||
(defn get-user-password!
|
||||
[key-uid callback]
|
||||
(keychain/get-credentials key-uid
|
||||
(fn [value]
|
||||
(callback (when value
|
||||
(-> value
|
||||
(oops/oget "password")
|
||||
(security/mask-data)))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/get-user-password
|
||||
(fn [[key-uid callback]]
|
||||
(get-user-password! key-uid callback)))
|
||||
(keychain/get-credentials
|
||||
key-uid
|
||||
#(if % (callback (security/mask-data (oops/oget % "password"))) (callback nil)))))
|
||||
|
||||
(rf/defn get-user-password
|
||||
[_ key-uid callback]
|
||||
{:keychain/get-user-password [key-uid callback]})
|
||||
|
||||
(defn- password-migration-key-name
|
||||
[key-uid]
|
||||
(str key-uid "-password-migration"))
|
||||
|
||||
(defn save-password-migration!
|
||||
[key-uid]
|
||||
(-> (keychain/save-credentials
|
||||
(password-migration-key-name key-uid)
|
||||
key-uid
|
||||
;; NOTE: using the key-uid as the password, but we don't really care about the
|
||||
;; value, we only care that it's there
|
||||
key-uid)
|
||||
(.catch (fn [error]
|
||||
(log/error "Failed to get the keychain password migration flag"
|
||||
{:error error
|
||||
:key-uid key-uid})))))
|
||||
|
||||
(defn get-password-migration!
|
||||
[key-uid callback]
|
||||
(keychain/get-credentials
|
||||
(password-migration-key-name key-uid)
|
||||
(comp callback boolean)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/clear-user-password
|
||||
(fn [key-uid]
|
||||
(keychain/reset-credentials (password-migration-key-name key-uid))
|
||||
(keychain/reset-credentials key-uid)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
@@ -138,28 +107,5 @@
|
||||
(fn [{:keys [key-uid masked-password on-success on-error]}]
|
||||
(-> (save-user-password! key-uid masked-password)
|
||||
(.then #(save-auth-method! key-uid auth-method-biometric))
|
||||
(.then #(save-password-migration! key-uid))
|
||||
(.then #(when on-success (on-success)))
|
||||
(.catch #(when on-error (on-error %))))))
|
||||
|
||||
;; NOTE: migrating the plaintext password in the keychain
|
||||
;; with the hashed one. Added due to the sync onboarding
|
||||
;; flow, where the password arrives already hashed.
|
||||
(re-frame/reg-fx
|
||||
:keychain/password-hash-migration
|
||||
(fn [{:keys [key-uid callback]
|
||||
:or {callback identity}}]
|
||||
(-> (get-password-migration! key-uid identity)
|
||||
(.then (fn [migrated?]
|
||||
(if migrated?
|
||||
(callback)
|
||||
(-> (get-user-password! key-uid identity)
|
||||
(.then security/hash-masked-password)
|
||||
(.then #(save-user-password! key-uid %))
|
||||
(.then #(save-password-migration! key-uid))
|
||||
(.then callback)))))
|
||||
(.catch (fn [err]
|
||||
(log/error "Failed to migrate the keychain password"
|
||||
{:error err
|
||||
:key-uid key-uid
|
||||
:event :keychain/password-hash-migration}))))))
|
||||
|
||||
@@ -170,5 +170,3 @@
|
||||
(def default-kdf-iterations 3200)
|
||||
|
||||
(def shell-navigation-disabled? false)
|
||||
|
||||
(def community-accounts-selection-enabled? false)
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
(def regx-address #"^0x[a-fA-F0-9]{40}$")
|
||||
(def regx-address-contains #"(?i)0x[a-fA-F0-9]{40}")
|
||||
(def regx-starts-with-uuid #"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
|
||||
(def regx-full-or-partial-address #"^0x[a-fA-F0-9]{1,40}$")
|
||||
(def regx-address-fragment #"^0x[a-fA-F0-9]{1,40}$")
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
|
||||
@@ -35,29 +35,25 @@
|
||||
(let [cleared (set (get-in db [:chat/link-previews :cleared]))]
|
||||
(when (or (empty? urls)
|
||||
(not= (set urls) cleared))
|
||||
(let [cache (get-in db [:chat/link-previews :cache])
|
||||
previews (urls->previews cache urls)
|
||||
new-urls (->> previews
|
||||
(filter :loading?)
|
||||
(map :url))
|
||||
status-link-preview? #(string/includes? % "status.app")
|
||||
status-link-urls (->> urls
|
||||
(filter status-link-preview?))
|
||||
(let [cache (get-in db [:chat/link-previews :cache])
|
||||
previews (urls->previews cache urls)
|
||||
new-urls (->> previews
|
||||
(filter :loading?)
|
||||
(map :url))
|
||||
;; `request-id` is a must because we need to process only the last
|
||||
;; unfurling event, as well as avoid needlessly updating the app db
|
||||
;; if the user changes the URLs in the input text when there are
|
||||
;; in-flight RPC requests.
|
||||
request-id
|
||||
(new-request-id)]
|
||||
request-id (new-request-id)]
|
||||
(merge {:db (-> db
|
||||
(assoc-in [:chat/link-previews :unfurled] previews)
|
||||
(assoc-in [:chat/link-previews :request-id] request-id)
|
||||
(update :chat/link-previews dissoc :cleared))}
|
||||
(when (or (seq status-link-urls) (seq new-urls))
|
||||
(when (seq new-urls)
|
||||
(log/debug "Unfurling URLs" {:urls new-urls :request-id request-id})
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_unfurlURLs"
|
||||
:params [(concat new-urls status-link-urls)]
|
||||
:params [new-urls]
|
||||
:on-success #(rf/dispatch [:link-preview/unfurl-parsed-urls-success request-id %])
|
||||
:on-error #(rf/dispatch [:link-preview/unfurl-parsed-urls-error request-id
|
||||
%])}]}))))))
|
||||
@@ -86,22 +82,17 @@
|
||||
|
||||
(rf/defn unfurl-parsed-urls-success
|
||||
{:events [:link-preview/unfurl-parsed-urls-success]}
|
||||
[{:keys [db]} request-id {new-previews :linkPreviews status-link-previews :statusLinkPreviews}]
|
||||
(when (or (seq status-link-previews) (= request-id (get-in db [:chat/link-previews :request-id])))
|
||||
(let [new-previews (map data-store.messages/<-link-preview-rpc new-previews)
|
||||
status-link-previews (map data-store.messages/<-status-link-previews-rpc
|
||||
status-link-previews)
|
||||
curr-previews (get-in db [:chat/link-previews :unfurled])
|
||||
indexed-new-previews (utils.collection/index-by :url new-previews)
|
||||
indexed-status-link-previews (utils.collection/index-by :url status-link-previews)]
|
||||
[{:keys [db]} request-id {new-previews :linkPreviews}]
|
||||
(when (= request-id (get-in db [:chat/link-previews :request-id]))
|
||||
(let [new-previews (map data-store.messages/<-link-preview-rpc new-previews)
|
||||
curr-previews (get-in db [:chat/link-previews :unfurled])
|
||||
indexed-new-previews (utils.collection/index-by :url new-previews)]
|
||||
(log/debug "URLs unfurled"
|
||||
{:event :link-preview/unfurl-parsed-urls-success
|
||||
:previews (map #(update % :thumbnail dissoc :data-uri) new-previews)
|
||||
:request-id request-id})
|
||||
{:db (-> db
|
||||
(update-in [:chat/link-previews :unfurled] reconcile-unfurled indexed-new-previews)
|
||||
(assoc-in [:chat/status-link-previews :unfurled]
|
||||
status-link-previews)
|
||||
(update-in [:chat/link-previews :cache]
|
||||
merge
|
||||
indexed-new-previews
|
||||
@@ -139,12 +130,3 @@
|
||||
{:db (-> db
|
||||
(update :chat/link-previews dissoc :unfurled :request-id)
|
||||
(assoc-in [:chat/link-previews :cleared] unfurled-urls))}))
|
||||
|
||||
(rf/defn clear-status-link-previews
|
||||
{:events [:status-link-preview/clear]}
|
||||
[{:keys [db]}]
|
||||
(let [unfurled-urls (set (map :url (get-in db [:chat/status-link-previews :unfurled])))]
|
||||
{:db (-> db
|
||||
(update :chat/status-link-previews dissoc :unfurled)
|
||||
(assoc-in [:chat/status-link-previews :cleared] unfurled-urls))}))
|
||||
|
||||
|
||||
@@ -20,37 +20,26 @@
|
||||
|
||||
(defn f-view
|
||||
[]
|
||||
(let [previews (rf/sub [:chats/link-previews-unfurled])
|
||||
status-link-previews (rf/sub [:chats/status-link-previews-unfurled])
|
||||
height (use-animated-height (boolean (or (seq status-link-previews)
|
||||
(seq previews))))]
|
||||
(let [previews (rf/sub [:chats/link-previews-unfurled])
|
||||
height (use-animated-height (boolean (seq previews)))]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style {:height height} {:z-index 1})}
|
||||
[quo/url-preview-list
|
||||
{:key-fn :url
|
||||
:preview-width (- (:width (rn/get-window))
|
||||
(* 2 style/padding-horizontal))
|
||||
:container-style (when (or (seq status-link-previews) (seq previews)) style/preview-list)
|
||||
:container-style (when (seq previews) style/preview-list)
|
||||
:container-style-item {:height style/preview-height}
|
||||
:horizontal-spacing style/padding-horizontal
|
||||
:loading-message (i18n/label :t/link-preview-loading-message)
|
||||
:on-clear #(do
|
||||
(rf/dispatch [:status-link-preview/clear])
|
||||
(rf/dispatch [:link-preview/clear]))
|
||||
:data (map (fn [{:keys [title thumbnail hostname loading? url community]}]
|
||||
(if (seq community)
|
||||
(let [{:keys [display-name banner]} community]
|
||||
{:title display-name
|
||||
:body "status.app"
|
||||
:loading? loading?
|
||||
:thumbnail (:data-uri banner)
|
||||
:url url})
|
||||
{:title title
|
||||
:body hostname
|
||||
:loading? loading?
|
||||
:thumbnail (:data-uri thumbnail)
|
||||
:url url}))
|
||||
(set (concat previews status-link-previews)))}]]))
|
||||
:on-clear #(rf/dispatch [:link-preview/clear])
|
||||
:data (map (fn [{:keys [title thumbnail hostname loading? url]}]
|
||||
{:title title
|
||||
:body hostname
|
||||
:loading? loading?
|
||||
:thumbnail (:data-uri thumbnail)
|
||||
:url url})
|
||||
previews)}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.url :as url]))
|
||||
|
||||
;; these constants are used when there is no width or height defined for a specific image
|
||||
(def ^:const fallback-image-width 1000)
|
||||
(def ^:const fallback-image-height 1000)
|
||||
|
||||
(defn calculate-dimensions
|
||||
[width height max-container-width max-container-height]
|
||||
(let [max-width (if (> width height) max-container-width (* 1.5 constants/image-size))
|
||||
@@ -19,12 +15,7 @@
|
||||
{:width (min width max-width) :height (min height max-height)}))
|
||||
|
||||
(defn image-message
|
||||
[index
|
||||
{:keys [content image-width image-height message-id]
|
||||
:as message
|
||||
:or {image-width fallback-image-width
|
||||
image-height fallback-image-height}}
|
||||
{:keys [on-long-press]}
|
||||
[index {:keys [content image-width image-height message-id] :as message} {:keys [on-long-press]}
|
||||
message-container-data]
|
||||
(let [insets (safe-area/get-insets)
|
||||
{:keys [window-width padding-left padding-right avatar-container-width
|
||||
|
||||
@@ -13,32 +13,15 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [chat-id message-id]}]
|
||||
(let [previews (rf/sub [:chats/message-link-previews chat-id message-id])
|
||||
status-link-previews (rf/sub [:chats/message-status-link-previews chat-id message-id])]
|
||||
(when (or (seq status-link-previews)
|
||||
(seq previews))
|
||||
(let [previews (rf/sub [:chats/message-link-previews chat-id message-id])]
|
||||
(when (seq previews)
|
||||
[:<>
|
||||
(for [{:keys [url title description thumbnail hostname community]}
|
||||
(concat status-link-previews previews)]
|
||||
(for [{:keys [url title description thumbnail hostname]} previews]
|
||||
^{:key url}
|
||||
(if community
|
||||
(let [{community-description :description
|
||||
community-icon :icon
|
||||
community-banner :banner
|
||||
community-name :display-name
|
||||
members-count :members-count} community]
|
||||
[quo/status-link-preview-community
|
||||
{:description community-description
|
||||
:members-count members-count
|
||||
:title community-name
|
||||
:banner (:url community-banner)
|
||||
:icon (:url community-icon)
|
||||
:link url
|
||||
:on-press #(rf/dispatch [:universal-links/handle-url url])}])
|
||||
[quo/link-preview
|
||||
{:title title
|
||||
:description description
|
||||
:link hostname
|
||||
:thumbnail (:url thumbnail)
|
||||
:thumbnail-size (when (nearly-square? thumbnail) :large)
|
||||
:container-style {:margin-top 8}}]))])))
|
||||
[quo/link-preview
|
||||
{:title title
|
||||
:description description
|
||||
:link hostname
|
||||
:thumbnail (:url thumbnail)
|
||||
:thumbnail-size (when (nearly-square? thumbnail) :large)
|
||||
:container-style {:margin-top 8}}])])))
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
(ns status-im2.contexts.communities.actions.accounts-selection.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im2.common.password-authentication.view :as password-authentication]
|
||||
[status-im2.contexts.communities.actions.request-to-join.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn join-community-and-navigate-back
|
||||
[id]
|
||||
(rf/dispatch [:password-authentication/show
|
||||
{:content (fn [] [password-authentication/view])}
|
||||
{:label (i18n/label :t/join-open-community)
|
||||
:on-press #(rf/dispatch [:communities/request-to-join
|
||||
{:community-id id :password %}])}])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(fn []
|
||||
(let [{:keys [_name
|
||||
id
|
||||
_images]} (rf/sub [:get-screen-params])]
|
||||
[rn/view {:flex 1}
|
||||
[gesture/scroll-view {:style {:flex 1}}
|
||||
[rn/view style/page-container
|
||||
[rn/view {:style (style/bottom-container)}
|
||||
[quo/button
|
||||
{:accessibility-label :cancel
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:type :grey
|
||||
:container-style style/cancel-button}
|
||||
(i18n/label :t/cancel)]
|
||||
[quo/button
|
||||
{:accessibility-label :join-community-button
|
||||
:on-press #(join-community-and-navigate-back id)
|
||||
:container-style {:flex 1}}
|
||||
(i18n/label :t/request-to-join)]]]]])))
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im2.contexts.communities.overview.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]))
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def screen-horizontal-padding 20)
|
||||
|
||||
@@ -42,16 +41,6 @@
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(def floating-shell-button
|
||||
{:position :absolute
|
||||
:bottom 21})
|
||||
|
||||
(defn channel-list-component
|
||||
[]
|
||||
{:margin-top 8
|
||||
:margin-bottom (+ 21 jump-to.constants/floating-shell-button-height)
|
||||
:flex 1})
|
||||
|
||||
(defn token-gated-container
|
||||
[]
|
||||
{:border-radius 16
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[status-im2.common.password-authentication.view :as password-authentication]
|
||||
[status-im2.common.scroll-page.style :as scroll-page.style]
|
||||
[status-im2.common.scroll-page.view :as scroll-page]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im2.contexts.communities.actions.community-options.view :as options]
|
||||
@@ -83,7 +82,7 @@
|
||||
{:on-layout #(on-first-channel-height-changed
|
||||
(+ 38 (int (Math/ceil (layout-y %))))
|
||||
(into #{} (map (comp :name second) channels-list)))
|
||||
:style (style/channel-list-component)}
|
||||
:style {:margin-top 8 :flex 1}}
|
||||
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
|
||||
[rn/view
|
||||
{:key category-id
|
||||
@@ -92,13 +91,12 @@
|
||||
:on-layout #(on-category-layout name (int (layout-y %)))}
|
||||
(when-not (= constants/empty-category-id category-id)
|
||||
[quo/divider-label
|
||||
{:on-press #(collapse-category community-id category-id collapsed?)
|
||||
:chevron-icon (if collapsed? :i/chevron-right :i/chevron-down)
|
||||
:container-style {:margin-top 8}
|
||||
:chevron :left}
|
||||
{:on-press #(collapse-category community-id category-id collapsed?)
|
||||
:chevron-icon (if collapsed? :i/chevron-right :i/chevron-down)
|
||||
:chevron :left}
|
||||
name])
|
||||
(when-not collapsed?
|
||||
[rn/view {:style {:padding-horizontal 8}}
|
||||
[rn/view {:style {:padding-horizontal 8 :padding-bottom 8}}
|
||||
(for [chat chats]
|
||||
^{:key (:id chat)}
|
||||
[channel-chat-item community-id community-color chat])])])])
|
||||
@@ -183,14 +181,10 @@
|
||||
(if (seq token-permissions)
|
||||
[token-gates community]
|
||||
[quo/button
|
||||
{:on-press
|
||||
(if config/community-accounts-selection-enabled?
|
||||
#(rf/dispatch [:open-modal :community-account-selection community])
|
||||
#(rf/dispatch [:open-modal :community-requests-to-join community]))
|
||||
|
||||
{:on-press #(rf/dispatch [:open-modal :community-requests-to-join community])
|
||||
:accessibility-label :show-request-to-join-screen-button
|
||||
:customization-color color
|
||||
:icon-left :i/communities}
|
||||
:icon-left :i/communities}
|
||||
(i18n/label :t/request-to-join-community)]))
|
||||
|
||||
(when (not (or joined pending? token-permissions))
|
||||
@@ -366,11 +360,9 @@
|
||||
|
||||
(defn community-card-page-view
|
||||
[id]
|
||||
(let [{:keys [id joined]
|
||||
(let [{:keys [id]
|
||||
:as community} (rf/sub [:communities/community id])
|
||||
pending? (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
(when joined
|
||||
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
|
||||
[community-scroll-page community pending?]))
|
||||
|
||||
(defn overview
|
||||
@@ -383,4 +375,5 @@
|
||||
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
style/floating-shell-button]]))
|
||||
{:position :absolute
|
||||
:bottom 34}]]))
|
||||
|
||||
@@ -151,34 +151,6 @@
|
||||
(reset! filtered-data nil)
|
||||
(reset! search-text ""))
|
||||
|
||||
(defn f-view
|
||||
[{:keys [render-emojis? search-text on-change-text clear-states active-category scroll-ref theme]
|
||||
:as sheet-opts}]
|
||||
(let [search-active? (pos? (count @search-text))]
|
||||
;; rendering emojis is heavy on the UI thread, we need to delay rendering until the navigation
|
||||
;; animation completes. 250 is based on the default 300ms navigation duration.
|
||||
(rn/use-effect #(js/setTimeout (fn [] (reset! render-emojis? true)) 250))
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:value @search-text
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
(when @render-emojis?
|
||||
[render-list sheet-opts])
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]]))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [{:keys [on-select]} (rf/sub [:get-screen-params])
|
||||
@@ -186,7 +158,6 @@
|
||||
set-scroll-ref #(reset! scroll-ref %)
|
||||
search-text (reagent/atom "")
|
||||
filtered-data (reagent/atom nil)
|
||||
render-emojis? (reagent/atom false)
|
||||
active-category (reagent/atom constants/default-category)
|
||||
clear-states #(clear {:active-category active-category
|
||||
:filtered-data filtered-data
|
||||
@@ -208,19 +179,31 @@
|
||||
{:event event
|
||||
:active-category active-category
|
||||
:should-update-active-category? (nil? @filtered-data)}))]
|
||||
(fn [sheet-opts]
|
||||
[:f> f-view
|
||||
(merge sheet-opts
|
||||
{:render-emojis? render-emojis?
|
||||
:search-text search-text
|
||||
:on-change-text on-change-text
|
||||
:clear-states clear-states
|
||||
:filtered-data @filtered-data
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:on-select on-select
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref})])))
|
||||
(fn [{:keys [theme] :as sheet-opts}]
|
||||
(let [search-active? (pos? (count @search-text))]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:value @search-text
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
[render-list
|
||||
(merge {:filtered-data @filtered-data
|
||||
:set-scroll-ref set-scroll-ref
|
||||
:on-select on-select
|
||||
:on-viewable-items-changed on-viewable-items-changed}
|
||||
sheet-opts)]
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im2.contexts.onboarding.enable-biometrics.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.common.biometric.events :as biometric]
|
||||
@@ -11,7 +12,8 @@
|
||||
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
|
||||
[status-im2.navigation.state :as state]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
|
||||
(defn page-title
|
||||
@@ -24,7 +26,7 @@
|
||||
:description-accessibility-label :enable-biometrics-sub-title}])
|
||||
|
||||
(defn enable-biometrics-buttons
|
||||
[insets]
|
||||
[insets theme]
|
||||
(let [supported-biometric-type (rf/sub [:biometric/supported-type])
|
||||
bio-type-label (biometric/get-label-by-type supported-biometric-type)
|
||||
profile-color (or (:color (rf/sub [:onboarding-2/profile]))
|
||||
@@ -32,12 +34,23 @@
|
||||
syncing-results? (= :syncing-results @state/root-id)]
|
||||
[rn/view {:style (style/buttons insets)}
|
||||
[standard-auth/button
|
||||
{:size 40
|
||||
:accessibility-label :enable-biometrics-button
|
||||
:icon-left :i/face-id
|
||||
:customization-color profile-color
|
||||
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
|
||||
:button-label (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})}]
|
||||
(merge
|
||||
{:size 40
|
||||
:accessibility-label :enable-biometrics-button
|
||||
:icon-left :i/face-id
|
||||
:customization-color profile-color
|
||||
:button-label (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})}
|
||||
(if syncing-results?
|
||||
{:theme theme
|
||||
:blur? true
|
||||
:on-enter-password (fn [entered-password]
|
||||
(rf/dispatch
|
||||
[:onboarding-2/authenticate-enable-biometrics
|
||||
(security/safe-unmask-data
|
||||
entered-password)])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:auth-button-label (i18n/label :t/confirm)}
|
||||
{:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])}))]
|
||||
[quo/button
|
||||
{:accessibility-label :maybe-later-button
|
||||
:background :blur
|
||||
@@ -65,16 +78,18 @@
|
||||
:source (resources/get-image :biometrics)}]))
|
||||
|
||||
(defn f-enable-biometrics
|
||||
[]
|
||||
[{:keys [theme]}]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[page-title]
|
||||
(if whitelist/whitelisted?
|
||||
[enable-biometrics-parallax]
|
||||
[enable-biometrics-simple])
|
||||
[enable-biometrics-buttons insets]]))
|
||||
[enable-biometrics-buttons insets theme]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[:f> f-enable-biometrics])
|
||||
|
||||
(defn- internale-enable-biometrics
|
||||
[params]
|
||||
[:f> f-enable-biometrics params])
|
||||
|
||||
(def view (quo.theme/with-theme internale-enable-biometrics))
|
||||
|
||||
@@ -35,6 +35,15 @@
|
||||
{:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
|
||||
(rf/defn authenticate-enable-biometrics
|
||||
{:events [:onboarding-2/authenticate-enable-biometrics]}
|
||||
[{:keys [db]} password]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding-2/profile :password] password)
|
||||
(assoc-in [:onboarding-2/profile :syncing?] true))
|
||||
:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
|
||||
(rf/defn navigate-to-enable-notifications
|
||||
{:events [:onboarding-2/navigate-to-enable-notifications]}
|
||||
[{:keys [db]}]
|
||||
@@ -145,9 +154,7 @@
|
||||
biometric-enabled?
|
||||
(assoc :keychain/save-password-and-auth-method
|
||||
{:key-uid key-uid
|
||||
:masked-password (if syncing?
|
||||
masked-password
|
||||
(security/hash-masked-password masked-password))
|
||||
:masked-password masked-password
|
||||
:on-success (fn []
|
||||
(if syncing?
|
||||
(rf/dispatch [:onboarding-2/navigate-to-enable-notifications])
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
(defn login
|
||||
[]
|
||||
{;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is resolved
|
||||
{;; Temporary fix until https://github.com/status-im/status-go/issues/3024 is
|
||||
;; resolved
|
||||
:wakuV2Nameserver "8.8.8.8"
|
||||
:openseaAPIKey config/opensea-api-key
|
||||
:poktToken config/POKT_TOKEN
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
[status-im.group-chats.core :as group-chats]
|
||||
[status-im.mobile-sync-settings.core :as mobile-network]
|
||||
[status-im.transport.core :as transport]
|
||||
[status-im2.common.biometric.events :as biometric]
|
||||
[status-im2.common.keychain.events :as keychain]
|
||||
[status-im2.common.log :as logging]
|
||||
[status-im2.config :as config]
|
||||
@@ -41,22 +42,11 @@
|
||||
{:db (assoc-in db [:profile/login :processing] true)
|
||||
::login [key-uid (native-module/sha3 (security/safe-unmask-data password))]}))
|
||||
|
||||
(rf/defn biometrics-login
|
||||
{:events [:profile.login/biometrics-login]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (:profile/login db)]
|
||||
{:db (assoc-in db [:profile/login :processing] true)
|
||||
::login [key-uid (security/safe-unmask-data password)]}))
|
||||
|
||||
(rf/defn login-local-paired-user
|
||||
{:events [:profile.login/local-paired-user]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])
|
||||
masked-password (security/mask-data password)]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding-2/profile :password] masked-password)
|
||||
(assoc-in [:onboarding-2/profile :syncing?] true))
|
||||
::login [key-uid password]}))
|
||||
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])]
|
||||
{::login [key-uid password]}))
|
||||
|
||||
(rf/defn redirect-to-root
|
||||
[{:keys [db] :as cofx}]
|
||||
@@ -161,16 +151,20 @@
|
||||
|
||||
(rf/defn get-auth-method-success
|
||||
{:events [:profile.login/get-auth-method-success]}
|
||||
[{:keys [db]} auth-method key-uid]
|
||||
[{:keys [db]} auth-method]
|
||||
(merge {:db (assoc db :auth-method auth-method)}
|
||||
(when (= auth-method keychain/auth-method-biometric)
|
||||
{:keychain/password-hash-migration
|
||||
{:key-uid key-uid
|
||||
:callback (fn []
|
||||
(rf/dispatch [:biometric/authenticate
|
||||
{:on-success #(rf/dispatch [:profile.login/biometric-success])
|
||||
:on-fail #(rf/dispatch
|
||||
[:profile.login/biometric-auth-fail %])}]))}})))
|
||||
{:biometric/authenticate
|
||||
{:on-success #(rf/dispatch [:profile.login/biometric-success])
|
||||
:on-faile #(rf/dispatch [:profile.login/biometric-auth-fail])}})))
|
||||
|
||||
(rf/defn biometric-auth-success
|
||||
{:events [:profile.login/biometric-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
(keychain/get-user-password cofx
|
||||
key-uid
|
||||
#(rf/dispatch [:profile.login/get-user-password-success %]))))
|
||||
|
||||
;; result of :keychain/get-auth-method above
|
||||
(rf/defn get-user-password-success
|
||||
@@ -181,29 +175,14 @@
|
||||
cofx
|
||||
{:db (assoc-in db [:profile/login :password] password)}
|
||||
(navigation/init-root :progress)
|
||||
(biometrics-login))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/biometric-success
|
||||
(fn [{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
{:db db
|
||||
:fx [[:biometric/reset-not-enrolled-error key-uid]
|
||||
[:keychain/get-user-password
|
||||
[key-uid #(rf/dispatch [:profile.login/get-user-password-success %])]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile.login/biometric-auth-fail
|
||||
(fn [{:keys [db]} [code]]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
{:db db
|
||||
:fx [[:dispatch [:init-root :profiles]]
|
||||
(if (= code "NOT_ENROLLED")
|
||||
[:biometric/supress-not-enrolled-error
|
||||
[key-uid
|
||||
[:biometric/show-message code]]]
|
||||
[:dispatch [:biometric/show-message code]])]})))
|
||||
(login))))
|
||||
|
||||
(rf/defn biometric-auth-fail
|
||||
{:events [:profile.login/biometric-auth-fail]}
|
||||
[{:keys [db] :as cofx} code]
|
||||
(rf/merge cofx
|
||||
(navigation/init-root :profiles)
|
||||
(biometric/show-message code)))
|
||||
|
||||
(rf/defn verify-database-password
|
||||
{:events [:profile.login/verify-database-password]}
|
||||
@@ -218,7 +197,7 @@
|
||||
|
||||
(rf/defn verify-database-password-success
|
||||
{:events [:profile.login/verified-database-password]}
|
||||
[{:keys [db]} valid? callback]
|
||||
[{:keys [db] :as cofx} valid? callback]
|
||||
(if valid?
|
||||
(do
|
||||
(when (fn? callback)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.header.avatar
|
||||
(:require [quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im2.contexts.profile.settings.header.style :as style]))
|
||||
|
||||
(def scroll-animation-input-range [0 50])
|
||||
(def header-extrapolation-option
|
||||
{:extrapolateLeft "clamp"
|
||||
:extrapolateRight "clamp"})
|
||||
|
||||
(defn f-avatar
|
||||
[{:keys [scroll-y full-name online? profile-picture customization-color]}]
|
||||
(let [image-scale-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[1 0.5]
|
||||
header-extrapolation-option)
|
||||
image-top-margin-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[0 20]
|
||||
header-extrapolation-option)
|
||||
image-side-margin-animation (reanimated/interpolate scroll-y
|
||||
scroll-animation-input-range
|
||||
[0 -20]
|
||||
header-extrapolation-option)
|
||||
theme (quo.theme/get-theme)]
|
||||
[reanimated/view
|
||||
{:style (style/avatar-container theme
|
||||
image-scale-animation
|
||||
image-top-margin-animation
|
||||
image-side-margin-animation)}
|
||||
[quo/user-avatar
|
||||
{:full-name full-name
|
||||
:online? online?
|
||||
:profile-picture profile-picture
|
||||
:status-indicator? true
|
||||
:ring? true
|
||||
:customization-color customization-color
|
||||
:size :big}]]))
|
||||
|
||||
(defn view
|
||||
[props]
|
||||
[:f> f-avatar props])
|
||||
@@ -1,36 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.header.header-shape
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.svg :as svg]
|
||||
[status-im2.contexts.profile.settings.header.style :as style]))
|
||||
|
||||
(defn left-radius
|
||||
[background-color]
|
||||
[svg/svg {:width "20" :height "20" :viewBox "0 0 20 20" :fill "none"}
|
||||
[svg/path
|
||||
{:d "M20 0C7 2 0 10 0 20V0H15Z"
|
||||
:fill background-color}]])
|
||||
|
||||
(defn right-radius
|
||||
[background-color]
|
||||
[svg/svg {:width "20" :height "21" :viewBox "0 0 20 21" :fill "none"}
|
||||
[svg/path
|
||||
{:d "M20 20V0H0C11 0 20 9 20 20Z"
|
||||
:fill background-color}]])
|
||||
|
||||
(defn f-view
|
||||
[{:keys [scroll-y customization-color theme]}]
|
||||
(let [background-color (colors/resolve-color customization-color theme 40)
|
||||
opacity-animation (reanimated/interpolate scroll-y
|
||||
[0 45 50]
|
||||
[1 1 0])]
|
||||
[:<>
|
||||
[rn/view {:style (style/header-middle-shape background-color)}]
|
||||
[reanimated/view {:style (style/radius-container opacity-animation)}
|
||||
[left-radius background-color]
|
||||
[right-radius background-color]]]))
|
||||
|
||||
(defn view
|
||||
[props]
|
||||
[:f> f-view props])
|
||||
@@ -1,48 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.header.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(defn header-view
|
||||
[customization-color theme]
|
||||
{:background-color (colors/resolve-color customization-color theme 40)
|
||||
:min-height 100
|
||||
:flex 1})
|
||||
|
||||
(def avatar-row-wrapper
|
||||
{:display :flex
|
||||
:padding-left 16
|
||||
:padding-right 12
|
||||
:margin-top -60
|
||||
:margin-bottom -4
|
||||
:align-items :flex-end
|
||||
:justify-content :space-between
|
||||
:flex-direction :row})
|
||||
|
||||
(def title-container
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(defn header-middle-shape
|
||||
[background-color]
|
||||
{:background-color background-color
|
||||
:height 48
|
||||
:flex-grow 1})
|
||||
|
||||
(defn radius-container
|
||||
[opacity-animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:opacity opacity-animation}
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between}))
|
||||
|
||||
(defn avatar-container
|
||||
[theme scale-animation top-margin-animation side-margin-animation]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:scale scale-animation}]
|
||||
:margin-top top-margin-animation
|
||||
:margin-left side-margin-animation
|
||||
:margin-bottom side-margin-animation}
|
||||
{:align-items :flex-start
|
||||
:border-width 4
|
||||
:border-color (colors/theme-colors colors/border-avatar-light colors/neutral-80-opa-80 theme)
|
||||
:border-radius 100}))
|
||||
@@ -1,49 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.header.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.contexts.profile.settings.header.avatar :as header.avatar]
|
||||
[status-im2.contexts.profile.settings.header.header-shape :as header.shape]
|
||||
[status-im2.contexts.profile.settings.header.style :as style]
|
||||
[status-im2.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- f-view
|
||||
[{:keys [theme scroll-y]}]
|
||||
(let [{:keys [public-key emoji-hash] :as profile} (rf/sub [:profile/profile-with-image])
|
||||
online? (rf/sub [:visibility-status-updates/online?
|
||||
public-key])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
emoji-string (string/join emoji-hash)]
|
||||
[:<>
|
||||
[header.shape/view
|
||||
{:scroll-y scroll-y
|
||||
:customization-color customization-color
|
||||
:theme theme}]
|
||||
[rn/view {:style style/avatar-row-wrapper}
|
||||
[header.avatar/view
|
||||
{:scroll-y scroll-y
|
||||
:display-name full-name
|
||||
:online? online?
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture}]
|
||||
[rn/view {:style {:margin-bottom 4}}
|
||||
[quo/dropdown
|
||||
{:background :blur
|
||||
:size :size-32
|
||||
:type :outline
|
||||
:icon? true
|
||||
:icon-name :i/online
|
||||
:on-press not-implemented/alert}
|
||||
(i18n/label :t/online)]]]
|
||||
[quo/text-combinations
|
||||
{:container-style style/title-container
|
||||
:emoji-hash emoji-string
|
||||
:title full-name}]]))
|
||||
|
||||
(def view (quo.theme/with-theme f-view))
|
||||
@@ -1,83 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.list-items
|
||||
(:require [status-im2.common.not-implemented :as not-implemented]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def items
|
||||
[[{:title (i18n/label :t/edit-profile)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/edit
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/password)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/password
|
||||
:image :icon
|
||||
:action :arrow}]
|
||||
[{:title (i18n/label :t/messages)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/messages
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/wallet)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/wallet
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/dapps)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/placeholder
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title "Browser"
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/browser
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/keycard)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/keycard
|
||||
:image :icon
|
||||
:action :arrow}]
|
||||
[{:title (i18n/label :t/syncing)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/syncing
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/notifications)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/notifications
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/appearance)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/light
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/language-and-currency)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/globe
|
||||
:image :icon
|
||||
:action :arrow}]
|
||||
[{:title (i18n/label :t/data-usage)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/mobile
|
||||
:image :icon
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/advanced)
|
||||
:on-press not-implemented/alert
|
||||
:image-props :i/settings
|
||||
:image :icon
|
||||
:action :arrow}]
|
||||
;; temporary link to legacy settings
|
||||
[{:title "Legacy settings"
|
||||
:on-press #(rf/dispatch [:navigate-to :my-profile])
|
||||
:action :arrow
|
||||
:image :icon
|
||||
:image-props :i/toggle}]
|
||||
[{:title (i18n/label :t/about)
|
||||
:on-press not-implemented/alert
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/status-help)
|
||||
:on-press not-implemented/alert
|
||||
:action :arrow}]])
|
||||
@@ -1,11 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(defn navigation-wrapper
|
||||
[{:keys [customization-color inset theme]}]
|
||||
{:padding-top inset
|
||||
:background-color (colors/resolve-color customization-color theme 40)})
|
||||
|
||||
(def footer-container
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
@@ -1,71 +0,0 @@
|
||||
(ns status-im2.contexts.profile.settings.view
|
||||
(:require [oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.contexts.profile.settings.header.view :as settings.header]
|
||||
[status-im2.contexts.profile.settings.list-items :as settings.items]
|
||||
[status-im2.contexts.profile.settings.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- settings-item-view
|
||||
[data]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? true
|
||||
:data data}])
|
||||
|
||||
(defn scroll-handler
|
||||
[event scroll-y]
|
||||
(let [current-y (oops/oget event "nativeEvent.contentOffset.y")]
|
||||
(reanimated/set-shared-value scroll-y current-y)))
|
||||
|
||||
(defn- footer
|
||||
[logout-press]
|
||||
[rn/view {:style style/footer-container}
|
||||
[quo/button
|
||||
{:on-press logout-press
|
||||
:type :danger
|
||||
:icon-left :i/log-out}
|
||||
(i18n/label :t/logout)]])
|
||||
|
||||
(defn- settings-view
|
||||
[theme]
|
||||
(let [insets (safe-area/get-insets)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
scroll-y (reanimated/use-shared-value 0)
|
||||
logout-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])]
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view
|
||||
{:style (style/navigation-wrapper {:customization-color customization-color
|
||||
:inset (:top insets)
|
||||
:theme theme})}
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/multi-profile :on-press #(rf/dispatch [:open-modal :sign-in])}
|
||||
{:icon-name :i/qr-code :on-press not-implemented/alert}
|
||||
{:icon-name :i/share
|
||||
:on-press #(debounce/dispatch-and-chill [:open-modal :share-shell] 1000)}]}]]
|
||||
[rn/flat-list
|
||||
{:header [settings.header/view {:scroll-y scroll-y}]
|
||||
:data settings.items/items
|
||||
:key-fn :title
|
||||
:shows-vertical-scroll-indicator false
|
||||
:render-fn settings-item-view
|
||||
:footer [footer logout-press]
|
||||
:scroll-event-throttle 16
|
||||
:on-scroll #(scroll-handler % scroll-y)
|
||||
:bounces false}]]))
|
||||
|
||||
(defn- internal-view
|
||||
[props]
|
||||
[:f> settings-view props])
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
@@ -1,47 +0,0 @@
|
||||
(ns status-im2.contexts.quo-preview.dropdowns.dropdown-input
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :state
|
||||
:type :select
|
||||
:options [{:key :default}
|
||||
{:key :active}
|
||||
{:key :disabled}]}
|
||||
{:key :icon?
|
||||
:type :boolean}
|
||||
{:key :label?
|
||||
:type :boolean}
|
||||
{:key :blur?
|
||||
:type :boolean}
|
||||
{:key :header-label
|
||||
:type :text}
|
||||
{:key :label
|
||||
:type :text}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:state :default
|
||||
:label "Dropdown"
|
||||
:header-label "Label"
|
||||
:icon? true
|
||||
:label? true
|
||||
:blur? false})
|
||||
label (reagent/cursor state [:label])
|
||||
blur? (reagent/cursor state [:blur?])]
|
||||
[:f>
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:component-container-style (when-not @blur?
|
||||
{:align-items :center
|
||||
:margin-horizontal 30})
|
||||
:blur-container-style {:align-items :center}
|
||||
:blur? @blur?
|
||||
:show-blur-background? true}
|
||||
[quo/dropdown-input
|
||||
(assoc @state :on-press #(js/alert "Pressed dropdown"))
|
||||
@label]])]))
|
||||
@@ -1,9 +0,0 @@
|
||||
(ns status-im2.contexts.quo-preview.ios.drawer-bar
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[preview/preview-container {}
|
||||
[quo/drawer-bar]])
|
||||
@@ -9,10 +9,8 @@
|
||||
:type :select
|
||||
:options [{:key :default} {:key :balance-positive} {:key :balance-neutral} {:key :balance-negative}
|
||||
{:key :tag} {:key :action}]}
|
||||
{:key :selectable? :type :boolean}
|
||||
{:key :title-icon? :type :boolean}
|
||||
{:key :state
|
||||
:type :select
|
||||
:options [{:key :active} {:key :selected}]}
|
||||
{:key :emoji
|
||||
:type :text}
|
||||
(preview/customization-color-option {:key :account-color})
|
||||
@@ -22,8 +20,8 @@
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:type :default
|
||||
:selectable? false
|
||||
:title-icon? false
|
||||
:state :default
|
||||
:customization-color :blue
|
||||
:account-color :purple
|
||||
:emoji "🍑"
|
||||
|
||||
@@ -58,8 +58,6 @@
|
||||
[status-im2.contexts.quo-preview.drawers.permission-drawers :as
|
||||
permission-drawers]
|
||||
[status-im2.contexts.quo-preview.dropdowns.dropdown :as dropdown]
|
||||
[status-im2.contexts.quo-preview.dropdowns.dropdown-input :as
|
||||
dropdown-input]
|
||||
[status-im2.contexts.quo-preview.dropdowns.network-dropdown :as
|
||||
network-dropdown]
|
||||
[status-im2.contexts.quo-preview.empty-state.empty-state :as empty-state]
|
||||
@@ -78,7 +76,6 @@
|
||||
recovery-phrase-input]
|
||||
[status-im2.contexts.quo-preview.inputs.search-input :as search-input]
|
||||
[status-im2.contexts.quo-preview.inputs.title-input :as title-input]
|
||||
[status-im2.contexts.quo-preview.ios.drawer-bar :as drawer-bar]
|
||||
[status-im2.contexts.quo-preview.keycard.keycard :as keycard]
|
||||
[status-im2.contexts.quo-preview.links.link-preview :as link-preview]
|
||||
[status-im2.contexts.quo-preview.links.url-preview :as url-preview]
|
||||
@@ -145,7 +142,6 @@
|
||||
[status-im2.contexts.quo-preview.settings.settings-item :as settings-item]
|
||||
[status-im2.contexts.quo-preview.share.qr-code :as qr-code]
|
||||
[status-im2.contexts.quo-preview.share.share-qr-code :as share-qr-code]
|
||||
[status-im2.contexts.quo-preview.status-link-preview.community :as status-preview-community]
|
||||
[status-im2.contexts.quo-preview.style :as style]
|
||||
[status-im2.contexts.quo-preview.switcher.group-messaging-card :as group-messaging-card]
|
||||
[status-im2.contexts.quo-preview.switcher.switcher-cards :as switcher-cards]
|
||||
@@ -162,11 +158,8 @@
|
||||
[status-im2.contexts.quo-preview.tags.tags :as tags]
|
||||
[status-im2.contexts.quo-preview.tags.tiny-tag :as tiny-tag]
|
||||
[status-im2.contexts.quo-preview.tags.token-tag :as token-tag]
|
||||
[status-im2.contexts.quo-preview.text-combinations.channel-name :as
|
||||
channel-name]
|
||||
[status-im2.contexts.quo-preview.text-combinations.preview :as
|
||||
text-combinations]
|
||||
[status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title]
|
||||
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]
|
||||
[status-im2.contexts.quo-preview.wallet.account-origin :as account-origin]
|
||||
[status-im2.contexts.quo-preview.wallet.account-overview :as
|
||||
@@ -280,9 +273,7 @@
|
||||
:dropdowns [{:name :dropdown
|
||||
:component dropdown/view}
|
||||
{:name :network-dropdown
|
||||
:component network-dropdown/view}
|
||||
{:name :dropdown-input
|
||||
:component dropdown-input/view}]
|
||||
:component network-dropdown/view}]
|
||||
:empty-state [{:name :empty-state
|
||||
:component empty-state/view}]
|
||||
:gradient [{:name :gradient-cover
|
||||
@@ -311,8 +302,6 @@
|
||||
:component search-input/view}
|
||||
{:name :title-input
|
||||
:component title-input/view}]
|
||||
:ios [{:name :drawer-bar
|
||||
:component drawer-bar/view}]
|
||||
:numbered-keyboard [{:name :keyboard-key
|
||||
:component keyboard-key/view}
|
||||
{:name :numbered-keyboard
|
||||
@@ -325,10 +314,7 @@
|
||||
:component url-preview-list/view}
|
||||
{:name :link-preview
|
||||
:options {:insets {:top? true}}
|
||||
:component link-preview/view}
|
||||
{:name :status-preview-community
|
||||
:options {:insets {:top true}}
|
||||
:component status-preview-community/view}]
|
||||
:component link-preview/view}]
|
||||
:list-items [{:name :account
|
||||
:component account-item/view}
|
||||
{:name :account-list-card
|
||||
@@ -459,11 +445,7 @@
|
||||
{:name :token-tag
|
||||
:component token-tag/view}]
|
||||
:text-combinations [{:name :text-combinations
|
||||
:component text-combinations/view}
|
||||
{:name :channel-name
|
||||
:component channel-name/view}
|
||||
{:name :standard-title
|
||||
:component standard-title/view}]
|
||||
:component text-combinations/view}]
|
||||
:wallet [{:name :account-card :component account-card/view}
|
||||
{:name :account-origin :component account-origin/view}
|
||||
{:name :account-overview
|
||||
|
||||