Update usage for toolbars
Replace all the usage of the button without component Use quo Fix tests List item in multiaccounts Use list items in contacts Fix welcome screen button Experiment long press Big list item Remove old bottom sheet Use bottom sheet Keycard Add error to list item Stickers panel button Images panel Fix z-index in profile Fix android crash Fix signing list item Try fixing test iOs gas sheet keyboard Disable root alert in e2e keycard signing sheet height Clean up bottom sheet events Replace flat list in profile Memorise the manual-close value for bottom sheet Mailserver QR scanner Fix e2e tests E2e fix 2 Fix e2e 3 Remove extra fn Reduce bridging time for animation Trick android layout Try hooks Fix profile missing ens-name Disable press on control in list-view allow disabling animations in list item Use simple list in wallet assets settings TBD - this screen should be rewritten from scratch. Now on every interaction the full list is re-rendered, also it makes the wallet main screen to re-render. Fix send sheet Handle long press in main thread UI fixes perf Update e2e fix missing user name in image long press Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
parent
fad1bd25c0
commit
497af38a7f
1
.env
1
.env
|
@ -23,3 +23,4 @@ STATUS_GO_PROTOCOL=0
|
|||
STATUS_GO_ENABLE_NIMBUS=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
|
|
1
.env.e2e
1
.env.e2e
|
@ -23,3 +23,4 @@ TOOLTIP_EVENTS=1
|
|||
COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
|
@ -21,3 +21,4 @@ CONTRACT_NODES=1
|
|||
MOBILE_UI_FOR_DESKTOP=1
|
||||
STATUS_GO_ENABLE_NIMBUS=0
|
||||
KEYCARD_TEST_MENU=0
|
||||
ENABLE_ROOT_ALERT=1
|
|
@ -18,3 +18,4 @@ PARTITIONED_TOPIC=0
|
|||
CONTRACT_NODES=1
|
||||
MOBILE_UI_FOR_DESKTOP=1
|
||||
HARDWALLET_ENABLED=1
|
||||
ENABLE_ROOT_ALERT=1
|
|
@ -17,3 +17,4 @@ RPC_NETWORKS_ONLY=1
|
|||
PARTITIONED_TOPIC=0
|
||||
MOBILE_UI_FOR_DESKTOP=1
|
||||
HARDWALLET_ENABLED=1
|
||||
ENABLE_ROOT_ALERT=1
|
|
@ -199,7 +199,7 @@ public class MainActivity extends ReactFragmentActivity
|
|||
private static final Integer FREQUENCY_OF_REMINDER_IN_PERCENT = 5;
|
||||
|
||||
private boolean shouldShowRootedNotification() {
|
||||
if (RootUtil.isDeviceRooted()) {
|
||||
if (RootUtil.isDeviceRooted() && BuildConfig.ENABLE_ROOT_ALERT == "1") {
|
||||
if (userRejectedRootedNotification()) {
|
||||
return ((Math.random() * 100) < FREQUENCY_OF_REMINDER_IN_PERCENT);
|
||||
} else return true;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
(def react-native
|
||||
(clj->js {:NativeModules {:RNGestureHandlerModule {:Direction (fn [])}
|
||||
:ReanimatedModule {:configureProps (fn [])}}
|
||||
:ReanimatedModule {:configureProps (fn [])}}
|
||||
|
||||
:View {}
|
||||
:FlatList {}
|
||||
|
|
|
@ -174,11 +174,14 @@
|
|||
(defn loop* [opts]
|
||||
(ocall redash "loop" (clj->js opts)))
|
||||
|
||||
(defn use-value [value]
|
||||
(.useValue ^js redash value))
|
||||
(def use-value (.-useValue ^js redash))
|
||||
|
||||
(defn use-clock []
|
||||
(.useClock ^js redash))
|
||||
(def use-clock (.-useClock ^js redash))
|
||||
|
||||
(defn use-gesture [opts]
|
||||
(let [gesture (.useGestureHandler ^js redash (clj->js opts))]
|
||||
{:onHandlerStateChange (.-onHandlerStateChange ^js gesture)
|
||||
:onGestureEvent (.-onGestureEvent ^js gesture)}))
|
||||
|
||||
(defn snap-point [value velocity snap-points]
|
||||
(.snapPoint ^js redash value velocity (to-array snap-points)))
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
(ns quo.components.animated.pressable
|
||||
(:require [quo.animated :as animated]
|
||||
[quo.react :as react]
|
||||
[reagent.core :as reagent]
|
||||
[cljs-bean.core :as bean]
|
||||
[quo.gesture-handler :as gesture-handler]))
|
||||
|
||||
(def long-press-duration 500)
|
||||
|
@ -38,6 +41,12 @@
|
|||
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
|
||||
:opacity (animated/mix animation 1 opactiy)}})
|
||||
|
||||
(defmethod type->animation :scale
|
||||
[{:keys [animation]}]
|
||||
{:background {:opacity 0}
|
||||
:foreground {:transform [{:scale (animated/mix animation 1 scale-down-small)}]
|
||||
:opacity (animated/mix animation 1 opactiy)}})
|
||||
|
||||
(def absolute-fill
|
||||
{:top 0
|
||||
:bottom 0
|
||||
|
@ -45,58 +54,76 @@
|
|||
:right 0
|
||||
:position :absolute})
|
||||
|
||||
(defn pressable []
|
||||
(let [state (animated/value (:undetermined gesture-handler/states))
|
||||
active (animated/eq state (:began gesture-handler/states))
|
||||
gesture-handler (animated/on-gesture {:state state})
|
||||
duration (animated/cond* active time-in time-out)
|
||||
long-pressed (animated/value 0)
|
||||
long-duration (animated/cond* active long-press-duration 0)
|
||||
long-timing (animated/with-timing-transition active
|
||||
{:duration long-duration})
|
||||
animation (animated/with-timing-transition active
|
||||
{:duration duration
|
||||
:easing (:ease-in animated/easings)})]
|
||||
(fn [{:keys [background-color border-radius type disabled
|
||||
on-press on-long-press on-press-start
|
||||
accessibility-label]
|
||||
:or {border-radius 0
|
||||
type :primary}}
|
||||
& children]
|
||||
(let [{:keys [background foreground]}
|
||||
(type->animation {:type type
|
||||
:animation animation})
|
||||
handle-press (fn [] (when on-press (on-press)))
|
||||
handle-press-start (fn [] (when on-press-start (on-press-start)))
|
||||
handle-long-press (fn [] (when on-long-press (on-long-press)))]
|
||||
[:<>
|
||||
(when on-long-press
|
||||
[animated/code
|
||||
{:exec (animated/block
|
||||
[(animated/cond* (animated/eq long-timing 1)
|
||||
(animated/set long-pressed 1))
|
||||
(animated/cond* long-pressed
|
||||
[(animated/set long-pressed 0)
|
||||
(animated/call* [] handle-long-press)
|
||||
(animated/set state (:undetermined gesture-handler/states))])])}])
|
||||
[animated/code
|
||||
{:key (str on-press on-long-press on-press-start)
|
||||
:exec (animated/on-change state
|
||||
[(animated/cond* (animated/eq state (:began gesture-handler/states))
|
||||
(animated/call* [] handle-press-start))
|
||||
(animated/cond* (animated/and* (animated/eq state (:end gesture-handler/states))
|
||||
(animated/not* long-pressed))
|
||||
[(animated/call* [] handle-press)
|
||||
(animated/set state (:undetermined gesture-handler/states))])])}]
|
||||
[gesture-handler/tap-gesture-handler
|
||||
(merge gesture-handler
|
||||
{:shouldCancelWhenOutside true
|
||||
:enabled (not disabled)})
|
||||
[animated/view {:accessible true
|
||||
:accessibility-label accessibility-label}
|
||||
[animated/view {:style (merge absolute-fill
|
||||
background
|
||||
{:background-color background-color
|
||||
:border-radius border-radius})}]
|
||||
(into [animated/view {:style foreground}]
|
||||
children)]]]))))
|
||||
(defn pressable-hooks [props]
|
||||
(let [{background-color :bgColor
|
||||
border-radius :borderRadius
|
||||
type :type
|
||||
disabled :disabled
|
||||
on-press :onPress
|
||||
on-long-press :onLongPress
|
||||
on-press-start :onPressStart
|
||||
accessibility-label :accessibilityLabel
|
||||
children :children
|
||||
:or {border-radius 0
|
||||
type "primary"}}
|
||||
(bean/bean props)
|
||||
long-press-ref (react/create-ref)
|
||||
state (animated/use-value (:undetermined gesture-handler/states))
|
||||
active (animated/eq state (:began gesture-handler/states))
|
||||
gesture-handler (animated/use-gesture {:state state})
|
||||
animation (react/use-memo
|
||||
(fn []
|
||||
(animated/with-timing-transition active
|
||||
{:duration (animated/cond* active time-in time-out)
|
||||
:easing (:ease-in animated/easings)}))
|
||||
[])
|
||||
{:keys [background
|
||||
foreground]} (react/use-memo
|
||||
(fn []
|
||||
(type->animation {:type (keyword type)
|
||||
:animation animation}))
|
||||
[type])
|
||||
handle-press (fn [] (when on-press (on-press)))
|
||||
handle-press-start (fn [] (when on-press-start (on-press-start)))
|
||||
long-gesture-handler (fn [^js evt]
|
||||
(when (and on-long-press
|
||||
(= (-> evt .-nativeEvent .-state)
|
||||
(:active gesture-handler/states)))
|
||||
(on-long-press)
|
||||
(animated/set-value state (:undetermined gesture-handler/states))))]
|
||||
(animated/code!
|
||||
(fn []
|
||||
(when on-press-start
|
||||
(animated/cond* (animated/eq state (:began gesture-handler/states))
|
||||
(animated/call* [] handle-press-start))))
|
||||
[on-press-start])
|
||||
(animated/code!
|
||||
(fn []
|
||||
(when on-press
|
||||
(animated/cond* (animated/eq state (:end gesture-handler/states))
|
||||
[(animated/set state (:undetermined gesture-handler/states))
|
||||
(animated/call* [] handle-press)])))
|
||||
[on-press])
|
||||
(reagent/as-element
|
||||
[gesture-handler/long-press-gesture-handler
|
||||
{:enabled (boolean (and on-long-press (not disabled)))
|
||||
:on-handler-state-change long-gesture-handler
|
||||
:min-duration-ms long-press-duration
|
||||
:ref long-press-ref}
|
||||
[animated/view {:accessible true
|
||||
:accessibility-label accessibility-label}
|
||||
[gesture-handler/tap-gesture-handler
|
||||
(merge gesture-handler
|
||||
{:shouldCancelWhenOutside true
|
||||
:wait-for long-press-ref
|
||||
:enabled (boolean (and (or on-press on-long-press on-press-start)
|
||||
(not disabled)))})
|
||||
[animated/view
|
||||
[animated/view {:style (merge absolute-fill
|
||||
background
|
||||
{:background-color background-color
|
||||
:border-radius border-radius})}]
|
||||
(into [animated/view {:style foreground}]
|
||||
(react/get-children children))]]]])))
|
||||
|
||||
(def pressable (reagent/adapt-react-class (react/memo pressable-hooks)))
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
[quo.components.safe-area :as safe-area]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.platform :as platform]
|
||||
[quo.react-native :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn header-wrapper-style [{:keys [value offset]}]
|
||||
|
@ -18,7 +17,8 @@
|
|||
:outputRange [0 4]
|
||||
:extrapolate (:clamp animated/extrapolate)})})
|
||||
(when (and offset platform/ios?)
|
||||
{:shadow-opacity (animated/interpolate
|
||||
{:z-index 2
|
||||
:shadow-opacity (animated/interpolate
|
||||
value
|
||||
{:inputRange [0 offset]
|
||||
:outputRange [0 1]
|
||||
|
@ -66,8 +66,9 @@
|
|||
:title-align :left}
|
||||
(dissoc props :extended-header))]]
|
||||
(into [animated/scroll-view {:on-scroll on-scroll
|
||||
:scrollEventThrottle 1}
|
||||
[rn/view {:pointer-events :box-none}
|
||||
:style {:z-index 1}
|
||||
:scrollEventThrottle 16}
|
||||
[animated/view {:pointer-events :box-none}
|
||||
[animated/view {:pointer-events :box-none
|
||||
:on-layout on-layout}
|
||||
[extended-header {:value y
|
||||
|
|
|
@ -21,10 +21,12 @@
|
|||
;; NOTE(Ferossgp): RNGH does not work in modal react native
|
||||
(defn modal [{:keys [visible] :as props} & children]
|
||||
(if platform/android?
|
||||
(when visible (into [:<>] children))
|
||||
(into [rn/view {:style styles/container
|
||||
:pointer-events (if visible :box-none :none)}]
|
||||
children)
|
||||
(into [rn/modal props] children)))
|
||||
|
||||
(defn bottom-sheet-raw [props]
|
||||
(defn bottom-sheet-hooks [props]
|
||||
(let [{on-cancel :onCancel
|
||||
disable-drag? :disableDrag?
|
||||
show-handle? :showHandle?
|
||||
|
@ -37,86 +39,102 @@
|
|||
back-button-cancel true}}
|
||||
(bean/bean props)
|
||||
|
||||
{:keys [on-layout height]}
|
||||
(rn/use-layout)
|
||||
{window-height :height} (rn/use-window-dimensions)
|
||||
{:keys [keyboard-shown keyboard-height]}
|
||||
(rn/use-keyboard)
|
||||
safe-area (safe-area/use-safe-area)
|
||||
min-height (+ (* styles/vertical-padding 2) (:bottom safe-area))
|
||||
max-height (- window-height (:top safe-area) styles/margin-top)
|
||||
content-height (react/state 0)
|
||||
visible (react/state false)
|
||||
|
||||
on-close (fn []
|
||||
(when @visible
|
||||
(reset! visible false)
|
||||
(when on-cancel (on-cancel))))
|
||||
|
||||
master-translation-y (animated/use-value 0)
|
||||
master-velocity-y (animated/use-value (:undetermined gesture-handler/states))
|
||||
master-state (animated/use-value (:undetermined gesture-handler/states))
|
||||
tap-state (animated/use-value 0)
|
||||
manual-open (animated/use-value 0)
|
||||
manual-close (animated/value 0)
|
||||
manual-close (animated/use-value 0)
|
||||
offset (animated/use-value 0)
|
||||
clock (animated/use-clock)
|
||||
body-ref (react/create-ref)
|
||||
master-ref (react/create-ref)
|
||||
tap-gesture-handler (animated/on-gesture {:state tap-state})
|
||||
on-master-event (animated/event [{:nativeEvent
|
||||
{:translationY master-translation-y
|
||||
:state master-state
|
||||
:velocityY master-velocity-y}}])
|
||||
tap-gesture-handler (animated/use-gesture {:state tap-state})
|
||||
on-master-event (animated/use-gesture
|
||||
{:translationY master-translation-y
|
||||
:state master-state
|
||||
:velocityY master-velocity-y})
|
||||
on-body-event on-master-event
|
||||
sheet-height (min max-height @content-height)
|
||||
open-snap-point (* -1 sheet-height)
|
||||
close-snap-point 0
|
||||
close-sheet (fn []
|
||||
(animated/set-value manual-close 1))
|
||||
open-sheet (fn []
|
||||
(animated/set-value manual-open 1))
|
||||
on-snap (fn [pos]
|
||||
(when (= close-snap-point (aget pos 0))
|
||||
(on-close)))
|
||||
resistance (animated/cond* (animated/less-or-eq master-translation-y 0)
|
||||
(animated/divide master-translation-y 2)
|
||||
master-translation-y)
|
||||
translate-y (animated/with-easing
|
||||
{:value resistance
|
||||
:velocity master-velocity-y
|
||||
:offset offset
|
||||
:state master-state
|
||||
:on-snap on-snap
|
||||
:snap-points [open-snap-point close-snap-point]})
|
||||
opacity (animated/cond*
|
||||
open-snap-point
|
||||
(animated/interpolate
|
||||
translate-y
|
||||
{:inputRange [(animated/multiply open-snap-point opacity-coeff) 0]
|
||||
:outputRange [1 0]
|
||||
:extrapolate (:clamp animated/extrapolate)}))
|
||||
on-layout (fn [evt]
|
||||
(->> ^js evt
|
||||
.-nativeEvent
|
||||
.-layout
|
||||
.-height
|
||||
(+ styles/border-radius)
|
||||
(reset! content-height))
|
||||
(js/requestAnimationFrame open-sheet))]
|
||||
sheet-height (min max-height
|
||||
(+ styles/border-radius height))
|
||||
|
||||
open-snap-point (animated/use-value 0)
|
||||
close-snap-point 0
|
||||
on-close (fn []
|
||||
(when @visible
|
||||
(reset! visible false)
|
||||
(when on-cancel
|
||||
(on-cancel))))
|
||||
close-sheet (fn []
|
||||
(animated/set-value manual-close 1))
|
||||
on-snap (fn [pos]
|
||||
(when (= close-snap-point (aget pos 0))
|
||||
(on-close)))
|
||||
interrupted (animated/and* (animated/eq master-state (:began gesture-handler/states))
|
||||
(animated/clock-running clock))
|
||||
translate-y (react/use-memo
|
||||
(fn []
|
||||
(animated/with-easing
|
||||
{:value (animated/cond* (animated/less-or-eq master-translation-y 0)
|
||||
(animated/divide master-translation-y 2)
|
||||
master-translation-y)
|
||||
:velocity master-velocity-y
|
||||
:offset offset
|
||||
:state master-state
|
||||
:on-snap on-snap
|
||||
:snap-points [open-snap-point close-snap-point]}))
|
||||
[on-close])
|
||||
opacity (react/use-memo
|
||||
(fn []
|
||||
(animated/cond*
|
||||
open-snap-point
|
||||
(animated/interpolate
|
||||
translate-y
|
||||
{:inputRange [(animated/multiply open-snap-point opacity-coeff) 0]
|
||||
:outputRange [1 0]
|
||||
:extrapolate (:clamp animated/extrapolate)})))
|
||||
[])]
|
||||
(animated/code!
|
||||
(fn []
|
||||
(animated/block
|
||||
[(animated/on-change tap-state
|
||||
[(animated/cond* (animated/and* (animated/eq tap-state (:end gesture-handler/states))
|
||||
(animated/not* manual-close))
|
||||
[(animated/set manual-close 1)
|
||||
(animated/set tap-state (:undetermined gesture-handler/states))])])
|
||||
(animated/cond* manual-open
|
||||
[(animated/cond* (animated/and* interrupted manual-open)
|
||||
[(animated/set manual-open 0)
|
||||
(animated/set offset open-snap-point)
|
||||
(animated/stop-clock clock)])
|
||||
(animated/cond* (animated/and* manual-open
|
||||
(animated/not* manual-close))
|
||||
[(animated/set offset
|
||||
(animated/re-spring {:from offset
|
||||
:to open-snap-point
|
||||
:clock clock
|
||||
:config spring-config}))
|
||||
(animated/cond* (animated/not* (animated/clock-running clock))
|
||||
(animated/set manual-open 0))])
|
||||
(animated/cond* (animated/and* manual-close
|
||||
(animated/not* manual-open))
|
||||
(animated/set manual-open 0))])]))
|
||||
[])
|
||||
(animated/code!
|
||||
(fn []
|
||||
(animated/block
|
||||
[(animated/cond* (animated/and* interrupted manual-close)
|
||||
[(animated/set manual-close 0)
|
||||
(animated/set offset close-snap-point)
|
||||
(animated/call* [] on-close)
|
||||
(animated/stop-clock clock)])
|
||||
(animated/cond* (animated/eq tap-state (:end gesture-handler/states))
|
||||
[(animated/cond* (animated/and* (animated/not* manual-close))
|
||||
[(animated/stop-clock clock)
|
||||
(animated/set manual-close 1)])
|
||||
(animated/set tap-state (:undetermined gesture-handler/states))])
|
||||
(animated/cond* manual-close
|
||||
[(animated/set offset
|
||||
(animated/re-timing {:from offset
|
||||
:to close-snap-point
|
||||
|
@ -125,14 +143,24 @@
|
|||
:duration close-duration}))
|
||||
(animated/cond* (animated/not* (animated/clock-running clock))
|
||||
[(animated/set manual-close 0)
|
||||
(animated/set manual-open 0)
|
||||
(animated/call* [] on-close)])])]))
|
||||
[open-snap-point on-close])
|
||||
[on-cancel])
|
||||
(animated/code!
|
||||
(fn []
|
||||
(when (and (> height min-height)
|
||||
@visible)
|
||||
(animated/block
|
||||
[(animated/stop-clock clock)
|
||||
(animated/set open-snap-point (* -1 sheet-height))
|
||||
(animated/set manual-open 1)])))
|
||||
[height @visible])
|
||||
;; NOTE(Ferossgp): Remove me when RNGH will suport modal
|
||||
(rn/use-back-handler
|
||||
(fn []
|
||||
(when back-button-cancel
|
||||
(close-sheet))
|
||||
true))
|
||||
@visible))
|
||||
(react/effect!
|
||||
(fn []
|
||||
(cond
|
||||
|
@ -145,14 +173,14 @@
|
|||
(close-sheet)))
|
||||
[visible?])
|
||||
(reagent/as-element
|
||||
[rn/modal {:visible @visible
|
||||
:transparent true
|
||||
:status-bar-translucent true
|
||||
:presentation-style :overFullScreen
|
||||
:hardware-accelerated true
|
||||
:on-request-close (fn []
|
||||
(when back-button-cancel
|
||||
(close-sheet)))}
|
||||
[modal {:visible @visible
|
||||
:transparent true
|
||||
:status-bar-translucent true
|
||||
:presentation-style :overFullScreen
|
||||
:hardware-accelerated true
|
||||
:on-request-close (fn []
|
||||
(when back-button-cancel
|
||||
(close-sheet)))}
|
||||
[rn/view {:style styles/container
|
||||
:pointer-events :box-none}
|
||||
[gesture-handler/tap-gesture-handler (merge {:enabled backdrop-dismiss?}
|
||||
|
@ -162,30 +190,34 @@
|
|||
[animated/view {:style (merge (styles/content-container window-height)
|
||||
{:transform [{:translateY translate-y}
|
||||
{:translateY (* window-height 2)}]})}
|
||||
[gesture-handler/pan-gesture-handler {:ref master-ref
|
||||
:wait-for body-ref
|
||||
:enabled (not disable-drag?)
|
||||
:onGestureEvent on-master-event
|
||||
:onHandlerStateChange on-master-event}
|
||||
[gesture-handler/pan-gesture-handler (merge on-master-event
|
||||
{:ref master-ref
|
||||
:wait-for body-ref
|
||||
:enabled (not disable-drag?)})
|
||||
[animated/view {:style styles/content-header}
|
||||
(when show-handle?
|
||||
[rn/view {:style styles/handle}])]]
|
||||
[gesture-handler/pan-gesture-handler {:ref body-ref
|
||||
:wait-for master-ref
|
||||
:enabled (and (not disable-drag?)
|
||||
(not= sheet-height max-height))
|
||||
:onGestureEvent on-body-event
|
||||
:onHandlerStateChange on-body-event}
|
||||
[animated/view {:pointer-events :box-none
|
||||
:height sheet-height}
|
||||
[gesture-handler/pan-gesture-handler (merge on-body-event
|
||||
{:ref body-ref
|
||||
:wait-for master-ref
|
||||
:enabled (and (not disable-drag?)
|
||||
(not= sheet-height max-height))})
|
||||
[animated/view {:height sheet-height}
|
||||
[animated/scroll-view {:bounces false
|
||||
:flex 1
|
||||
:scroll-enabled (= sheet-height max-height)}
|
||||
[animated/view {:style {:padding-top styles/vertical-padding
|
||||
:padding-bottom (+ styles/vertical-padding
|
||||
(:bottom safe-area))}
|
||||
[animated/view {:style (merge
|
||||
(when (and platform/android? (not @visible))
|
||||
;; NOTE(Ferossgp): Remove when RNGH will support modals,
|
||||
;; now need to trigger on-layout when closed
|
||||
{:height 0})
|
||||
{:padding-top styles/vertical-padding
|
||||
:padding-bottom (+ styles/vertical-padding
|
||||
(if (and platform/ios? keyboard-shown)
|
||||
keyboard-height
|
||||
(:bottom safe-area)))})
|
||||
:on-layout on-layout}
|
||||
(into [:<>] (react/get-children children))]]]]]]])))
|
||||
(into [:<>]
|
||||
(react/get-children children))]]]]]]])))
|
||||
|
||||
(defn bottom-sheet [props & children]
|
||||
(into [:> bottom-sheet-raw props] children))
|
||||
(def bottom-sheet (reagent/adapt-react-class (react/memo bottom-sheet-hooks)))
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
[quo.design-system.spacing :as spacing]
|
||||
[quo.components.text :as text]
|
||||
;; FIXME:
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.utils.label :as utils.label]))
|
||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||
|
||||
(defn style-container [type]
|
||||
(merge {:height 44
|
||||
|
@ -16,8 +15,8 @@
|
|||
:flex-direction :row}
|
||||
(case type
|
||||
:primary (:base spacing/padding-horizontal)
|
||||
:secondary (:tiny spacing/padding-horizontal)
|
||||
:icon {:padding-horizontal 2}
|
||||
:secondary (:x-tiny spacing/padding-horizontal)
|
||||
:icon {}
|
||||
nil)))
|
||||
|
||||
(defn content-style [type]
|
||||
|
@ -32,6 +31,9 @@
|
|||
:main {:icon-color (:icon-04 @colors/theme)
|
||||
:background-color (:interactive-02 @colors/theme)
|
||||
:text-color (:text-04 @colors/theme)}
|
||||
:icon {:icon-color (:icon-01 @colors/theme)
|
||||
:background-color (:interactive-02 @colors/theme)
|
||||
:text-color (:text-01 @colors/theme)}
|
||||
:negative {:icon-color (:negative-01 @colors/theme)
|
||||
:background-color (:negative-02 @colors/theme)
|
||||
:text-color (:negative-01 @colors/theme)}
|
||||
|
@ -45,15 +47,18 @@
|
|||
:background-color (:ui-01 @colors/theme)
|
||||
:text-color (:text-02 @colors/theme)}))
|
||||
|
||||
(defn button [{:keys [on-press disabled type theme before after icon
|
||||
(defn button [{:keys [on-press disabled type theme before after
|
||||
haptic-feedback haptic-type on-long-press on-press-start
|
||||
accessibility-label loading]
|
||||
accessibility-label loading border-radius]
|
||||
:or {theme :main
|
||||
type :primary
|
||||
haptic-feedback true
|
||||
border-radius 8
|
||||
haptic-type :selection}}
|
||||
children]
|
||||
(let [theme' (if disabled :disabled theme)
|
||||
(let [theme' (cond
|
||||
disabled :disabled
|
||||
:else theme)
|
||||
{:keys [icon-color background-color text-color]}
|
||||
(themes theme')
|
||||
|
||||
|
@ -61,8 +66,8 @@
|
|||
(when haptic-feedback
|
||||
(haptic/trigger haptic-type)))]
|
||||
|
||||
[animation/pressable (merge {:background-color background-color
|
||||
:border-radius 8
|
||||
[animation/pressable (merge {:bg-color background-color
|
||||
:border-radius border-radius
|
||||
:type type
|
||||
:disabled disabled
|
||||
:accessibility-label accessibility-label}
|
||||
|
@ -90,13 +95,13 @@
|
|||
{:opacity 0}))}
|
||||
(cond
|
||||
(= type :icon)
|
||||
[icons/icon icon {:color icon-color}]
|
||||
[icons/icon children {:color icon-color}]
|
||||
|
||||
(or (keyword? children) (string? children))
|
||||
(string? children)
|
||||
[text/text {:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color text-color}}
|
||||
(utils.label/stringify children)]
|
||||
children]
|
||||
|
||||
(vector? children)
|
||||
children)]
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
(reagent/as-element
|
||||
[gh/tap-gesture-handler (merge tap-handler
|
||||
{:shouldCancelWhenOutside true
|
||||
:enabled (not disabled)})
|
||||
:enabled (boolean (and onChange (not disabled)))})
|
||||
[animated/view
|
||||
[component {:transition transition
|
||||
:hold hold}]]]))))
|
||||
|
@ -66,6 +66,6 @@
|
|||
[animated/view {:style (styles/check-icon-style transition hold)}
|
||||
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]])
|
||||
|
||||
(def switch (reagent/adapt-react-class (control-builder switch-view)))
|
||||
(def radio (reagent/adapt-react-class (control-builder radio-view)))
|
||||
(def checkbox (reagent/adapt-react-class (control-builder checkbox-view)))
|
||||
(def switch (reagent/adapt-react-class (react/memo (control-builder switch-view))))
|
||||
(def radio (reagent/adapt-react-class (react/memo (control-builder radio-view))))
|
||||
(def checkbox (reagent/adapt-react-class (react/memo (control-builder checkbox-view))))
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(ns quo.components.header
|
||||
(:require [oops.core :refer [oget]]
|
||||
[quo.animated :as animated]
|
||||
[quo.components.button.view :as button]
|
||||
[quo.components.text :as text]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.design-system.spacing :as spacing]
|
||||
[quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def header-height 56)
|
||||
|
||||
|
@ -64,25 +64,21 @@
|
|||
(def header-action-placeholder
|
||||
{:width (:base spacing/spacing)})
|
||||
|
||||
(def header-icon-touchable
|
||||
(merge
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(:tiny spacing/padding-horizontal)))
|
||||
|
||||
(def element {:align-items :center
|
||||
:justify-content :center
|
||||
:flex 1})
|
||||
|
||||
(defn header-action [{:keys [icon label on-press accessibility-label]}]
|
||||
[rn/touchable-opacity {:on-press on-press}
|
||||
[rn/view (merge {:style header-icon-touchable}
|
||||
(when accessibility-label
|
||||
{:accessibility-label accessibility-label}))
|
||||
(cond
|
||||
icon [icons/icon icon {:color (:icon-01 @colors/theme)}]
|
||||
label [text/text {:color :link} label])]])
|
||||
[button/button (merge {:on-press on-press}
|
||||
(cond
|
||||
icon {:type :icon
|
||||
:theme :icon}
|
||||
label {:type :secondary})
|
||||
(when accessibility-label
|
||||
{:accessibility-label accessibility-label}))
|
||||
(cond
|
||||
icon icon
|
||||
label label)])
|
||||
|
||||
(defn header-actions [{:keys [accessories component]}]
|
||||
[rn/view {:style element}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
(ns quo.components.list.item
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo.platform :as platform]
|
||||
[quo.haptic :as haptic]
|
||||
[quo.design-system.spacing :as spacing]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.components.text :as text]
|
||||
[quo.components.controls.view :as controls]
|
||||
[quo.components.tooltip :as tooltip]
|
||||
;; FIXME:
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[quo.components.animated.pressable :as animated]))
|
||||
|
@ -47,6 +49,11 @@
|
|||
:small 52
|
||||
64))
|
||||
|
||||
(defn size->single-title-size [size]
|
||||
(case size
|
||||
:small :base
|
||||
:large))
|
||||
|
||||
(defn container [{:keys [size]} & children]
|
||||
(into [rn/view {:style (merge (:tiny spacing/padding-horizontal)
|
||||
{:min-height (size->container-size size)
|
||||
|
@ -59,9 +66,7 @@
|
|||
|
||||
(defn- icon-column [{:keys [icon icon-bg-color icon-color size]}]
|
||||
(when icon
|
||||
(let [icon-size (if (= size :default)
|
||||
40
|
||||
36)]
|
||||
(let [icon-size (size->icon-size size)]
|
||||
[rn/view {:style (:tiny spacing/padding-horizontal)}
|
||||
(cond
|
||||
(vector? icon)
|
||||
|
@ -76,29 +81,42 @@
|
|||
:background-color icon-bg-color}}
|
||||
[icons/icon icon {:color icon-color}]])])))
|
||||
|
||||
(defn title-column [{:keys [title text-color subtitle subtitle-max-lines]}]
|
||||
(defn title-column
|
||||
[{:keys [title text-color subtitle subtitle-max-lines
|
||||
title-accessibility-label size]}]
|
||||
[rn/view {:style (merge (:tiny spacing/padding-horizontal)
|
||||
{:justify-content :center})}
|
||||
{:justify-content :center
|
||||
:flex 1})}
|
||||
(cond
|
||||
|
||||
(and title subtitle)
|
||||
[:<>
|
||||
[text/text {:weight :medium
|
||||
:style {:color text-color}
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1}
|
||||
title]
|
||||
[text/text {:weight :regular
|
||||
:color :secondary
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines subtitle-max-lines}
|
||||
subtitle]]
|
||||
;; FIXME(Ferossgp): ReactNative 63 will support view inside text on andrid, remove thess if when migrating
|
||||
(if (string? title)
|
||||
[text/text {:weight :medium
|
||||
:style {:color text-color}
|
||||
:accessibility-label title-accessibility-label
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1}
|
||||
title]
|
||||
title)
|
||||
(if (string? subtitle)
|
||||
[text/text {:weight :regular
|
||||
:color :secondary
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines subtitle-max-lines}
|
||||
subtitle]
|
||||
subtitle)]
|
||||
|
||||
title [text/text {:number-of-lines 1
|
||||
:style {:color text-color}
|
||||
:ellipsize-mode :tail
|
||||
:size :large}
|
||||
title])])
|
||||
title
|
||||
(if (string? title)
|
||||
[text/text {:number-of-lines 1
|
||||
:style {:color text-color}
|
||||
:title-accessibility-label title-accessibility-label
|
||||
:ellipsize-mode :tail
|
||||
:size (size->single-title-size size)}
|
||||
title]
|
||||
title))])
|
||||
|
||||
(defn left-side [props]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
|
@ -107,56 +125,85 @@
|
|||
[icon-column props]
|
||||
[title-column props]])
|
||||
|
||||
(defn right-side [{:keys [chevron on-press active accessory accessory-text]}]
|
||||
[rn/view {:style {:align-items :center
|
||||
:flex-direction :row}}
|
||||
[rn/view {:style (:tiny spacing/padding-horizontal)}
|
||||
(case accessory
|
||||
:radio [controls/radio {:value active
|
||||
:on-change on-press}]
|
||||
:checkbox [controls/checkbox {:value active
|
||||
:on-change on-press}]
|
||||
:switch [controls/switch {:value active
|
||||
:on-change on-press}]
|
||||
:text [text/text {:color :secondary
|
||||
:number-of-lines 1}
|
||||
accessory-text]
|
||||
nil)]
|
||||
(when (and chevron platform/ios?)
|
||||
[rn/view {:style {:padding-right (:tiny spacing/spacing)}}
|
||||
[icons/icon :main-icons/next {:container-style {:opacity 0.4
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:color (:icon-02 @colors/theme)}]])])
|
||||
(defn right-side [{:keys [chevron active accessory accessory-text]}]
|
||||
(when (or chevron accessory)
|
||||
[rn/view {:style {:align-items :center
|
||||
:flex-direction :row}}
|
||||
[rn/view {:style (:tiny spacing/padding-horizontal)}
|
||||
(case accessory
|
||||
:radio [controls/radio {:value active}]
|
||||
:checkbox [controls/checkbox {:value active}]
|
||||
:switch [controls/switch {:value active}]
|
||||
:text [text/text {:color :secondary
|
||||
:number-of-lines 1}
|
||||
accessory-text]
|
||||
accessory)]
|
||||
(when (and chevron platform/ios?)
|
||||
[rn/view {:style {:padding-right (:tiny spacing/spacing)}}
|
||||
[icons/icon :main-icons/next {:container-style {:opacity 0.4
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:color (:icon-02 @colors/theme)}]])]))
|
||||
|
||||
(defn list-item
|
||||
[{:keys [theme accessory disabled subtitle-max-lines icon title
|
||||
subtitle active on-press on-long-press chevron size
|
||||
accessory-text]
|
||||
accessory-text accessibility-label title-accessibility-label
|
||||
haptic-feedback haptic-type error animated]
|
||||
:or {subtitle-max-lines 1
|
||||
theme :main}}]
|
||||
(let [theme (if disabled :disabled theme)
|
||||
theme :main
|
||||
haptic-feedback true
|
||||
animated true
|
||||
haptic-type :selection}}]
|
||||
(let [theme (if disabled :disabled theme)
|
||||
{:keys [icon-color text-color icon-bg-color
|
||||
active-background passive-background]}
|
||||
(themes theme)]
|
||||
[rn/view {:background-color (if active active-background passive-background)}
|
||||
[animated/pressable {:type :list-item
|
||||
:disabled disabled
|
||||
:background-color active-background
|
||||
:on-press on-press
|
||||
:on-long-press on-long-press}
|
||||
(themes theme)
|
||||
optional-haptic (fn []
|
||||
(when haptic-feedback
|
||||
(haptic/trigger haptic-type)))
|
||||
component (cond
|
||||
(and (not on-press)
|
||||
(not on-long-press))
|
||||
rn/view
|
||||
animated animated/pressable
|
||||
:else rn/touchable-opacity)]
|
||||
[rn/view {:background-color (if (and (= accessory :radio) active)
|
||||
active-background
|
||||
passive-background)}
|
||||
[component
|
||||
(merge {:type :list-item
|
||||
:disabled disabled
|
||||
:bg-color active-background
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press (fn []
|
||||
(optional-haptic)
|
||||
(on-press))})
|
||||
(when on-long-press
|
||||
{:on-long-press (fn []
|
||||
(optional-haptic)
|
||||
(on-long-press))}))
|
||||
[container {:size size}
|
||||
[left-side {:icon-color icon-color
|
||||
:text-color text-color
|
||||
:icon-bg-color icon-bg-color
|
||||
:icon icon
|
||||
:title title
|
||||
:size size
|
||||
:subtitle subtitle
|
||||
:subtitle-max-lines subtitle-max-lines}]
|
||||
[left-side {:icon-color icon-color
|
||||
:text-color text-color
|
||||
:icon-bg-color icon-bg-color
|
||||
:title-accessibility-label title-accessibility-label
|
||||
:icon icon
|
||||
:title title
|
||||
:size size
|
||||
:subtitle subtitle
|
||||
:subtitle-max-lines subtitle-max-lines}]
|
||||
[right-side {:chevron chevron
|
||||
:active active
|
||||
:on-press on-press
|
||||
:accessory-text accessory-text
|
||||
:accessory accessory}]]]]))
|
||||
:accessory accessory}]]]
|
||||
(when error
|
||||
[tooltip/tooltip (merge {:bottom-value 0}
|
||||
(when accessibility-label
|
||||
{:accessibility-label (str (name accessibility-label) "-error")}))
|
||||
[text/text {:color :negative
|
||||
:size :small}
|
||||
error]])]))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns quo.react-native
|
||||
(:require [reagent.core :as reagent]
|
||||
[cljs-bean.core :as bean]
|
||||
["react-native" :as rn]
|
||||
["@react-native-community/hooks" :as hooks]))
|
||||
|
||||
|
@ -73,3 +74,16 @@
|
|||
:width (.-window ^js window)}))
|
||||
|
||||
(def use-back-handler (.-useBackHandler hooks))
|
||||
|
||||
(defn use-keyboard []
|
||||
(let [kb (.useKeyboard hooks)]
|
||||
{:keyboard-shown (.-keyboardShown ^js kb)
|
||||
:keyboard-height (.-keyboardHeight ^js kb)}))
|
||||
|
||||
(defn use-layout []
|
||||
(let [{:keys [onLayout x y height width]} (bean/bean (.useLayout hooks))]
|
||||
{:on-layout onLayout
|
||||
:x x
|
||||
:y y
|
||||
:height height
|
||||
:width width}))
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
[status-im.stickers.core :as stickers]
|
||||
[status-im.transport.core :as transport]
|
||||
[status-im.transport.message.core :as transport.message]
|
||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.currency-settings.models
|
||||
:as
|
||||
|
@ -50,8 +49,6 @@
|
|||
status-im.wallet.choose-recipient.core
|
||||
status-im.wallet.collectibles.core
|
||||
status-im.wallet.accounts.core
|
||||
status-im.multiaccounts.biometric.core
|
||||
status-im.hardwallet.core
|
||||
status-im.popover.core
|
||||
[status-im.hardwallet.core :as hardwallet]
|
||||
[status-im.utils.dimensions :as dimensions]
|
||||
|
@ -61,6 +58,7 @@
|
|||
[status-im.ui.components.permissions :as permissions]
|
||||
[status-im.utils.http :as http]
|
||||
[status-im.utils.utils :as utils]
|
||||
status-im.ui.components.bottom-sheet.core
|
||||
status-im.ui.screens.add-new.new-chat.events
|
||||
status-im.ui.screens.group.chat-settings.events
|
||||
status-im.ui.screens.group.events
|
||||
|
@ -402,7 +400,9 @@
|
|||
{:ui/show-confirmation {:title (i18n/label :t/clear-history-title)
|
||||
:content (i18n/label :t/clear-history-confirmation-content)
|
||||
:confirm-button-text (i18n/label :t/clear-history-action)
|
||||
:on-accept #(re-frame/dispatch [:chat.ui/clear-history chat-id])}}))
|
||||
:on-accept #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:chat.ui/clear-history chat-id]))}}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/fetch-history-pressed
|
||||
|
@ -465,7 +465,9 @@
|
|||
{:ui/show-confirmation {:title (i18n/label :t/delete-confirmation)
|
||||
:content (i18n/label :t/delete-chat-confirmation)
|
||||
:confirm-button-text (i18n/label :t/delete)
|
||||
:on-accept #(re-frame/dispatch [:chat.ui/remove-chat chat-id])}}))
|
||||
:on-accept #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:chat.ui/remove-chat chat-id]))}}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:chat.ui/set-chat-ui-props
|
||||
|
@ -789,7 +791,9 @@
|
|||
{:ui/show-confirmation {:title (i18n/label :t/leave-confirmation)
|
||||
:content (i18n/label :t/leave-chat-confirmation)
|
||||
:confirm-button-text (i18n/label :t/leave)
|
||||
:on-accept #(re-frame/dispatch [:group-chats.ui/leave-chat-confirmed chat-id])}}))
|
||||
:on-accept #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:group-chats.ui/leave-chat-confirmed chat-id]))}}))
|
||||
(handlers/register-handler-fx
|
||||
:group-chats.ui/join-pressed
|
||||
(fn [cofx [_ chat-id]]
|
||||
|
@ -980,23 +984,6 @@
|
|||
(fn [cofx _]
|
||||
(stickers/pending-timeout cofx)))
|
||||
|
||||
;; Tribute to Talk
|
||||
|
||||
|
||||
;; bottom-sheet events
|
||||
(handlers/register-handler-fx
|
||||
:bottom-sheet/show-sheet
|
||||
(fn [cofx [_ view options]]
|
||||
(bottom-sheet/show-bottom-sheet
|
||||
cofx
|
||||
{:view view
|
||||
:options options})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:bottom-sheet/hide-sheet
|
||||
(fn [cofx _]
|
||||
(bottom-sheet/hide-bottom-sheet cofx)))
|
||||
|
||||
;;custom tokens
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:hardwallet :setup-step] :pair))
|
||||
:dispatch [:bottom-sheet/hide-sheet]}
|
||||
:dispatch [:bottom-sheet/hide]}
|
||||
(common/listen-to-hardware-back-button)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-pair nil)))
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
:margin-vertical 15})
|
||||
|
||||
(def bottom-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
{:flex-direction :row
|
||||
:padding-vertical 4})
|
||||
|
||||
(def container
|
||||
styles/flex)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.network.core :as network]
|
||||
[status-im.network.ui.edit-network.styles :as styles]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
|
@ -60,8 +59,9 @@
|
|||
:on-change-text #(re-frame/dispatch [::network/input-changed :network-id %])}]])]]
|
||||
[react/view styles/bottom-container
|
||||
[react/view components.styles/flex]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/save)
|
||||
:disabled? (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [::network/save-network-pressed])}]]]])))
|
||||
[quo/button
|
||||
{:after :main-icons/next
|
||||
:type :secondary
|
||||
:disabled (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [::network/save-network-pressed])}
|
||||
(i18n/label :t/save)]]]])))
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
(ns status-im.network.ui.network-details.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.network.core :as network]
|
||||
[status-im.network.ui.styles :as st]
|
||||
[status-im.network.ui.views :as network-settings]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.topbar :as topbar])
|
||||
|
@ -40,7 +40,5 @@
|
|||
(when custom?
|
||||
[react/view st/bottom-container
|
||||
[react/view components.styles/flex
|
||||
[components.common/button {:label (i18n/label :t/delete)
|
||||
:button-style st/delete-button
|
||||
:label-style st/delete-button-text
|
||||
:on-press #(re-frame/dispatch [::network/delete-network-pressed id])}]]])]])))
|
||||
[quo/button {:on-press #(re-frame/dispatch [::network/delete-network-pressed id])}
|
||||
(i18n/label :t/delete)]]])]])))
|
||||
|
|
|
@ -85,11 +85,5 @@
|
|||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
|
||||
(def delete-button
|
||||
{:background-color colors/white-persist})
|
||||
|
||||
(def delete-button-text
|
||||
{:color colors/red})
|
||||
|
||||
(def container
|
||||
components.styles/flex)
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
(ns status-im.ui.components.bottom-sheet.core
|
||||
(:require [status-im.ui.components.bottom-sheet.view :as view]
|
||||
[status-im.ui.components.bottom-sheet.events :as events]))
|
||||
(:require [status-im.ui.components.bottom-sheet.events :as events]))
|
||||
|
||||
(def show-bottom-sheet events/show-bottom-sheet)
|
||||
(def hide-bottom-sheet events/hide-bottom-sheet)
|
||||
|
||||
(def bottom-sheet view/bottom-sheet)
|
||||
|
|
|
@ -17,3 +17,11 @@
|
|||
:bottom-sheet/hide
|
||||
(fn [cofx]
|
||||
(hide-bottom-sheet cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:bottom-sheet/show-sheet
|
||||
(fn [cofx [_ view options]]
|
||||
(show-bottom-sheet
|
||||
cofx
|
||||
{:view view
|
||||
:options options})))
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
(ns status-im.ui.components.bottom-sheet.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def border-radius 16)
|
||||
(def vertical-padding 8)
|
||||
(def margin-top 56)
|
||||
|
||||
(def container
|
||||
{:position :absolute
|
||||
:left 0
|
||||
:top 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:flex 1
|
||||
:justify-content :flex-end})
|
||||
|
||||
(defn shadow [opacity-value]
|
||||
{:flex 1
|
||||
:position :absolute
|
||||
:left 0
|
||||
:top 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:opacity opacity-value
|
||||
:background-color colors/black-transparent-40-persist})
|
||||
|
||||
(defn content-container
|
||||
[window-height content-height bottom-value]
|
||||
{:background-color colors/white
|
||||
:border-top-left-radius border-radius
|
||||
:border-top-right-radius border-radius
|
||||
:height (+ content-height window-height)
|
||||
:bottom (- window-height)
|
||||
:transform [{:translateY bottom-value}]})
|
||||
|
||||
(def sheet-wrapper {:flex 1
|
||||
:justify-content :flex-end})
|
||||
|
||||
(def content-header
|
||||
{:height border-radius
|
||||
:align-self :stretch
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(def handle
|
||||
{:width 31
|
||||
:height 4
|
||||
:background-color colors/gray-transparent-40
|
||||
:border-radius 2})
|
|
@ -1,199 +0,0 @@
|
|||
(ns status-im.ui.components.bottom-sheet.view
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.bottom-sheet.styles :as styles]
|
||||
[status-im.utils.platform :as platform]
|
||||
["react-native" :refer (BackHandler)]
|
||||
[reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(def initial-animation-duration 400)
|
||||
(def release-animation-duration 150)
|
||||
(def cancellation-animation-duration 100)
|
||||
(def swipe-opacity-range 100)
|
||||
(def cancellation-coefficient 0.3)
|
||||
(def min-opacity 0.05)
|
||||
(def min-velocity 0.4)
|
||||
|
||||
(defn- animate
|
||||
[{:keys [opacity new-opacity-value
|
||||
bottom new-bottom-value
|
||||
duration callback]}]
|
||||
(when (fn? callback)
|
||||
(js/setTimeout callback duration))
|
||||
(animation/start
|
||||
(animation/parallel
|
||||
[(animation/timing opacity
|
||||
{:toValue new-opacity-value
|
||||
:duration duration
|
||||
:useNativeDriver true})
|
||||
(animation/spring bottom
|
||||
{:toValue new-bottom-value
|
||||
:duration duration
|
||||
:tension 40
|
||||
:friction 6
|
||||
:useNativeDriver true})])))
|
||||
|
||||
(defn- on-move
|
||||
[{:keys [height bottom-value opacity-value]}]
|
||||
(fn [_ ^js state]
|
||||
(let [dy (.-dy state)]
|
||||
(cond (pos? dy)
|
||||
(let [opacity (max min-opacity (- 1 (/ dy (- height swipe-opacity-range))))]
|
||||
(animation/set-value bottom-value dy)
|
||||
(animation/set-value opacity-value opacity))
|
||||
(neg? dy)
|
||||
(animation/set-value bottom-value dy)))))
|
||||
|
||||
(defn- cancelled? [height dy vy]
|
||||
(or
|
||||
(<= min-velocity vy)
|
||||
(> (* cancellation-coefficient height) (- height dy))))
|
||||
|
||||
(defn- on-release
|
||||
[{:keys [height bottom-value close-sheet opacity-value]}]
|
||||
(fn [_ state]
|
||||
(let [{:strs [dy vy]} (js->clj state)]
|
||||
(if (cancelled? height dy vy)
|
||||
(close-sheet)
|
||||
(animate {:bottom bottom-value
|
||||
:new-bottom-value 0
|
||||
:opacity opacity-value
|
||||
:new-opacity-value 1
|
||||
:duration release-animation-duration})))))
|
||||
|
||||
(defn- swipe-pan-responder [opts]
|
||||
(.create
|
||||
^js react/pan-responder
|
||||
(clj->js
|
||||
{:onMoveShouldSetPanResponder (fn [_ ^js state]
|
||||
(or (< 10 (js/Math.abs (.-dx state)))
|
||||
(< 5 (js/Math.abs (.-dy state)))))
|
||||
:onPanResponderMove (on-move opts)
|
||||
:onPanResponderRelease (on-release opts)
|
||||
:onPanResponderTerminate (on-release opts)})))
|
||||
|
||||
(defn- pan-handlers [^js pan-responder]
|
||||
(js->clj (.-panHandlers pan-responder)))
|
||||
|
||||
(defn- on-open [{:keys [bottom-value internal-atom opacity-value]}]
|
||||
(when-not @internal-atom
|
||||
(react/dismiss-keyboard!)
|
||||
(reset! internal-atom true)
|
||||
(animate {:bottom bottom-value
|
||||
:new-bottom-value 0
|
||||
:opacity opacity-value
|
||||
:new-opacity-value 1
|
||||
:duration initial-animation-duration})))
|
||||
|
||||
(defn- on-close
|
||||
[{:keys [bottom-value opacity-value on-cancel internal-atom height]}]
|
||||
(when @internal-atom
|
||||
(animate {:bottom bottom-value
|
||||
:new-bottom-value height
|
||||
:opacity opacity-value
|
||||
:new-opacity-value 0
|
||||
:duration cancellation-animation-duration
|
||||
:callback (fn []
|
||||
(when (fn? on-cancel)
|
||||
(animation/set-value bottom-value height)
|
||||
(animation/set-value opacity-value 0)
|
||||
(reset! internal-atom false)
|
||||
(on-cancel)))})))
|
||||
|
||||
(defn bottom-sheet-view [{:keys [window-height]}]
|
||||
(let [opacity-value (animation/create-value 0)
|
||||
bottom-value (animation/create-value window-height)
|
||||
content-height (reagent/atom (* 0.4 window-height))
|
||||
internal-visible (reagent/atom false)
|
||||
external-visible (reagent/atom false)
|
||||
back-listener (reagent/atom nil)]
|
||||
(fn [{:keys [content on-cancel disable-drag? show-handle? show?
|
||||
backdrop-dismiss? safe-area window-height back-button-cancel]
|
||||
:or {show-handle? true
|
||||
backdrop-dismiss? true
|
||||
back-button-cancel true
|
||||
on-cancel #(re-frame/dispatch [:bottom-sheet/hide])}}]
|
||||
(let [height (+ @content-height
|
||||
styles/border-radius)
|
||||
max-height (- window-height
|
||||
(:top safe-area)
|
||||
styles/margin-top)
|
||||
sheet-height (min max-height height)
|
||||
close-sheet (fn []
|
||||
(when (and platform/android? @back-listener)
|
||||
(.remove ^js @back-listener)
|
||||
(reset! back-listener nil))
|
||||
(on-close {:opacity-value opacity-value
|
||||
:bottom-value bottom-value
|
||||
:height height
|
||||
:internal-atom internal-visible
|
||||
:on-cancel on-cancel}))
|
||||
handle-back (fn []
|
||||
(when back-button-cancel
|
||||
(close-sheet))
|
||||
true)]
|
||||
(when-not (= @external-visible show?)
|
||||
(reset! external-visible show?)
|
||||
(cond
|
||||
(true? show?)
|
||||
(do (on-open {:bottom-value bottom-value
|
||||
:opacity-value opacity-value
|
||||
:internal-atom internal-visible
|
||||
:height height})
|
||||
(when platform/android?
|
||||
(reset! back-listener (.addEventListener BackHandler
|
||||
"hardwareBackPress"
|
||||
handle-back))))
|
||||
|
||||
(false? show?)
|
||||
(close-sheet)))
|
||||
(when @internal-visible
|
||||
[react/view {:style styles/container}
|
||||
[react/touchable-highlight (merge {:style styles/container}
|
||||
(when backdrop-dismiss?
|
||||
{:on-press #(close-sheet)}))
|
||||
[react/animated-view {:style (styles/shadow opacity-value)}]]
|
||||
|
||||
[react/keyboard-avoiding-view {:pointer-events "box-none"
|
||||
:behaviour "position"
|
||||
:style styles/sheet-wrapper}
|
||||
[react/animated-view (merge
|
||||
{:style (styles/content-container window-height sheet-height bottom-value)}
|
||||
(when-not (or disable-drag? (= max-height sheet-height))
|
||||
(pan-handlers
|
||||
(swipe-pan-responder {:bottom-value bottom-value
|
||||
:opacity-value opacity-value
|
||||
:height height
|
||||
:close-sheet #(close-sheet)}))))
|
||||
[react/view (merge {:style styles/content-header}
|
||||
(when (and (not disable-drag?)
|
||||
(= max-height sheet-height))
|
||||
(pan-handlers
|
||||
(swipe-pan-responder {:bottom-value bottom-value
|
||||
:opacity-value opacity-value
|
||||
:height height
|
||||
:close-sheet #(close-sheet)}))))
|
||||
(when show-handle?
|
||||
[react/view styles/handle])]
|
||||
[react/animated-view {:style {:height sheet-height}}
|
||||
;; NOTE(Ferossgp): For a better UX on onScrollBeginDrag we can start dragging the sheet.
|
||||
[react/scroll-view {:bounces false
|
||||
:scroll-enabled true
|
||||
:style {:flex 1}}
|
||||
[react/view {:style {:padding-top styles/vertical-padding
|
||||
:padding-bottom (+ styles/vertical-padding
|
||||
(:bottom safe-area))}
|
||||
:on-layout #(->> ^js %
|
||||
.-nativeEvent
|
||||
.-layout
|
||||
.-height
|
||||
(reset! content-height))}
|
||||
[content]]]]]]])))))
|
||||
|
||||
(defn bottom-sheet [props]
|
||||
(let [props (assoc props :window-height @(re-frame/subscribe [:dimensions/window-height]))]
|
||||
[react/safe-area-consumer
|
||||
(fn [insets]
|
||||
(reagent/as-element
|
||||
[bottom-sheet-view (assoc props :safe-area (js->clj insets :keywordize-keys true))]))]))
|
|
@ -1,84 +0,0 @@
|
|||
(ns status-im.ui.components.button
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.utils.label :as utils.label]))
|
||||
|
||||
(defn style-container [type disabled? theme]
|
||||
(merge
|
||||
(when (= type :main)
|
||||
{:margin-vertical 8 :margin-horizontal 16})
|
||||
(cond
|
||||
(#{:main :secondary} type)
|
||||
{:padding-horizontal 32}
|
||||
(= :next type)
|
||||
{:padding-right 12 :padding-left 20}
|
||||
(= :previous type)
|
||||
{:padding-right 20 :padding-left 12}
|
||||
:else nil)
|
||||
{:height 44 :border-radius 8
|
||||
:align-items :center :justify-content :center
|
||||
:background-color (cond
|
||||
(#{:secondary :next :previous} type)
|
||||
""
|
||||
disabled?
|
||||
colors/gray-transparent-10
|
||||
(= type :main)
|
||||
(case theme
|
||||
:red colors/red-transparent-10
|
||||
:green colors/green-transparent-10
|
||||
colors/blue-transparent-10)
|
||||
:else
|
||||
"")}))
|
||||
|
||||
(defn button
|
||||
|
||||
"A general purpose status-react specfic button component
|
||||
'type'
|
||||
:main (default), :secondary, :next, :previous
|
||||
|
||||
`theme`
|
||||
:blue (default), :green, :red
|
||||
|
||||
`label`
|
||||
Any one of string, keyword representing translated string in the form of :t/{translation-key-in-translation-files}
|
||||
|
||||
`disabled?`
|
||||
Bool
|
||||
|
||||
`on-press`
|
||||
Fn
|
||||
|
||||
Spec: https://www.figma.com/file/cb4p8AxLtTF3q1L6JYDnKN15/Index?node-id=858%3A0"
|
||||
|
||||
[{:keys [label type theme disabled? on-press accessibility-label style container-style text-style]
|
||||
:or {type :main theme :blue}}]
|
||||
(let [label (utils.label/stringify label)]
|
||||
[react/touchable-opacity (cond-> {:on-press on-press
|
||||
:active-opacity 0.5
|
||||
:style style}
|
||||
;;NOTE `:disabled` must be of type boolean
|
||||
disabled?
|
||||
(assoc :disabled (boolean disabled?))
|
||||
accessibility-label
|
||||
(assoc :accessibility-label accessibility-label))
|
||||
[react/view {:style (merge (style-container type disabled? theme) container-style)}
|
||||
[react/view {:flex-direction :row :align-items :center}
|
||||
(when (= type :previous)
|
||||
[vector-icons/icon :main-icons/back {:container-style {:width 24 :height 24 :margin-right 4}
|
||||
:color (if disabled? colors/gray colors/blue)}])
|
||||
[react/text {:style (merge {:color (cond
|
||||
disabled?
|
||||
colors/gray
|
||||
(#{:main :secondary :next :previous} type)
|
||||
(case theme
|
||||
:green colors/green
|
||||
:red colors/red
|
||||
colors/blue)
|
||||
:else
|
||||
"")}
|
||||
text-style)}
|
||||
label]
|
||||
(when (= type :next)
|
||||
[vector-icons/icon :main-icons/next {:container-style {:width 24 :height 24 :margin-left 4}
|
||||
:color (if disabled? colors/gray colors/blue)}])]]]))
|
|
@ -93,17 +93,9 @@
|
|||
(when dapp?
|
||||
[dapp-badge styles])])
|
||||
|
||||
(defn contact-icon-contacts-tab [contact]
|
||||
[contact-icon-view contact
|
||||
{:container styles/container-chat-list
|
||||
:online-view-wrapper styles/online-view-wrapper
|
||||
:online-view styles/online-view
|
||||
:online-dot-left styles/online-dot-left
|
||||
:online-dot-right styles/online-dot-right
|
||||
:size 40
|
||||
:chat-icon styles/chat-icon-chat-list
|
||||
:default-chat-icon (styles/default-chat-icon-chat-list colors/default-chat-color)
|
||||
:default-chat-icon-text (styles/default-chat-icon-text 40)}])
|
||||
(defn contact-icon-contacts-tab [photo-path]
|
||||
[react/view styles/container-chat-list
|
||||
[photos/photo photo-path {:size 40}]])
|
||||
|
||||
(defn dapp-icon-permission [contact size]
|
||||
[contact-icon-view contact
|
||||
|
@ -141,15 +133,4 @@
|
|||
[react/i18n-text {:style styles/profile-icon-edit-text :key :edit}]])
|
||||
(if (and photo-path (seq photo-path))
|
||||
[photos/photo photo-path styles]
|
||||
[default-chat-icon name styles])]))
|
||||
|
||||
(defn my-profile-icon [{multiaccount :multiaccount
|
||||
edit? :edit?}]
|
||||
(let [color colors/default-chat-color
|
||||
size 64]
|
||||
[profile-icon-view
|
||||
(multiaccounts/displayed-photo multiaccount)
|
||||
(multiaccounts/displayed-name multiaccount)
|
||||
color
|
||||
edit?
|
||||
size {}]))
|
||||
[default-chat-icon name styles])]))
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.ui.components.common.common
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.styles :as styles]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react])
|
||||
|
@ -16,42 +15,6 @@
|
|||
[react/view (merge styles/separator-wrapper wrapper-style)
|
||||
[react/view (merge styles/separator style)]])
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.button
|
||||
(defn bottom-button [{:keys [accessibility-label
|
||||
label
|
||||
disabled?
|
||||
on-press
|
||||
forward?
|
||||
back?]}]
|
||||
(let [color (if disabled? colors/gray colors/blue)]
|
||||
[react/touchable-highlight {:on-press on-press :disabled disabled?}
|
||||
[react/view styles/bottom-button
|
||||
(when back?
|
||||
[vector-icons/icon :main-icons/back {:color color
|
||||
:container-style {:align-self :baseline}}])
|
||||
[react/text {:style {:color color}
|
||||
:accessibility-label accessibility-label}
|
||||
(or label (i18n/label :t/next))]
|
||||
(when forward?
|
||||
[vector-icons/icon :main-icons/next {:color color}])]]))
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.button
|
||||
(defn button [{:keys [on-press label background? button-style label-style disabled? accessibility-label] :or {background? true disabled? false}}]
|
||||
[react/touchable-highlight {:style (styles/button button-style background? disabled?)
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:disabled disabled?}
|
||||
[react/text {:style (merge styles/button-label label-style)}
|
||||
label]])
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.button
|
||||
;;TODO implement :red type if needed
|
||||
(defn red-button [props]
|
||||
[react/view {:align-items :center}
|
||||
[button (merge props
|
||||
{:label-style {:color colors/red :font-size 15}
|
||||
:button-style {:padding-horizontal 32 :background-color colors/red-light}})]])
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.badge
|
||||
(defn counter
|
||||
([value] (counter nil value))
|
||||
|
|
|
@ -25,25 +25,6 @@
|
|||
:color :none
|
||||
:container-style {}})
|
||||
|
||||
(def bottom-button
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn button [style background? disabled?]
|
||||
(merge
|
||||
{:padding-vertical 12
|
||||
:padding-horizontal 42
|
||||
:border-radius 8
|
||||
:background-color (cond disabled?
|
||||
colors/gray-lighter
|
||||
background?
|
||||
colors/blue-transparent-10)}
|
||||
style))
|
||||
|
||||
(def button-label
|
||||
{:text-align :center
|
||||
:color colors/blue})
|
||||
|
||||
(defn counter-container [size]
|
||||
{:width size
|
||||
:height size
|
||||
|
|
|
@ -21,32 +21,16 @@
|
|||
(def primary-text-base
|
||||
{:font-size 16})
|
||||
|
||||
(def primary-text
|
||||
primary-text-base)
|
||||
|
||||
(def primary-text-only
|
||||
(merge primary-text-base
|
||||
{:padding-vertical 16}))
|
||||
|
||||
(def secondary-text
|
||||
{:font-size 14
|
||||
:color colors/gray
|
||||
:padding-top 4})
|
||||
|
||||
(def image-size 40)
|
||||
|
||||
(def item-image
|
||||
{:width image-size
|
||||
:height image-size})
|
||||
|
||||
(def big-item-image
|
||||
{:width image-size
|
||||
:height image-size
|
||||
:margin-right 16
|
||||
:border-radius (/ image-size 2)
|
||||
:border-color colors/gray-transparent-10
|
||||
:border-width 1})
|
||||
|
||||
(def icon-size 24)
|
||||
(def icon-wrapper-size (+ icon-size (* 2 8)))
|
||||
|
||||
|
@ -72,68 +56,6 @@
|
|||
(def right-item-wrapper
|
||||
{:justify-content :center})
|
||||
|
||||
(def settings-item
|
||||
{:padding-left 16
|
||||
:padding-right 8
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:height 64})
|
||||
|
||||
(defn settings-item-icon
|
||||
[icon-color large?]
|
||||
(cond-> {:background-color (colors/alpha icon-color 0.1)
|
||||
:width 40
|
||||
:height 40
|
||||
:border-radius 40
|
||||
:margin-right 16
|
||||
:justify-content :center
|
||||
:align-items :center}
|
||||
large?
|
||||
(merge {:align-self :flex-start
|
||||
:margin-top 12})))
|
||||
|
||||
(defn settings-item-text
|
||||
[color]
|
||||
{:typography :title
|
||||
:flex 1
|
||||
:flex-wrap :nowrap
|
||||
:color color})
|
||||
|
||||
(def settings-item-text-container
|
||||
{:flex 1
|
||||
:align-self :flex-start
|
||||
:margin-top 12})
|
||||
|
||||
(def settings-item-main-text-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def settings-item-subtext
|
||||
{:margin-top 2
|
||||
:color colors/gray})
|
||||
|
||||
(def settings-item-value
|
||||
{:flex-wrap :nowrap
|
||||
:text-align :right
|
||||
:padding-right 10
|
||||
:color colors/gray})
|
||||
|
||||
(def new-label
|
||||
{:background-color colors/blue
|
||||
:border-radius 4
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:height 16
|
||||
:margin-right 6})
|
||||
|
||||
(def new-label-text
|
||||
{:color colors/white
|
||||
:margin-left 6
|
||||
:margin-right 4
|
||||
:font-size 11
|
||||
:font-weight "700"})
|
||||
|
||||
(def base-separator
|
||||
{:height 1
|
||||
:background-color colors/black-transparent})
|
||||
|
|
|
@ -18,13 +18,9 @@
|
|||
|
||||
[section-list {:sections [{:title \"\" :key :unik :render-fn render :data {:title \"\" :subtitle \"\"}}]}]
|
||||
"
|
||||
(:require [clojure.string :as string]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.list.styles :as styles]
|
||||
[status-im.ui.components.radio :as radio]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -67,13 +63,6 @@
|
|||
[react/image {:source (if (fn? source) (source) source)
|
||||
:style (merge styles/item-image image-style)}]])
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn item-primary
|
||||
([s] (item-primary nil s))
|
||||
([{:keys [style] :as props} s]
|
||||
[react/text (merge {:style (merge styles/primary-text style)}
|
||||
(dissoc props :style))
|
||||
s]))
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn item-primary-only
|
||||
([s] (item-primary-only nil s))
|
||||
([{:keys [style] :as props} s]
|
||||
|
@ -81,29 +70,10 @@
|
|||
(dissoc props :style))
|
||||
s]))
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn item-secondary
|
||||
([s] (item-secondary nil s))
|
||||
([{:keys [style]} s]
|
||||
[react/text
|
||||
{:style (merge styles/secondary-text style)
|
||||
:ellipsize-mode :middle
|
||||
:number-of-lines 1}
|
||||
s]))
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn item-content
|
||||
[& children]
|
||||
(into [react/view {:style styles/item-content-view}] (keep identity children)))
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn list-item-with-checkbox
|
||||
[{:keys [on-value-change style checked? on-long-press] :as props} item]
|
||||
[react/touchable-highlight (merge {:on-press #(on-value-change (not checked?))}
|
||||
(when on-long-press
|
||||
{:on-long-press on-long-press}))
|
||||
(conj item
|
||||
[react/view {:style (merge style styles/item-checkbox)}
|
||||
[checkbox/checkbox (dissoc props :on-value-change)]])])
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn list-item-with-radio-button
|
||||
[{:keys [on-value-change style checked?] :as props} item]
|
||||
|
@ -113,56 +83,6 @@
|
|||
[radio/radio (:checked? props)]])])
|
||||
|
||||
;;TODO DEPRECATED, use status-im.ui.components.list-item.views
|
||||
(defn big-list-item
|
||||
[{:keys [style text text-style subtext action-fn active? hide-chevron?
|
||||
accessory-value text-color new? activity-indicator
|
||||
accessibility-label icon icon-color image-source]
|
||||
:or {icon-color colors/blue
|
||||
text-color colors/black
|
||||
active? true
|
||||
style {}}}]
|
||||
{:pre [text
|
||||
(or (nil? accessibility-label) (keyword? accessibility-label))]}
|
||||
[react/touchable-highlight
|
||||
{:on-press action-fn
|
||||
:style style
|
||||
:accessibility-label accessibility-label
|
||||
:disabled (not active?)}
|
||||
[react/view styles/settings-item
|
||||
(cond
|
||||
icon
|
||||
[react/view (styles/settings-item-icon icon-color subtext)
|
||||
[vector-icons/icon icon {:color icon-color}]]
|
||||
image-source
|
||||
[react/image {:source {:uri image-source}
|
||||
:style styles/big-item-image}]
|
||||
activity-indicator
|
||||
[react/view (styles/settings-item-icon icon-color subtext)
|
||||
[react/activity-indicator activity-indicator]])
|
||||
(if subtext
|
||||
[react/view {:style styles/settings-item-text-container}
|
||||
[react/view {:style styles/settings-item-main-text-container}
|
||||
(when new?
|
||||
[react/view {:style styles/new-label}
|
||||
[react/text {:style styles/new-label-text}
|
||||
(string/upper-case (i18n/label :t/new))]])
|
||||
[react/text {:style (merge (styles/settings-item-text text-color) text-style)}
|
||||
text]]
|
||||
[react/view {:style {:margin-top 2
|
||||
:justify-content :flex-start}}
|
||||
[react/text {:style styles/settings-item-subtext
|
||||
:number-of-lines 2}
|
||||
subtext]]]
|
||||
[react/text {:style (merge (styles/settings-item-text text-color) text-style)
|
||||
:number-of-lines 1}
|
||||
text])
|
||||
(when accessory-value
|
||||
[react/text {:style styles/settings-item-value
|
||||
:number-of-lines 1}
|
||||
(str accessory-value)])
|
||||
(when-not hide-chevron?
|
||||
[vector-icons/icon :main-icons/next {:color colors/gray-transparent-40}])]])
|
||||
|
||||
(defn- wrap-render-fn [f]
|
||||
(fn [^js data]
|
||||
(reagent/as-element (f (.-item data) (.-index data) (.-separators data)))))
|
||||
|
@ -207,7 +127,7 @@
|
|||
`list-item/list-item` config map and `companent`."
|
||||
[item _]
|
||||
(cond
|
||||
(map? item) [list-item/list-item item]
|
||||
(map? item) [quo/list-item item]
|
||||
(vector? item) item
|
||||
(nil? item) nil
|
||||
:else [item]))
|
||||
|
|
|
@ -1,199 +0,0 @@
|
|||
(ns status-im.ui.components.list-item.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(defn container [type selected?]
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:padding-horizontal 16
|
||||
;; We need `:min-height` to ensure design spec conformance
|
||||
;; and maintain `vertical-rythm` regardless of inner content height.
|
||||
;; Spec: https://www.figma.com/file/cb4p8AxLtTF3q1L6JYDnKN15/Index?node-id=790%3A35
|
||||
|
||||
;; Without it `:small` type will be height 42 in some cases
|
||||
;; 44 in others. Something similar can happen to `:default`.
|
||||
;; Not really needed for `:section-header` but good to have
|
||||
;; it, if not for anything, for reference.
|
||||
|
||||
;; - Why not have 15px or 14px top/bottom padding as spec indicates,
|
||||
;; as a strategy for list-item not collapsing to 42/44 height instead?
|
||||
;; - Why `:small` type has same 10px top/bottom padding like `:default` does
|
||||
;; instead of 14px?
|
||||
|
||||
;; Because native switch button height(at least in iOS)
|
||||
;; is > 22px(title line-height), and > 24px(accessory icon height in spec).
|
||||
;; Plus there might be a need for <= 32px accessory or something, in edge cases.
|
||||
|
||||
;; Think of it like an alternate design strategy for components with
|
||||
;; variable content whose height might vary. Like, instead of controlling
|
||||
;; the overall component's height using line-height, top/bottom padding,
|
||||
;; or explicit height.
|
||||
|
||||
;; And, better to have 32px content vertical space (for :small)
|
||||
;; to play with in this setup; So, we stretch vertically the inner
|
||||
;; containers; and vertically center content inside them. Allows for
|
||||
;; flexibility, with as little constraint and superfluous styling attributes
|
||||
;; as possible.
|
||||
|
||||
;; Note: this is `min-height` so if we have > 32px accessory or some other
|
||||
;; content inside it `vertical-rythm` can break. We leave it up to the
|
||||
;; list-item consuming implementation to be aware of it.
|
||||
:min-height (case type
|
||||
:default 64
|
||||
:small 52
|
||||
:section-header 40
|
||||
0)
|
||||
:padding-top (if (= type :section-header) 14 10)
|
||||
:padding-bottom (if (= type :section-header) 4 10)
|
||||
:align-items :center}
|
||||
(when selected?
|
||||
{:background-color colors/blue-light})))
|
||||
|
||||
(def icon-column-container
|
||||
{:margin-right 14
|
||||
:padding-vertical 2
|
||||
:justify-content :flex-start
|
||||
:max-width 40
|
||||
:align-items :center
|
||||
:align-self :stretch})
|
||||
|
||||
(defn icon-container [color]
|
||||
{:border-radius 20
|
||||
:width 40
|
||||
:height 40
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color (or color colors/blue-light)})
|
||||
|
||||
(defn icon [color]
|
||||
{:color (or color colors/blue)
|
||||
:font-size 16})
|
||||
|
||||
(defn title-column-container [accessories?]
|
||||
{:margin-right (if accessories? 16 0)
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:align-items :flex-start
|
||||
:align-self :stretch})
|
||||
|
||||
(def title-row-container
|
||||
{:min-height 22
|
||||
:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-self :stretch})
|
||||
|
||||
(defn title-prefix-icon-container
|
||||
[title-prefix-height title-prefix-width]
|
||||
(merge
|
||||
{:width 16
|
||||
:height 16
|
||||
:justify-content :center
|
||||
:margin-top (if (not title-prefix-height) 4 0)
|
||||
:align-items :center}
|
||||
(when title-prefix-width
|
||||
{:width title-prefix-width})
|
||||
(when title-prefix-height
|
||||
{:height title-prefix-height})))
|
||||
|
||||
(defn title-prefix-text [type theme icon? subtitle
|
||||
content title-prefix-width disabled?]
|
||||
(merge {:margin-left (if icon? 2 0)
|
||||
:align-self :stretch
|
||||
;; we are doing the following to achieve pixel perfection
|
||||
;; as reasonably possible as it can be, and achieve the
|
||||
;; intent of the design spec
|
||||
:line-height 22}
|
||||
(when (= type :default)
|
||||
(if (or subtitle content)
|
||||
{:typography :main-medium
|
||||
:line-height 22}
|
||||
{:typography :title
|
||||
:line-height 20}))
|
||||
|
||||
(when title-prefix-width
|
||||
{:width title-prefix-width})
|
||||
|
||||
(if disabled?
|
||||
{:color colors/gray}
|
||||
(case theme
|
||||
:action-destructive {:color colors/red}
|
||||
:action {:color colors/blue}
|
||||
{}))))
|
||||
|
||||
(defn title [type theme icon? title-prefix subtitle
|
||||
content title-row-accessory disabled?
|
||||
title-color-override]
|
||||
(merge {:margin-left (if icon? 2 0)
|
||||
:flex 1
|
||||
:align-self :stretch
|
||||
;; we are doing the following to achieve pixel perfection
|
||||
;; as reasonably possible as it can be, and achieve the
|
||||
;; intent of the design spec
|
||||
:line-height 22}
|
||||
(when (= type :default)
|
||||
(if (or subtitle content)
|
||||
{:typography :main-medium
|
||||
:line-height 22}
|
||||
{:typography :title
|
||||
:line-height 20}))
|
||||
|
||||
(when title-prefix
|
||||
{:margin-left (if (string? title-prefix) 0 2)})
|
||||
|
||||
(when title-row-accessory
|
||||
{:margin-right 16})
|
||||
|
||||
(if (or disabled? (= :section-header type))
|
||||
{:color colors/gray}
|
||||
;; else
|
||||
(if title-color-override
|
||||
{:color title-color-override}
|
||||
;; else
|
||||
(case theme
|
||||
:action-destructive {:color colors/red}
|
||||
:action {:color colors/blue}
|
||||
{})))))
|
||||
|
||||
(def title-row-accessory-container
|
||||
{:margin-top 2
|
||||
:align-self :stretch})
|
||||
|
||||
(def subtitle-row-container
|
||||
{:min-height 22
|
||||
:flex-direction :row
|
||||
:justify-content :flex-start
|
||||
:align-self :stretch})
|
||||
|
||||
(defn subtitle [icon? subtitle-row-accessory]
|
||||
(cond-> {:margin-left (if icon? 2 0)
|
||||
:flex 1
|
||||
:align-self :stretch
|
||||
:color colors/gray
|
||||
;; we are doing the following to achieve pixel perfection
|
||||
;; as reasonably possible as it can be, and achieve the
|
||||
;; intent of the design spec
|
||||
:line-height 22}
|
||||
subtitle-row-accessory
|
||||
(assoc :margin-right 16)))
|
||||
|
||||
(def subtitle-row-accessory-container
|
||||
{:justify-content :flex-end
|
||||
:align-self :stretch})
|
||||
|
||||
(def accessories-container
|
||||
{:align-self :stretch
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :flex-start})
|
||||
|
||||
(defn accessory-text [width last]
|
||||
{:color colors/gray
|
||||
:max-width (if last (* @width 0.62) (* @width 0.55))
|
||||
;; we are doing the following to achieve pixel perfection
|
||||
;; as reasonably possible as it can be, and achieve the
|
||||
;; intent of the design spec
|
||||
:line-height 22})
|
||||
|
||||
(def error
|
||||
{:bottom-value 0
|
||||
:font-size 12})
|
|
@ -1,410 +0,0 @@
|
|||
(ns status-im.ui.components.list-item.views
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.list-item.styles :as styles]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.profile.db :as profile.db]
|
||||
[status-im.utils.label :as utils.label]
|
||||
[status-im.ui.components.radio :as radio]))
|
||||
|
||||
(defn divider []
|
||||
[react/view {:height 1 :background-color colors/gray-lighter}])
|
||||
|
||||
(defn- icon-column [icon theme disabled?]
|
||||
[react/view styles/icon-column-container
|
||||
(cond
|
||||
(vector? icon)
|
||||
icon
|
||||
|
||||
(and (qualified-keyword? icon)
|
||||
(= "main-icons" (namespace icon)))
|
||||
(let [colors
|
||||
(if disabled?
|
||||
{:container colors/gray-lighter
|
||||
:icon colors/gray-transparent-40}
|
||||
(if (= theme :action-destructive)
|
||||
{:container colors/red-transparent-10
|
||||
:icon colors/red}
|
||||
{:container nil
|
||||
:icon nil}))]
|
||||
[react/view (styles/icon-container (:container colors))
|
||||
[icons/icon icon (styles/icon (:icon colors))]])
|
||||
|
||||
(and (string? icon)
|
||||
(profile.db/base64-encoded-image-path? icon))
|
||||
[photos/photo icon {:size 40}]
|
||||
|
||||
:else [icon])])
|
||||
|
||||
(defn- title-row
|
||||
[{:keys [title title-color-override title-prefix
|
||||
title-prefix-width title-prefix-height
|
||||
title-accessibility-label title-row-accessory]}
|
||||
type icon? disabled? theme subtitle content]
|
||||
[react/view styles/title-row-container
|
||||
(when title-prefix
|
||||
(cond
|
||||
(and (qualified-keyword? title-prefix)
|
||||
(= "main-icons" (namespace title-prefix)))
|
||||
[icons/icon title-prefix
|
||||
(merge
|
||||
{:color colors/black
|
||||
:width 16
|
||||
:height 16
|
||||
:container-style
|
||||
(styles/title-prefix-icon-container
|
||||
title-prefix-height title-prefix-width)}
|
||||
(when title-prefix-width
|
||||
{:width title-prefix-width})
|
||||
(when title-prefix-height
|
||||
{:height title-prefix-height}))]
|
||||
|
||||
(or (string? title-prefix)
|
||||
(number? title-prefix)
|
||||
(keyword? title-prefix))
|
||||
[react/text {:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:style
|
||||
(styles/title-prefix-text
|
||||
type theme icon? subtitle content
|
||||
title-prefix-width disabled?)}
|
||||
(if title-prefix-width
|
||||
(utils.label/stringify title-prefix)
|
||||
(if (string? title)
|
||||
(str (utils.label/stringify title-prefix) " ")
|
||||
(utils.label/stringify title-prefix)))]
|
||||
|
||||
(vector? title-prefix)
|
||||
title-prefix
|
||||
|
||||
:else
|
||||
[title-prefix]))
|
||||
|
||||
(cond
|
||||
(or (string? title) (keyword? title) (number? title))
|
||||
[react/text
|
||||
(merge
|
||||
{:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:style
|
||||
(styles/title
|
||||
type theme icon? title-prefix subtitle
|
||||
content title-row-accessory disabled?
|
||||
title-color-override)}
|
||||
(when title-accessibility-label
|
||||
{:accessibility-label title-accessibility-label}))
|
||||
(utils.label/stringify title)]
|
||||
|
||||
(vector? title)
|
||||
[react/view {:flex 1}
|
||||
title]
|
||||
|
||||
:else
|
||||
[react/view {:flex 1}
|
||||
[title]])
|
||||
|
||||
(when title-row-accessory
|
||||
[react/view styles/title-row-accessory-container title-row-accessory])])
|
||||
|
||||
(defn subtitle-row
|
||||
[_ _]
|
||||
(let [subtitle-row-accessory-width (reagent/atom 0)]
|
||||
(reagent/create-class
|
||||
{:reagent-render
|
||||
(fn [{:keys [subtitle subtitle-max-lines subtitle-row-accessory]} icon?]
|
||||
[react/view styles/subtitle-row-container
|
||||
(cond
|
||||
(or (string? subtitle) (keyword? subtitle) (number? subtitle))
|
||||
[react/text {:style
|
||||
(merge
|
||||
(styles/subtitle
|
||||
icon? (pos? @subtitle-row-accessory-width)))
|
||||
:number-of-lines subtitle-max-lines
|
||||
:ellipsize-mode :tail}
|
||||
(utils.label/stringify subtitle)]
|
||||
|
||||
(vector? subtitle)
|
||||
[react/view
|
||||
(styles/subtitle icon? (pos? @subtitle-row-accessory-width))
|
||||
subtitle]
|
||||
|
||||
:else
|
||||
[react/view
|
||||
(styles/subtitle icon? (pos? @subtitle-row-accessory-width))
|
||||
[subtitle]])
|
||||
|
||||
(when subtitle-row-accessory
|
||||
[react/view
|
||||
{:style styles/subtitle-row-accessory-container
|
||||
:on-layout #(reset!
|
||||
subtitle-row-accessory-width
|
||||
(-> ^js % .-nativeEvent .-layout .-width))}
|
||||
;; We do this so that the bottom of the component is 12 device px
|
||||
;; from bottom of the touchable container, instead of 10.
|
||||
[react/view {:transform [{:translateY -2}]}
|
||||
subtitle-row-accessory]])])})))
|
||||
|
||||
(defn- title-column [{:keys [title] :as title-row-elements}
|
||||
{:keys [subtitle] :as subtitle-row-elements}
|
||||
type icon? disabled? theme content accessories]
|
||||
[react/view (styles/title-column-container accessories)
|
||||
(when title
|
||||
[title-row
|
||||
title-row-elements type icon? disabled?
|
||||
theme subtitle content])
|
||||
|
||||
(when (and subtitle (= :default type))
|
||||
[subtitle-row subtitle-row-elements icon?])
|
||||
|
||||
(when content
|
||||
[react/view {:margin-left (if icon? 2 0)}
|
||||
(if (vector? content)
|
||||
content
|
||||
[content])])])
|
||||
|
||||
(defn- accessories-column [accessories width]
|
||||
(let [last-accessory (peek accessories)]
|
||||
(into
|
||||
[react/view styles/accessories-container]
|
||||
(for [accessory accessories]
|
||||
(when-not (nil? accessory)
|
||||
(with-meta
|
||||
(cond
|
||||
(= :chevron accessory)
|
||||
[icons/icon :main-icons/next
|
||||
{:container-style {:width 10
|
||||
:height 16
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
:resize-mode :center
|
||||
:color colors/gray-transparent-40}]
|
||||
|
||||
(and (qualified-keyword? accessory)
|
||||
(= "main-icons" (namespace accessory)))
|
||||
[icons/icon
|
||||
accessory
|
||||
{:color colors/gray-transparent-40
|
||||
:container-style
|
||||
{:margin-right (if (= accessory last-accessory) 0 12)}}]
|
||||
|
||||
:else
|
||||
[react/view (cond-> {:margin-right (if (= accessory last-accessory) 0 16)}
|
||||
;; `:chevron` container is 10px wide (see up)
|
||||
;; but the chevron icon itself is 9px aligned in the
|
||||
;; container to the right - so 1px white-space on left
|
||||
;; thats 1px + 15px margin, which makes 16px
|
||||
;; as intended in design spec
|
||||
(= last-accessory :chevron)
|
||||
(assoc :margin-right 15))
|
||||
(cond
|
||||
(or (string? accessory) (keyword? accessory) (number? accessory))
|
||||
[react/text {:style
|
||||
(styles/accessory-text width (= accessory last-accessory))
|
||||
:ellipsize-mode :middle
|
||||
:number-of-lines 1}
|
||||
(utils.label/stringify accessory)]
|
||||
|
||||
(vector? accessory)
|
||||
accessory
|
||||
|
||||
:else nil)])
|
||||
{:key (name (gensym "accessory"))}))))))
|
||||
|
||||
(defn list-item
|
||||
"A general purpose status-react specfic list item component.
|
||||
Every key is optional. Use as needed.
|
||||
Combination of around 4 related keys are enough for most cases.
|
||||
Spec: https://www.figma.com/file/cb4p8AxLtTF3q1L6JYDnKN15/Index?node-id=787%3A1108
|
||||
|
||||
`react-key`
|
||||
String - (default generated automatically using `gensym`)
|
||||
A react unique key meta data. Usually for homogeneous list-items.
|
||||
Usually needed for list-items generated by looping over
|
||||
some kind of collection.
|
||||
More here https://reactjs.org/docs/lists-and-keys.html#keys
|
||||
|
||||
`type`
|
||||
`:default` (default), `:small`, `:section-header`, or `:divider`
|
||||
`:section-header`
|
||||
Specifying only these is sufficient.
|
||||
{:title <Section title> :type :section-header}
|
||||
Optionally set `container-margin-top/bottom`
|
||||
`:divider`
|
||||
A simple common gray divider seen in various screens.
|
||||
Simply use:
|
||||
{:type :divider} and specify nothing else.
|
||||
White-space above and below it can be controlled by
|
||||
`container-margin-top/bottom` specified for list-item above/below
|
||||
|
||||
`theme`
|
||||
`:default` (default), `:action`, `:action-destructive`,
|
||||
or `:selectable`
|
||||
`:selectable`
|
||||
A theme for list-item groups having radio button accessory.
|
||||
Use it together with `selected?` key. See below.
|
||||
|
||||
`container-margin-top`
|
||||
`container-margin-bottom`
|
||||
Integer - 0 by default
|
||||
Usually the first item has top margin, and the last item has bottom margin.
|
||||
|
||||
`icon`
|
||||
Any one of keyword representing `:main-icon/icon`, or
|
||||
string representing `photo-path` base64 data, or `component`.
|
||||
If component make sure to make it 40x40 size.
|
||||
|
||||
`title-prefix`
|
||||
Any one of keyword representing an `vector-icon/icon`,
|
||||
`:main-icons/tiny-icons`(16x16) are preferred
|
||||
In which case it will automatically have 4px `:margin-top`;
|
||||
Any other `vector-icon/icon` is also acceptable.
|
||||
In which case it is better to specify height.
|
||||
Best to keep it <= 20. See related height/width below.
|
||||
String, keyword (gets converted to string),
|
||||
Number (gets converted to string), or component.
|
||||
|
||||
`title-prefix-width`
|
||||
`title-prefix-height`
|
||||
Optional width/height for when title/prefix is not a tiny-icon
|
||||
i.e. when icon height/height > 16, or when component.
|
||||
Do not specify if title-prefix is tiny-icon
|
||||
|
||||
`title`
|
||||
Any one of string, keyword representing translated string in the form of
|
||||
:t/{translation-key-in-translation-files},
|
||||
Keyword(gets converted to string),
|
||||
Number(gets converted to string), or
|
||||
Component - When component is used best to keep the style similar.
|
||||
to `styles/title-row-container` and/or `styles/title`.
|
||||
|
||||
`title-color-override`
|
||||
colors/color - only occasionally needed, self-explanatory
|
||||
|
||||
`title-accessibility-label`
|
||||
`:accessibility-label` for title text component.
|
||||
Sometimes needed for title - e.g. chat-list-item.
|
||||
Makes sense since `title` is the key element of a list item.
|
||||
|
||||
`title-row-accessory`
|
||||
Component - Especially made for chat list item, but may serve other
|
||||
purpose in the unlikely future. Wrapper already has 2px :margin-top.
|
||||
Best to keep it <= 18px high.
|
||||
|
||||
`subtitle`
|
||||
Any one of string, keyword representing translated string in the form of
|
||||
:t/{translation-key-in-translation-files},
|
||||
Keyword(gets converted to string),
|
||||
Number(gets converted to string), or
|
||||
Component - when component is used best to keep the style similar
|
||||
to `styles/subtitle-title-row-container` and/or `styles/subtitle`.
|
||||
|
||||
`subtitle-max-lines`
|
||||
Integer - 1 by default - self-explanatory
|
||||
|
||||
`subtitle-row-accessory`
|
||||
Component
|
||||
Made specially for chat-list to hold unread messages counter.
|
||||
|
||||
Content
|
||||
component - to replace entire title-column area
|
||||
For visual consistancy with other list-items
|
||||
Best to keep height <= 40 for `:default` `type`.
|
||||
Best to keep height <= 30 for `:small` `type`.
|
||||
Best to keep inner element styles similar to
|
||||
`styles/subtitle-title-row-container` and/or `styles/subtitle`.
|
||||
|
||||
`accessories`
|
||||
Vector of `:chevron`, Any one of keyword representing `:main-icon/icon`,
|
||||
`number`, `keyword` or `component`
|
||||
Long stringified accessory has max-width of 62% of device width.
|
||||
That means `title` is also constrained to not be longer than
|
||||
30ish%(considering hard right-margin in `title` of 16px)
|
||||
In cases of edge cases where title/accessories are
|
||||
butting against each other, use component for textual accessories
|
||||
with `title` as component as well as necessary.
|
||||
Use best judgement with respect to smaller width screens.
|
||||
|
||||
`on-press/on-long-press`
|
||||
Function - self explanatory
|
||||
|
||||
`error`
|
||||
String - error tooltip
|
||||
|
||||
`accessibility-label`
|
||||
:keyword - self explanatory
|
||||
|
||||
`disabled?`
|
||||
Boolean - false by default - self explanatory
|
||||
|
||||
`selected?`
|
||||
Boolean
|
||||
When (= :theme :selectable) this switch controls whether the
|
||||
list-item is in a visually selected state. Background-color
|
||||
of list-item is colors/gray-selected. Useful for selectable
|
||||
list-items like list with radio buttons."
|
||||
|
||||
[_]
|
||||
(let [width (reagent/atom 0)
|
||||
r-key (name (gensym "list-item"))]
|
||||
(reagent/create-class
|
||||
{:reagent-render
|
||||
(fn
|
||||
[{:keys [react-key type theme container-margin-top container-margin-bottom
|
||||
icon title-prefix title-prefix-width title-prefix-height
|
||||
title title-color-override title-row-accessory
|
||||
title-accessibility-label subtitle subtitle-max-lines
|
||||
subtitle-row-accessory content accessories on-press
|
||||
on-long-press error accessibility-label disabled? selected?]
|
||||
:or {react-key r-key
|
||||
type :default
|
||||
theme :default
|
||||
disabled? false
|
||||
container-margin-top 0
|
||||
container-margin-bottom 0
|
||||
subtitle-max-lines 1}}]
|
||||
(let [title-row-elements {:title title
|
||||
:title-color-override title-color-override
|
||||
:title-accessibility-label title-accessibility-label
|
||||
:title-prefix title-prefix
|
||||
:title-prefix-width title-prefix-width
|
||||
:title-prefix-height title-prefix-height
|
||||
:title-row-accessory title-row-accessory}
|
||||
subtitle-row-elements {:subtitle subtitle
|
||||
:subtitle-max-lines subtitle-max-lines
|
||||
:subtitle-row-accessory subtitle-row-accessory}
|
||||
theme-select? (= theme :selectable)
|
||||
radio-selected? (and theme-select? selected?)]
|
||||
^{:key react-key}
|
||||
(if (= type :divider)
|
||||
divider
|
||||
[react/view {:style {:margin-top container-margin-top
|
||||
:margin-bottom container-margin-bottom}
|
||||
:on-layout #(reset! width (-> ^js % .-nativeEvent .-layout .-width))}
|
||||
[react/touchable-highlight
|
||||
(cond-> {:on-press (when (not theme-select?) on-press)
|
||||
:on-press-in (when theme-select? on-press)
|
||||
:on-long-press on-long-press
|
||||
:underlay-color colors/gray-transparent-40
|
||||
:active-opacity (if theme-select? 1 0.85)
|
||||
:disabled (or (not on-press) selected? disabled?)}
|
||||
accessibility-label
|
||||
(assoc :accessibility-label accessibility-label))
|
||||
[react/view {:style (styles/container type radio-selected?)}
|
||||
(when icon
|
||||
[icon-column icon theme disabled?])
|
||||
|
||||
(when (or title subtitle content)
|
||||
[title-column
|
||||
title-row-elements subtitle-row-elements
|
||||
type icon disabled? theme content accessories])
|
||||
|
||||
(if theme-select?
|
||||
[react/view styles/accessories-container
|
||||
[radio/radio radio-selected?]]
|
||||
(when accessories
|
||||
[accessories-column accessories width]))]]
|
||||
(when error
|
||||
[tooltip/tooltip error styles/error])])))})))
|
|
@ -1,17 +1,31 @@
|
|||
(ns status-im.ui.components.toolbar
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.button :as button]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(defn toolbar [{:keys [center left right show-border?]}]
|
||||
(defn toolbar-container [{:keys [show-border? size center?]
|
||||
:or {size :default}}]
|
||||
(merge {:align-items :center
|
||||
:padding-horizontal 8
|
||||
:flex-direction :row}
|
||||
(when center?
|
||||
{:justify-content :center})
|
||||
(when show-border?
|
||||
{:border-top-width 1
|
||||
:border-top-color colors/gray-lighter})
|
||||
(case size
|
||||
:large {:height 60}
|
||||
{:height 52})))
|
||||
|
||||
;; TODO(Ferossgp): Allow components when moving to Quo
|
||||
(defn toolbar [{:keys [center left right show-border? size]}]
|
||||
(if center
|
||||
[react/view (merge {:height 52 :align-items :center :justify-content :center}
|
||||
(when show-border? {:border-top-width 1 :border-top-color colors/gray-lighter}))
|
||||
[button/button center]]
|
||||
[react/view (merge {:height 52 :align-items :center :flex-direction :row}
|
||||
(when show-border? {:border-top-width 1 :border-top-color colors/gray-lighter}))
|
||||
(when left
|
||||
[button/button left])
|
||||
[react/view {:style (toolbar-container {:show-border? show-border?
|
||||
:center? true
|
||||
:size size})}
|
||||
center]
|
||||
[react/view {:style (toolbar-container {:show-border? show-border?
|
||||
:center? false
|
||||
:size size})}
|
||||
(when left left)
|
||||
[react/view {:flex 1}]
|
||||
(when right
|
||||
[button/button right])]))
|
||||
(when right right)]))
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
(ns status-im.ui.components.topbar
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[quo.core :as quo]
|
||||
[status-im.utils.label :as utils.label]))
|
||||
|
||||
(defn default-navigation [modal?]
|
||||
|
@ -21,17 +21,17 @@
|
|||
|
||||
(defn button [value nav?]
|
||||
(let [{:keys [handler icon label accessibility-label]} value]
|
||||
[react/touchable-highlight {:on-press #(when handler (handler))}
|
||||
[react/view (cond-> {:padding-horizontal (if nav? 16 10) :height 56
|
||||
:align-items :center :justify-content :center}
|
||||
accessibility-label
|
||||
(assoc :accessibility-label accessibility-label))
|
||||
[react/view {:padding-horizontal (if nav? 8 0)}
|
||||
[quo/button (merge {:on-press #(when handler (handler))}
|
||||
(cond
|
||||
icon {:type :icon
|
||||
:theme :icon}
|
||||
label {:type :secondary})
|
||||
(when accessibility-label
|
||||
{:accessibility-label accessibility-label}))
|
||||
(cond
|
||||
icon
|
||||
[icons/icon icon]
|
||||
label
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(utils.label/stringify label)])]]))
|
||||
icon icon
|
||||
label (utils.label/stringify label))]]))
|
||||
|
||||
(def default-title-padding 16)
|
||||
;; TODO(Ferossgp): Tobbar should handle safe area
|
||||
|
|
|
@ -1,65 +1,45 @@
|
|||
(ns status-im.ui.screens.about-app.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.copyable-text :as copyable-text]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.about-app.styles :as styles])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- data [app-version node-version]
|
||||
[{:type :small
|
||||
:title :t/privacy-policy
|
||||
:accessibility-label :privacy-policy
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:privacy-policy/privacy-policy-button-pressed])
|
||||
:accessories [:chevron]}
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text app-version}
|
||||
[list-item/list-item
|
||||
{:type :small
|
||||
:accessibility-label :app-version
|
||||
:title-prefix :t/version
|
||||
:title
|
||||
[react/text
|
||||
{:number-of-lines 1
|
||||
:ellipsize-mode :middle
|
||||
:style
|
||||
{:color colors/gray
|
||||
:padding-left 16
|
||||
:text-align :right
|
||||
:line-height 22}}
|
||||
app-version]}]]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text node-version}
|
||||
[list-item/list-item
|
||||
{:type :small
|
||||
:accessibility-label :node-version
|
||||
:title-prefix :t/node-version
|
||||
:title
|
||||
[react/text
|
||||
{:number-of-lines 1
|
||||
:ellipsize-mode :middle
|
||||
:style
|
||||
{:color colors/gray
|
||||
:padding-left 16
|
||||
:text-align :right
|
||||
:line-height 22}}
|
||||
node-version]}]]])
|
||||
|
||||
(views/defview about-app []
|
||||
(views/letsubs [app-version [:get-app-short-version]
|
||||
node-version [:get-app-node-version]]
|
||||
[react/view {:flex 1 :background-color colors/white}
|
||||
[topbar/topbar {:title :t/about-app}]
|
||||
[list/flat-list
|
||||
{:data (data app-version node-version)
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]]))
|
||||
[react/scroll-view
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/privacy-policy)
|
||||
:accessibility-label :privacy-policy
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:privacy-policy/privacy-policy-button-pressed])
|
||||
:chevron true}]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text app-version}
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:accessibility-label :app-version
|
||||
:title (i18n/label :t/version)
|
||||
:accessory :text
|
||||
:accessory-text app-version}]]
|
||||
[copyable-text/copyable-text-view
|
||||
{:copied-text node-version}
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:accessibility-label :node-version
|
||||
:title (i18n/label :t/node-version)
|
||||
:accessory :text
|
||||
:accessory-text node-version}]]]]))
|
||||
|
||||
(views/defview learn-more-sheet []
|
||||
(views/letsubs [{:keys [title content]} [:bottom-sheet/options]]
|
||||
|
|
|
@ -5,24 +5,24 @@
|
|||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.add-new.new-chat.styles :as styles]
|
||||
[status-im.utils.debounce :as debounce]
|
||||
[quo.core :as quo]
|
||||
[status-im.utils.utils :as utils])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- render-row [row _ _]
|
||||
[list-item/list-item
|
||||
{:title (multiaccounts/displayed-name row)
|
||||
:icon [chat-icon/contact-icon-contacts-tab row]
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/start-chat
|
||||
(:public-key row)
|
||||
{:navigation-reset? true}])}])
|
||||
[quo/list-item
|
||||
{:title (multiaccounts/displayed-name row)
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:chat.ui/start-chat
|
||||
(:public-key row)
|
||||
{:navigation-reset? true}])}])
|
||||
|
||||
(defn- icon-wrapper [color icon]
|
||||
[react/view
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.ui.screens.advanced-settings.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar])
|
||||
|
@ -11,74 +12,68 @@
|
|||
waku-enabled
|
||||
waku-bloom-filter-mode
|
||||
current-fleet]}]
|
||||
[{:type :small
|
||||
:title :t/network
|
||||
[{:size :small
|
||||
:title (i18n/label :t/network)
|
||||
:accessibility-label :network-button
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :network-settings])
|
||||
:accessories [network-name :chevron]}
|
||||
{:type :small
|
||||
:title :t/network-info
|
||||
:accessory :text
|
||||
:accessory-text network-name
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/network-info)
|
||||
:accessibility-label :network-button
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :network-info])
|
||||
:accessories [:chevron]}
|
||||
:chevron true}
|
||||
;; TODO - uncomment when implemented
|
||||
;; {:type :small
|
||||
;; {:size :small
|
||||
;; :title :t/les-ulc
|
||||
;; :accessibility-label :log-level-settings-button
|
||||
;; :accessories [:t/ulc-enabled :chevron]}
|
||||
{:type :small
|
||||
:title :t/log-level
|
||||
{:size :small
|
||||
:title (i18n/label :t/log-level)
|
||||
:accessibility-label :log-level-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :log-level-settings])
|
||||
:accessories [current-log-level :chevron]}
|
||||
{:type :small
|
||||
:title :t/fleet
|
||||
:accessory :text
|
||||
:accessory-text current-log-level
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/fleet)
|
||||
:accessibility-label :fleet-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :fleet-settings])
|
||||
:accessories [current-fleet :chevron]}
|
||||
{:type :small
|
||||
:title :t/bootnodes
|
||||
:accessory :text
|
||||
:accessory-text current-fleet
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/bootnodes)
|
||||
:accessibility-label :bootnodes-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||
:accessories [:chevron]}
|
||||
{:type :small
|
||||
:title :t/waku-enabled
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/waku-enabled)
|
||||
:accessibility-label :waku-enabled-settings-switch
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-enabled-switched (not waku-enabled)])
|
||||
:accessories
|
||||
[[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value waku-enabled
|
||||
:on-value-change
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-enabled-switched (not waku-enabled)])
|
||||
:disabled false}]]}
|
||||
{:type :small
|
||||
:title :t/waku-bloom-filter-mode
|
||||
:accessory :switch
|
||||
:active waku-enabled}
|
||||
{:size :small
|
||||
:title (i18n/label :t/waku-bloom-filter-mode)
|
||||
:accessibility-label :waku-bloom-filter-mode-settings-switch
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
:accessories
|
||||
[[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value waku-bloom-filter-mode
|
||||
:on-value-change
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
:disabled false}]]}
|
||||
#_{:type :small
|
||||
:accessory :switch
|
||||
:active waku-bloom-filter-mode}
|
||||
#_{:size :small
|
||||
:title :t/dev-mode
|
||||
:accessibility-label :dev-mode-settings-switch
|
||||
:container-margin-bottom 8
|
||||
|
@ -97,22 +92,17 @@
|
|||
|
||||
(defn- dev-mode-settings-data [chaos-mode?]
|
||||
[{:container-margin-top 8
|
||||
;; FIXME
|
||||
:type :section-header
|
||||
:title :t/dev-mode-settings}
|
||||
{:type :small
|
||||
:title :t/chaos-mode
|
||||
:title (i18n/label :t/dev-mode-settings)}
|
||||
{:size :small
|
||||
:title (i18n/label :t/chaos-mode)
|
||||
:accessibility-label :chaos-mode-settings-switch
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/chaos-mode-switched (not chaos-mode?)])
|
||||
:accessories
|
||||
[[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value chaos-mode?
|
||||
:on-value-change
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/chaos-mode-switched (not chaos-mode?)])
|
||||
:disabled false}]]}
|
||||
:accessory :switch
|
||||
:active chaos-mode?}
|
||||
[react/view {:height 24}]])
|
||||
|
||||
(defn- flat-list-data [{:keys [dev-mode?
|
||||
|
@ -125,6 +115,11 @@
|
|||
;; else
|
||||
(normal-mode-settings-data options)))
|
||||
|
||||
(defn- render-item [props]
|
||||
(if (= (:type props) :section-header)
|
||||
[quo/list-header (:title props)]
|
||||
[quo/list-item props]))
|
||||
|
||||
(views/defview advanced-settings []
|
||||
(views/letsubs [{:keys [chaos-mode?]} [:multiaccount]
|
||||
network-name [:network-name]
|
||||
|
@ -136,13 +131,12 @@
|
|||
[topbar/topbar {:title :t/advanced}]
|
||||
[list/flat-list
|
||||
{:data (flat-list-data
|
||||
{:network-name network-name
|
||||
:current-log-level current-log-level
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:waku-enabled waku-enabled
|
||||
{:network-name network-name
|
||||
:current-log-level current-log-level
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:waku-enabled waku-enabled
|
||||
:waku-bloom-filter-mode waku-bloom-filter-mode
|
||||
:chaos-mode? chaos-mode?})
|
||||
|
||||
:chaos-mode? chaos-mode?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]]))
|
||||
:render-fn render-item}]]))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
(views/letsubs [{:keys [appearance]} [:multiaccount]]
|
||||
[react/view {:flex 1}
|
||||
[topbar/topbar {:title :t/appearance :show-border? true}]
|
||||
[list-item/list-item {:type :section-header :title :t/preference :container-margin-top 8}]
|
||||
[quo/list-header (i18n/label :t/preference)]
|
||||
[react/view {:flex-direction :row :flex 1 :padding-horizontal 8
|
||||
:justify-content :space-between :margin-top 16}
|
||||
[button :t/light :theme-light 1 (= 1 appearance)]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.ui.screens.biometric.views
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.biometric.core :as biometric]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
|
@ -43,14 +43,15 @@
|
|||
(if description-label
|
||||
[(i18n/label description-label {:bio-type-label bio-type-label})]
|
||||
description-text)))
|
||||
[button/button {:label (i18n/label ok-button-label
|
||||
{:bio-type-label bio-type-label})
|
||||
:style {:margin-top 24}
|
||||
:on-press #(re-frame/dispatch [on-confirm])}]
|
||||
[button/button {:label (or cancel-button-label :t/cancel)
|
||||
:style {:margin-bottom 24}
|
||||
:type :secondary
|
||||
:on-press #(re-frame/dispatch [(or on-cancel :hide-popover)])}]]))
|
||||
[react/view {:padding-vertical 16}
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/button {:on-press #(re-frame/dispatch [on-confirm])}
|
||||
(i18n/label ok-button-label
|
||||
{:bio-type-label bio-type-label})]]
|
||||
[quo/button {:type :secondary
|
||||
:on-press #(re-frame/dispatch [(or on-cancel :hide-popover)])}
|
||||
(or cancel-button-label
|
||||
(i18n/label :t/cancel))]]]))
|
||||
|
||||
(defn disable-password-saving-popover []
|
||||
(let [bio-label-type (get-bio-type-label)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
|
||||
(:require [status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.utils.styles :as styles]))
|
||||
|
||||
(def edit-bootnode-view
|
||||
|
@ -8,11 +7,6 @@
|
|||
:margin-horizontal 16
|
||||
:margin-vertical 15})
|
||||
|
||||
(def bottom-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
|
||||
(def button-container
|
||||
{:margin-top 8
|
||||
:margin-bottom 16
|
||||
|
@ -32,6 +26,3 @@
|
|||
(def delete-button
|
||||
(assoc button
|
||||
:background-color colors/red))
|
||||
|
||||
(def container
|
||||
components.styles/flex)
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
|
||||
|
@ -28,44 +27,44 @@
|
|||
name (get-in manage-bootnode [:name :value])
|
||||
is-valid? (empty? validation-errors)
|
||||
invalid-url? (contains? validation-errors :url)]
|
||||
[react/view styles/container
|
||||
[react/keyboard-avoiding-view components.styles/flex
|
||||
[topbar/topbar {:title (if id :t/bootnode-details :t/add-bootnode)}]
|
||||
[react/scroll-view {:keyboard-should-persist-taps :handled}
|
||||
[react/view styles/edit-bootnode-view
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/name)
|
||||
:placeholder (i18n/label :t/specify-name)
|
||||
:accessibility-label :bootnode-name
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
|
||||
:auto-focus true}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-vertical 8}
|
||||
[quo/text-input
|
||||
(merge
|
||||
{:label (i18n/label :t/bootnode-address)
|
||||
:placeholder (i18n/label :t/bootnode-format)
|
||||
:accessibility-label :bootnode-address
|
||||
:default-value url
|
||||
:show-cancel false
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])
|
||||
:error (when (and (not (string/blank? url)) invalid-url?)
|
||||
(i18n/label :t/invalid-format
|
||||
{:format (i18n/label :t/bootnode-format)}))
|
||||
:bottom-value 0
|
||||
:after {:icon :main-icons/qr
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
|
||||
{:title (i18n/label :t/add-bootnode)
|
||||
:handler :bootnodes.callback/qr-code-scanned}])}})]]
|
||||
(when id
|
||||
[delete-button id])]]
|
||||
[react/view styles/bottom-container
|
||||
[react/view components.styles/flex]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/save)
|
||||
:disabled? (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:bootnodes.ui/save-pressed])}]]]])))
|
||||
[react/keyboard-avoiding-view {:flex 1}
|
||||
[topbar/topbar {:title (if id :t/bootnode-details :t/add-bootnode)}]
|
||||
[react/scroll-view {:keyboard-should-persist-taps :handled}
|
||||
[react/view styles/edit-bootnode-view
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/name)
|
||||
:placeholder (i18n/label :t/specify-name)
|
||||
:accessibility-label :bootnode-name
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
|
||||
:auto-focus true}]]
|
||||
[react/view
|
||||
{:flex 1
|
||||
:padding-vertical 8}
|
||||
[quo/text-input
|
||||
(merge
|
||||
{:label (i18n/label :t/bootnode-address)
|
||||
:placeholder (i18n/label :t/bootnode-format)
|
||||
:accessibility-label :bootnode-address
|
||||
:default-value url
|
||||
:show-cancel false
|
||||
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])
|
||||
:error (when (and (not (string/blank? url)) invalid-url?)
|
||||
(i18n/label :t/invalid-format
|
||||
{:format (i18n/label :t/bootnode-format)}))
|
||||
:bottom-value 0
|
||||
:after {:icon :main-icons/qr
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
|
||||
{:title (i18n/label :t/add-bootnode)
|
||||
:handler :bootnodes.callback/qr-code-scanned}])}})]]
|
||||
(when id
|
||||
[delete-button id])]]
|
||||
[toolbar/toolbar
|
||||
{:right
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:bootnodes.ui/save-pressed])}
|
||||
(i18n/label :t/save)]}]])))
|
||||
|
|
|
@ -2,20 +2,21 @@
|
|||
(:require [status-im.ui.components.list.views :as list]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.utils.utils :as utils]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(defn render-account [dapps-account]
|
||||
(fn [account]
|
||||
[list-item/list-item
|
||||
{:theme :selectable
|
||||
:selected? (= (:address dapps-account) (:address account))
|
||||
:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||
:title (:name account)
|
||||
:subtitle (utils/get-shortened-checksum-address (:address account))
|
||||
:on-press #(re-frame/dispatch [:dapps-account-selected (:address account)])}]))
|
||||
[quo/list-item
|
||||
(merge {:accessory :radio
|
||||
:active (= (:address dapps-account) (:address account))
|
||||
:icon [chat-icon/custom-icon-view-list (:name account) (:color account)]
|
||||
:title (:name account)
|
||||
:subtitle (utils/get-shortened-checksum-address (:address account))}
|
||||
(when (not= (:address dapps-account) (:address account))
|
||||
{:on-press #(re-frame/dispatch [:dapps-account-selected (:address account)])}))]))
|
||||
|
||||
(defn accounts-list [accounts dapps-account]
|
||||
(fn []
|
||||
|
@ -24,4 +25,4 @@
|
|||
(i18n/label :t/select-account-dapp)]
|
||||
[list/flat-list {:data accounts
|
||||
:key-fn :address
|
||||
:render-fn (render-account dapps-account)}]]))
|
||||
:render-fn (render-account dapps-account)}]]))
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
:border-radius 36
|
||||
:padding-horizontal 8
|
||||
:padding-vertical 6
|
||||
:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:shadow-offset {:width 0 :height 1}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.browser.accounts :as accounts]
|
||||
|
@ -14,32 +14,32 @@
|
|||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn list-item [{:keys [browser-id name url]}]
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
{:on-press #(re-frame/dispatch [:browser.ui/browser-item-selected browser-id])
|
||||
:on-long-press (fn []
|
||||
(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[react/view {:flex 1}
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/remove
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/remove)
|
||||
:accessibility-label :remove-dapp-from-list
|
||||
:icon :main-icons/delete
|
||||
:on-press #(hide-sheet-and-dispatch [:browser.ui/remove-browser-pressed browser-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action-destructive
|
||||
:title :t/clear-all
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/clear-all)
|
||||
:accessibility-label :clear-all-dapps
|
||||
:icon :main-icons/delete
|
||||
:on-press #(hide-sheet-and-dispatch [:browser.ui/clear-all-browsers-pressed])}]])
|
||||
:content-height 128}]))
|
||||
:title name
|
||||
:subtitle (or url :t/dapp)
|
||||
:subtitle (or url (i18n/label :t/dapp))
|
||||
:icon [react/view (styles/browser-icon-container)
|
||||
[icons/icon :main-icons/browser {:color colors/gray}]]}])
|
||||
|
||||
|
@ -61,8 +61,7 @@
|
|||
(i18n/label :t/recent)]])])
|
||||
|
||||
(views/defview select-account []
|
||||
(views/letsubs [height [:dimensions/window-height]
|
||||
accounts [:accounts-without-watch-only]
|
||||
(views/letsubs [accounts [:accounts-without-watch-only]
|
||||
{:keys [name color] :as dapps-account} [:dapps-account]]
|
||||
[react/view {:position :absolute
|
||||
:z-index 2
|
||||
|
@ -71,17 +70,17 @@
|
|||
:left 0
|
||||
:right 0
|
||||
:padding-horizontal 32}
|
||||
[react/touchable-highlight
|
||||
[quo/button
|
||||
{:accessibility-label :select-account
|
||||
:type :scale
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (accounts/accounts-list accounts dapps-account)
|
||||
:content-height (/ height 2)}])}
|
||||
{:content (accounts/accounts-list accounts dapps-account)}])}
|
||||
[react/view (styles/dapps-account color)
|
||||
[icons/icon :main-icons/account {:color colors/white-persist}]
|
||||
[react/view {:flex-shrink 1}
|
||||
[react/text {:numberOfLines 1
|
||||
:style {:margin-horizontal 6 :color colors/white-persist
|
||||
:typography :main-medium}}
|
||||
:typography :main-medium}}
|
||||
name]]
|
||||
[icons/icon :main-icons/dropdown {:color colors/white-transparent-persist}]]]]))
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.browser.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.button :as button])
|
||||
[quo.core :as quo])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn hide-panel-anim
|
||||
|
@ -116,14 +116,20 @@
|
|||
(:name dapps-account)]]])
|
||||
[react/text {:style styles/permissions-panel-description-label :number-of-lines 2}
|
||||
description]
|
||||
[react/view {:flex-direction :row :margin-top 24}
|
||||
[button/button
|
||||
{:theme :red
|
||||
:style {:flex 1}
|
||||
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-denied])
|
||||
:label (i18n/label :t/deny)}]
|
||||
[button/button
|
||||
{:theme :green
|
||||
:style {:flex 1}
|
||||
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-allowed])
|
||||
:label (i18n/label :t/allow)}]]]]))))
|
||||
[react/view {:style {:flex-direction :row
|
||||
:justify-content :center
|
||||
:margin-horizontal 8
|
||||
:margin-top 24}}
|
||||
[react/view {:flex 1
|
||||
:margin-horizontal 8}
|
||||
[quo/button
|
||||
{:theme :negative
|
||||
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-denied])}
|
||||
(i18n/label :t/deny)]]
|
||||
[react/view {:flex 1
|
||||
:margin-horizontal 8}
|
||||
[quo/button
|
||||
{:theme :positive
|
||||
:style {:margin-horizontal 8}
|
||||
:on-press #(re-frame/dispatch [:browser.permissions.ui/dapp-permission-allowed])}
|
||||
(i18n/label :t/allow)]]]]]))))
|
||||
|
|
|
@ -6,16 +6,18 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[quo.core :as quo]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn button [showing?]
|
||||
[react/touchable-highlight
|
||||
[quo/button
|
||||
{:on-press (fn [_]
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-bottom-sheet (when-not showing? :extensions)}])
|
||||
(when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
|
||||
:accessibility-label :show-extensions-icon}
|
||||
[icons/icon :main-icons/commands {:container-style {:margin 14 :margin-right 10}
|
||||
:color (if showing? colors/blue colors/gray)}]])
|
||||
:accessibility-label :show-extensions-icon
|
||||
:type :icon
|
||||
:theme (if showing? :main :disabled)}
|
||||
:main-icons/commands])
|
||||
|
||||
(defn show-panel-anim
|
||||
[bottom-anim-value alpha-value]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.ui.screens.chat.group
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.universal-links.core :as links]
|
||||
[status-im.ui.screens.chat.styles.main :as style]
|
||||
|
@ -10,10 +10,10 @@
|
|||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn join-chat-button [chat-id]
|
||||
[button/button
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/join-pressed chat-id])
|
||||
:label :t/join-group-chat}])
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/join-pressed chat-id])}
|
||||
(i18n/label :t/join-group-chat)])
|
||||
|
||||
(defn decline-chat [chat-id]
|
||||
[react/touchable-highlight
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
(:require [status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.screens.chat.sheets :as sheets]))
|
||||
|
||||
|
@ -18,17 +19,17 @@
|
|||
:background-color :black})
|
||||
:resize-mode :contain
|
||||
:source {:uri (:image content)}}]]
|
||||
[react/view {:flex-direction :row :padding-horizontal 8
|
||||
:justify-content :space-between :align-items :center}
|
||||
[react/view {:flex-direction :row :padding-horizontal 8
|
||||
:justify-content :space-between :align-items :center}
|
||||
[react/view {:width 64}]
|
||||
[button/button {:on-press #(re-frame/dispatch [:navigate-back])
|
||||
:type :secondary
|
||||
:label :t/close
|
||||
:text-style {:color colors/white-persist}}]
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])
|
||||
:type :secondary
|
||||
:text-style {:color colors/white-persist}}
|
||||
(i18n/label :t/close)]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (sheets/image-long-press message true)
|
||||
:height 64}])}
|
||||
[icons/icon :main-icons/more {:container-style {:width 24 :height 24
|
||||
[icons/icon :main-icons/more {:container-style {:width 24 :height 24
|
||||
:margin 20}
|
||||
:color colors/white-persist}]]]]]))
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.utils.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||
[status-im.ui.components.animation :as anim]))
|
||||
|
||||
(defn show-panel-anim
|
||||
[bottom-anim-value alpha-value]
|
||||
|
@ -18,34 +18,32 @@
|
|||
:useNativeDriver true})])))
|
||||
|
||||
(defn input-button [images-showing?]
|
||||
[react/touchable-highlight
|
||||
{:on-press
|
||||
(fn [_]
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props
|
||||
{:input-bottom-sheet (when-not images-showing? :images)}])
|
||||
(when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
|
||||
:accessibility-label :show-photo-icon}
|
||||
[icons/icon
|
||||
:main-icons/photo
|
||||
{:container-style {:margin 14 :margin-right 6}
|
||||
:color (if images-showing? colors/blue colors/gray)}]])
|
||||
[quo/button
|
||||
{:on-press (fn [_]
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props
|
||||
{:input-bottom-sheet (when-not images-showing? :images)}])
|
||||
(when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
|
||||
:accessibility-label :show-photo-icon
|
||||
:type :icon
|
||||
:theme (if images-showing? :main :disabled)}
|
||||
:main-icons/photo])
|
||||
|
||||
(defn take-picture []
|
||||
(react/show-image-picker-camera #(re-frame/dispatch [:chat.ui/image-captured (.-path %)]) {}))
|
||||
|
||||
(defn buttons []
|
||||
[react/view
|
||||
[react/touchable-highlight {:on-press take-picture}
|
||||
[react/view {:style {:width 44 :height 44
|
||||
:align-items :center :justify-content :center}
|
||||
:accessibility-label :take-picture}
|
||||
[icons/icon :main-icons/camera {:color colors/black}]]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/open-image-picker])
|
||||
:style {:margin-top 8}}
|
||||
[react/view {:style {:width 44 :height 44
|
||||
:align-items :center :justify-content :center}
|
||||
:accessibility-label :open-gallery}
|
||||
[icons/icon :main-icons/gallery {:color colors/black}]]]])
|
||||
[quo/button {:type :icon
|
||||
:theme :icon
|
||||
:accessibility-label :take-picture
|
||||
:on-press take-picture}
|
||||
:main-icons/camera]
|
||||
[react/view {:style {:padding-top 8}}
|
||||
[quo/button {:on-press #(re-frame/dispatch [:chat.ui/open-image-picker])
|
||||
:accessibility-label :open-gallery
|
||||
:type :icon
|
||||
:theme :icon}
|
||||
:main-icons/gallery]]])
|
||||
|
||||
(defn image-preview [uri first? panel-height]
|
||||
(let [wh (/ (- panel-height 8) 2)]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.ui.screens.chat.input.send-button
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.screens.chat.styles.input.send-button :as style]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(defn sendable? [input-text-empty? disconnected? login-processing?]
|
||||
|
@ -14,9 +14,9 @@
|
|||
(letsubs [disconnected? [:disconnected?]
|
||||
{:keys [processing]} [:multiaccounts/login]]
|
||||
(when (sendable? input-text-empty? disconnected? processing)
|
||||
[react/touchable-highlight
|
||||
{:on-press on-send-press}
|
||||
[quo/button {:type :scale
|
||||
:on-press on-send-press}
|
||||
[vector-icons/icon :main-icons/arrow-up
|
||||
{:container-style style/send-message-container
|
||||
:accessibility-label :send-message-button
|
||||
:color colors/white-persist}]])))
|
||||
:color colors/white-persist}]])))
|
||||
|
|
|
@ -5,258 +5,252 @@
|
|||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.utils.universal-links.core :as universal-links]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.ui.screens.chat.styles.message.sheets :as sheets.styles]
|
||||
[status-im.ui.components.list-item.views :as list-item]))
|
||||
[quo.core :as quo]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn view-profile [{:keys [name helper]}]
|
||||
[react/view
|
||||
[react/text {:style {:font-weight "500"
|
||||
:line-height 22
|
||||
:font-size 15
|
||||
:color colors/black}}
|
||||
name]
|
||||
[react/text {:style {:line-height 22
|
||||
:font-size 15
|
||||
:color colors/gray}}
|
||||
(i18n/label helper)]])
|
||||
|
||||
(defn one-to-one-chat-actions [{:keys [chat-id]}]
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path chat-id])
|
||||
(defn one-to-one-chat-accents [{:keys [chat-id]}]
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path chat-id])
|
||||
contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity chat-id])]
|
||||
[react/view
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:icon photo
|
||||
:title [view-profile {:name contact-name
|
||||
:helper :t/view-profile}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab photo]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/mark-all-read
|
||||
:chevron true
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/mark-all-read)
|
||||
:accessibility-label :mark-all-read-button
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/clear-history
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/clear-history)
|
||||
:accessibility-label :clear-history-button
|
||||
:icon :main-icons/close
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/fetch-history
|
||||
:icon :main-icons/close
|
||||
:on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/fetch-history)
|
||||
:accessibility-label :fetch-history-button
|
||||
:icon :main-icons/arrow-down
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/fetch-history-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action-destructive
|
||||
:title :t/delete-chat
|
||||
:icon :main-icons/arrow-down
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/fetch-history-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/delete-chat)
|
||||
:accessibility-label :delete-chat-button
|
||||
:icon :main-icons/delete
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
||||
:icon :main-icons/delete
|
||||
:on-press #(re-frame/dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
||||
|
||||
(defn public-chat-actions [{:keys [chat-id]}]
|
||||
(defn public-chat-accents [{:keys [chat-id]}]
|
||||
(let [link (universal-links/generate-link :public-chat :external chat-id)
|
||||
message (i18n/label :t/share-public-chat-text {:link link})]
|
||||
[react/view
|
||||
(when-not platform/desktop?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/share-chat
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/share-chat)
|
||||
:accessibility-label :share-chat-button
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(list-selection/open-share {:message message}))}])
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/mark-all-read
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
;; https://github.com/facebook/react-native/pull/26839
|
||||
(js/setTimeout
|
||||
#(list-selection/open-share {:message message})
|
||||
250))}])
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/mark-all-read)
|
||||
:accessibility-label :mark-all-read-button
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/clear-history
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/clear-history)
|
||||
:accessibility-label :clear-history-button
|
||||
:icon :main-icons/close
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/fetch-history
|
||||
:icon :main-icons/close
|
||||
:on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/fetch-history)
|
||||
:accessibility-label :fetch-history-button
|
||||
:icon :main-icons/arrow-down
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/fetch-history-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action-destructive
|
||||
:title :t/delete-chat
|
||||
:icon :main-icons/arrow-down
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/fetch-history-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/delete-chat)
|
||||
:accessibility-label :delete-chat-button
|
||||
:icon :main-icons/delete
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
||||
:icon :main-icons/delete
|
||||
:on-press #(re-frame/dispatch [:chat.ui/remove-chat-pressed chat-id])}]]))
|
||||
|
||||
(defn group-chat-actions []
|
||||
(defn group-chat-accents []
|
||||
(fn [{:keys [chat-id group-chat chat-name color]}]
|
||||
(let [{:keys [joined?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])]
|
||||
[react/view
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title [view-profile {:name chat-name
|
||||
:helper :t/group-info}]
|
||||
:icon [chat-icon/chat-icon-view-chat-sheet
|
||||
chat-id group-chat chat-name color]
|
||||
:accessories [:chevron]
|
||||
:on-press #(hide-sheet-and-dispatch [:show-group-chat-profile chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/mark-all-read
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title chat-name
|
||||
:subtitle (i18n/label :t/group-info)
|
||||
:icon [chat-icon/chat-icon-view-chat-sheet
|
||||
chat-id group-chat chat-name color]
|
||||
:chevron true
|
||||
:on-press #(hide-sheet-and-dispatch [:show-group-chat-profile chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/mark-all-read)
|
||||
:accessibility-label :mark-all-read-button
|
||||
:icon :main-icons/check
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/clear-history
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/clear-history)
|
||||
:accessibility-label :clear-history-button
|
||||
:icon :main-icons/close
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/fetch-history
|
||||
:on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed chat-id])}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/fetch-history)
|
||||
:accessibility-label :fetch-history-button
|
||||
:icon :main-icons/arrow-down
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/fetch-history-pressed chat-id])}]
|
||||
(when joined?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/leave-chat
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/leave-chat)
|
||||
:accessibility-label :leave-chat-button
|
||||
:icon :main-icons/arrow-left
|
||||
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])])))
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])])))
|
||||
|
||||
(defn actions [{:keys [public? group-chat]
|
||||
:as current-chat}]
|
||||
(cond
|
||||
public? [public-chat-actions current-chat]
|
||||
group-chat [group-chat-actions current-chat]
|
||||
:else [one-to-one-chat-actions current-chat]))
|
||||
public? [public-chat-accents current-chat]
|
||||
group-chat [group-chat-accents current-chat]
|
||||
:else [one-to-one-chat-accents current-chat]))
|
||||
|
||||
(defn options [chat-id message-id]
|
||||
(fn []
|
||||
[react/view
|
||||
[react/i18n-text {:style sheets.styles/sheet-text :key :message-not-sent}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/resend-message
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/resend-message)
|
||||
:icon :main-icons/refresh
|
||||
:accessibility-label :resend-message-button
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/resend-message chat-id message-id])}]
|
||||
[list-item/list-item
|
||||
{:theme :action-destructive
|
||||
:title :t/delete-message
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/delete-message)
|
||||
:icon :main-icons/delete
|
||||
:accessibility-label :delete-transaction-button
|
||||
:accessibility-label :delete-transaccent-button
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/delete-message chat-id message-id])}]]))
|
||||
|
||||
(defn message-long-press [{:keys [content from outgoing] :as message}]
|
||||
(fn []
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path from])
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path from])
|
||||
contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
[react/view
|
||||
(when-not outgoing
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:icon photo
|
||||
:title [view-profile {:name contact-name
|
||||
:helper :t/view-profile}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab photo]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile from])}])
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/message-reply
|
||||
:chevron true
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile from])}])
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/message-reply)
|
||||
:icon :main-icons/reply
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/reply-to-message message])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/sharing-copy-to-clipboard
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/sharing-copy-to-clipboard)
|
||||
:icon :main-icons/copy
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(react/copy-to-clipboard (:text content)))}]
|
||||
(when-not platform/desktop?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/sharing-share
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/sharing-share)
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(list-selection/open-share {:message (:text content)}))}])])))
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
;; https://github.com/facebook/react-native/pull/26839
|
||||
(js/setTimeout
|
||||
#(list-selection/open-share {:message (:text content)})
|
||||
250))}])])))
|
||||
|
||||
(defn sticker-long-press [{:keys [from]}]
|
||||
(fn []
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path from])
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path from])
|
||||
contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
[react/view
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:icon photo
|
||||
:title [view-profile {:name contact-name
|
||||
:helper :t/view-profile}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab photo]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:accessories [:chevron]
|
||||
:chevron true
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/show-profile from])}]])))
|
||||
|
||||
(defn image-long-press [{:keys [content identicon from outgoing] :as message} from-preview?]
|
||||
(fn []
|
||||
(let [{:keys [ens-name alias]} @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
[react/view
|
||||
(when-not outgoing
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:icon (multiaccounts/displayed-photo {:identicon identicon
|
||||
:public-key from})
|
||||
:title [view-profile {:name (or ens-name alias)
|
||||
:helper :t/view-profile}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo {:identicon identicon
|
||||
:public-key from})]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:accessories [:chevron]
|
||||
:chevron true
|
||||
:on-press #(do
|
||||
(when from-preview?
|
||||
(re-frame/dispatch [:navigate-back]))
|
||||
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/message-reply
|
||||
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/message-reply)
|
||||
:icon :main-icons/reply
|
||||
:on-press #(do
|
||||
(when from-preview?
|
||||
(re-frame/dispatch [:navigate-back]))
|
||||
(hide-sheet-and-dispatch [:chat.ui/reply-to-message message]))}]
|
||||
;; we have only base64 string for image, so we need to find a way how to copy it
|
||||
#_[list-item/list-item
|
||||
{:theme :action
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-copy-to-clipboard
|
||||
:icon :main-icons/copy
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(react/copy-to-clipboard (:image content)))}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/save
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/save)
|
||||
:icon :main-icons/download
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/save-image-to-gallery (:image content)]))}]
|
||||
;; we have only base64 string for image, so we need to find a way how to share it
|
||||
#_[list-item/list-item
|
||||
{:theme :action
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-share
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(list-selection/open-share {:message (:image content)}))}]])))
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.chat.stickers.styles :as styles]
|
||||
[status-im.ui.components.animation :as anim]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
|
@ -21,26 +22,26 @@
|
|||
(def scroll-x (reagent/atom 0))
|
||||
|
||||
(defn button [stickers-showing?]
|
||||
[react/touchable-highlight
|
||||
{:on-press (fn [_]
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-bottom-sheet (when-not stickers-showing? :stickers)}])
|
||||
(when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
|
||||
:accessibility-label :show-stickers-icon}
|
||||
[vector-icons/icon :main-icons/stickers {:container-style {:margin 14 :margin-right 6}
|
||||
:color (if stickers-showing? colors/blue colors/gray)}]])
|
||||
[quo/button
|
||||
{:on-press (fn [_]
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:input-bottom-sheet (when-not stickers-showing? :stickers)}])
|
||||
(when-not platform/desktop? (js/setTimeout #(react/dismiss-keyboard!) 100)))
|
||||
:accessibility-label :show-stickers-icon
|
||||
:type :icon
|
||||
:theme (if stickers-showing? :main :disabled)}
|
||||
:main-icons/stickers])
|
||||
|
||||
(defn- no-stickers-yet-panel []
|
||||
[react/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[vector-icons/icon :stickers-icons/stickers-big {:color colors/gray
|
||||
:width 64
|
||||
:height 64}]
|
||||
[react/text {:style {:margin-top 8 :font-size 17}} (i18n/label :t/you-dont-have-stickers)]
|
||||
[react/touchable-opacity {:on-press #(do
|
||||
(re-frame/dispatch [:stickers/load-packs])
|
||||
(re-frame/dispatch [:navigate-to :stickers]))}
|
||||
[react/view {:margin-top 6 :height 44 :justify-content :center}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/get-stickers)]]]])
|
||||
[react/text {:style {:margin-vertical 8 :font-size 17}} (i18n/label :t/you-dont-have-stickers)]
|
||||
[quo/button {:type :secondary
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:stickers/load-packs])
|
||||
(re-frame/dispatch [:navigate-to :stickers]))}
|
||||
(i18n/label :t/get-stickers)]])
|
||||
|
||||
(defn- stickers-panel [stickers window-width]
|
||||
[react/view {:width window-width :flex 1}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
(def input-container
|
||||
{:flex-direction :row
|
||||
:align-items :flex-end})
|
||||
:align-items :center})
|
||||
|
||||
(def input-view
|
||||
{:flex 1
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
:line-height 16
|
||||
:color colors/text-gray})
|
||||
|
||||
(def last-activity-text
|
||||
{:font-size 14
|
||||
:margin-top 4
|
||||
:color colors/text-gray})
|
||||
|
||||
;; this map looks a bit strange
|
||||
;; but this way of setting elevation seems to be the only way to set z-index (in RN 0.30)
|
||||
(defn add-contact []
|
||||
|
|
|
@ -52,13 +52,6 @@
|
|||
{:color colors/blue}]
|
||||
[react/i18n-text {:style style/add-contact-text :key :add-to-contacts}]]])))
|
||||
|
||||
(defn intro-header [name]
|
||||
[react/text {:style (assoc style/intro-header-description
|
||||
:margin-bottom 32)}
|
||||
(str
|
||||
(i18n/label :t/empty-chat-description-one-to-one)
|
||||
name)])
|
||||
|
||||
(defn chat-intro [{:keys [chat-id
|
||||
chat-name
|
||||
group-chat
|
||||
|
|
|
@ -4,16 +4,19 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.list.views :as list.views]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.topbar :as topbar])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn contacts-list-item [{:keys [public-key] :as contact}]
|
||||
[list.views/big-list-item
|
||||
;;TODO this should be done in a subscription
|
||||
{:text (multiaccounts/displayed-name contact)
|
||||
:image-source (multiaccounts/displayed-photo contact)
|
||||
:action-fn #(re-frame/dispatch [:chat.ui/show-profile public-key])}])
|
||||
[quo/list-item
|
||||
{:title (multiaccounts/displayed-name contact)
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}])
|
||||
|
||||
(defview contacts-list []
|
||||
(letsubs [blocked-contacts-count [:contacts/blocked-count]
|
||||
|
@ -22,18 +25,20 @@
|
|||
[topbar/topbar {:title :t/contacts}]
|
||||
[react/scroll-view {:flex 1}
|
||||
(when (pos? blocked-contacts-count)
|
||||
[list.views/big-list-item
|
||||
{:style {:margin-vertical 16}
|
||||
:text (i18n/label :t/blocked-users)
|
||||
:icon :main-icons/cancel
|
||||
:icon-color colors/red
|
||||
:accessibility-label :blocked-users-list-button
|
||||
:accessory-value blocked-contacts-count
|
||||
:action-fn #(re-frame/dispatch [:navigate-to :blocked-users-list])}])
|
||||
[react/view {:margin-vertical 16}
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/blocked-users)
|
||||
:icon :main-icons/cancel
|
||||
:theme :negative
|
||||
:accessibility-label :blocked-users-list-button
|
||||
:chevron true
|
||||
:accessory :text
|
||||
:accessory-text blocked-contacts-count
|
||||
:on-press #(re-frame/dispatch [:navigate-to :blocked-users-list])}]])
|
||||
[list.views/flat-list
|
||||
{:data contacts
|
||||
:key-fn :address
|
||||
:render-fn contacts-list-item}]]]))
|
||||
{:data contacts
|
||||
:key-fn :address
|
||||
:render-fn contacts-list-item}]]]))
|
||||
|
||||
(defview blocked-users-list []
|
||||
(letsubs [blocked-contacts [:contacts/blocked]]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.screens.dapps-permissions.styles :as styles]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.topbar :as topbar]))
|
||||
|
||||
|
@ -16,20 +16,20 @@
|
|||
[icons/icon :main-icons/dapp {:color colors/gray}]])
|
||||
|
||||
(defn prepare-items [{:keys [dapp permissions]}]
|
||||
{:title dapp
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions {:dapp dapp :permissions permissions}])
|
||||
:icon d-icon})
|
||||
{:title dapp
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions {:dapp dapp :permissions permissions}])
|
||||
:icon [d-icon]})
|
||||
|
||||
(defn prepare-items-manage [name]
|
||||
(fn [permission]
|
||||
{:title (cond
|
||||
(= permission constants/dapp-permission-web3)
|
||||
name
|
||||
(= permission constants/dapp-permission-contact-code)
|
||||
:t/contact-code)
|
||||
:type :small
|
||||
:accessories [:main-icons/check]}))
|
||||
{:title (cond
|
||||
(= permission constants/dapp-permission-web3)
|
||||
name
|
||||
(= permission constants/dapp-permission-contact-code)
|
||||
(i18n/label :t/contact-code))
|
||||
:size :small
|
||||
:accessory [icons/icon :main-icons/check {}]}))
|
||||
|
||||
(views/defview dapps-permissions []
|
||||
(views/letsubs [permissions [:dapps/permissions]]
|
||||
|
@ -38,7 +38,7 @@
|
|||
[list/flat-list
|
||||
{:data (vec (map prepare-items (vals permissions)))
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]]))
|
||||
:render-fn quo/list-item}]]))
|
||||
|
||||
(views/defview manage []
|
||||
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]
|
||||
|
@ -48,7 +48,9 @@
|
|||
[list/flat-list
|
||||
{:data (vec (map (prepare-items-manage name) permissions))
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]
|
||||
[react/view {:padding-vertical 16}
|
||||
[components.common/red-button {:label (i18n/label :t/revoke-access)
|
||||
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}]]]))
|
||||
:render-fn quo/list-item}]
|
||||
[react/view {:padding-vertical 16
|
||||
:padding-horizontal 16}
|
||||
[quo/button {:theme :negative
|
||||
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}
|
||||
(i18n/label :t/revoke-access)]]]))
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.radio :as radio]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.chat.utils :as chat.utils]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.screens.chat.message.message :as message]
|
||||
[status-im.ui.screens.chat.styles.message.message :as message.style]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
|
@ -29,16 +28,6 @@
|
|||
[quo.core :as quo])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- button
|
||||
[{:keys [on-press] :as m} label]
|
||||
[components.common/button (merge {:button-style {:margin-vertical 8
|
||||
:padding-horizontal 32
|
||||
:justify-content :center
|
||||
:align-items :center}
|
||||
:on-press on-press
|
||||
:label label}
|
||||
m)])
|
||||
|
||||
(defn- link
|
||||
[{:keys [on-press]} label]
|
||||
[react/touchable-opacity {:on-press on-press
|
||||
|
@ -278,27 +267,6 @@
|
|||
"\n"
|
||||
(i18n/label :t/ens-understand)]])
|
||||
|
||||
(defn- registration-bottom-bar [checked? amount-label sufficient-funds?]
|
||||
[react/view {:style {:border-top-width 1
|
||||
:border-top-color colors/gray-lighter
|
||||
:padding-horizontal 16
|
||||
:padding-vertical 8
|
||||
:flex-direction :row
|
||||
:justify-content :space-between}}
|
||||
[react/view {:flex-direction :row :align-items :center}
|
||||
[react/image {:source tokens/snt-icon-source
|
||||
:style {:width 36 :height 36}}]
|
||||
[react/view {:flex-direction :column :margin 8}
|
||||
[react/text {:style {:font-size 15}}
|
||||
amount-label]
|
||||
[react/text {:style {:color colors/gray :font-size 15}}
|
||||
(i18n/label :t/ens-deposit)]]]
|
||||
[quo/button {:disabled (or (not @checked?) (not sufficient-funds?))
|
||||
:on-press #(debounce/dispatch-and-chill [::ens/register-name-pressed] 2000)}
|
||||
(if sufficient-funds?
|
||||
(i18n/label :t/ens-register)
|
||||
(i18n/label :t/not-enough-snt))]])
|
||||
|
||||
(defn- registration
|
||||
[checked contract address public-key]
|
||||
[react/view {:style {:flex 1 :margin-top 24}}
|
||||
|
@ -309,38 +277,56 @@
|
|||
:content public-key}]]
|
||||
[agreement checked contract]])
|
||||
|
||||
(views/defview checkout []
|
||||
(views/letsubs [{:keys [username address custom-domain? public-key
|
||||
contract amount-label sufficient-funds?]}
|
||||
[:ens/checkout-screen]]
|
||||
(let [checked? (reagent/atom false)]
|
||||
[react/keyboard-avoiding-view {:flex 1}
|
||||
[toolbar]
|
||||
[react/scroll-view {:style {:flex 1}}
|
||||
[react/view {:style {:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
[big-blue-icon nil]
|
||||
[react/text {:text-align :center
|
||||
:style {:flex 1
|
||||
:font-size 22
|
||||
:padding-horizontal 48}}
|
||||
username]
|
||||
[react/view {:style {:height 36
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 12
|
||||
:margin-top 24
|
||||
:margin-horizontal 16
|
||||
:border-color colors/gray-lighter :border-radius 20
|
||||
:border-width 1
|
||||
:flex-direction :row}}
|
||||
[react/text {:style {:font-size 13
|
||||
:typography :main-medium}}
|
||||
(domain-label custom-domain?)]
|
||||
[react/view {:flex 1 :min-width 24}]]]
|
||||
[registration checked? contract address public-key]]
|
||||
[registration-bottom-bar checked? amount-label sufficient-funds?]])))
|
||||
(defn checkout []
|
||||
(let [checked? (reagent/atom false)]
|
||||
(fn []
|
||||
(let [{:keys [username address custom-domain? public-key
|
||||
contract amount-label sufficient-funds?]}
|
||||
@(re-frame/subscribe [:ens/checkout-screen])]
|
||||
[react/keyboard-avoiding-view {:flex 1}
|
||||
[toolbar]
|
||||
[react/scroll-view {:style {:flex 1}}
|
||||
[react/view {:style {:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
[big-blue-icon nil]
|
||||
[react/text {:text-align :center
|
||||
:style {:flex 1
|
||||
:font-size 22
|
||||
:padding-horizontal 48}}
|
||||
username]
|
||||
[react/view {:style {:height 36
|
||||
:align-items :center
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 12
|
||||
:margin-top 24
|
||||
:margin-horizontal 16
|
||||
:border-color colors/gray-lighter :border-radius 20
|
||||
:border-width 1
|
||||
:flex-direction :row}}
|
||||
[react/text {:style {:font-size 13
|
||||
:typography :main-medium}}
|
||||
(domain-label custom-domain?)]
|
||||
[react/view {:flex 1 :min-width 24}]]]
|
||||
[registration checked? contract address public-key]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:size :large
|
||||
:left [react/view {:flex-direction :row :align-items :center}
|
||||
[react/image {:source tokens/snt-icon-source
|
||||
:style {:width 36 :height 36}}]
|
||||
[react/view {:flex-direction :column :margin 8}
|
||||
[react/text {:style {:font-size 15}}
|
||||
amount-label]
|
||||
[react/text {:style {:color colors/gray :font-size 15}}
|
||||
(i18n/label :t/ens-deposit)]]]
|
||||
:right [react/view {:padding-horizontal 8}
|
||||
[quo/button
|
||||
{:disabled? (or (not @checked?) (not sufficient-funds?))
|
||||
:on-press #(debounce/dispatch-and-chill [::ens/register-name-pressed] 2000)}
|
||||
(if sufficient-funds?
|
||||
(i18n/label :t/ens-register)
|
||||
(i18n/label :t/not-enough-snt))]]}]]))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; CONFIRMATION SCREEN
|
||||
|
@ -350,10 +336,10 @@
|
|||
[state]
|
||||
(case state
|
||||
:registration-failed
|
||||
[react/view {:style {:width 40 :height 40 :border-radius 30 :background-color colors/red-light
|
||||
[react/view {:style {:width 40 :height 40 :border-radius 30 :background-color colors/red-light
|
||||
:align-items :center :justify-content :center}}
|
||||
[vector-icons/icon :main-icons/warning {:color colors/red}]]
|
||||
[react/view {:style {:width 40 :height 40 :border-radius 30 :background-color colors/gray-lighter
|
||||
[react/view {:style {:width 40 :height 40 :border-radius 30 :background-color colors/gray-lighter
|
||||
:align-items :center :justify-content :center}}
|
||||
[vector-icons/icon :main-icons/check {:color colors/blue}]]))
|
||||
|
||||
|
@ -415,12 +401,11 @@
|
|||
[final-state-details state username]]
|
||||
(if (= state :registration-failed)
|
||||
[react/view
|
||||
[button {:on-press #(re-frame/dispatch [::ens/retry-pressed])}
|
||||
[quo/button {:on-press #(re-frame/dispatch [::ens/retry-pressed])}
|
||||
(i18n/label :t/retry)]
|
||||
[button {:background? false
|
||||
:on-press #(re-frame/dispatch [::ens/cancel-pressed])}
|
||||
[quo/button {:on-press #(re-frame/dispatch [::ens/cancel-pressed])}
|
||||
(i18n/label :t/cancel)]]
|
||||
[button {:on-press #(re-frame/dispatch [::ens/got-it-pressed])}
|
||||
[quo/button {:on-press #(re-frame/dispatch [::ens/got-it-pressed])}
|
||||
(i18n/label :t/ens-got-it)])]]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -512,32 +497,22 @@
|
|||
;;TODO this is temporary fix for accounts with failed txs
|
||||
;;we still need this for regular ens names (not pending) but we need to detach public key in the contract
|
||||
(when pending?
|
||||
[list/big-list-item {:text (i18n/label :t/ens-remove-username)
|
||||
;:subtext (i18n/label :t/ens-remove-hints)
|
||||
:text-color colors/red
|
||||
:text-style {:font-weight "500"}
|
||||
:icon :main-icons/close
|
||||
:icon-color colors/red
|
||||
:hide-chevron? true
|
||||
:action-fn #(re-frame/dispatch [::ens/remove-username name])}])
|
||||
[quo/list-item {:title (i18n/label :t/ens-remove-username)
|
||||
;:subtext (i18n/label :t/ens-remove-hints)
|
||||
:icon :main-icons/close
|
||||
:theme :negative
|
||||
:on-press #(re-frame/dispatch [::ens/remove-username name])}])
|
||||
(when (and (not custom-domain?) (not pending?))
|
||||
[react/view {:style {:margin-top 18}}
|
||||
[list/big-list-item {:text (i18n/label :t/ens-release-username)
|
||||
:text-color (if releasable?
|
||||
colors/blue
|
||||
colors/gray)
|
||||
:text-style {:font-weight "500"}
|
||||
:subtext (when (and expiration-date
|
||||
(not releasable?))
|
||||
(i18n/label :t/ens-locked
|
||||
{:date expiration-date}))
|
||||
:icon :main-icons/delete
|
||||
:icon-color (if releasable?
|
||||
colors/blue
|
||||
colors/gray)
|
||||
:active? releasable?
|
||||
:hide-chevron? true
|
||||
:action-fn #(open-release-instructions-link!)}]])]]]]))
|
||||
[quo/list-item {:title (i18n/label :t/ens-release-username)
|
||||
:theme :accent
|
||||
:disabled (not releasable?)
|
||||
:subtitle (when (and expiration-date
|
||||
(not releasable?))
|
||||
(i18n/label :t/ens-locked
|
||||
{:date expiration-date}))
|
||||
:icon :main-icons/delete
|
||||
:on-press #(open-release-instructions-link!)}]])]]]]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; WELCOME SCREEN
|
||||
|
@ -594,16 +569,17 @@
|
|||
(i18n/label :t/ens-welcome-point-verify)]]
|
||||
[react/text {:style {:margin-top 16 :text-align :center :color colors/gray :typography :caption :padding-bottom 96}}
|
||||
(i18n/label :t/ens-powered-by)]]
|
||||
[react/view {:align-items :center :background-color colors/white
|
||||
:position :absolute :left 0 :right 0 :bottom 0
|
||||
:border-top-width 1 :border-top-color colors/gray-lighter}
|
||||
[button {:on-press #(re-frame/dispatch [::ens/get-started-pressed])
|
||||
:label (i18n/label :t/get-started)}]]]))
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right [quo/button {:on-press #(re-frame/dispatch [::ens/get-started-pressed])
|
||||
:type :secondary
|
||||
:after :main-icons/next}
|
||||
(i18n/label :t/get-started)]}]]))
|
||||
|
||||
(defn- name-item [{:keys [name action subtitle]}]
|
||||
(let [stateofus-username (stateofus/username name)
|
||||
s (or stateofus-username name)]
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
{:title s
|
||||
:subtitle (if subtitle
|
||||
subtitle
|
||||
|
@ -624,7 +600,7 @@
|
|||
[react/view {:style {:flex 1}}
|
||||
(for [name names]
|
||||
(let [action #(do (re-frame/dispatch [::ens/save-preferred-name name])
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet]))]
|
||||
(re-frame/dispatch [:bottom-sheet/hide]))]
|
||||
^{:key name}
|
||||
[react/touchable-highlight {:on-press action}
|
||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center :margin-right 16}}
|
||||
|
@ -654,9 +630,9 @@
|
|||
[react/view {:style {:flex 1}}
|
||||
[react/scroll-view
|
||||
[react/view {:style {:margin-top 8}}
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/ens-add-username)
|
||||
:theme :action
|
||||
:theme :accent
|
||||
:on-press #(re-frame/dispatch [::ens/add-username-pressed])
|
||||
:icon :main-icons/add}]]
|
||||
[react/view {:style {:margin-top 22 :margin-bottom 8}}
|
||||
|
|
|
@ -5,15 +5,13 @@
|
|||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.button :as button]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.contact.contact :as contact]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.keyboard-avoid-presentation
|
||||
:as
|
||||
kb-presentation]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -28,9 +26,10 @@
|
|||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- render-contact [row]
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
{:title (contact/format-name row)
|
||||
:icon [chat-icon/contact-icon-contacts-tab row]}])
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]}])
|
||||
|
||||
(defn- on-toggle [allow-new-users? checked? public-key]
|
||||
(cond
|
||||
|
@ -57,11 +56,13 @@
|
|||
(defn- toggle-item []
|
||||
(fn [allow-new-users? subs-name {:keys [public-key] :as contact} on-toggle]
|
||||
(let [contact-selected? @(re-frame/subscribe [subs-name public-key])]
|
||||
[list-item/list-item
|
||||
{:title (contact/format-name contact)
|
||||
:icon [chat-icon/contact-icon-contacts-tab contact]
|
||||
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
|
||||
:accessories [[checkbox/checkbox {:checked? contact-selected?}]]}])))
|
||||
[quo/list-item
|
||||
{:title (contact/format-name contact)
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
|
||||
:active contact-selected?
|
||||
:accessory :checkbox}])))
|
||||
|
||||
(defn- group-toggle-contact [allow-new-users? contact]
|
||||
[toggle-item allow-new-users? :is-contact-selected? contact on-toggle])
|
||||
|
@ -91,10 +92,10 @@
|
|||
{:style (styles/no-contact-text)}
|
||||
no-contacts]
|
||||
(when-not platform/desktop?
|
||||
[button/button
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press handle-invite-friends-pressed
|
||||
:label :t/invite-friends}])])
|
||||
:on-press handle-invite-friends-pressed}
|
||||
(i18n/label :t/invite-friends)])])
|
||||
|
||||
(defn filter-contacts [filter-text contacts]
|
||||
(let [lower-filter-text (string/lower-case (str filter-text))
|
||||
|
@ -145,18 +146,19 @@
|
|||
:enable-empty-sections true}]]]
|
||||
[bottom-toolbar/toolbar
|
||||
{:show-border? true
|
||||
:left {:type :previous
|
||||
:accessibility-label :previous-button
|
||||
:label (i18n/label :t/back)
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
:right {:type :secondary
|
||||
:container-style {:padding-horizontal 16}
|
||||
:text-style {:font-weight "500"}
|
||||
:accessibility-label :create-group-chat-button
|
||||
:label (i18n/label :t/create-group-chat)
|
||||
:disabled? (not save-btn-enabled?)
|
||||
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/create-pressed group-name]
|
||||
300)}}]]])))
|
||||
:left
|
||||
[quo/button {:type :secondary
|
||||
:before :main-icon/back
|
||||
:accessibility-label :previous-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/back)]
|
||||
:right
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :create-group-chat-button
|
||||
:disabled (not save-btn-enabled?)
|
||||
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/create-pressed group-name]
|
||||
300)}
|
||||
(i18n/label :t/create-group-chat)]}]]])))
|
||||
|
||||
(defn searchable-contact-list []
|
||||
(let [search-value (reagent/atom nil)]
|
||||
|
@ -195,11 +197,13 @@
|
|||
(dec constants/max-group-chat-participants))}]
|
||||
[bottom-toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right {:type :next
|
||||
:accessibility-label :next-button
|
||||
:label (i18n/label :t/next)
|
||||
:disabled? (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :new-group])}}]]))
|
||||
:right
|
||||
[quo/button {:type :secondary
|
||||
:after :main-icon/next
|
||||
:accessibility-label :next-button
|
||||
:disabled (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :new-group])}
|
||||
(i18n/label :t/next)]}]]))
|
||||
|
||||
;; Add participants to existing group chat
|
||||
(views/defview add-participants-toggle-list []
|
||||
|
@ -227,11 +231,12 @@
|
|||
constants/max-group-chat-participants)}]
|
||||
[bottom-toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center {:type :secondary
|
||||
:accessibility-label :next-button
|
||||
:label (i18n/label :t/add)
|
||||
:disabled? (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/add-members-pressed])}}]])))
|
||||
:center
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :next-button
|
||||
:disabled (zero? selected-contacts-count)
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/add-members-pressed])}
|
||||
(i18n/label :t/add)]}]])))
|
||||
|
||||
(views/defview edit-group-chat-name []
|
||||
(views/letsubs [{:keys [name chat-id]} [:chats/current-chat]
|
||||
|
@ -253,14 +258,15 @@
|
|||
[react/view {:style {:flex 1}}]
|
||||
[bottom-toolbar/toolbar
|
||||
{:show-border? true
|
||||
:center {:type :secondary
|
||||
:accessibility-label :done
|
||||
:label (i18n/label :t/done)
|
||||
:disabled? (and (<= (count @new-group-chat-name) 1)
|
||||
(not (nil? @new-group-chat-name)))
|
||||
:on-press #(cond
|
||||
(< 1 (count @new-group-chat-name))
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name])
|
||||
:center
|
||||
[quo/button {:type :secondary
|
||||
:accessibility-label :done
|
||||
:disabled (and (<= (count @new-group-chat-name) 1)
|
||||
(not (nil? @new-group-chat-name)))
|
||||
:on-press #(cond
|
||||
(< 1 (count @new-group-chat-name))
|
||||
(re-frame/dispatch [:group-chats.ui/name-changed chat-id @new-group-chat-name])
|
||||
|
||||
(nil? @new-group-chat-name)
|
||||
(re-frame/dispatch [:navigate-back]))}}]]))
|
||||
(nil? @new-group-chat-name)
|
||||
(re-frame/dispatch [:navigate-back]))}
|
||||
(i18n/label :t/done)]}]]))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[quo.core :as quo]
|
||||
[status-im.hardwallet.login :as login]
|
||||
[status-im.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
@ -32,13 +32,13 @@
|
|||
[react/view {:margin-bottom 24
|
||||
:margin-horizontal 24
|
||||
:align-items :center}
|
||||
[components.common/button
|
||||
{:on-press #(re-frame/dispatch [::login/reset-pin])
|
||||
:button-style {:margin-top 24}
|
||||
:label (i18n/label :t/keycard-is-frozen-reset)}]
|
||||
[react/view {:style {:margin-top 24}}
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [::login/reset-pin])}
|
||||
(i18n/label :t/keycard-is-frozen-reset)]]
|
||||
(when show-dismiss-button?
|
||||
[components.common/button
|
||||
{:on-press #(re-frame/dispatch [::login/frozen-keycard-popover-dismissed])
|
||||
:button-style {:margin-top 24}
|
||||
:background? false
|
||||
:label (i18n/label :t/dismiss)}])]])
|
||||
[react/view {:margin-top 24}
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [::login/frozen-keycard-popover-dismissed])
|
||||
:background? false}
|
||||
(i18n/label :t/dismiss)]])]])
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:border-radius 50
|
||||
:border-radius (/ (if small-screen? 50 64) 2)
|
||||
:background-color colors/blue-light})
|
||||
|
||||
(defn numpad-delete-button [small-screen?]
|
||||
|
|
|
@ -4,39 +4,13 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ui.screens.keycard.views :as keycard.views]
|
||||
[status-im.hardwallet.common :as hardwallet.common]))
|
||||
|
||||
(defn- action-row [{:keys [icon label on-press color-theme]}]
|
||||
[react/touchable-highlight
|
||||
{:on-press on-press}
|
||||
[react/view {:flex-direction :row
|
||||
:margin-top 15}
|
||||
[react/view {:background-color (case color-theme
|
||||
:red colors/red-transparent-10
|
||||
colors/blue-light)
|
||||
:width 40
|
||||
:height 40
|
||||
:border-radius 50
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[vector-icons/icon icon {:color (case color-theme
|
||||
:red colors/red
|
||||
colors/blue)}]]
|
||||
[react/view {:align-items :center
|
||||
:justify-content :center
|
||||
:margin-left 16}
|
||||
[react/text {:style {:font-size 17
|
||||
:color (case color-theme
|
||||
:red colors/red
|
||||
colors/blue)}}
|
||||
(i18n/label label)]]]])
|
||||
|
||||
(defn- activity-indicator [loading?]
|
||||
(when loading?
|
||||
[react/view {:margin-top 35}
|
||||
|
@ -44,12 +18,14 @@
|
|||
:size :large}]]))
|
||||
|
||||
(defn- reset-card-next-button [disabled?]
|
||||
[react/view {:margin-right 18
|
||||
:margin-bottom 15}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-next-button-pressed])
|
||||
:disabled? disabled?
|
||||
:forward? true}]])
|
||||
[react/view {:margin-right 6
|
||||
:margin-bottom 8}
|
||||
[quo/button
|
||||
;; TODO: Should have label?:
|
||||
{:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-next-button-pressed])
|
||||
:disabled disabled?
|
||||
:type :secondary
|
||||
:after :main-icon/next}]])
|
||||
|
||||
(defview reset-card []
|
||||
(letsubs [disabled? [:keycard-reset-card-disabled?]]
|
||||
|
@ -92,10 +68,8 @@
|
|||
pairing [:keycard-multiaccount-pairing]]
|
||||
[react/view {:flex 1}
|
||||
[topbar/topbar {:title :t/status-keycard}]
|
||||
[react/view {:flex 1
|
||||
:background-color colors/white}
|
||||
[react/scroll-view {:flex 1}
|
||||
[react/view {:margin-top 47
|
||||
:flex 1
|
||||
:align-items :center}
|
||||
[react/image {:source (resources/get-image :hardwallet-card)
|
||||
:style {:width 255
|
||||
|
@ -104,35 +78,36 @@
|
|||
[react/view {:margin-top 27}
|
||||
[react/text
|
||||
(i18n/label :t/linked-on {:date paired-on})]])]
|
||||
[react/view {:margin-left 16
|
||||
:flex 1
|
||||
:width "90%"
|
||||
:flex-direction :column}
|
||||
[react/view {:padding-vertical 16}
|
||||
(if (zero? puk-retry-counter)
|
||||
[card-blocked]
|
||||
[react/view
|
||||
[action-row {:icon :main-icons/help
|
||||
:label :t/help-capitalized
|
||||
:on-press #(.openURL ^js react/linking
|
||||
constants/faq-keycard)}]
|
||||
[:<>
|
||||
[quo/list-item {:icon :main-icons/help
|
||||
:size :small
|
||||
:title (i18n/label :t/help-capitalized)
|
||||
:on-press #(.openURL ^js react/linking
|
||||
constants/faq-keycard)}]
|
||||
(when pairing
|
||||
[react/view
|
||||
[action-row {:icon :main-icons/add
|
||||
:label :t/change-pin
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/change-pin-pressed])}]
|
||||
[:<>
|
||||
[quo/list-item {:icon :main-icons/add
|
||||
:size :small
|
||||
:title (i18n/label :t/change-pin)
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/change-pin-pressed])}]
|
||||
;; TODO(rasom): uncomment this when unpairing will be enabled
|
||||
;; https://github.com/status-im/status-react/issues/9227
|
||||
#_[action-row {:icon :main-icons/close
|
||||
:label :t/unpair-card
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]
|
||||
#_[quo/list-item {:icon :main-icons/close
|
||||
:size :small
|
||||
:title (i18n/label :t/unpair-card)
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/unpair-card-pressed])}]])])]
|
||||
; NOTE: Reset card is hidden until multiaccount removal will be implemented
|
||||
#_(when pairing
|
||||
[react/view {:margin-bottom 35
|
||||
:margin-left 16}
|
||||
[action-row {:icon :main-icons/warning
|
||||
:color-theme :red
|
||||
:label :t/reset-card
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-pressed])}]])]]))
|
||||
[quo/list-item {:icon :main-icons/warning
|
||||
:theme :negative
|
||||
:size :small
|
||||
:title (i18n/label :t/reset-card)
|
||||
:on-press #(re-frame/dispatch [:keycard-settings.ui/reset-card-pressed])}]])]]))
|
||||
|
||||
(defn reset-pin []
|
||||
[keycard.views/login-pin
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
(ns status-im.ui.screens.help-center.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
|
@ -8,27 +10,27 @@
|
|||
[status-im.constants :as constants]))
|
||||
|
||||
(def data
|
||||
[{:type :small
|
||||
:title :t/faq
|
||||
[{:size :small
|
||||
:title (i18n/label :t/faq)
|
||||
:accessibility-label :faq-button
|
||||
:on-press
|
||||
#(.openURL ^js react/linking
|
||||
constants/faq)
|
||||
:accessories [:chevron]}
|
||||
{:type :small
|
||||
:title :t/glossary
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/glossary)
|
||||
:accessibility-label :glossary-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :glossary])
|
||||
:accessories [:chevron]}
|
||||
{:type :small
|
||||
:title :t/submit-bug
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/submit-bug)
|
||||
:accessibility-label :submit-bug-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:logging.ui/send-logs-pressed])
|
||||
:accessories [:chevron]}
|
||||
{:type :small
|
||||
:title :t/request-feature
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/request-feature)
|
||||
:accessibility-label :request-a-feature-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:chat.ui/start-public-chat
|
||||
|
@ -36,7 +38,7 @@
|
|||
"status-desktop"
|
||||
"status")
|
||||
{:navigation-reset? false}])
|
||||
:accessories [:chevron]}])
|
||||
:chevron true}])
|
||||
|
||||
(defn help-center []
|
||||
[react/view {:flex 1 :background-color colors/white}
|
||||
|
@ -44,4 +46,4 @@
|
|||
[list/flat-list
|
||||
{:data data
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]])
|
||||
:render-fn quo/list-item}]])
|
||||
|
|
|
@ -3,42 +3,45 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn add-new-view []
|
||||
[react/view
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/start-new-chat
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/start-new-chat)
|
||||
:accessibility-label :start-1-1-chat-button
|
||||
:icon :main-icons/one-on-one-chat
|
||||
:on-press #(hide-sheet-and-dispatch [:navigate-to :new-chat])}]
|
||||
(when config/group-chat-enabled?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/start-group-chat
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/start-group-chat)
|
||||
:accessibility-label :start-group-chat-button
|
||||
:icon :main-icons/group-chat
|
||||
:on-press #(hide-sheet-and-dispatch [:contact.ui/start-group-chat-pressed])}])
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/new-public-group-chat
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/new-public-group-chat)
|
||||
:accessibility-label :join-public-chat-button
|
||||
:icon :main-icons/public-chat
|
||||
:on-press #(hide-sheet-and-dispatch [:navigate-to :new-public-chat])}]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/invite-friends
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/invite-friends)
|
||||
:accessibility-label :chats-menu-invite-friends-button
|
||||
:icon :main-icons/share
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||
(list-selection/open-share {:message (i18n/label :t/get-status-at)}))}]])
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
;; https://github.com/facebook/react-native/pull/26839
|
||||
(js/setTimeout
|
||||
#(list-selection/open-share {:message (i18n/label :t/get-status-at)})
|
||||
250))}]])
|
||||
|
||||
(def add-new
|
||||
{:content add-new-view})
|
||||
{:content add-new-view})
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
(ns status-im.ui.screens.home.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def last-message-container
|
||||
{:flex-shrink 1})
|
||||
|
||||
(def last-message-text
|
||||
{:flex 1
|
||||
:align-self :stretch
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.home.styles :as styles]
|
||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.search-input.view :as search-input]
|
||||
[cljs-bean.core :as bean]
|
||||
[status-im.ui.components.topbar :as topbar])
|
||||
|
@ -41,32 +40,31 @@
|
|||
[react/i18n-text {:style styles/welcome-text-description
|
||||
:key :welcome-to-status-description}]]
|
||||
[react/view {:align-items :center :margin-bottom 50}
|
||||
[components.common/button {:on-press
|
||||
#(re-frame/dispatch [:navigate-reset {:index 0
|
||||
:routes [{:name :tabs}]}])
|
||||
:accessibility-label :lets-go-button
|
||||
:label (i18n/label :t/lets-go)}]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-reset {:index 0
|
||||
:routes [{:name :tabs}]}])
|
||||
:accessibility-label :lets-go-button}
|
||||
(i18n/label :t/lets-go)]]])
|
||||
|
||||
(defn home-tooltip-view []
|
||||
[react/view (styles/chat-tooltip)
|
||||
[react/view {:style {:flex-direction :row}}
|
||||
[react/view {:flex 1}
|
||||
[react/view {:style styles/empty-chats-header-container}
|
||||
[react/view {:style {:width 66 :position :absolute :top -6 :background-color colors/white
|
||||
[react/view {:style {:width 66 :position :absolute :top -6 :background-color colors/white
|
||||
:align-items :center}}
|
||||
[react/image {:source (resources/get-image :empty-chats-header)
|
||||
:style {:width 50 :height 50}}]]]
|
||||
[react/touchable-highlight
|
||||
{:style {:position :absolute :right 0 :top 0
|
||||
:width 44 :height 44 :align-items :center :justify-content :center}
|
||||
{:style {:position :absolute :right 0 :top 0
|
||||
:width 44 :height 44 :align-items :center :justify-content :center}
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.ui/hide-home-tooltip])
|
||||
:accessibility-label :hide-home-button}
|
||||
[icons/icon :main-icons/close-circle {:color colors/gray}]]]]
|
||||
[react/i18n-text {:style styles/no-chats-text :key :chat-and-transact}]
|
||||
[react/view {:align-items :center :margin-top 16}
|
||||
[button/button {:label :t/invite-friends
|
||||
:on-press #(list-selection/open-share {:message (i18n/label :t/get-status-at)})
|
||||
:accessibility-label :invite-friends-button}]]
|
||||
[quo/button {:on-press #(list-selection/open-share {:message (i18n/label :t/get-status-at)})
|
||||
:accessibility-label :invite-friends-button}
|
||||
(i18n/label :t/invite-friends)]]
|
||||
[react/view {:align-items :center :margin-top 16}
|
||||
[react/view {:style (styles/hr-wrapper)}]
|
||||
[react/i18n-text {:style (styles/or-text) :key :or}]]
|
||||
|
@ -126,10 +124,10 @@
|
|||
(views/defview plus-button []
|
||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||
[react/view styles/action-button-container
|
||||
[react/touchable-highlight
|
||||
{:accessibility-label :new-chat-button
|
||||
:on-press (when-not logging-in?
|
||||
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))}
|
||||
[quo/button {:type :scale
|
||||
:accessibility-label :new-chat-button
|
||||
:on-press (when-not logging-in?
|
||||
#(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))}
|
||||
[react/view (styles/action-button)
|
||||
(if logging-in?
|
||||
[react/activity-indicator {:color colors/white-persist
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
[status-im.constants :as constants]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.badge :as badge]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.chat.sheets :as sheets]
|
||||
[status-im.ui.screens.home.styles :as styles]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
[status-im.utils.core :as utils]
|
||||
[status-im.utils.datetime :as time])
|
||||
|
@ -67,7 +69,7 @@
|
|||
parsed-text)))
|
||||
|
||||
(defn message-content-text [{:keys [content content-type]}]
|
||||
[react/view styles/last-message-container
|
||||
[:<>
|
||||
(cond
|
||||
|
||||
(not (and content content-type))
|
||||
|
@ -93,18 +95,31 @@
|
|||
(render-subheader (:parsed-text content)))])
|
||||
|
||||
(defn message-timestamp [timestamp]
|
||||
(when timestamp
|
||||
[react/text {:style styles/datetime-text
|
||||
:accessibility-label :last-message-time-text}
|
||||
;;TODO (perf) move to event
|
||||
(string/upper-case (time/to-short-str timestamp))]))
|
||||
[react/view
|
||||
(when timestamp
|
||||
[react/text {:style styles/datetime-text
|
||||
:number-of-lines 1
|
||||
:accessibility-label :last-message-time-text}
|
||||
;;TODO (perf) move to event
|
||||
(string/upper-case (time/to-short-str timestamp))])])
|
||||
|
||||
(defn unviewed-indicator [{:keys [unviewed-messages-count public?]}]
|
||||
(when (pos? unviewed-messages-count)
|
||||
(if public?
|
||||
[react/view {:style styles/public-unread
|
||||
:accessibility-label :unviewed-messages-public}]
|
||||
[badge/message-counter unviewed-messages-count])))
|
||||
[react/view {:padding-left 16
|
||||
:justify-content :flex-end
|
||||
:align-items :flex-end}
|
||||
(if public?
|
||||
[react/view {:style styles/public-unread
|
||||
:accessibility-label :unviewed-messages-public}]
|
||||
[badge/message-counter unviewed-messages-count])]))
|
||||
|
||||
(defn icon-style []
|
||||
{:color colors/black
|
||||
:width 15
|
||||
:height 15
|
||||
:container-style {:width 15
|
||||
:height 15
|
||||
:margin-right 2}})
|
||||
|
||||
(defn home-list-item [home-item]
|
||||
(let [{:keys [chat-id chat-name color online group-chat
|
||||
|
@ -112,27 +127,41 @@
|
|||
home-item
|
||||
private-group? (and group-chat (not public?))
|
||||
public-group? (and group-chat public?)]
|
||||
;; NOTE(Ferossgp): Change icon color to black in refactor PR
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
{:icon [chat-icon.screen/chat-icon-view-chat-list
|
||||
chat-id group-chat chat-name color online false]
|
||||
:title-prefix (cond
|
||||
private-group? :main-icons/tiny-group
|
||||
public-group? :main-icons/tiny-public
|
||||
:else :main-icons/tiny-new-contact)
|
||||
:title (if group-chat
|
||||
(utils/truncate-str chat-name 30)
|
||||
;; This looks a bit odd, but I would like only to subscribe
|
||||
;; if it's a one-to-one. If wrapped in a component styling
|
||||
;; won't be applied correctly.
|
||||
@(re-frame/subscribe [:contacts/contact-name-by-identity chat-id]))
|
||||
:title [react/view {:flex-direction :row
|
||||
:flex 1}
|
||||
[react/view {:flex-direction :row
|
||||
:flex 1
|
||||
:padding-right 16
|
||||
:align-items :center}
|
||||
(cond
|
||||
private-group?
|
||||
[icons/icon :main-icons/tiny-group (icon-style)]
|
||||
public-group?
|
||||
[icons/icon :main-icons/tiny-public (icon-style)]
|
||||
:else
|
||||
[icons/icon :main-icons/tiny-new-contact (icon-style)])
|
||||
[quo/text {:weight :medium
|
||||
:accessibility-label :chat-name-text
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1}
|
||||
(if group-chat
|
||||
(utils/truncate-str chat-name 30)
|
||||
;; This looks a bit odd, but I would like only to subscribe
|
||||
;; if it's a one-to-one. If wrapped in a component styling
|
||||
;; won't be applied correctly.
|
||||
@(re-frame/subscribe [:contacts/contact-name-by-identity chat-id]))]]
|
||||
[message-timestamp (if (pos? (:whisper-timestamp last-message))
|
||||
(:whisper-timestamp last-message)
|
||||
timestamp)]]
|
||||
:title-accessibility-label :chat-name-text
|
||||
:title-row-accessory [message-timestamp (if (pos? (:whisper-timestamp last-message))
|
||||
(:whisper-timestamp last-message)
|
||||
timestamp)]
|
||||
:subtitle [message-content-text {:content (:content last-message)
|
||||
:content-type (:content-type last-message)}]
|
||||
:subtitle-row-accessory [unviewed-indicator home-item]
|
||||
:subtitle [react/view {:flex-direction :row}
|
||||
[react/view {:flex 1}
|
||||
[message-content-text {:content (:content last-message)
|
||||
:content-type (:content-type last-message)}]]
|
||||
[unviewed-indicator home-item]]
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:dismiss-keyboard])
|
||||
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
|
||||
|
@ -141,5 +170,4 @@
|
|||
(re-frame/dispatch [:chat.ui/mark-messages-seen :chat])))
|
||||
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[sheets/actions home-item])
|
||||
:height 256}])}]))
|
||||
[sheets/actions home-item])}])}]))
|
||||
|
|
|
@ -59,17 +59,12 @@
|
|||
:background-color (if selected? colors/blue-light colors/white)
|
||||
:padding-vertical 12})
|
||||
|
||||
(def list-item-body
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:align-items :flex-start})
|
||||
|
||||
(def multiaccount-image
|
||||
{:width 40
|
||||
:height 40
|
||||
:border-radius 20
|
||||
:border-width 1
|
||||
:border-color colors/black-transparent})
|
||||
{:width 40
|
||||
:height 40
|
||||
:border-radius 20
|
||||
:border-width 1
|
||||
:border-color colors/black-transparent})
|
||||
|
||||
(defn password-text-input [width]
|
||||
{:typography :header
|
||||
|
@ -83,18 +78,4 @@
|
|||
{:padding-horizontal 24
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:flex-direction :row})
|
||||
|
||||
(def disabled-bottom-button
|
||||
(assoc bottom-button :background-color colors/gray-transparent-10))
|
||||
|
||||
(def disabled-bottom-button-text
|
||||
{:color colors/gray-transparent-40})
|
||||
|
||||
(defn bottom-arrow []
|
||||
{:flex-direction :row
|
||||
:justify-content :flex-end
|
||||
:align-self :stretch
|
||||
:padding-top 16
|
||||
:border-top-width 1
|
||||
:border-top-color colors/gray-lighter})
|
||||
:flex-direction :row})
|
|
@ -7,19 +7,19 @@
|
|||
[status-im.privacy-policy.core :as privacy-policy]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.radio :as radio]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.intro.styles :as styles]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.utils.gfycat.core :as gfy]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.security :as security]
|
||||
[status-im.ui.screens.intro.carousel :as carousel]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.intro.carousel :as carousel]
|
||||
[status-im.utils.utils :as utils])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
|
@ -37,13 +37,13 @@
|
|||
:title :intro-title3
|
||||
:text :intro-text3}] window-height view-id]
|
||||
[react/view styles/buttons-container
|
||||
[components.common/button {:button-style (assoc styles/bottom-button :margin-bottom 24)
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard])
|
||||
:label (i18n/label :t/get-started)}]
|
||||
[react/view {:style (assoc styles/bottom-button :margin-bottom 16)}
|
||||
[quo/button {:on-press #(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard])}
|
||||
(i18n/label :t/get-started)]]
|
||||
[react/nested-text
|
||||
{:style styles/welcome-text-bottom-note}
|
||||
(i18n/label :t/intro-privacy-policy-note1)
|
||||
[{:style (assoc styles/welcome-text-bottom-note :color colors/blue)
|
||||
[{:style (assoc styles/welcome-text-bottom-note :color colors/blue)
|
||||
:on-press privacy-policy/open-privacy-policy-link!}
|
||||
(i18n/label :t/intro-privacy-policy-note2)]]]]))
|
||||
|
||||
|
@ -72,29 +72,21 @@
|
|||
(let [selected? (= (:id acc) selected-id)
|
||||
public-key (get-in acc [:derived constants/path-whisper-keyword :public-key])]
|
||||
^{:key public-key}
|
||||
[react/touchable-highlight
|
||||
{:accessibility-label (keyword (str "select-account-button-" accessibility-n))
|
||||
:on-press #(re-frame/dispatch [:intro-wizard/on-key-selected (:id acc)])}
|
||||
[react/view {:style (styles/list-item selected?)}
|
||||
[react/view {:style styles/list-item-body}
|
||||
[react/image {:source {:uri (identicon/identicon public-key)}
|
||||
:resize-mode :cover
|
||||
:style styles/multiaccount-image}]
|
||||
[react/view {:style {:padding-horizontal 16
|
||||
:flex 1}}
|
||||
[react/text {:style (assoc styles/wizard-text :text-align :left
|
||||
:color colors/black
|
||||
:line-height 22
|
||||
:font-weight "500")
|
||||
:number-of-lines 2
|
||||
:ellipsize-mode :middle}
|
||||
(gfy/generate-gfy public-key)]
|
||||
[react/text {:style (assoc styles/wizard-text
|
||||
:text-align :left
|
||||
:line-height 22
|
||||
:font-family "monospace")}
|
||||
(utils/get-shortened-address public-key)]]]
|
||||
[radio/radio selected?]]]))]])
|
||||
[quo/list-item {:accessibility-label (keyword (str "select-account-button-" accessibility-n))
|
||||
:active selected?
|
||||
:title [quo/text {:number-of-lines 2
|
||||
:weight :medium
|
||||
:ellipsize-mode :middle
|
||||
:accessibility-label :username}
|
||||
(gfy/generate-gfy public-key)]
|
||||
:subtitle [quo/text {:weight :monospace
|
||||
:color :secondary}
|
||||
(utils/get-shortened-address public-key)]
|
||||
:accessory :radio
|
||||
:on-press #(re-frame/dispatch [:intro-wizard/on-key-selected (:id acc)])
|
||||
:icon [react/image {:source {:uri (identicon/identicon public-key)}
|
||||
:resize-mode :cover
|
||||
:style styles/multiaccount-image}]}]))]])
|
||||
|
||||
(defn storage-entry [{:keys [type icon icon-width icon-height
|
||||
image image-selected image-width image-height
|
||||
|
@ -199,63 +191,56 @@
|
|||
forward-action
|
||||
next-button-disabled?
|
||||
processing? existing-account?]}]
|
||||
[react/view {:style {:margin-bottom (if (or (#{:choose-key :select-key-storage
|
||||
:enter-phrase :recovery-success} step)
|
||||
(and (#{:create-code :confirm-code} step)
|
||||
encrypt-with-password?))
|
||||
20
|
||||
32)
|
||||
:align-items :center}}
|
||||
[react/view {:style {:align-items :center}}
|
||||
(cond (and (#{:generate-key :recovery-success} step) processing?)
|
||||
[react/view {:min-height 46 :max-height 46 :align-self :stretch}
|
||||
[react/view {:min-height 46 :max-height 46 :align-self :stretch :margin-bottom 16}
|
||||
[react/activity-indicator {:animating true
|
||||
:size :large}]]
|
||||
(#{:generate-key :recovery-success} step)
|
||||
(let [label-kw (case step
|
||||
:generate-key :generate-a-key
|
||||
:recovery-success :re-encrypt-key
|
||||
:generate-key :t/generate-a-key
|
||||
:recovery-success :t/re-encrypt-key
|
||||
:intro-wizard-title6)]
|
||||
[react/view {:min-height 46 :max-height 46}
|
||||
[components.common/button
|
||||
{:button-style (if existing-account?
|
||||
styles/disabled-bottom-button
|
||||
styles/bottom-button)
|
||||
:on-press (when-not existing-account?
|
||||
#(re-frame/dispatch [forward-action]))
|
||||
:accessibility-label :onboarding-next-button
|
||||
:label (i18n/label label-kw)
|
||||
:label-style (when existing-account?
|
||||
styles/disabled-bottom-button-text)}]])
|
||||
[react/view (:style (assoc styles/bottom-button :margin-bottom 16))
|
||||
[quo/button
|
||||
{:disabled existing-account?
|
||||
:on-press #(re-frame/dispatch [forward-action])
|
||||
:accessibility-label :onboarding-next-button}
|
||||
(i18n/label label-kw)]])
|
||||
(and (#{:create-code :confirm-code} step)
|
||||
(not encrypt-with-password?))
|
||||
[components.common/button {:button-style styles/bottom-button
|
||||
:label (i18n/label :t/encrypt-with-password)
|
||||
:accessibility-label :encrypt-with-password-button
|
||||
:on-press #(re-frame/dispatch [:intro-wizard/on-encrypt-with-password-pressed])
|
||||
:background? false}]
|
||||
[react/view {:margin-bottom 16}
|
||||
[quo/button {:style styles/bottom-button
|
||||
:accessibility-label :encrypt-with-password-button
|
||||
:on-press #(re-frame/dispatch [:intro-wizard/on-encrypt-with-password-pressed])
|
||||
:type :secondary}
|
||||
(i18n/label :t/encrypt-with-password)]]
|
||||
|
||||
:else
|
||||
[react/view {:style (styles/bottom-arrow)}
|
||||
[react/view {:style {:margin-right 10}}
|
||||
[components.common/bottom-button {:on-press #(re-frame/dispatch [forward-action])
|
||||
:accessibility-label :onboarding-next-button
|
||||
:disabled? (or processing?
|
||||
(and (= step :create-code) weak-password?)
|
||||
(and (= step :enter-phrase) next-button-disabled?))
|
||||
:forward? true}]]])
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:right [quo/button
|
||||
{:on-press #(re-frame/dispatch [forward-action])
|
||||
:accessibility-label :onboarding-next-button
|
||||
:disabled (or processing?
|
||||
(and (= step :create-code) weak-password?)
|
||||
(and (= step :enter-phrase) next-button-disabled?))
|
||||
:type :secondary
|
||||
:after :main-icons/next}
|
||||
(i18n/label :t/next)]}])
|
||||
(when (and (= :generate-key step) (not processing?))
|
||||
[components.common/button
|
||||
{:button-style (assoc styles/bottom-button :margin-top 8)
|
||||
:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
:label (i18n/label :t/access-existing-keys)
|
||||
:background? false}])
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
:type :secondary}
|
||||
(i18n/label :t/access-existing-keys)]])
|
||||
(when (or (= :generate-key step) (and processing? (= :recovery-success step)))
|
||||
[react/text {:style (assoc styles/wizard-text :margin-top 20)}
|
||||
[react/text {:style (assoc styles/wizard-text :margin-top 20 :margin-bottom 16)}
|
||||
(i18n/label (cond (= :recovery-success step)
|
||||
:t/processing
|
||||
processing? :t/generating-keys
|
||||
:else :t/this-will-take-few-seconds))])])
|
||||
:else :t/this-will-take-few-seconds))])])
|
||||
|
||||
(defn top-bar [{:keys [step encrypt-with-password?]}]
|
||||
(let [hide-subtitle? (or (= step :confirm-code)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.keycard.components.style :as styles]))
|
||||
|
||||
(defn turn-nfc-on []
|
||||
|
@ -16,11 +16,10 @@
|
|||
[react/view {:margin-top 16}
|
||||
[react/text {:style {:typography :title-bold}}
|
||||
(i18n/label :t/turn-nfc-on)]]
|
||||
[react/view {:margin-top 8}
|
||||
[react/view {:margin-top 8
|
||||
:margin-bottom 16}
|
||||
[react/text {:number-of-lines 2
|
||||
:style styles/helper-text-style}
|
||||
(i18n/label :t/turn-nfc-description)]]
|
||||
|
||||
[button/button {:label :t/open-nfc-settings
|
||||
:style {:margin-top 16}
|
||||
:on-press #(re-frame/dispatch [:keycard.onboarding.nfc-on/open-nfc-settings-pressed])}]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.nfc-on/open-nfc-settings-pressed])}
|
||||
(i18n/label :t/open-nfc-settings)]]])
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
(fn [{:keys [on-card-connected connected? on-card-disconnected params]}]
|
||||
(let [translation (or (get-in params [:state-translations @state])
|
||||
(get state->translations @state))]
|
||||
[react/view {:style styles/container-style}
|
||||
[react/view {:style styles/container-style
|
||||
:height 286}
|
||||
[react/view {:height 200
|
||||
:margin-bottom 20}
|
||||
[animated-circles {:state state
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
(ns status-im.ui.screens.keycard.onboarding.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.hardwallet.onboarding :as hardwallet.onboarding]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar :as bottom-toolbar]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
|
||||
|
@ -22,11 +21,9 @@
|
|||
[react/view styles/container
|
||||
[topbar/topbar]
|
||||
[react/view {:flex 1
|
||||
:flex-direction :column
|
||||
:justify-content :space-between
|
||||
:align-items :center}
|
||||
[react/view {:flex-direction :column
|
||||
:align-items :center}
|
||||
[react/view {:align-items :center}
|
||||
[react/view
|
||||
[react/view {:align-items :center
|
||||
:justify-content :center}
|
||||
|
@ -88,18 +85,8 @@
|
|||
:padding-right 35}}
|
||||
text]]]]))]
|
||||
[react/view {:margin-bottom 40}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.intro.ui/begin-setup-pressed])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}
|
||||
:accessibility-label :begin-set-up}
|
||||
(i18n/label :t/begin-set-up)]]]]]]))
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.intro.ui/begin-setup-pressed])}
|
||||
(i18n/label :t/begin-set-up)]]]]))
|
||||
|
||||
(defview puk-code []
|
||||
(letsubs [secrets [:hardwallet-secrets]
|
||||
|
@ -148,10 +135,10 @@
|
|||
(i18n/label :t/puk-code)]]
|
||||
[react/view {:justify-content :flex-start
|
||||
:flex 1}
|
||||
[react/text {:style {:typography :header
|
||||
:font-family "monospace"
|
||||
:text-align :center
|
||||
:color colors/blue}
|
||||
[react/text {:style {:typography :header
|
||||
:font-family "monospace"
|
||||
:text-align :center
|
||||
:color colors/blue}
|
||||
:accessibility-label :puk-code}
|
||||
puk-code]]]]
|
||||
[react/view {:margin-top 16}
|
||||
|
@ -185,16 +172,12 @@
|
|||
[react/view {:margin-top 16}
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(i18n/label :t/pair-code-explanation)]]]]
|
||||
[react/view {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:height 86}
|
||||
[react/view components.styles/flex]
|
||||
[react/view {:margin-right 20}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.puk-code.ui/next-pressed])
|
||||
:forward? true}]]]]]]))
|
||||
[bottom-toolbar/toolbar
|
||||
{:right
|
||||
[quo/button {:type :secondary
|
||||
:after :main-icon/next
|
||||
:on-press #(re-frame/dispatch [:keycard.onboarding.puk-code.ui/next-pressed])}
|
||||
(i18n/label :t/next)]}]]]]))
|
||||
|
||||
(defview pin []
|
||||
(letsubs [pin [:hardwallet/pin]
|
||||
|
@ -298,22 +281,17 @@
|
|||
:margin-left 12}
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(str (inc i) ". ")]
|
||||
[react/text {:accessibility-label (str "word" i)}
|
||||
[react/text {:accessibility-label (str "word" i)}
|
||||
word]])])]
|
||||
[react/view {:margin-top 24}
|
||||
[react/text {:style {:text-align :center}}
|
||||
(i18n/label :t/keycard-onboarding-recovery-phrase-description)]]]
|
||||
[react/view {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:height 86}
|
||||
[react/view components.styles/flex]
|
||||
[react/view {:margin-right 20}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase.ui/next-pressed])
|
||||
:label (i18n/label :t/confirm)
|
||||
:forward? true}]]]]]))
|
||||
[bottom-toolbar/toolbar
|
||||
{:right
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase.ui/next-pressed])
|
||||
:type :secondary
|
||||
:after :main-icon/next}
|
||||
(i18n/label :t/confirm)]}]]]))
|
||||
|
||||
(defview recovery-phrase-confirm-word []
|
||||
(letsubs [word [:hardwallet-recovery-phrase-word]
|
||||
|
@ -362,20 +340,16 @@
|
|||
[react/view {:margin-top 5
|
||||
:width 250}
|
||||
[tooltip/tooltip error]]]
|
||||
[react/view {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:height 86}
|
||||
[react/view {:margin-left 20}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/back-pressed])
|
||||
:back? true
|
||||
:label (i18n/label :t/back)}]]
|
||||
[react/view {:margin-right 20}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed])
|
||||
:label (i18n/label :t/next)
|
||||
:accessibility-label :next
|
||||
:disabled? (empty? input-word)
|
||||
:forward? true}]]]]])))
|
||||
[bottom-toolbar/toolbar
|
||||
{:left
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/back-pressed])
|
||||
:type :secondary
|
||||
:before :main-icon/back}
|
||||
(i18n/label :t/back)]
|
||||
:right
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed])
|
||||
:accessibility-label :next
|
||||
:disabled (empty? input-word)
|
||||
:type :secondary
|
||||
:after :main-icon/next}
|
||||
(i18n/label :t/next)]}]]])))
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
[status-im.hardwallet.recovery :as hardwallet.recovery]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.toolbar :as bottom-toolbar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.tooltip.views :as tooltip]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
|
@ -29,11 +29,13 @@
|
|||
:align-items :center}
|
||||
[react/view {:flex-direction :column
|
||||
:align-items :center}
|
||||
|
||||
[react/view {:margin-top 16
|
||||
:width 311}
|
||||
[react/text {:style {:typography :header
|
||||
:text-align :center}}
|
||||
(i18n/label :t/keycard-recovery-intro-header)]]
|
||||
|
||||
[react/view {:margin-top 16
|
||||
:width 311}
|
||||
[react/text {:style {:font-size 15
|
||||
|
@ -41,6 +43,7 @@
|
|||
:color colors/gray
|
||||
:text-align :center}}
|
||||
(i18n/label :t/keycard-recovery-intro-text)]]
|
||||
|
||||
[react/view {:margin-top 33}
|
||||
[react/touchable-highlight {:on-press #(.openURL ^js react/linking
|
||||
constants/keycard-integration-link)}
|
||||
|
@ -52,24 +55,17 @@
|
|||
(i18n/label :t/learn-more-about-keycard)]
|
||||
[vector-icons/tiny-icon :tiny-icons/tiny-external {:color colors/blue
|
||||
:container-style {:margin-left 5}}]]]]]
|
||||
[react/view
|
||||
[react/view {:align-items :center
|
||||
:justify-content :center}
|
||||
[react/image {:source (resources/get-image :keycard)
|
||||
:style {:width 144
|
||||
:height 114}}]]]
|
||||
|
||||
[react/view {:align-items :center
|
||||
:justify-content :center}
|
||||
[react/image {:source (resources/get-image :keycard)
|
||||
:style {:width 144
|
||||
:height 114}}]]
|
||||
|
||||
[react/view {:margin-bottom 50}
|
||||
[react/touchable-highlight
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:keycard.recovery.intro.ui/begin-recovery-pressed])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/keycard-recovery-intro-button-text)]]]]]])
|
||||
(i18n/label :t/keycard-recovery-intro-button-text)]]]])
|
||||
|
||||
(defview pin []
|
||||
(letsubs [pin [:hardwallet/pin]
|
||||
|
@ -158,18 +154,13 @@
|
|||
[react/view {:margin-top 5
|
||||
:width 250}
|
||||
[tooltip/tooltip error]]]
|
||||
[react/view {:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:width "100%"
|
||||
:height 86}
|
||||
[react/view]
|
||||
[react/view {:margin-right 20}
|
||||
[components.common/bottom-button
|
||||
{:on-press #(re-frame/dispatch [:keycard.onboarding.pair.ui/next-pressed])
|
||||
:label (i18n/label :t/pair-card)
|
||||
:disabled? (empty? pair-code)
|
||||
:forward? true}]]]]]))
|
||||
[bottom-toolbar/toolbar
|
||||
{:right
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.onboarding.pair.ui/next-pressed])
|
||||
:disabled (empty? pair-code)
|
||||
:type :secondary
|
||||
:after :main-icon/next}
|
||||
(i18n/label :t/pair-card)]}]]]))
|
||||
|
||||
(defview success []
|
||||
(letsubs [address [:hardwallet-multiaccount-wallet-address]
|
||||
|
@ -215,17 +206,8 @@
|
|||
:ellipsize-mode :middle}
|
||||
(utils.core/truncate-str address 14 true)]]]
|
||||
[react/view {:margin-bottom 50}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:keycard.recovery.success/finish-pressed])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/finish)]]]]]]))
|
||||
[quo/button {:on-press #(re-frame/dispatch [:keycard.recovery.success/finish-pressed])}
|
||||
(i18n/label :t/finish)]]]]))
|
||||
|
||||
(defview no-key []
|
||||
(letsubs [card-state [:hardwallet-card-state]]
|
||||
|
@ -263,20 +245,10 @@
|
|||
:style {:width 165
|
||||
:height 110}}])]]]
|
||||
[react/view {:margin-bottom 50}
|
||||
[react/touchable-highlight
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:keycard.recovery.no-key.ui/generate-key-pressed])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 190
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/generate-new-key)]]]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
[react/text {:style {:text-align :center
|
||||
:padding-top 27
|
||||
:color colors/blue}}
|
||||
(i18n/label :t/cancel)]]]]]))
|
||||
(i18n/label :t/generate-new-key)]
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/cancel)]]]]))
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
|
||||
[status-im.ui.screens.keycard.styles :as styles]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ui.components.button :as button]
|
||||
[status-im.hardwallet.login :as hardwallet.login]
|
||||
[status-im.ui.screens.hardwallet.frozen-card.view :as frozen-card.view])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
@ -47,17 +47,8 @@
|
|||
:style {:width 144
|
||||
:height 114}}]]
|
||||
[react/view {:margin-bottom 32}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/ok-got-it)]]]]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/ok-got-it)]]]])
|
||||
|
||||
;; NOTE(Ferossgp): Seems like it should be in popover
|
||||
(defn wrong []
|
||||
|
@ -87,17 +78,8 @@
|
|||
:style {:width 255
|
||||
:height 124}}]]
|
||||
[react/view {:margin-bottom 32}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/ok-got-it)]]]]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/ok-got-it)]]]])
|
||||
|
||||
(defn unpaired []
|
||||
[react/view {:flex 1
|
||||
|
@ -128,22 +110,13 @@
|
|||
[react/view {:margin-bottom 32
|
||||
:flex-direction :column
|
||||
:align-items :center}
|
||||
[react/touchable-highlight
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:keycard.login.ui/pair-card-pressed])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/pair-this-card)]]]
|
||||
(i18n/label :t/pair-this-card)]
|
||||
[react/view {:margin-top 27}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:keycard.login.ui/dismiss-pressed])}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/dismiss)]]]]]])
|
||||
[quo/button {:type :secondary
|
||||
:on-press #(re-frame/dispatch [:keycard.login.ui/dismiss-pressed])}
|
||||
(i18n/label :t/dismiss)]]]]])
|
||||
|
||||
;; NOTE(Ferossgp): Seems like it should be in popover
|
||||
(defn not-keycard []
|
||||
|
@ -185,17 +158,8 @@
|
|||
[vector-icons/tiny-icon :tiny-icons/tiny-external {:color colors/blue
|
||||
:container-style {:margin-left 5}}]]]]]
|
||||
[react/view {:margin-bottom 32}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
[react/view {:background-color colors/blue-light
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction :row
|
||||
:width 133
|
||||
:height 44
|
||||
:border-radius 10}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/ok-got-it)]]]]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/ok-got-it)]]]])
|
||||
|
||||
(defn photo [_ _]
|
||||
(reagent/create-class
|
||||
|
@ -213,16 +177,16 @@
|
|||
|
||||
(defn access-is-reset [{:keys [hide-login-actions?]}]
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
{:style {:flex 1
|
||||
:align-items :center}}
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
{:style {:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center}}
|
||||
[react/view
|
||||
{:style
|
||||
{:background-color colors/green-transparent-10
|
||||
:margin-bottom 32
|
||||
:margin-bottom 32
|
||||
:width 40
|
||||
:height 40
|
||||
:align-items :center
|
||||
|
@ -236,15 +200,13 @@
|
|||
[react/text (i18n/label :t/keycard-can-use-with-new-passcode)]]
|
||||
(when-not hide-login-actions?
|
||||
[react/view
|
||||
{:style {:width 160
|
||||
{:style {:width 160
|
||||
:margin-bottom 15}}
|
||||
[button/button
|
||||
{:type :main
|
||||
:style {:align-self :stretch}
|
||||
:container-style {:height 52}
|
||||
:label (i18n/label :t/open)
|
||||
:on-press #(re-frame/dispatch
|
||||
[::hardwallet.login/login-after-reset])}]])])
|
||||
[react/view {:flex-direction :row
|
||||
:height 52}
|
||||
[quo/button {:on-press #(re-frame/dispatch
|
||||
[::hardwallet.login/login-after-reset])}
|
||||
(i18n/label :t/open)]]])])
|
||||
|
||||
(defn frozen-card []
|
||||
[frozen-card.view/frozen-card
|
||||
|
@ -297,7 +259,7 @@
|
|||
(defview login-pin [{:keys [back-button-handler
|
||||
hide-login-actions?
|
||||
default-enter-step]
|
||||
:or {default-enter-step :login}}]
|
||||
:or {default-enter-step :login}}]
|
||||
(letsubs [pin [:hardwallet/pin]
|
||||
enter-step [:hardwallet/pin-enter-step]
|
||||
status [:hardwallet/pin-status]
|
||||
|
@ -310,27 +272,27 @@
|
|||
;; TODO(rasom): this hack fixes state mess when more then two
|
||||
;; pin-view instances are used at the same time. Should be properly
|
||||
;; refactored instead
|
||||
enter-step (or enter-step default-enter-step)]
|
||||
enter-step (or enter-step default-enter-step)]
|
||||
[react/view styles/container
|
||||
[topbar/topbar
|
||||
{:accessories [(when-not hide-login-actions?
|
||||
{:icon :main-icons/more
|
||||
:handler #(re-frame/dispatch [:keycard.login.pin.ui/more-icon-pressed])})]
|
||||
:content (cond
|
||||
(= :reset enter-step)
|
||||
[step-view 1]
|
||||
:content (cond
|
||||
(= :reset enter-step)
|
||||
[step-view 1]
|
||||
|
||||
(= :reset-confirmation enter-step)
|
||||
[step-view 2]
|
||||
(= :reset-confirmation enter-step)
|
||||
[step-view 2]
|
||||
|
||||
(and (= :puk enter-step)
|
||||
(not= :blocked-card status))
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(i18n/label :t/enter-puk-code)]])
|
||||
(and (= :puk enter-step)
|
||||
(not= :blocked-card status))
|
||||
[react/view
|
||||
{:style {:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center}}
|
||||
[react/text {:style {:color colors/gray}}
|
||||
(i18n/label :t/enter-puk-code)]])
|
||||
:navigation
|
||||
{:icon :main-icons/arrow-left
|
||||
:accessibility-label :back-button
|
||||
|
@ -399,20 +361,21 @@
|
|||
#{:reset :reset-confirmation :puk}
|
||||
enter-step))}])
|
||||
(when-not hide-login-actions?
|
||||
[react/view {:margin-bottom (if small-screen? 25 32)}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed])}
|
||||
[react/text {:style {:color colors/blue}}
|
||||
(i18n/label :t/recover-key)]]])]])))
|
||||
[toolbar/toolbar
|
||||
{:center [quo/button
|
||||
{:on-press #(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
:type :secondary}
|
||||
(i18n/label :t/recover-key)]}])]])))
|
||||
|
||||
(defn- more-sheet-content []
|
||||
[react/view {:flex 1}
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/create-new-key
|
||||
:icon :main-icons/profile
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.create.ui/get-new-key])}]])
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/create-new-key)
|
||||
:icon :main-icons/profile
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:multiaccounts.create.ui/get-new-key]))}]])
|
||||
|
||||
(def more-sheet
|
||||
{:content more-sheet-content
|
||||
:content-height 65})
|
||||
{:content more-sheet-content})
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
[status-im.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.list-item.views :as list-item]))
|
||||
[quo.core :as quo]))
|
||||
|
||||
(defn title [label]
|
||||
[react/view {:style styles/title}
|
||||
|
@ -59,16 +59,16 @@
|
|||
[react/view {:align-items :center}
|
||||
[title :mobile-syncing-sheet-title]
|
||||
[details :mobile-syncing-sheet-details]]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/mobile-network-continue-syncing
|
||||
:subtitle :t/mobile-network-continue-syncing-details
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/mobile-network-continue-syncing)
|
||||
:subtitle (i18n/label :t/mobile-network-continue-syncing-details)
|
||||
:icon :main-icons/network
|
||||
:on-press #(re-frame/dispatch [:mobile-network/continue-syncing])}]
|
||||
[list-item/list-item
|
||||
{:theme :action-destructive
|
||||
:title :t/mobile-network-stop-syncing
|
||||
:subtitle :t/mobile-network-stop-syncing-details
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/mobile-network-stop-syncing)
|
||||
:subtitle (i18n/label :t/mobile-network-stop-syncing-details)
|
||||
:icon :main-icons/cancel
|
||||
:on-press #(re-frame/dispatch [:mobile-network/stop-syncing])}]
|
||||
[separator]
|
||||
|
@ -82,10 +82,10 @@
|
|||
[react/view {:align-items :center}
|
||||
[title :t/mobile-network-sheet-offline]
|
||||
[details :t/mobile-network-sheet-offline-details]]
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/mobile-network-start-syncing
|
||||
:subtitle :t/mobile-network-continue-syncing-details
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/mobile-network-start-syncing)
|
||||
:subtitle (i18n/label :t/mobile-network-continue-syncing-details)
|
||||
:icon :main-icons/network
|
||||
:on-press #(re-frame/dispatch [:mobile-network/continue-syncing])}]
|
||||
[separator]
|
||||
|
|
|
@ -9,10 +9,15 @@
|
|||
[status-im.ui.screens.mobile-network-settings.sheets :as sheets]
|
||||
[status-im.ui.components.topbar :as topbar]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn settings-separator []
|
||||
[react/view
|
||||
{:style (styles/settings-separator)}])
|
||||
|
||||
;; TODO(Ferossgp): To refactor, uses outdated components
|
||||
(views/defview mobile-network-settings []
|
||||
(views/letsubs
|
||||
[{:keys [syncing-on-mobile-network?
|
||||
|
@ -24,7 +29,7 @@
|
|||
[profile.components/settings-switch-item
|
||||
{:label-kw :t/mobile-network-use-mobile
|
||||
:value syncing-on-mobile-network?
|
||||
:action-fn #(re-frame/dispatch [:mobile-network/set-syncing %])}]]
|
||||
:action-fn #(hide-sheet-and-dispatch [:mobile-network/set-syncing %])}]]
|
||||
[react/view {:style styles/details}
|
||||
[react/text {:style styles/use-mobile-data-text}
|
||||
(i18n/label :t/mobile-network-use-mobile-data)]]
|
||||
|
@ -32,19 +37,17 @@
|
|||
[profile.components/settings-switch-item
|
||||
{:label-kw :t/mobile-network-ask-me
|
||||
:value (not remember-syncing-choice?)
|
||||
:action-fn #(re-frame/dispatch [:mobile-network/ask-on-mobile-network? %])}]]
|
||||
:action-fn #(hide-sheet-and-dispatch [:mobile-network/ask-on-mobile-network? %])}]]
|
||||
[settings-separator]
|
||||
[react/view
|
||||
{:style styles/defaults-container}
|
||||
[react/text
|
||||
{:style styles/defaults
|
||||
:on-press #(re-frame/dispatch [:mobile-network/restore-defaults])}
|
||||
:on-press #(hide-sheet-and-dispatch [:mobile-network/restore-defaults])}
|
||||
"Restore Defaults"]]]))
|
||||
|
||||
(def settings-sheet
|
||||
{:content-height 340
|
||||
:content sheets/settings-sheet})
|
||||
{:content sheets/settings-sheet})
|
||||
|
||||
(def offline-sheet
|
||||
{:content sheets/offline-sheet
|
||||
:content-height 180})
|
||||
{:content sheets/offline-sheet})
|
||||
|
|
|
@ -17,22 +17,6 @@
|
|||
{:margin-top 16
|
||||
:color colors/gray})
|
||||
|
||||
(def bottom-button
|
||||
{:padding-horizontal 24
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:align-self :center
|
||||
:flex-direction :row})
|
||||
|
||||
(defn bottom-button-container []
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:border-top-width 1
|
||||
:border-top-color colors/gray-lighter
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(def login-badge
|
||||
{:align-items :center})
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.checkbox.view :as checkbox]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.multiaccounts.login.styles :as styles]
|
||||
|
@ -14,7 +12,9 @@
|
|||
[status-im.utils.utils :as utils]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.topbar :as topbar])
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.components.colors :as colors])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn login-multiaccount [^js password-text-input]
|
||||
|
@ -92,18 +92,20 @@
|
|||
[react/view styles/processing-view
|
||||
[react/activity-indicator {:animating true}]
|
||||
[react/i18n-text {:style styles/processing :key :processing}]])
|
||||
[react/view {:style (styles/bottom-button-container)}
|
||||
[components.common/button
|
||||
{:label (i18n/label :t/access-existing-keys)
|
||||
:button-style styles/bottom-button
|
||||
:background? false
|
||||
:on-press #(do
|
||||
(react/dismiss-keyboard!)
|
||||
(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]))}]
|
||||
[components.common/button
|
||||
{:label (i18n/label :t/submit)
|
||||
:button-style styles/bottom-button
|
||||
:label-style {:color (if (or (not sign-in-enabled?) processing) colors/gray colors/blue)}
|
||||
:background? true
|
||||
:disabled? (or (not sign-in-enabled?) processing)
|
||||
:on-press #(login-multiaccount @password-text-input)}]]]))
|
||||
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:size :large
|
||||
:left
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:on-press #(do
|
||||
(react/dismiss-keyboard!)
|
||||
(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]))}
|
||||
(i18n/label :t/access-existing-keys)]
|
||||
:right
|
||||
[react/view {:padding-horizontal 8}
|
||||
[quo/button
|
||||
{:disabled (or (not sign-in-enabled?) processing)
|
||||
:on-press #(login-multiaccount @password-text-input)}
|
||||
(i18n/label :t/submit)]]}]]))
|
||||
|
|
|
@ -8,16 +8,19 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[quo.core :as quo]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.button :as button]))
|
||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defview custom-seed-phrase []
|
||||
[react/view
|
||||
[react/view {:margin-top 24 :margin-horizontal 24 :align-items :center}
|
||||
[react/view {:width 32 :height 32 :border-radius 16
|
||||
[react/view {:width 32 :height 32 :border-radius 16
|
||||
:align-items :center :justify-content :center}
|
||||
[icons/icon :main-icons/help {:color colors/blue}]]
|
||||
[react/text {:style {:typography :title-bold
|
||||
|
@ -35,44 +38,40 @@
|
|||
(i18n/label :t/custom-seed-phrase-text-1)]]
|
||||
[react/view {:margin-vertical 24
|
||||
:align-items :center}
|
||||
[button/button {:on-press #(re-frame/dispatch [:hide-popover])
|
||||
:accessibility-label :cancel-custom-seed-phrase
|
||||
:type :secondary
|
||||
:label (i18n/label :t/cancel)}]]]])
|
||||
[quo/button {:on-press #(re-frame/dispatch [:hide-popover])
|
||||
:accessibility-label :cancel-custom-seed-phrase
|
||||
:type :secondary}
|
||||
(i18n/label :t/cancel)]]]])
|
||||
|
||||
(defn bottom-sheet-view []
|
||||
[react/view {:flex 1 :flex-direction :row}
|
||||
[react/view {:flex 1}
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/enter-seed-phrase
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/enter-seed-phrase)
|
||||
:accessibility-label :enter-seed-phrase-button
|
||||
:icon :main-icons/text
|
||||
:on-press #(re-frame/dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
|
||||
:on-press #(hide-sheet-and-dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
|
||||
(when (and config/hardwallet-enabled?
|
||||
(or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
(nfc/nfc-supported?))
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/recover-with-keycard
|
||||
:disabled? (not config/hardwallet-enabled?)
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/recover-with-keycard)
|
||||
:disabled (not config/hardwallet-enabled?)
|
||||
:accessibility-label :recover-with-keycard-button
|
||||
:icon [react/view {:border-width 1
|
||||
:border-radius 20
|
||||
:border-color colors/blue-light
|
||||
:background-color colors/blue-light
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:width 40
|
||||
:height 40}
|
||||
[react/image {:source (resources/get-image :keycard-logo-blue)
|
||||
:style {:width 24 :height 24}}]]
|
||||
:on-press #(re-frame/dispatch [::hardwallet/recover-with-keycard-pressed])}])]])
|
||||
:icon [react/view {:border-width 1
|
||||
:border-radius 20
|
||||
:border-color colors/blue-light
|
||||
:background-color colors/blue-light
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:width 40
|
||||
:height 40}
|
||||
[react/image {:source (resources/get-image :keycard-logo-blue)
|
||||
:style {:width 24 :height 24}}]]
|
||||
:on-press #(hide-sheet-and-dispatch [::hardwallet/recover-with-keycard-pressed])}])]])
|
||||
|
||||
(defn bottom-sheet []
|
||||
{:content bottom-sheet-view
|
||||
:content-height (if (and platform/android?
|
||||
(nfc/nfc-supported?))
|
||||
130
|
||||
65)})
|
||||
(def bottom-sheet
|
||||
{:content bottom-sheet-view})
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
(ns status-im.ui.screens.multiaccounts.sheets
|
||||
(:require [status-im.ui.components.list-item.views :as list-item]
|
||||
(:require [quo.core :as quo]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(defn actions-sheet []
|
||||
[react/view
|
||||
[list-item/list-item {:theme :action
|
||||
:on-press #(do (re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard]))
|
||||
:icon :main-icons/add
|
||||
:accessibility-label :generate-a-new-key
|
||||
:title :t/generate-a-new-key}]])
|
||||
[quo/list-item {:theme :accent
|
||||
:on-press #(do (re-frame/dispatch [:bottom-sheet/hide])
|
||||
(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard]))
|
||||
:icon :main-icons/add
|
||||
:accessibility-label :generate-a-new-key
|
||||
:title (i18n/label :t/generate-a-new-key)}]])
|
||||
|
|
|
@ -1,39 +1,14 @@
|
|||
(ns status-im.ui.screens.multiaccounts.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
(ns status-im.ui.screens.multiaccounts.styles)
|
||||
|
||||
(def multiaccounts-view
|
||||
{:flex 1})
|
||||
|
||||
(def multiaccounts-container
|
||||
{:flex 1
|
||||
:margin-top 24
|
||||
:justify-content :space-between})
|
||||
|
||||
(def multiaccount-image-size 40)
|
||||
|
||||
(def multiaccounts-list-container
|
||||
{:flex 1
|
||||
{:padding-top 24
|
||||
:padding-bottom 8})
|
||||
|
||||
(def multiaccount-view
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 16
|
||||
:height 64})
|
||||
|
||||
(def multiaccount-badge-text-view
|
||||
{:margin-left 16
|
||||
:margin-right 31
|
||||
:flex-shrink 1})
|
||||
|
||||
(def multiaccount-badge-text
|
||||
{:font-weight "500"})
|
||||
|
||||
(defn bottom-button-container []
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:border-top-width 1
|
||||
:border-top-color colors/gray-lighter
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
|
|
@ -6,44 +6,33 @@
|
|||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.ui.components.button :as button]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.screens.multiaccounts.sheets :as sheets]
|
||||
[status-im.react-native.resources :as resources]))
|
||||
|
||||
(defn multiaccount-view
|
||||
[{:keys [key-uid photo-path name keycard-pairing]}]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.login.ui/multiaccount-selected key-uid])}
|
||||
[react/view styles/multiaccount-view
|
||||
[photos/photo photo-path {:size styles/multiaccount-image-size}]
|
||||
[react/view styles/multiaccount-badge-text-view
|
||||
[react/view {:flex-direction :row}
|
||||
[react/text {:style styles/multiaccount-badge-text
|
||||
:ellipsize-mode :middle
|
||||
:numberOfLines 1}
|
||||
name]]
|
||||
;;TODO we don't have public key in multiaccounts
|
||||
#_[react/text {:style styles/multiaccount-badge-pub-key-text}
|
||||
(utils/get-shortened-address public-key)]]
|
||||
[react/view {:flex 1}]
|
||||
(when keycard-pairing
|
||||
[react/view {:justify-content :center
|
||||
:align-items :center
|
||||
:margin-right 7
|
||||
:width 32
|
||||
:height 32
|
||||
:border-radius 24
|
||||
:background-color colors/white
|
||||
:border-width 1
|
||||
:border-color colors/black-transparent}
|
||||
[react/image {:source (resources/get-image :keycard-key)
|
||||
:style {:width 11
|
||||
:height 19}}]])
|
||||
[icons/icon :main-icons/next {:color colors/gray-transparent-40}]]])
|
||||
[quo/list-item {:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.login.ui/multiaccount-selected key-uid])
|
||||
:icon [photos/photo photo-path {:size styles/multiaccount-image-size}]
|
||||
:title name
|
||||
:accessory (when keycard-pairing
|
||||
[react/view {:justify-content :center
|
||||
:align-items :center
|
||||
:margin-right 7
|
||||
:width 32
|
||||
:height 32
|
||||
:border-radius 24
|
||||
:background-color colors/white
|
||||
:border-width 1
|
||||
:border-color colors/black-transparent}
|
||||
[react/image {:source (resources/get-image :keycard-key)
|
||||
:style {:width 11
|
||||
:height 19}}]])
|
||||
:chevron true}])
|
||||
|
||||
(defview multiaccounts []
|
||||
(letsubs [multiaccounts [:multiaccounts/multiaccounts]]
|
||||
|
@ -51,15 +40,18 @@
|
|||
[topbar/topbar {:show-border? true
|
||||
:navigation :none
|
||||
:title (i18n/label :t/your-keys)
|
||||
:accessories [{:icon :more
|
||||
:accessories [{:icon :more
|
||||
:accessibility-label :your-keys-more-icon
|
||||
:handler #(re-frame/dispatch [:bottom-sheet/show-sheet {:content sheets/actions-sheet}])}]}]
|
||||
:handler #(re-frame/dispatch [:bottom-sheet/show-sheet {:content sheets/actions-sheet}])}]}]
|
||||
[react/view styles/multiaccounts-container
|
||||
[react/view styles/multiaccounts-list-container
|
||||
[list/flat-list {:data (vals multiaccounts)
|
||||
:key-fn :address
|
||||
:render-fn (fn [multiaccount] [multiaccount-view multiaccount])}]]
|
||||
[react/view {:style (styles/bottom-button-container)}
|
||||
[button/button {:on-press #(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
:type :secondary
|
||||
:label (i18n/label :t/access-existing-keys)}]]]]))
|
||||
[list/flat-list {:data (vals multiaccounts)
|
||||
:contentContainerStyle styles/multiaccounts-list-container
|
||||
:key-fn :address
|
||||
:render-fn multiaccount-view}]]
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:size :large
|
||||
:center [quo/button
|
||||
{:on-press #(re-frame/dispatch [:multiaccounts.recover.ui/recover-multiaccount-button-pressed])
|
||||
:type :secondary}
|
||||
(i18n/label :t/access-existing-keys)]}]]))
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
(def qr-code
|
||||
{:padding 16})
|
||||
|
||||
(def bottom-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 12
|
||||
:margin-vertical 15})
|
||||
|
||||
(def button-container
|
||||
{:margin-top 8
|
||||
:margin-bottom 16
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles :as styles]
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.topbar :as topbar]))
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles :as styles]
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.topbar :as topbar]))
|
||||
|
||||
(defn connect-button [id]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:mailserver.ui/connect-pressed id])}
|
||||
|
@ -29,14 +25,6 @@
|
|||
[react/text {:style styles/button-label}
|
||||
(i18n/label :t/delete)]]]])
|
||||
|
||||
(def qr-code
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
|
||||
{:title (i18n/label :t/add-mailserver)
|
||||
:handler :mailserver.callback/qr-code-scanned}])
|
||||
:style styles/qr-code}
|
||||
[react/view
|
||||
[vector-icons/icon :main-icons/qr {:color colors/blue}]]])
|
||||
|
||||
(views/defview edit-mailserver []
|
||||
(views/letsubs [mailserver [:mailserver.edit/mailserver]
|
||||
connected? [:mailserver.edit/connected?]
|
||||
|
@ -48,40 +36,43 @@
|
|||
(not (string/blank? name))
|
||||
(empty? validation-errors))
|
||||
invalid-url? (contains? validation-errors :url)]
|
||||
[react/view components.styles/flex
|
||||
[react/keyboard-avoiding-view components.styles/flex
|
||||
[topbar/topbar {:title (if id :t/mailserver-details :t/add-mailserver)}]
|
||||
[react/scroll-view {:keyboard-should-persist-taps :handled}
|
||||
[react/view styles/edit-mailserver-view
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/name)
|
||||
:placeholder (i18n/label :t/specify-name)
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :name %])
|
||||
:auto-focus true}]]
|
||||
[react/view {:flex 1
|
||||
:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/mailserver-address)
|
||||
:placeholder (i18n/label :t/mailserver-format)
|
||||
:content qr-code
|
||||
:default-value url
|
||||
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :url %])
|
||||
:bottom-value 0
|
||||
:error (when (and (not (string/blank? url))
|
||||
invalid-url?)
|
||||
(i18n/label :t/invalid-format
|
||||
{:format (i18n/label :t/mailserver-format)}))}]]
|
||||
(when (and id
|
||||
(not connected?))
|
||||
[react/view
|
||||
[connect-button id]
|
||||
[delete-button id]])]]
|
||||
[react/view styles/bottom-container
|
||||
[react/view components.styles/flex]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/save)
|
||||
:disabled? (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:mailserver.ui/save-pressed])}]]]])))
|
||||
[react/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[topbar/topbar {:title (if id :t/mailserver-details :t/add-mailserver)}]
|
||||
[react/scroll-view {:keyboard-should-persist-taps :handled}
|
||||
[react/view styles/edit-mailserver-view
|
||||
[react/view {:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/name)
|
||||
:placeholder (i18n/label :t/specify-name)
|
||||
:default-value name
|
||||
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :name %])
|
||||
:auto-focus true}]]
|
||||
[react/view {:flex 1
|
||||
:padding-vertical 8}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/mailserver-address)
|
||||
:placeholder (i18n/label :t/mailserver-format)
|
||||
:default-value url
|
||||
:show-cancel false
|
||||
:on-change-text #(re-frame/dispatch [:mailserver.ui/input-changed :url %])
|
||||
:bottom-value 0
|
||||
:error (when (and (not (string/blank? url))
|
||||
invalid-url?)
|
||||
(i18n/label :t/invalid-format
|
||||
{:format (i18n/label :t/mailserver-format)}))
|
||||
:after {:icon :main-icons/qr
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.ui/scan-qr-code-pressed
|
||||
{:title (i18n/label :t/add-mailserver)
|
||||
:handler :mailserver.callback/qr-code-scanned}])}}]]
|
||||
(when (and id
|
||||
(not connected?))
|
||||
[react/view
|
||||
[connect-button id]
|
||||
[delete-button id]])]]
|
||||
[toolbar/toolbar
|
||||
{:right
|
||||
[quo/button {:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (not is-valid?)
|
||||
:on-press #(re-frame/dispatch [:mailserver.ui/save-pressed])}
|
||||
(i18n/label :t/save)]}]])))
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.utils.platform :as utils.platform]
|
||||
[status-im.ui.components.styles :as components.styles]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.checkbox.view :as checkbox.views]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -147,13 +146,14 @@
|
|||
:auto-focus true}]]]
|
||||
[react/view styles/bottom-container
|
||||
[react/view components.styles/flex]
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:label (i18n/label :t/continue)
|
||||
:disabled? (string/blank? @installation-name)
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (string/blank? @installation-name)
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:pairing.ui/set-name-pressed @installation-name])
|
||||
(reset! installation-name ""))}]]])
|
||||
(reset! installation-name ""))}
|
||||
(i18n/label :t/continue)]]])
|
||||
|
||||
(defn info-section []
|
||||
[react/view {:style styles/info-section}
|
||||
|
|
|
@ -1,96 +1,69 @@
|
|||
(ns status-im.ui.screens.privacy-and-security-settings.views
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.multiaccounts.biometric.core :as biometric]
|
||||
[status-im.ui.components.topbar :as topbar]
|
||||
[status-im.utils.platform :as platform])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn- list-data [mnemonic preview-privacy? supported-biometric-auth biometric-auth? _]
|
||||
[{:type :section-header
|
||||
:title :t/security
|
||||
:container-margin-top 6}
|
||||
{:type :small
|
||||
:title :t/back-up-seed-phrase
|
||||
:accessibility-label :back-up-recovery-phrase-button
|
||||
:disabled? (not mnemonic)
|
||||
;; TODO - remove container bottom margin
|
||||
;; when items below are implemented
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :backup-seed])
|
||||
:accessories
|
||||
(when mnemonic
|
||||
[[components.common/counter {:size 22} 1]
|
||||
:chevron])}
|
||||
(when supported-biometric-auth
|
||||
{:type :small
|
||||
:title (str (i18n/label :t/lock-app-with) " " (biometric/get-label supported-biometric-auth))
|
||||
:container-margin-bottom 8
|
||||
:accessibility-label :biometric-auth-settings-switch
|
||||
:accessories [[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value (boolean biometric-auth?)
|
||||
:on-value-change #(re-frame/dispatch [:multiaccounts.ui/biometric-auth-switched %])
|
||||
:disabled (not supported-biometric-auth)}]]
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.ui/biometric-auth-switched
|
||||
((complement boolean) biometric-auth?)])})
|
||||
;; TODO - uncomment when implemented
|
||||
;; {:type :small
|
||||
;; :title :t/change-password
|
||||
;; :accessories [:chevron]}
|
||||
;; {:type :small
|
||||
;; :title :t/change-passcode
|
||||
;; :accessories [:chevron]
|
||||
;; :container-margin-bottom 8}
|
||||
{:type :divider}
|
||||
{:container-margin-top 8
|
||||
:type :section-header
|
||||
:title :t/privacy}
|
||||
{:type :small
|
||||
:title :t/set-dapp-access-permissions
|
||||
:on-press #(re-frame/dispatch [:navigate-to :dapps-permissions])
|
||||
:accessibility-label :dapps-permissions-button
|
||||
:accessories [:chevron]}
|
||||
{:type :small
|
||||
:title (if platform/android?
|
||||
:t/hide-content-when-switching-apps
|
||||
:t/hide-content-when-switching-apps-ios)
|
||||
:container-margin-bottom 8
|
||||
:accessories
|
||||
[[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value (boolean preview-privacy?)
|
||||
:on-value-change
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/preview-privacy-mode-switched %])
|
||||
:disabled false}]]
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/preview-privacy-mode-switched
|
||||
((complement boolean) preview-privacy?)])}
|
||||
{:type :divider}
|
||||
;; TODO - uncomment when implemented
|
||||
(comment
|
||||
{:container-margin-top 8
|
||||
:type :small
|
||||
:title :t/delete-my-account
|
||||
:container-margin-bottom 24
|
||||
:theme :action-destructive})])
|
||||
|
||||
(views/defview privacy-and-security []
|
||||
(views/letsubs [{:keys [mnemonic preview-privacy?]} [:multiaccount]
|
||||
supported-biometric-auth [:supported-biometric-auth]
|
||||
auth-method [:auth-method]
|
||||
keycard-multiaccount? [:keycard-multiaccount?]]
|
||||
auth-method [:auth-method]]
|
||||
[react/view {:flex 1 :background-color colors/white}
|
||||
[topbar/topbar {:title :t/privacy-and-security}]
|
||||
[list/flat-list
|
||||
{:data (list-data mnemonic preview-privacy? supported-biometric-auth
|
||||
(= auth-method "biometric") keycard-multiaccount?)
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn list/flat-list-generic-render-fn}]]))
|
||||
[react/scroll-view {:padding-vertical 8}
|
||||
[quo/list-header (i18n/label :t/security)]
|
||||
[quo/list-item {:size :small
|
||||
:title (i18n/label :t/back-up-seed-phrase)
|
||||
:accessibility-label :back-up-recovery-phrase-button
|
||||
:disabled (not mnemonic)
|
||||
:chevron (boolean mnemonic)
|
||||
:accessory (when mnemonic [components.common/counter {:size 22} 1])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :backup-seed])}]
|
||||
(when supported-biometric-auth
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (str (i18n/label :t/lock-app-with) " " (biometric/get-label supported-biometric-auth))
|
||||
:active (= auth-method "biometric")
|
||||
:accessibility-label :biometric-auth-settings-switch
|
||||
:accessory :switch
|
||||
:on-press #(re-frame/dispatch [:multiaccounts.ui/biometric-auth-switched
|
||||
((complement boolean) (= auth-method "biometric"))])}])
|
||||
[react/view {:margin-vertical 8
|
||||
:background-color colors/gray-lighter
|
||||
:height 1}]
|
||||
;; TODO - uncomment when implemented
|
||||
;; {:size :small
|
||||
;; :title (i18n/label :t/change-password)
|
||||
;; :chevron true}
|
||||
;; {:size :small
|
||||
;; :title (i18n/label :t/change-passcode)
|
||||
;; :chevron true}
|
||||
|
||||
[quo/list-header (i18n/label :t/privacy)]
|
||||
[quo/list-item {:size :small
|
||||
:title (i18n/label :t/set-dapp-access-permissions)
|
||||
:on-press #(re-frame/dispatch [:navigate-to :dapps-permissions])
|
||||
:accessibility-label :dapps-permissions-button
|
||||
:chevron true}]
|
||||
[quo/list-item {:size :small
|
||||
:title (if platform/android?
|
||||
(i18n/label :t/hide-content-when-switching-apps)
|
||||
(i18n/label :t/hide-content-when-switching-apps-ios))
|
||||
:container-margin-bottom 8
|
||||
:active preview-privacy?
|
||||
:accessory :switch
|
||||
:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.ui/preview-privacy-mode-switched
|
||||
((complement boolean) preview-privacy?)])}]
|
||||
|
||||
(comment
|
||||
{:container-margin-top 8
|
||||
:size :small
|
||||
:title :t/delete-my-account
|
||||
:theme :negative})]]))
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
[react/text {:style styles/sheet-text}
|
||||
(i18n/label :t/block-contact-details)]
|
||||
[react/view {:align-items :center :margin-top 16}
|
||||
[quo/button {:theme :negative :disabled @in-progress? :loading @in-progress?
|
||||
[quo/button {:theme :negative
|
||||
:disabled @in-progress?
|
||||
:loading @in-progress?
|
||||
:accessibility-label :block-contact-confirm
|
||||
:on-press #(do (reset! in-progress? true)
|
||||
(re-frame/dispatch [:contact.ui/block-contact-confirmed public-key]))}
|
||||
:t/block]
|
||||
:on-press #(do (reset! in-progress? true)
|
||||
(re-frame/dispatch [:contact.ui/block-contact-confirmed public-key]))}
|
||||
(i18n/label :t/block)]
|
||||
[react/view {:height 8}]
|
||||
[quo/button {:type :secondary :disabled @in-progress?
|
||||
[quo/button {:type :secondary
|
||||
:disabled @in-progress?
|
||||
:on-press #(re-frame/dispatch [:hide-popover])}
|
||||
:t/close]]]))
|
||||
(i18n/label :t/close)]]]))
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.profile-header.view :as profile-header]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.profile.components.sheets :as sheets]
|
||||
|
@ -50,28 +48,27 @@
|
|||
; contact])
|
||||
|
||||
(defn render-detail [{:keys [alias public-key ens-name] :as detail}]
|
||||
[list-item/list-item
|
||||
{:title alias
|
||||
:subtitle (utils/get-shortened-address public-key)
|
||||
:icon [chat-icon/contact-icon-contacts-tab detail]
|
||||
[quo/list-item
|
||||
{:title (or alias ens-name)
|
||||
:subtitle (utils/get-shortened-address public-key)
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo detail)]
|
||||
:accessibility-label :profile-public-key
|
||||
:on-press #(re-frame/dispatch [:show-popover {:view :share-chat-key :address public-key :ens-name ens-name}])
|
||||
:accessories [[icons/icon :main-icons/share styles/contact-profile-detail-share-icon]]}])
|
||||
|
||||
(defn profile-details-list-view [contact]
|
||||
[list/flat-list {:data [contact]
|
||||
:default-separator? true
|
||||
:key-fn :public-key
|
||||
:render-fn render-detail}])
|
||||
:on-press #(re-frame/dispatch [:show-popover {:view :share-chat-key
|
||||
:address public-key
|
||||
:ens-name ens-name}])
|
||||
:accessory [icons/icon :main-icons/share styles/contact-profile-detail-share-icon]}])
|
||||
|
||||
(defn profile-details [contact]
|
||||
(when contact
|
||||
[react/view
|
||||
[list-item/list-item {:type :section-header
|
||||
:title :t/profile-details
|
||||
:title-accessibility-label :profile-details}]
|
||||
[profile-details-list-view contact]]))
|
||||
[quo/list-header
|
||||
[quo/text {:accessibility-label :profile-details
|
||||
:color :inherit}
|
||||
(i18n/label :t/profile-details)]]
|
||||
[render-detail contact]]))
|
||||
|
||||
;; TODO: List item
|
||||
(defn block-contact-action [{:keys [blocked? public-key]}]
|
||||
[react/touchable-highlight {:on-press (if blocked?
|
||||
#(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key])
|
||||
|
@ -116,13 +113,14 @@
|
|||
|
||||
[react/view {:padding-top 12}
|
||||
(for [{:keys [label subtext accessibility-label icon action disabled?]} (actions contact)]
|
||||
[list-item/list-item {:theme :action
|
||||
:title label
|
||||
:subtitle subtext
|
||||
:icon icon
|
||||
:accessibility-label accessibility-label
|
||||
:disabled? disabled?
|
||||
:on-press action}])]
|
||||
(when label
|
||||
[quo/list-item {:theme :accent
|
||||
:title label
|
||||
:subtitle subtext
|
||||
:icon icon
|
||||
:accessibility-label accessibility-label
|
||||
:disabled disabled?
|
||||
:on-press action}]))]
|
||||
[react/view styles/contact-profile-details-container
|
||||
[profile-details (cond-> contact
|
||||
(and ens-verified name)
|
||||
|
|
|
@ -15,8 +15,4 @@
|
|||
(defn base64-jpeg? [photo-path]
|
||||
(string/starts-with? photo-path "data:image/jpeg;base64,"))
|
||||
|
||||
(defn base64-encoded-image-path? [photo-path]
|
||||
(or (base64-png? photo-path)
|
||||
(base64-jpeg? photo-path)))
|
||||
|
||||
(spec/def :profile/name correct-name?)
|
|
@ -6,8 +6,6 @@
|
|||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.components.contact.contact :as contact]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.profile-header.view :as profile-header]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
@ -20,51 +18,55 @@
|
|||
|
||||
(defn member-sheet [chat-id member us-admin?]
|
||||
[react/view
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:icon (multiaccounts/displayed-photo member)
|
||||
:title [chat.sheets/view-profile {:name (contact/format-name member)
|
||||
:helper :t/view-profile}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:title (contact/format-name member)
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:accessories [:chevron]
|
||||
:chevron true
|
||||
:on-press #(chat.sheets/hide-sheet-and-dispatch
|
||||
[(if platform/desktop? :show-profile-desktop :chat.ui/show-profile)
|
||||
(:public-key member)])}]
|
||||
(when (and us-admin?
|
||||
(not (:admin? member)))
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/make-admin
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/make-admin)
|
||||
:accessibility-label :make-admin
|
||||
;; TODO(Ferossgp): Fix case for make admin icon
|
||||
:icon :main-icons/make-admin
|
||||
:on-press #(chat.sheets/hide-sheet-and-dispatch [:group-chats.ui/make-admin-pressed chat-id (:public-key member)])}])
|
||||
(when-not (:admin? member)
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/remove-from-chat
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/remove-from-chat)
|
||||
:accessibility-label :remove-from-chat
|
||||
:icon :main-icons/remove-contact
|
||||
:on-press #(chat.sheets/hide-sheet-and-dispatch [:group-chats.ui/remove-member-pressed chat-id (:public-key member)])}])])
|
||||
|
||||
(defn render-member [chat-id {:keys [public-key] :as member} admin? current-user-identity]
|
||||
[list-item/list-item
|
||||
[quo/list-item
|
||||
(merge
|
||||
{:title (contact/format-name member)
|
||||
{:title (contact/format-name member)
|
||||
:accessibility-label :member-item
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:on-press (when (not= public-key current-user-identity)
|
||||
#(re-frame/dispatch [(if platform/desktop? :show-profile-desktop :chat.ui/show-profile) public-key]))}
|
||||
(when (:admin? member)
|
||||
{:accessories [(i18n/label :t/group-chat-admin)]})
|
||||
{:accessory :text
|
||||
:accessory-text (i18n/label :t/group-chat-admin)})
|
||||
(when (and admin?
|
||||
(not (:admin? member))
|
||||
(not= public-key current-user-identity))
|
||||
{:accessories [[react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[member-sheet chat-id member admin?])}])
|
||||
:accessibility-label :menu-option}
|
||||
[vector-icons/icon :main-icons/more {:accessibility-label :options}]]]}))])
|
||||
{:accessory [quo/button {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn []
|
||||
[member-sheet chat-id member admin?])}])
|
||||
:type :icon
|
||||
:theme :icon
|
||||
:accessibility-label :menu-option}
|
||||
:main-icons/more]}))])
|
||||
|
||||
(defview chat-group-members-view [chat-id admin? current-user-identity]
|
||||
(letsubs [members [:contacts/current-chat-contacts]]
|
||||
|
@ -75,12 +77,12 @@
|
|||
|
||||
(defn members-list [{:keys [chat-id admin? current-pk allow-adding-members?]}]
|
||||
[react/view
|
||||
[list-item/list-item {:title :t/members-title :type :section-header}]
|
||||
[quo/list-header (i18n/label :t/members-title)]
|
||||
(when allow-adding-members?
|
||||
[list-item/list-item
|
||||
{:title :t/add-members
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/add-members)
|
||||
:icon :main-icons/add-contact
|
||||
:theme :action
|
||||
:theme :accent
|
||||
:on-press #(re-frame/dispatch [:navigate-to :add-participants-toggle-list])}])
|
||||
[chat-group-members-view chat-id admin? current-pk]])
|
||||
|
||||
|
@ -109,9 +111,9 @@
|
|||
:subtitle-icon :icons/tiny-group})}
|
||||
[react/view profile.components.styles/profile-form
|
||||
(when joined?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
:title :t/leave-chat
|
||||
[quo/list-item
|
||||
{:theme :negative
|
||||
:title (i18n/label :t/leave-chat)
|
||||
:accessibility-label :leave-chat-button
|
||||
:icon :main-icons/arrow-left
|
||||
:on-press #(re-frame/dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])
|
||||
|
|
|
@ -52,9 +52,6 @@
|
|||
(def twelve-words-spacer
|
||||
{:flex 1})
|
||||
|
||||
(def twelve-words-button-container
|
||||
{:align-items :flex-end})
|
||||
|
||||
(def twelve-words-columns
|
||||
{:margin-top 8
|
||||
:margin-bottom 16
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
(ns status-im.ui.screens.profile.seed.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar.view :as not.toolbar]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.common.styles :as components.common.styles]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[clojure.string :as string]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.ui.screens.profile.seed.styles :as styles]
|
||||
|
@ -35,15 +35,15 @@
|
|||
:justify-content :center}}
|
||||
(when-not platform/desktop?
|
||||
[react/image {:source (resources/get-image :lock)
|
||||
:style styles/intro-image}])
|
||||
:style styles/intro-image}])
|
||||
[react/i18n-text {:style styles/intro-text
|
||||
:key :your-data-belongs-to-you}]
|
||||
[react/i18n-text {:style styles/intro-description
|
||||
:key :your-data-belongs-to-you-description}]
|
||||
[components.common/button
|
||||
{:button-style styles/intro-button
|
||||
:on-press #(re-frame/dispatch [:set-in [:my-profile/seed :step] :12-words])
|
||||
:label (i18n/label :t/ok-continue)}]])
|
||||
[quo/button
|
||||
{:style styles/intro-button
|
||||
:on-press #(re-frame/dispatch [:set-in [:my-profile/seed :step] :12-words])}
|
||||
(i18n/label :t/ok-continue)]])
|
||||
|
||||
(defn six-words [words]
|
||||
[react/view {:style styles/six-words-container}
|
||||
|
@ -61,38 +61,24 @@
|
|||
(defview twelve-words [{:keys [mnemonic]}]
|
||||
(letsubs [mnemonic-vec (vec (map-indexed vector (clojure.string/split mnemonic #" ")))
|
||||
ref (reagent/atom nil)]
|
||||
[react/view {:style styles/twelve-words-container}
|
||||
[react/text {:style styles/twelve-words-label}
|
||||
(i18n/label :t/your-recovery-phrase)]
|
||||
[react/view {:style styles/twelve-words-columns
|
||||
:ref (partial reset! ref)}
|
||||
[six-words (subvec mnemonic-vec 0 6)]
|
||||
[react/view {:style styles/twelve-words-columns-separator}]
|
||||
[six-words (subvec mnemonic-vec 6 12)]]
|
||||
[react/text {:style styles/twelve-words-description}
|
||||
(i18n/label :t/your-recovery-phrase-description)]
|
||||
[react/view styles/twelve-words-spacer]
|
||||
[react/view styles/twelve-words-button-container
|
||||
[components.common/bottom-button
|
||||
{:forward? true
|
||||
:on-press #(re-frame/dispatch [:my-profile/enter-two-random-words])}]]]))
|
||||
|
||||
(defview input [error next-handler idx]
|
||||
(letsubs [ref (reagent/atom nil)]
|
||||
[quo/text-input
|
||||
{:placeholder (i18n/label :t/enter-word)
|
||||
:label [:<>
|
||||
(i18n/label :t/check-your-recovery-phrase)
|
||||
" "
|
||||
[quo/text {:color :secondary}
|
||||
(i18n/label :t/word-n {:number (inc idx)})]]
|
||||
:ref (partial reset! ref)
|
||||
:auto-focus true
|
||||
:auto-correct false
|
||||
:keyboard-type "visible-password"
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:my-profile/seed :word] %])
|
||||
:on-submit-editing next-handler
|
||||
:error error}]))
|
||||
[react/view {:flex 1}
|
||||
[react/view {:style styles/twelve-words-container}
|
||||
[react/text {:style styles/twelve-words-label}
|
||||
(i18n/label :t/your-recovery-phrase)]
|
||||
[react/view {:style styles/twelve-words-columns
|
||||
:ref (partial reset! ref)}
|
||||
[six-words (subvec mnemonic-vec 0 6)]
|
||||
[react/view {:style styles/twelve-words-columns-separator}]
|
||||
[six-words (subvec mnemonic-vec 6 12)]]
|
||||
[react/text {:style styles/twelve-words-description}
|
||||
(i18n/label :t/your-recovery-phrase-description)]
|
||||
[react/view styles/twelve-words-spacer]]
|
||||
[toolbar/toolbar
|
||||
{:right
|
||||
[quo/button {:type :secondary
|
||||
:after :main-icon/next
|
||||
:on-press #(re-frame/dispatch [:my-profile/enter-two-random-words])}
|
||||
(i18n/label :t/next)]}]]))
|
||||
|
||||
(defn next-handler [word entered-word step]
|
||||
(fn [_]
|
||||
|
@ -110,18 +96,34 @@
|
|||
|
||||
(defn enter-word [step [idx word] error entered-word]
|
||||
^{:key word}
|
||||
[react/view {:style styles/enter-word-container}
|
||||
[react/view {:padding-bottom 8}
|
||||
[input error (next-handler word entered-word step) idx]]
|
||||
[react/text {:style styles/enter-word-n-description}
|
||||
(i18n/label :t/word-n-description {:number (inc idx)})]
|
||||
[react/view styles/twelve-words-spacer]
|
||||
[react/view styles/twelve-words-button-container
|
||||
[components.common/bottom-button
|
||||
{:forward? (not= :second-word step)
|
||||
:label (when (= :second-word step) (i18n/label :t/done))
|
||||
:disabled? (string/blank? entered-word)
|
||||
:on-press (next-handler word entered-word step)}]]])
|
||||
[react/view {:flex 1}
|
||||
[react/view {:style styles/enter-word-container}
|
||||
[quo/text-input
|
||||
{:placeholder (i18n/label :t/enter-word)
|
||||
:label [:<>
|
||||
(i18n/label :t/check-your-recovery-phrase)
|
||||
" "
|
||||
[quo/text {:color :secondary}
|
||||
(i18n/label :t/word-n {:number (inc idx)})]]
|
||||
:auto-focus true
|
||||
:auto-correct false
|
||||
:keyboard-type "visible-password"
|
||||
:on-change-text #(re-frame/dispatch [:set-in [:my-profile/seed :word] %])
|
||||
:on-submit-editing next-handler
|
||||
:error error}]
|
||||
[react/text {:style styles/enter-word-n-description}
|
||||
(i18n/label :t/word-n-description {:number (inc idx)})]
|
||||
[react/view styles/twelve-words-spacer]]
|
||||
[toolbar/toolbar
|
||||
{:right
|
||||
[quo/button (merge {:type :secondary
|
||||
:disabled (string/blank? entered-word)
|
||||
:on-press (next-handler word entered-word step)}
|
||||
(when-not (= :second-word step)
|
||||
{:after :main-icon/next}))
|
||||
(if (= :second-word step)
|
||||
(i18n/label :t/done)
|
||||
(i18n/label :t/next))]}]])
|
||||
|
||||
(defn finish []
|
||||
[react/view {:style styles/finish-container}
|
||||
|
@ -132,18 +134,18 @@
|
|||
(i18n/label :t/you-are-all-set)]
|
||||
[react/text {:style styles/finish-description}
|
||||
(i18n/label :t/you-are-all-set-description)]
|
||||
[components.common/button {:button-style styles/finish-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])
|
||||
:label (i18n/label :t/ok-got-it)}]])
|
||||
[quo/button {:style styles/finish-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}
|
||||
(i18n/label :t/ok-got-it)]])
|
||||
|
||||
(defview backup-seed []
|
||||
(letsubs [current-multiaccount [:multiaccount]
|
||||
{:keys [step first-word second-word error word]} [:my-profile/recovery]]
|
||||
[react/keyboard-avoiding-view {:style {:flex 1}}
|
||||
[toolbar/toolbar
|
||||
[not.toolbar/toolbar
|
||||
nil
|
||||
(when-not (= :finish step)
|
||||
(toolbar/nav-button (actions/back #(step-back step))))
|
||||
(not.toolbar/nav-button (actions/back #(step-back step))))
|
||||
[react/view
|
||||
[react/text {:style styles/backup-seed}
|
||||
(i18n/label :t/backup-recovery-phrase)]
|
||||
|
|
|
@ -19,18 +19,6 @@
|
|||
{:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def intro-button
|
||||
{:margin-vertical 8
|
||||
:padding-horizontal 32
|
||||
:align-self :center
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(def bottom-toolbar
|
||||
{:height 60
|
||||
:border-top-width 1
|
||||
:border-top-color colors/gray-lighter})
|
||||
|
||||
(def step-n
|
||||
{:margin-top 5
|
||||
:font-size 14
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
[status-im.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.actions :as actions]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.toolbar.view :as not.toolbar]
|
||||
[status-im.ui.components.toolbar :as toolbar]
|
||||
[status-im.ui.screens.profile.tribute-to-talk.styles :as styles])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
|
@ -277,7 +278,7 @@
|
|||
(defn learn-more [owner?]
|
||||
[react/view {:flex 1}
|
||||
(when-not owner?
|
||||
[toolbar/toolbar nil toolbar/default-nav-close
|
||||
[not.toolbar/toolbar nil not.toolbar/default-nav-close
|
||||
[react/view
|
||||
[react/text {:style styles/tribute-to-talk}
|
||||
(i18n/label :t/tribute-to-talk)]
|
||||
|
@ -325,10 +326,10 @@
|
|||
[:tribute-to-talk/settings-ui]]
|
||||
[react/keyboard-avoiding-view {:style styles/container}
|
||||
[react/view {:style {:flex 1}}
|
||||
[toolbar/toolbar
|
||||
[not.toolbar/toolbar
|
||||
nil
|
||||
(when-not (= :finish step)
|
||||
(toolbar/nav-button
|
||||
(not.toolbar/nav-button
|
||||
(actions/back #(re-frame/dispatch
|
||||
[:tribute-to-talk.ui/step-back-pressed]))))
|
||||
[react/view
|
||||
|
@ -338,29 +339,31 @@
|
|||
[react/text {:style styles/step-n}
|
||||
(if (= step :finish)
|
||||
(i18n/label (case state
|
||||
:completed :t/completed
|
||||
:pending :t/pending
|
||||
:signing :t/signing
|
||||
:completed :t/completed
|
||||
:pending :t/pending
|
||||
:signing :t/signing
|
||||
:transaction-failed :t/transaction-failed
|
||||
:disabled :t/disabled))
|
||||
(i18n/label :t/step-i-of-n {:step ((steps-numbers editing?) step)
|
||||
:disabled :t/disabled))
|
||||
(i18n/label :t/step-i-of-n {:step ((steps-numbers editing?) step)
|
||||
:number (if editing? 2 3)}))])
|
||||
(when (= step :learn-more)
|
||||
[react/text {:style styles/step-n}
|
||||
(i18n/label :t/learn-more)])]]
|
||||
|
||||
(case step
|
||||
:intro [intro]
|
||||
:set-snt-amount [set-snt-amount snt-amount]
|
||||
:edit [edit snt-amount fiat-value]
|
||||
:learn-more [learn-more step]
|
||||
:finish [finish snt-amount state])
|
||||
:intro [intro]
|
||||
:set-snt-amount [set-snt-amount snt-amount]
|
||||
:edit [edit snt-amount fiat-value]
|
||||
:learn-more [learn-more step]
|
||||
:finish [finish snt-amount state])
|
||||
|
||||
(when-not (#{:learn-more :edit} step)
|
||||
[react/view {:style styles/bottom-toolbar}
|
||||
[components.common/button {:button-style styles/intro-button
|
||||
:disabled? disable-button?
|
||||
:label-style (when disable-button? {:color colors/gray})
|
||||
:on-press #(re-frame/dispatch
|
||||
[:tribute-to-talk.ui/step-forward-pressed])
|
||||
:label (i18n/label (step-forward-label step))}]])]]))
|
||||
[toolbar/toolbar
|
||||
{:show-border? true
|
||||
:size :large
|
||||
:center
|
||||
[quo/button {:disabled disable-button?
|
||||
:type :secondary
|
||||
:on-press #(re-frame/dispatch
|
||||
[:tribute-to-talk.ui/step-forward-pressed])}
|
||||
(i18n/label (step-forward-label step))]}])]]))
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
(def share-link-button
|
||||
{:margin-top 12
|
||||
:margin-bottom 8})
|
||||
:margin-horizontal 16
|
||||
:margin-bottom 16})
|
||||
|
|
|
@ -2,19 +2,17 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.copyable-text :as copyable-text]
|
||||
[status-im.ui.components.list-selection :as list-selection]
|
||||
[status-im.ui.components.list.views :as list.views]
|
||||
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.profile.user.styles :as styles]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.config :as config]
|
||||
[quo.core :as quo]
|
||||
[status-im.utils.gfycat.core :as gfy]
|
||||
[status-im.utils.universal-links.core :as universal-links]
|
||||
[status-im.ui.components.profile-header.view :as profile-header])
|
||||
|
@ -52,160 +50,148 @@
|
|||
:font-family "monospace"}}
|
||||
address]]]
|
||||
[react/view styles/share-link-button
|
||||
;;TODO implement icon support
|
||||
[button/button
|
||||
[quo/button
|
||||
{:on-press #(list-selection/open-share {:message link})
|
||||
:label :t/share-link
|
||||
;:icon :main-icons/link
|
||||
:accessibility-label :share-my-contact-code-button}]]])))
|
||||
:accessibility-label :share-my-contact-code-button}
|
||||
(i18n/label :t/share-link)]]])))
|
||||
|
||||
(defn tribute-to-talk-item
|
||||
[opts]
|
||||
[list.views/big-list-item
|
||||
(merge {:text (i18n/label :t/tribute-to-talk)
|
||||
[quo/list-item
|
||||
(merge {:title (i18n/label :t/tribute-to-talk)
|
||||
:accessibility-label :notifications-button
|
||||
:action-fn #(re-frame/dispatch
|
||||
:on-press #(re-frame/dispatch
|
||||
[:tribute-to-talk.ui/menu-item-pressed])}
|
||||
opts)])
|
||||
|
||||
(defn- flat-list-content
|
||||
[preferred-name registrar tribute-to-talk
|
||||
active-contacts-count mnemonic
|
||||
keycard-account? notifications-enabled?]
|
||||
[(cond-> {:title (or (when registrar preferred-name)
|
||||
:t/ens-usernames)
|
||||
:subtitle (if registrar
|
||||
(if preferred-name
|
||||
:t/ens-your-your-name
|
||||
:t/ens-usernames-details)
|
||||
:t/ens-network-restriction)
|
||||
:subtitle-max-lines (if registrar
|
||||
(if preferred-name 1 2)
|
||||
1)
|
||||
:accessibility-label :ens-button
|
||||
:container-margin-top 8
|
||||
:disabled? (not registrar)
|
||||
:accessories [:chevron]
|
||||
:icon :main-icons/username}
|
||||
registrar
|
||||
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))
|
||||
;; TODO replace this with list-item config map
|
||||
;; left it as it is because not sure how to enable it for testing
|
||||
(when tribute-to-talk [tribute-to-talk-item tribute-to-talk])
|
||||
{:title :t/contacts
|
||||
:icon :main-icons/in-contacts
|
||||
:accessibility-label :contacts-button
|
||||
:accessories [(if (pos? active-contacts-count)
|
||||
(str active-contacts-count)
|
||||
:t/none)
|
||||
:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :contacts-list])}
|
||||
{:type :section-header
|
||||
:accessibility-label :settings-section
|
||||
:container-margin-top 16
|
||||
:title :t/settings}
|
||||
{:icon :main-icons/security
|
||||
:title :t/privacy-and-security
|
||||
:accessibility-label :privacy-and-security-settings-button
|
||||
:accessories
|
||||
[(when mnemonic
|
||||
[components.common/counter {:size 22} 1]) :chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}
|
||||
{:icon :main-icons/appearance
|
||||
:title :t/appearance
|
||||
:accessibility-label :appearance-settings-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :appearance])}
|
||||
(when (and platform/android?
|
||||
config/local-notifications?)
|
||||
{:icon :main-icons/notification
|
||||
:title :t/notifications
|
||||
:accessibility-label :notifications-button
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/notifications-switched (not notifications-enabled?)])
|
||||
:accessories
|
||||
[[react/switch
|
||||
{:track-color #js {:true colors/blue :false nil}
|
||||
:value notifications-enabled?
|
||||
:on-value-change
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/notifications-switched
|
||||
(not notifications-enabled?)])
|
||||
:disabled false}]]})
|
||||
{:icon :main-icons/mobile
|
||||
:title :t/sync-settings
|
||||
:accessibility-label :sync-settings-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}
|
||||
(when (and (or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
config/hardwallet-enabled?
|
||||
keycard-account?)
|
||||
{:icon :main-icons/keycard
|
||||
:title :t/keycard
|
||||
:accessibility-label :keycard-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :keycard-settings])})
|
||||
{:icon :main-icons/settings-advanced
|
||||
:title :t/advanced
|
||||
:accessibility-label :advanced-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :advanced-settings])}
|
||||
{:icon :main-icons/help
|
||||
:title :t/need-help
|
||||
:accessibility-label :help-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :help-center])}
|
||||
{:icon :main-icons/info
|
||||
:title :t/about-app
|
||||
:accessibility-label :about-button
|
||||
:accessories [:chevron]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :about-app])}
|
||||
{:icon :main-icons/log-out
|
||||
:title :t/sign-out
|
||||
:accessibility-label :log-out-button
|
||||
:container-margin-top 24
|
||||
:container-margin-bottom 24
|
||||
:theme :action-destructive
|
||||
:on-press
|
||||
#(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}])
|
||||
|
||||
(defn content []
|
||||
(let [{:keys [preferred-name
|
||||
mnemonic
|
||||
keycard-pairing
|
||||
notifications-enabled?]}
|
||||
@(re-frame/subscribe [:multiaccount])
|
||||
|
||||
active-contacts-count @(re-frame/subscribe [:contacts/active-count])
|
||||
tribute-to-talk @(re-frame/subscribe [:tribute-to-talk/profile])
|
||||
registrar @(re-frame/subscribe [:ens.stateofus/registrar])]
|
||||
[react/view
|
||||
(for [item (flat-list-content
|
||||
preferred-name registrar tribute-to-talk
|
||||
active-contacts-count mnemonic
|
||||
keycard-pairing notifications-enabled?)]
|
||||
^{:key (str "item" (:title item))}
|
||||
[list.views/flat-list-generic-render-fn item])]))
|
||||
[:<>
|
||||
[quo/list-item
|
||||
(cond-> {:title (or (when registrar preferred-name)
|
||||
(i18n/label :t/ens-usernames))
|
||||
:subtitle (if registrar
|
||||
(if preferred-name
|
||||
(i18n/label :t/ens-your-your-name)
|
||||
(i18n/label :t/ens-usernames-details))
|
||||
(i18n/label :t/ens-network-restriction))
|
||||
:subtitle-max-lines (if registrar
|
||||
(if preferred-name 1 2)
|
||||
1)
|
||||
:accessibility-label :ens-button
|
||||
:container-margin-top 8
|
||||
:disabled (not registrar)
|
||||
:chevron true
|
||||
:icon :main-icons/username}
|
||||
registrar
|
||||
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))]
|
||||
;; TODO replace this with list-item config map
|
||||
;; left it as it is because not sure how to enable it for testing
|
||||
(when tribute-to-talk [tribute-to-talk-item tribute-to-talk])
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/contacts)
|
||||
:icon :main-icons/in-contacts
|
||||
:accessibility-label :contacts-button
|
||||
:accessory :text
|
||||
:accessory-text (if (pos? active-contacts-count)
|
||||
(str active-contacts-count)
|
||||
(i18n/label :t/none))
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :contacts-list])}]
|
||||
[react/view {:padding-top 16}
|
||||
[quo/list-header (i18n/label :t/settings)]]
|
||||
[quo/list-item
|
||||
{:icon :main-icons/security
|
||||
:title (i18n/label :t/privacy-and-security)
|
||||
:accessibility-label :privacy-and-security-settings-button
|
||||
:chevron true
|
||||
:accessory (when mnemonic
|
||||
[components.common/counter {:size 22} 1])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}]
|
||||
[quo/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title (i18n/label :t/appearance)
|
||||
:accessibility-label :appearance-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :appearance])}]
|
||||
(when (and platform/android?
|
||||
config/local-notifications?)
|
||||
[quo/list-item
|
||||
{:icon :main-icons/notification
|
||||
:title (i18n/label :t/notifications)
|
||||
:accessibility-label :notifications-button
|
||||
:active notifications-enabled?
|
||||
:on-press #(re-frame/dispatch
|
||||
[:multiaccounts.ui/notifications-switched (not notifications-enabled?)])
|
||||
:accessory :switch}])
|
||||
[quo/list-item
|
||||
{:icon :main-icons/mobile
|
||||
:title (i18n/label :t/sync-settings)
|
||||
:accessibility-label :sync-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}]
|
||||
(when (and (or platform/android?
|
||||
config/keycard-test-menu-enabled?)
|
||||
config/hardwallet-enabled?
|
||||
keycard-pairing)
|
||||
[quo/list-item
|
||||
{:icon :main-icons/keycard
|
||||
:title (i18n/label :t/keycard)
|
||||
:accessibility-label :keycard-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :keycard-settings])}])
|
||||
[quo/list-item
|
||||
{:icon :main-icons/settings-advanced
|
||||
:title (i18n/label :t/advanced)
|
||||
:accessibility-label :advanced-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :advanced-settings])}]
|
||||
[quo/list-item
|
||||
{:icon :main-icons/help
|
||||
:title (i18n/label :t/need-help)
|
||||
:accessibility-label :help-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :help-center])}]
|
||||
[quo/list-item
|
||||
{:icon :main-icons/info
|
||||
:title (i18n/label :t/about-app)
|
||||
:accessibility-label :about-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :about-app])}]
|
||||
[react/view {:padding-vertical 24}
|
||||
[quo/list-item
|
||||
{:icon :main-icons/log-out
|
||||
:title (i18n/label :t/sign-out)
|
||||
:accessibility-label :log-out-button
|
||||
:theme :negative
|
||||
:on-press
|
||||
#(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}]]]))
|
||||
|
||||
(defn my-profile []
|
||||
(let [{:keys [public-key ens-verified preferred-name]
|
||||
:as account} @(re-frame/subscribe [:multiaccount])
|
||||
on-share #(re-frame/dispatch [:show-popover
|
||||
{:view :share-chat-key
|
||||
:address public-key
|
||||
:ens-name preferred-name}])]
|
||||
[react/view {:style {:flex 1}}
|
||||
[quo/animated-header
|
||||
{:right-accessories [{:icon :main-icons/share
|
||||
:on-press on-share}]
|
||||
:use-insets true
|
||||
:extended-header (profile-header/extended-header
|
||||
{:on-press on-share
|
||||
:title (multiaccounts/displayed-name account)
|
||||
:photo (multiaccounts/displayed-photo account)
|
||||
:subtitle (if (and ens-verified public-key)
|
||||
(gfy/generate-gfy public-key)
|
||||
public-key)})}
|
||||
[content]]]))
|
||||
(fn []
|
||||
(let [{:keys [public-key ens-verified preferred-name]
|
||||
:as account} @(re-frame/subscribe [:multiaccount])
|
||||
on-share #(re-frame/dispatch [:show-popover
|
||||
{:view :share-chat-key
|
||||
:address public-key
|
||||
:ens-name preferred-name}])]
|
||||
[react/view {:style {:flex 1}}
|
||||
[quo/animated-header
|
||||
{:right-accessories [{:icon :main-icons/share
|
||||
:on-press on-share}]
|
||||
:use-insets true
|
||||
:extended-header (profile-header/extended-header
|
||||
{:on-press on-share
|
||||
:title (multiaccounts/displayed-name account)
|
||||
:photo (multiaccounts/displayed-photo account)
|
||||
:subtitle (if (and ens-verified public-key)
|
||||
(gfy/generate-gfy public-key)
|
||||
public-key)})}
|
||||
[content]]])))
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[status-im.ui.screens.qr-scanner.styles :as styles]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.ui.components.button :as button]
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- topbar [_ {:keys [title] :as opts}]
|
||||
|
@ -36,15 +36,15 @@
|
|||
:align-items :center
|
||||
:justify-content :center}
|
||||
[react/text-input {:multiline true
|
||||
:style {:color colors/white-persist}
|
||||
:style {:color colors/white-persist}
|
||||
:on-change-text #(reset! text-value %)}]
|
||||
[react/view {:flex-direction :row}
|
||||
[button/button
|
||||
{:label "Cancel"
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-cancel opts])}]
|
||||
[button/button
|
||||
{:label "OK"
|
||||
:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-success opts (when-let [text @text-value] (string/trim text))])}]]]]))
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-cancel opts])}
|
||||
"Cancel"]
|
||||
[quo/button
|
||||
{:on-press #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-success opts (when-let [text @text-value] (string/trim text))])}
|
||||
"Ok"]]]]))
|
||||
|
||||
(defn corner [border1 border2 corner]
|
||||
[react/view (assoc {:border-color colors/white-persist :width 60 :height 60} border1 5 border2 5 corner 32)])
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
(fn []
|
||||
;; Reset currently mounted text inputs to their default values
|
||||
;; on navigating away; this is a privacy measure
|
||||
(println @quo/text-input-refs)
|
||||
(doseq [[_ {:keys [ref value]}] @quo/text-input-refs]
|
||||
(.setNativeProps ^js ref (clj->js {:text value})))
|
||||
(doseq [[^js text-input default-value] @react/text-input-refs]
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue