Use new component to animate headers
fix header title spacing Remove translate animation Add press for profile header Rebase Attempt to fix e2e Add back button accessibility-label Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
parent
01452794a1
commit
d35deefcb5
|
@ -10,7 +10,7 @@
|
|||
|
||||
(defn header-wrapper-style [{:keys [value offset]}]
|
||||
(merge
|
||||
{:background-color :white}
|
||||
{:background-color (:ui-background @colors/theme)}
|
||||
(when (and offset platform/android?)
|
||||
{:elevation (animated/interpolate
|
||||
value
|
||||
|
@ -24,26 +24,21 @@
|
|||
:outputRange [0 1]
|
||||
:extrapolate (:clamp animated/extrapolate)})
|
||||
:shadow-radius 16
|
||||
:z-index 2
|
||||
:shadow-color (:shadow-01 @colors/theme)
|
||||
:shadow-offset {:width 0 :height 4}})))
|
||||
|
||||
(defn header-opened-style [{:keys [value offset]}]
|
||||
(merge
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0}
|
||||
(when offset
|
||||
{:transform [{:translateY
|
||||
(animated/interpolate
|
||||
value
|
||||
{:inputRange [0 offset]
|
||||
:outputRange [0 (- header/header-height)]
|
||||
:extrapolateRight (:clamp animated/extrapolate)})}]})))
|
||||
(defn title-style [layout]
|
||||
{:flex 1
|
||||
:justify-content :center
|
||||
:padding-right (get-in layout [:right :width])})
|
||||
|
||||
(defn header-container []
|
||||
(let [y (animated/value 0)
|
||||
animation-value (animated/value 0)
|
||||
animation (animated/with-timing
|
||||
animation-value
|
||||
{:duration 250
|
||||
:easing (:ease-in animated/easings)})
|
||||
on-scroll (animated/on-scroll {:y y})
|
||||
layout (reagent/atom {})
|
||||
offset (reagent/atom 0)
|
||||
|
@ -52,23 +47,32 @@
|
|||
(fn [{:keys [extended-header] :as props} & children]
|
||||
[animated/view {:flex 1
|
||||
:pointer-events :box-none}
|
||||
[animated/code {:key (str @offset)
|
||||
:exec (animated/cond*
|
||||
(animated/and* (animated/greater-or-eq y @offset)
|
||||
(animated/greater-or-eq y 1))
|
||||
(animated/set animation-value 1)
|
||||
(animated/set animation-value 0))}]
|
||||
[animated/view {:pointer-events :box-none
|
||||
:style (header-wrapper-style {:value y
|
||||
:offset @offset})}
|
||||
[header/header (merge {:get-layout (fn [el l] (swap! layout assoc el l))}
|
||||
(dissoc props :extended-header))]
|
||||
[rn/view {:pointer-events :box-none}
|
||||
[animated/view {:style (header-opened-style {:value y
|
||||
:offset @offset})
|
||||
:pointer-events :box-none
|
||||
:on-layout on-layout}
|
||||
[header/header (merge
|
||||
{:get-layout (fn [el l] (swap! layout assoc el l))
|
||||
:title-component [animated/view {:style (title-style @layout)}
|
||||
[extended-header {:value y
|
||||
:layout @layout
|
||||
:offset @offset}]]]]
|
||||
:animation animation
|
||||
:minimized true
|
||||
:offset @offset}]]
|
||||
:title-align :left}
|
||||
(dissoc props :extended-header))]]
|
||||
(into [animated/scroll-view {:on-scroll on-scroll
|
||||
:scrollEventThrottle 1}
|
||||
[rn/view {:pointer-events :box-none
|
||||
:height @offset}]]
|
||||
[rn/view {:pointer-events :box-none}
|
||||
[animated/view {:pointer-events :box-none
|
||||
:on-layout on-layout}
|
||||
[extended-header {:value y
|
||||
:animation animation
|
||||
:offset @offset}]]]]
|
||||
children)])))
|
||||
|
||||
(defn header [{:keys [use-insets] :as props} & children]
|
||||
|
|
|
@ -46,11 +46,7 @@
|
|||
|
||||
(defn title-style [{:keys [left right]} title-align]
|
||||
(merge
|
||||
{:position :absolute
|
||||
:justify-content :center
|
||||
:top 0
|
||||
:bottom 0}
|
||||
(:tiny spacing/padding-horizontal)
|
||||
absolute-fill
|
||||
(case title-align
|
||||
:left {:left (:width left)
|
||||
:right (:width right)}
|
||||
|
@ -67,7 +63,7 @@
|
|||
(:tiny spacing/padding-horizontal)))
|
||||
|
||||
(def header-action-placeholder
|
||||
{:width (:tiny spacing/spacing)})
|
||||
{:width (:base spacing/spacing)})
|
||||
|
||||
(def header-icon-touchable
|
||||
(merge
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
(defn- wrap-render-fn [f]
|
||||
(fn [data]
|
||||
(reagent/as-element (f (.-item data) (.-index data) (.-separators data)))))
|
||||
(reagent/as-element (f (.-item ^js data) (.-index ^js data) (.-separators ^js data)))))
|
||||
|
||||
(defn- wrap-key-fn [f]
|
||||
(fn [data index]
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
(ns status-im.ui.components.large-toolbar.styles
|
||||
(:require [status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.animation :as animation]
|
||||
[status-im.ui.components.toolbar.styles :as toolbar.styles]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defonce toolbar-shadow-component-height
|
||||
(let [status-bar-height (get platform/platform-specific :status-bar-default-height)]
|
||||
(+ 50 toolbar.styles/toolbar-height (if (zero? status-bar-height) 50 status-bar-height))))
|
||||
|
||||
(defonce toolbar-statusbar-height
|
||||
(+ (get platform/platform-specific :status-bar-default-height) toolbar.styles/toolbar-height))
|
||||
|
||||
(defn minimized-toolbar-fade-in [anim-opacity]
|
||||
(animation/timing
|
||||
anim-opacity
|
||||
{:toValue 1
|
||||
:duration 200
|
||||
:easing (.-ease ^js animation/easing)
|
||||
:useNativeDriver true}))
|
||||
|
||||
(defn minimized-toolbar-fade-out [anim-opacity]
|
||||
(animation/timing
|
||||
anim-opacity
|
||||
{:toValue 0
|
||||
:duration 200
|
||||
:easing (.-ease ^js animation/easing)
|
||||
:useNativeDriver true}))
|
||||
|
||||
(defn- ios-shadow-opacity-anim [scroll-y]
|
||||
(if platform/ios?
|
||||
(animation/interpolate scroll-y
|
||||
{:inputRange [0 toolbar-statusbar-height]
|
||||
:outputRange [0 1]
|
||||
:extrapolate "clamp"})
|
||||
0))
|
||||
|
||||
(defn- android-shadow-elevation-anim [scroll-y]
|
||||
(if platform/android?
|
||||
(animation/interpolate scroll-y
|
||||
{:inputRange [0 toolbar-statusbar-height]
|
||||
:outputRange [0 9]
|
||||
:extrapolate "clamp"})
|
||||
0))
|
||||
|
||||
(defn bottom-border-opacity-anim [scroll-y]
|
||||
(animation/interpolate scroll-y
|
||||
{:inputRange [0 toolbar-statusbar-height]
|
||||
:outputRange [1 0]
|
||||
:extrapolate "clamp"}))
|
||||
|
||||
(defn animated-content-wrapper [anim-opacity]
|
||||
{:flex 1
|
||||
:align-self :stretch
|
||||
:opacity anim-opacity})
|
||||
|
||||
(def minimized-toolbar
|
||||
{:z-index 100
|
||||
:elevation 9})
|
||||
|
||||
(defn flat-list-with-large-header-bottom [scroll-y]
|
||||
{:height 16
|
||||
:opacity (bottom-border-opacity-anim scroll-y)
|
||||
:border-bottom-width 1
|
||||
:border-bottom-color colors/gray-lighter})
|
||||
|
||||
(defn flat-list-with-large-header-shadow [window-width scroll-y]
|
||||
(cond-> {:flex 1
|
||||
:align-self :stretch
|
||||
:position :absolute
|
||||
:height toolbar-shadow-component-height
|
||||
:width window-width
|
||||
:top (- toolbar-shadow-component-height)
|
||||
:shadow-radius 8
|
||||
:shadow-offset {:width 0 :height 2}
|
||||
:shadow-opacity 1
|
||||
:shadow-color "rgba(0, 9, 26, 0.12)"
|
||||
:elevation (android-shadow-elevation-anim scroll-y)
|
||||
:background-color colors/white}
|
||||
platform/ios?
|
||||
(assoc :opacity (ios-shadow-opacity-anim scroll-y))))
|
||||
|
||||
(def flat-list
|
||||
{:z-index -1})
|
|
@ -1,105 +0,0 @@
|
|||
(ns status-im.ui.components.large-toolbar.view
|
||||
(:require [reagent.core :as reagent]
|
||||
[status-im.ui.components.list.views :as list.views]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.components.large-toolbar.styles :as styles]
|
||||
[status-im.ui.components.animation :as animation])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
;; header-in-toolbar - component - small header in toolbar
|
||||
;; nav-item - component/nil - if nav-item like back button is needed, else nil
|
||||
;; action-items - status-im.ui.components.toolbar.view/actions
|
||||
(defn minimized-toolbar [header-in-toolbar nav-item action-items anim-opacity]
|
||||
(let [has-nav? (boolean nav-item)]
|
||||
[toolbar/toolbar
|
||||
{:transparent? true
|
||||
:style styles/minimized-toolbar}
|
||||
nav-item
|
||||
[react/animated-view
|
||||
{:style (cond-> (styles/animated-content-wrapper anim-opacity)
|
||||
(false? has-nav?)
|
||||
(assoc :margin-left -40 :margin-right 40))}
|
||||
header-in-toolbar]
|
||||
action-items]))
|
||||
|
||||
;; header - component that serves as large header without any top/bottom padding
|
||||
;; top(4px high) and bottom(16px high and with border) padding
|
||||
;; are assumed to be constant
|
||||
;; this is wrapped with padding components and merged with content
|
||||
;; content - vector - of the rest(from header) of the list components
|
||||
;; wrapped header and content form the data prop of flat-list
|
||||
;; list-ref - atom - a reference to flat-list for the purpose of invoking its
|
||||
;; methods
|
||||
;; scroll-y - animated value tracking the y scoll of the main content in flat-list-view
|
||||
(views/defview flat-list-with-large-header [header content list-ref scroll-y]
|
||||
(views/letsubs [window-width [:dimensions/window-width]]
|
||||
(let [header-top-padding [react/view {:height 4}]
|
||||
;; header bottom padding with border-bottom
|
||||
;; fades out as it approaches toolbar shadow
|
||||
header-bottom [react/animated-view
|
||||
{:style (styles/flat-list-with-large-header-bottom scroll-y)}]
|
||||
wrapped-data (into [header-top-padding header header-bottom] content)]
|
||||
[react/view {:flex 1}
|
||||
;; toolbar shadow
|
||||
[react/animated-view
|
||||
{:style (styles/flat-list-with-large-header-shadow window-width scroll-y)}]
|
||||
|
||||
[list.views/flat-list
|
||||
{:style styles/flat-list
|
||||
:data wrapped-data
|
||||
:initial-num-to-render 3
|
||||
:ref #(when % (reset! list-ref (.getNode ^js %)))
|
||||
:render-fn list.views/flat-list-generic-render-fn
|
||||
:key-fn (fn [item idx] (str idx))
|
||||
:scrollEventThrottle 16
|
||||
:on-scroll (animation/event
|
||||
[{:nativeEvent {:contentOffset {:y scroll-y}}}]
|
||||
{:useNativeDriver true})
|
||||
:keyboard-should-persist-taps :handled}
|
||||
{:animated? true}]])))
|
||||
|
||||
(defn generate-view
|
||||
"main function which generates views.
|
||||
- it will generate and return back:
|
||||
- minimized-toolbar
|
||||
- flat-list-with-large-header"
|
||||
[header-in-toolbar nav-item toolbar-action-items header content list-ref]
|
||||
(let [to-hide (reagent/atom true)
|
||||
anim-opacity (animation/create-value 0)
|
||||
scroll-y (animation/create-value 0)]
|
||||
(animation/add-listener scroll-y (fn [^js anim]
|
||||
(cond
|
||||
(and (>= (.-value anim) 40) (not @to-hide))
|
||||
(animation/start
|
||||
(styles/minimized-toolbar-fade-in anim-opacity)
|
||||
#(reset! to-hide true))
|
||||
|
||||
(and (< (.-value anim) 40) @to-hide)
|
||||
(animation/start
|
||||
(styles/minimized-toolbar-fade-out anim-opacity)
|
||||
#(reset! to-hide false)))))
|
||||
{:minimized-toolbar [minimized-toolbar header-in-toolbar nav-item toolbar-action-items anim-opacity]
|
||||
:content-with-header [flat-list-with-large-header header content list-ref scroll-y]}))
|
||||
|
||||
(defn add-listener [anim-opacity scroll-y]
|
||||
(let [to-hide (atom false)]
|
||||
(animation/add-listener
|
||||
scroll-y
|
||||
(fn [^js anim]
|
||||
(cond
|
||||
(and (>= (.-value anim) 40) (not @to-hide))
|
||||
(animation/start
|
||||
(styles/minimized-toolbar-fade-in anim-opacity)
|
||||
#(reset! to-hide true))
|
||||
|
||||
(and (< (.-value anim) 40) @to-hide)
|
||||
(animation/start
|
||||
(styles/minimized-toolbar-fade-out anim-opacity)
|
||||
#(reset! to-hide false)))))))
|
||||
|
||||
(defn minimized-toolbar-handler [header-in-toolbar nav-item toolbar-action-items anim-opacity]
|
||||
[minimized-toolbar header-in-toolbar nav-item toolbar-action-items anim-opacity])
|
||||
|
||||
(defn flat-list-with-header-handler [header content list-ref scroll-y]
|
||||
[flat-list-with-large-header header content list-ref scroll-y])
|
|
@ -0,0 +1,81 @@
|
|||
(ns status-im.ui.components.profile-header.view
|
||||
(:require [quo.core :as quo]
|
||||
[quo.animated :as animated]
|
||||
[quo.design-system.spacing :as spacing]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo.react-native :as rn]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]))
|
||||
|
||||
(def avatar-extended-size 64)
|
||||
(def avatar-minimized-size 40)
|
||||
(def subtitle-margin 4)
|
||||
|
||||
(defn container-style [{:keys [animation minimized]}]
|
||||
(merge {:flex-direction :row
|
||||
:align-items :center}
|
||||
(if-not minimized
|
||||
(:base spacing/padding-horizontal)
|
||||
{:opacity animation})))
|
||||
|
||||
(defn header-bottom-separator []
|
||||
{:margin-bottom (:tiny spacing/spacing)
|
||||
:height (:small spacing/spacing)
|
||||
:border-bottom-width 1
|
||||
:border-bottom-color (:ui-02 @colors/theme)})
|
||||
|
||||
(defn header-text []
|
||||
{:padding-left (:base spacing/spacing)
|
||||
:flex 1
|
||||
:justify-content :center})
|
||||
|
||||
(defn header-subtitle [{:keys [minimized]}]
|
||||
(merge {:padding-right (:large spacing/spacing)
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
(when-not minimized
|
||||
{:padding-top subtitle-margin})))
|
||||
|
||||
(defn extended-header [{:keys [title photo color subtitle subtitle-icon on-press]}]
|
||||
(fn [{:keys [animation minimized]}]
|
||||
(let [wrapper (if on-press
|
||||
[rn/touchable-opacity {:on-press on-press}]
|
||||
[:<>])]
|
||||
(into
|
||||
wrapper
|
||||
[[animated/view {:pointer-events :box-none}
|
||||
[animated/view {:style (container-style {:animation animation
|
||||
:minimized minimized})
|
||||
:pointer-events :box-none}
|
||||
[animated/view {:pointer-events :box-none}
|
||||
[chat-icon.screen/profile-icon-view
|
||||
photo title color nil
|
||||
(if minimized avatar-minimized-size avatar-extended-size)
|
||||
nil]]
|
||||
[animated/view {:style (header-text)
|
||||
:pointer-events :box-none}
|
||||
[quo/text {:animated? true
|
||||
:number-of-lines (if minimized 1 2)
|
||||
:size (if minimized :base :x-large)
|
||||
:weight :bold
|
||||
:elipsize-mode :tail
|
||||
:accessibility-role :text
|
||||
:accessibility-label :default-username}
|
||||
title]
|
||||
(when subtitle
|
||||
[animated/view {:style (header-subtitle {:minimized minimized})
|
||||
:pointer-events :box-none}
|
||||
(when subtitle-icon
|
||||
[vector-icons/icon subtitle-icon {:color (:icon-02 @colors/theme)
|
||||
:width 16
|
||||
:height 16
|
||||
:container-style {:margin-right 4}}])
|
||||
[quo/text {:number-of-lines 1
|
||||
:ellipsize-mode :middle
|
||||
:size (if minimized :small :base)
|
||||
:color :secondary}
|
||||
subtitle]])]]
|
||||
(when-not minimized
|
||||
[animated/view {:pointer-events :none
|
||||
:style (header-bottom-separator)}])]]))))
|
||||
|
|
@ -1,103 +1,12 @@
|
|||
(ns status-im.ui.screens.profile.components.views
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.components.common.common :as common]
|
||||
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.gfycat.core :as gfy]
|
||||
[status-im.ui.screens.profile.user.sheet.views :as sheets]
|
||||
[status-im.ui.screens.profile.components.styles :as styles]))
|
||||
|
||||
(defn- names [{:keys [usernames public-key] :as contact}]
|
||||
(let [generated-name (when public-key (gfy/generate-gfy public-key))]
|
||||
[react/view styles/profile-header-name-container-with-subtitle
|
||||
[react/text {:style styles/profile-name-text-with-subtitle
|
||||
:number-of-lines 2
|
||||
:ellipsize-mode :tail}
|
||||
(multiaccounts/displayed-name contact)]
|
||||
[react/text {:style styles/profile-three-words
|
||||
:number-of-lines 1}
|
||||
(if (seq usernames)
|
||||
generated-name
|
||||
public-key)]]))
|
||||
|
||||
(defn chat-key-popover [public-key ens-name]
|
||||
(re-frame/dispatch [:show-popover
|
||||
{:view :share-chat-key
|
||||
:address public-key
|
||||
:ens-name ens-name}]))
|
||||
|
||||
(defn- profile-header-display
|
||||
[{:keys [public-key preferred-name ens-name] :as contact}
|
||||
allow-icon-change? include-remove-action?]
|
||||
[react/touchable-opacity
|
||||
{:on-press #(chat-key-popover public-key (or ens-name
|
||||
preferred-name))}
|
||||
[react/view (merge styles/profile-header-display {:padding-horizontal 16})
|
||||
(if allow-icon-change?
|
||||
[react/view {:align-items :center
|
||||
:align-self :stretch
|
||||
:justify-content :center}
|
||||
[react/touchable-highlight
|
||||
{:accessibility-label :edit-profile-photo-button
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:bottom-sheet/show-sheet
|
||||
{:content (sheets/profile-icon-actions include-remove-action?)
|
||||
:content-height (if include-remove-action? 192 128)}])}
|
||||
[react/view
|
||||
[react/view {:background-color colors/white
|
||||
:border-radius 15
|
||||
:width 30
|
||||
:height 30
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:position :absolute
|
||||
:z-index 1
|
||||
:top -5
|
||||
:right -5}
|
||||
[react/view {:background-color colors/blue
|
||||
:border-radius 12
|
||||
:width 24
|
||||
:height 24
|
||||
:justify-content :center
|
||||
:align-items :center}
|
||||
[vector-icons/icon :tiny-edit {:color colors/white
|
||||
:width 16
|
||||
:height 16}]]]
|
||||
[chat-icon.screen/my-profile-icon {:multiaccount contact
|
||||
:edit? false}]]]]
|
||||
;; else
|
||||
[chat-icon.screen/my-profile-icon {:multiaccount contact
|
||||
:edit? false}])
|
||||
[names contact]]])
|
||||
|
||||
(defn group-header-display [{:keys [chat-name color contacts]}]
|
||||
[react/view (merge styles/profile-header-display {:padding-horizontal 16})
|
||||
[chat-icon.screen/profile-icon-view nil chat-name color nil 64 nil]
|
||||
[react/view styles/profile-header-name-container
|
||||
[react/text {:style styles/profile-name-text
|
||||
:number-of-lines 2
|
||||
:ellipsize-mode :tail}
|
||||
chat-name]
|
||||
[react/view {:style {:flex-direction :row
|
||||
:align-items :center}}
|
||||
[vector-icons/icon :icons/tiny-group {:color colors/gray
|
||||
:width 16
|
||||
:height 16
|
||||
:container-style {:margin-right 4}}]
|
||||
[react/text {:style {:line-height 22
|
||||
:color colors/gray}}
|
||||
(i18n/label :t/members-count {:count (count contacts)})]]]])
|
||||
|
||||
(defn profile-header
|
||||
[{:keys [contact allow-icon-change? include-remove-action?]}]
|
||||
[profile-header-display contact allow-icon-change? include-remove-action?])
|
||||
|
||||
;; settings items elements
|
||||
|
||||
(defn settings-item
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
[status-im.utils.utils :as utils]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.large-toolbar.view :as large-toolbar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||
[status-im.ui.screens.profile.contact.styles :as styles]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.ui.screens.profile.components.sheets :as sheets]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.multiaccounts.core :as multiaccounts])
|
||||
[status-im.ui.components.profile-header.view :as profile-header]
|
||||
[status-im.utils.gfycat.core :as gfy]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[quo.core :as quo])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn actions
|
||||
|
@ -89,51 +88,34 @@
|
|||
(i18n/label :t/unblock-contact)
|
||||
(i18n/label :t/block-contact))]])
|
||||
|
||||
(defn- header-in-toolbar [{:keys [public-key ens-name] :as account}]
|
||||
(let [displayed-name (multiaccounts/displayed-name account)]
|
||||
[react/touchable-opacity {:on-press #(profile.components/chat-key-popover public-key ens-name)
|
||||
:style {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:align-self :stretch}}
|
||||
;;TODO this should be done in a subscription
|
||||
[photos/photo (multiaccounts/displayed-photo account)
|
||||
{:size 40}]
|
||||
[react/text {:style {:typography :title-bold
|
||||
:line-height 21
|
||||
:margin-right 40
|
||||
:margin-left 16
|
||||
:text-align :left}
|
||||
:accessibility-label :account-name}
|
||||
displayed-name]]))
|
||||
|
||||
(defn- header [account]
|
||||
[profile.components/profile-header
|
||||
{:contact account
|
||||
:allow-icon-change? false
|
||||
:include-remove-action? false}])
|
||||
|
||||
(defn- toolbar-action-items [public-key ens-name]
|
||||
[toolbar/actions
|
||||
[{:icon :main-icons/share
|
||||
:icon-opts {:width 24
|
||||
:height 24}
|
||||
:handler #(profile.components/chat-key-popover public-key ens-name)}]])
|
||||
|
||||
;;TO-DO Rework generate-view to use 3 functions from large-toolbar
|
||||
(views/defview profile []
|
||||
(views/letsubs [list-ref (reagent/atom nil)
|
||||
{:keys [ens-verified name public-key] :as contact} [:contacts/current-contact]]
|
||||
(views/letsubs [{:keys [ens-verified name public-key]
|
||||
:as contact} [:contacts/current-contact]]
|
||||
(let [on-share #(re-frame/dispatch [:show-popover (merge
|
||||
{:view :share-chat-key
|
||||
:address public-key}
|
||||
(when (and ens-verified name)
|
||||
{:ens-name name}))])]
|
||||
(when contact
|
||||
(let [ens-name (when (and ens-verified name) name)
|
||||
contact (cond-> contact
|
||||
ens-name
|
||||
(assoc :usernames [ens-name]
|
||||
:ens-name ens-name))
|
||||
header-in-toolbar (header-in-toolbar contact)
|
||||
header (header contact)
|
||||
content
|
||||
[[react/view {:padding-top 12}
|
||||
[react/view
|
||||
{:style
|
||||
(merge {:flex 1})}
|
||||
[quo/animated-header
|
||||
{:use-insets true
|
||||
:right-accessories [{:icon :main-icons/share
|
||||
:on-press on-share}]
|
||||
:left-accessories [{:icon :main-icons/back
|
||||
:accessibility-label :back-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}]
|
||||
:extended-header (profile-header/extended-header
|
||||
{:on-press on-share
|
||||
:title (multiaccounts/displayed-name contact)
|
||||
:photo (multiaccounts/displayed-photo contact)
|
||||
:subtitle (if (and ens-verified public-key)
|
||||
(gfy/generate-gfy public-key)
|
||||
public-key)})}
|
||||
|
||||
[react/view {:padding-top 12}
|
||||
(for [{:keys [label subtext accessibility-label icon action disabled?]} (actions contact)]
|
||||
[list-item/list-item {:theme :action
|
||||
:title label
|
||||
|
@ -143,17 +125,7 @@
|
|||
:disabled? disabled?
|
||||
:on-press action}])]
|
||||
[react/view styles/contact-profile-details-container
|
||||
[profile-details contact]]
|
||||
[block-contact-action contact]]
|
||||
generated-view (large-toolbar/generate-view
|
||||
header-in-toolbar
|
||||
toolbar/default-nav-back
|
||||
(toolbar-action-items public-key ens-name)
|
||||
header
|
||||
content
|
||||
list-ref)]
|
||||
[react/view
|
||||
{:style
|
||||
(merge {:flex 1})}
|
||||
(:minimized-toolbar generated-view)
|
||||
(:content-with-header generated-view)]))))
|
||||
[profile-details (cond-> contact
|
||||
(and ens-verified name)
|
||||
(assoc :ens-name name))]]
|
||||
[block-contact-action contact]]]))))
|
||||
|
|
|
@ -14,16 +14,9 @@
|
|||
[status-im.ui.components.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.topbar :as topbar]))
|
||||
|
||||
(defn group-chat-profile-toolbar [admin?]
|
||||
[topbar/topbar
|
||||
(when admin?
|
||||
{:accessories
|
||||
[{:icon :icons/edit
|
||||
:accessibility-label :edit-button
|
||||
:handler #(re-frame/dispatch [:navigate-to :edit-group-chat-name])}]})])
|
||||
[quo.core :as quo]
|
||||
[status-im.ui.components.profile-header.view :as profile-header]
|
||||
[status-im.ui.components.list-item.views :as list-item]))
|
||||
|
||||
(defn member-sheet [chat-id member us-admin?]
|
||||
[react/view
|
||||
|
@ -92,24 +85,29 @@
|
|||
[chat-group-members-view chat-id admin? current-pk]])
|
||||
|
||||
(defview group-chat-profile []
|
||||
(letsubs [{:keys [admins chat-id joined?] :as current-chat} [:chats/current-chat]
|
||||
(letsubs [{:keys [admins chat-id joined? chat-name color contacts] :as current-chat} [:chats/current-chat]
|
||||
members [:contacts/current-chat-contacts]
|
||||
changed-chat [:group-chat-profile/profile]
|
||||
current-pk [:multiaccount/public-key]]
|
||||
(when current-chat
|
||||
(let [shown-chat (merge current-chat changed-chat)
|
||||
admin? (get admins current-pk)
|
||||
(let [admin? (get admins current-pk)
|
||||
allow-adding-members? (and admin? joined?
|
||||
(< (count members) constants/max-group-chat-participants))]
|
||||
[react/view profile.components.styles/profile
|
||||
[group-chat-profile-toolbar (and admin? joined?)]
|
||||
[react/scroll-view
|
||||
[quo/animated-header
|
||||
{:use-insets true
|
||||
:left-accessories [{:icon :main-icons/back
|
||||
:accessibility-label :back-button
|
||||
:on-press #(re-frame/dispatch [:navigate-back])}]
|
||||
:right-accessories (when (and admin? joined?)
|
||||
[{:icon :icons/edit
|
||||
:accessibility-label :edit-button
|
||||
:on-press #(re-frame/dispatch [:navigate-to :edit-group-chat-name])}])
|
||||
:extended-header (profile-header/extended-header
|
||||
{:title chat-name
|
||||
:color color
|
||||
:subtitle (i18n/label :t/members-count {:count (count contacts)})
|
||||
:subtitle-icon :icons/tiny-group})}
|
||||
[react/view profile.components.styles/profile-form
|
||||
[react/view {:style {:border-bottom-width 1
|
||||
:padding-bottom 15
|
||||
:margin-bottom 8
|
||||
:border-bottom-color colors/gray-lighter}}
|
||||
[profile.components/group-header-display shown-chat]]
|
||||
(when joined?
|
||||
[list-item/list-item
|
||||
{:theme :action
|
||||
|
|
|
@ -2,24 +2,22 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.button :as button]
|
||||
[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.large-toolbar.view :as large-toolbar]
|
||||
[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.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.chat.photos :as photos]
|
||||
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||
[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.animation :as animation])
|
||||
[status-im.ui.components.profile-header.view :as profile-header])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(views/defview share-chat-key []
|
||||
|
@ -61,38 +59,6 @@
|
|||
;:icon :main-icons/link
|
||||
:accessibility-label :share-my-contact-code-button}]]])))
|
||||
|
||||
(defn- header [account photo-added?]
|
||||
[profile.components/profile-header
|
||||
{:contact account
|
||||
;;set to true if we want to re-enable custom icon
|
||||
:allow-icon-change? false
|
||||
:include-remove-action? photo-added?}])
|
||||
|
||||
(defn- header-in-toolbar [{:keys [public-key preferred-name] :as account}]
|
||||
(let [displayed-name (multiaccounts/displayed-name account)]
|
||||
[react/touchable-opacity
|
||||
{:on-press #(profile.components/chat-key-popover public-key preferred-name)
|
||||
:style {:flex 1}}
|
||||
[react/view {:style {:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:align-self :stretch}}
|
||||
;;TODO this should be done in a subscription
|
||||
[photos/photo (multiaccounts/displayed-photo account) {:size 40}]
|
||||
[react/text {:style {:typography :title-bold
|
||||
:line-height 21
|
||||
:margin-right 40
|
||||
:margin-left 16
|
||||
:text-align :left}}
|
||||
displayed-name]]]))
|
||||
|
||||
(defn- toolbar-action-items [public-key preferred-name]
|
||||
[toolbar/actions
|
||||
[{:icon :main-icons/share
|
||||
:icon-opts {:width 24
|
||||
:height 24}
|
||||
:handler #(profile.components/chat-key-popover public-key preferred-name)}]])
|
||||
|
||||
(defn tribute-to-talk-item
|
||||
[opts]
|
||||
[list.views/big-list-item
|
||||
|
@ -204,40 +170,44 @@
|
|||
:on-press
|
||||
#(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}])
|
||||
|
||||
(defn minimized-toolbar-handler [anim-opacity]
|
||||
(let [{:keys [public-key preferred-name]
|
||||
:as multiaccount} @(re-frame/subscribe [:multiaccount])]
|
||||
[large-toolbar/minimized-toolbar-handler
|
||||
(header-in-toolbar multiaccount)
|
||||
nil
|
||||
(toolbar-action-items public-key preferred-name)
|
||||
anim-opacity]))
|
||||
|
||||
(defn content-with-header [list-ref scroll-y]
|
||||
(defn content []
|
||||
(let [{:keys [preferred-name
|
||||
mnemonic
|
||||
keycard-pairing
|
||||
notifications-enabled?]
|
||||
:as multiaccount} @(re-frame/subscribe [:multiaccount])
|
||||
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])
|
||||
photo-added? @(re-frame/subscribe [:profile/photo-added?])]
|
||||
[large-toolbar/flat-list-with-header-handler
|
||||
(header multiaccount photo-added?)
|
||||
registrar @(re-frame/subscribe [:ens.stateofus/registrar])]
|
||||
(flat-list-content
|
||||
preferred-name registrar tribute-to-talk
|
||||
active-contacts-count mnemonic
|
||||
keycard-pairing notifications-enabled?)
|
||||
list-ref
|
||||
scroll-y]))
|
||||
keycard-pairing notifications-enabled?)))
|
||||
|
||||
(defn my-profile []
|
||||
(let [list-ref (reagent/atom nil)
|
||||
anim-opacity (animation/create-value 0)
|
||||
scroll-y (animation/create-value 0)]
|
||||
(large-toolbar/add-listener anim-opacity scroll-y)
|
||||
(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}}
|
||||
[minimized-toolbar-handler anim-opacity]
|
||||
[content-with-header list-ref scroll-y]])))
|
||||
[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)})}
|
||||
[list.views/flat-list
|
||||
{:data (content)
|
||||
:initial-num-to-render 3
|
||||
:render-fn list.views/flat-list-generic-render-fn
|
||||
:key-fn (fn [_ idx] (str idx))
|
||||
:keyboard-should-persist-taps :handled}]]])))
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
{:name :chat
|
||||
:component chat/chat}
|
||||
{:name :profile
|
||||
:insets {:top false}
|
||||
:component profile.contact/profile}
|
||||
{:name :group-chat-profile
|
||||
:insets {:top false}
|
||||
:component profile.group-chat/group-chat-profile}
|
||||
{:name :stickers
|
||||
:component stickers/packs}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
[stack {:initial-route-name :my-profile
|
||||
:header-mode :none}
|
||||
[{:name :my-profile
|
||||
:insets {:top false}
|
||||
:style {:padding-bottom tabbar.styles/tabs-diff}
|
||||
:component profile.user/my-profile}
|
||||
{:name :contacts-list
|
||||
|
@ -66,6 +67,7 @@
|
|||
{:name :blocked-users-list
|
||||
:component contacts-list/blocked-users-list}
|
||||
{:name :profile
|
||||
:insets {:top false}
|
||||
:component profile.contact/profile}
|
||||
{:name :profile-photo-capture
|
||||
:component photo-capture/profile-photo-capture}
|
||||
|
|
|
@ -1,72 +1,29 @@
|
|||
(ns status-im.ui.screens.wallet.accounts.styles
|
||||
(:require [quo.animated :as reanimated]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.platform :as platform]))
|
||||
(:require [quo.animated :as animated]
|
||||
[status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def ^:const tabbar-height 56)
|
||||
;; TODO(Ferossgp): get layout size of total-value
|
||||
(def ^:const value-height (+ 40 22 8))
|
||||
(def ^:const scroll-offset value-height)
|
||||
(def ^:const minimized-value-line-height 28)
|
||||
(defn container [{:keys [minimized]}]
|
||||
(when-not minimized
|
||||
{:padding-bottom 8
|
||||
:padding-horizontal 16}))
|
||||
|
||||
(defn topbar [{:keys [value offset inset-top]}]
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 8
|
||||
:background-color colors/white
|
||||
:padding-top inset-top}
|
||||
(when platform/android?
|
||||
{:elevation (reanimated/interpolate
|
||||
value
|
||||
{:inputRange [0 offset]
|
||||
:outputRange [0 4]
|
||||
:extrapolate (:clamp reanimated/extrapolate)})})
|
||||
(when platform/ios?
|
||||
{:shadow-opacity (reanimated/interpolate
|
||||
value
|
||||
{:inputRange [0 offset]
|
||||
:outputRange [0 1]
|
||||
:extrapolate (:clamp reanimated/extrapolate)})
|
||||
:shadow-radius 16
|
||||
:z-index 2
|
||||
:shadow-color (if (colors/dark?)
|
||||
"rgba(0, 0, 0, 0.75)"
|
||||
"rgba(0, 9, 26, 0.12)")
|
||||
:shadow-offset {:width 0 :height 4}})))
|
||||
(defn value-container [{:keys [minimized animation]}]
|
||||
(when minimized
|
||||
{:opacity animation}))
|
||||
|
||||
(defn value-container [y]
|
||||
{:position :absolute
|
||||
:left 8
|
||||
:top 0
|
||||
:transform [{:translateY
|
||||
(reanimated/interpolate
|
||||
y
|
||||
{:inputRange [0 scroll-offset]
|
||||
:outputRange [scroll-offset
|
||||
(/ (- tabbar-height
|
||||
minimized-value-line-height) 2)]
|
||||
:extrapolateRight (:clamp reanimated/extrapolate)})}]})
|
||||
(defn value-text [{:keys [minimized]}]
|
||||
{:font-size (if minimized 20 32)
|
||||
:line-height 40
|
||||
:color colors/black})
|
||||
|
||||
(defn value-text [y]
|
||||
{:font-size (reanimated/interpolate
|
||||
y
|
||||
{:inputRange [0 scroll-offset]
|
||||
:outputRange [32 20]
|
||||
:extrapolate (:clamp reanimated/extrapolate)})
|
||||
:color colors/black
|
||||
:font-weight "600"})
|
||||
|
||||
(defn value-helper [y]
|
||||
{:opacity (reanimated/interpolate y
|
||||
{:inputRange [0 scroll-offset]
|
||||
:outputRange [1 0]})})
|
||||
|
||||
(defn accounts-mnemonic [y]
|
||||
{:flex 1
|
||||
(defn accounts-mnemonic [{:keys [animation]}]
|
||||
{:opacity (animated/b-interpolate animation 1 0)
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:opacity (reanimated/interpolate y
|
||||
{:inputRange [0 scroll-offset]
|
||||
:outputRange [1 0]})})
|
||||
:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0})
|
||||
|
||||
(defn card-common []
|
||||
{:margin-vertical 16
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.ui.screens.wallet.accounts.views
|
||||
(:require [oops.core :refer [oget]]
|
||||
[quo.animated :as reanimated]
|
||||
(:require [quo.animated :as reanimated]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.i18n :as i18n]
|
||||
|
@ -10,7 +10,6 @@
|
|||
[status-im.ui.components.list-item.views :as list-item]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.toolbar.styles :as toolbar.styles]
|
||||
[status-im.ui.screens.wallet.accounts.sheets :as sheets]
|
||||
[status-im.ui.screens.wallet.accounts.styles :as styles]
|
||||
[status-im.utils.utils :as utils.utils]
|
||||
|
@ -94,20 +93,6 @@
|
|||
:key-fn :name
|
||||
:render-fn (render-asset (:code currency) prices-loading?)}]))
|
||||
|
||||
(views/defview total-value [{:keys [y]}]
|
||||
(views/letsubs [currency [:wallet/currency]
|
||||
portfolio-value [:portfolio-value]]
|
||||
[reanimated/view {:style (styles/value-container y)}
|
||||
[reanimated/text {:style (styles/value-text y)}
|
||||
portfolio-value
|
||||
[reanimated/text {:style {:color colors/gray}}
|
||||
(str " " (:code currency))]]
|
||||
[reanimated/view {:style (styles/value-helper y)}
|
||||
[react/text {:style {:color colors/gray
|
||||
:font-size 15
|
||||
:line-height 22}}
|
||||
(i18n/label :t/wallet-total-value)]]]))
|
||||
|
||||
(defn- request-camera-permissions []
|
||||
(let [options {:handler :wallet.send/qr-scanner-result}]
|
||||
(re-frame/dispatch
|
||||
|
@ -122,58 +107,6 @@
|
|||
(i18n/label :t/camera-access-error)))
|
||||
50)}])))
|
||||
|
||||
(views/defview accounts-options [{:keys [y]}]
|
||||
(views/letsubs [{:keys [mnemonic]} [:multiaccount]
|
||||
empty-balances? [:empty-balances?]]
|
||||
;; TODO(Ferossgp): Use topbar component here
|
||||
[react/safe-area-consumer
|
||||
(fn [insets]
|
||||
(reagent/as-element
|
||||
[reanimated/view {:style (styles/topbar {:inset-top (oget insets "top")
|
||||
:value y
|
||||
:offset styles/scroll-offset})}
|
||||
[react/view {:flex 1
|
||||
:height styles/tabbar-height
|
||||
:padding-horizontal 8
|
||||
:flex-direction :row
|
||||
:align-items :center}
|
||||
[total-value {:y y}]
|
||||
(when (and mnemonic
|
||||
(not empty-balances?))
|
||||
[reanimated/view {:style (styles/accounts-mnemonic y)}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-to :backup-seed])}
|
||||
[react/view {:flex-direction :row :align-items :center}
|
||||
[react/view {:width 14
|
||||
:height 14
|
||||
:background-color colors/gray
|
||||
:border-radius 7
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-right 9}
|
||||
[react/text {:style {:color colors/white
|
||||
:font-size 13
|
||||
:font-weight "700"}}
|
||||
"!"]]
|
||||
[react/text {:style {:color colors/gray}
|
||||
:accessibility-label :back-up-your-seed-phrase-warning}
|
||||
(i18n/label :t/back-up-your-seed-phrase)]]]])]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(request-camera-permissions)}
|
||||
[react/view {:height toolbar.styles/toolbar-height
|
||||
:padding-horizontal 8
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[icons/icon :main-icons/qr {:accessibility-label :accounts-qr-code}]]]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (sheets/accounts-options mnemonic)}])}
|
||||
[react/view {:height toolbar.styles/toolbar-height
|
||||
:padding-horizontal 8
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[icons/icon :main-icons/more {:accessibility-label :accounts-more-options}]]]]))]))
|
||||
|
||||
(views/defview send-button []
|
||||
(views/letsubs [account [:multiaccount/default-account]]
|
||||
[react/view styles/send-button-container
|
||||
|
@ -194,17 +127,66 @@
|
|||
[account-card account])
|
||||
[add-card]]]))
|
||||
|
||||
(views/defview total-value [{:keys [animation minimized]}]
|
||||
(views/letsubs [currency [:wallet/currency]
|
||||
portfolio-value [:portfolio-value]
|
||||
empty-balances? [:empty-balances?]
|
||||
{:keys [mnemonic]} [:multiaccount]]
|
||||
[reanimated/view {:style (styles/container {:minimized minimized})
|
||||
:pointer-events :none}
|
||||
|
||||
(when (and mnemonic minimized (not empty-balances?))
|
||||
[reanimated/view {:style (styles/accounts-mnemonic {:animation animation})}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:navigate-to :backup-seed])}
|
||||
[react/view {:flex-direction :row :align-items :center}
|
||||
[react/view {:width 14
|
||||
:height 14
|
||||
:background-color colors/gray
|
||||
:border-radius 7
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-right 9}
|
||||
[react/text {:style {:color colors/white
|
||||
:font-size 13
|
||||
:font-weight "700"}}
|
||||
"!"]]
|
||||
[react/text {:style {:color colors/gray}
|
||||
:accessibility-label :back-up-your-seed-phrase-warning}
|
||||
(i18n/label :t/back-up-your-seed-phrase)]]]])
|
||||
|
||||
[reanimated/view {:style (styles/value-container {:minimized minimized
|
||||
:animation animation})}
|
||||
[reanimated/view {:style {:justify-content :center}}
|
||||
[quo/text {:animated? true
|
||||
:weight :semi-bold
|
||||
:style (styles/value-text {:minimized minimized})}
|
||||
portfolio-value
|
||||
[quo/text {:animated? true
|
||||
:size :inherit
|
||||
:weight :inherit
|
||||
:color :secondary}
|
||||
(str " " (:code currency))]]]]
|
||||
(when-not minimized
|
||||
[reanimated/view
|
||||
[quo/text {:color :secondary}
|
||||
(i18n/label :t/wallet-total-value)]])]))
|
||||
|
||||
(defn accounts-overview []
|
||||
(let [y (reanimated/value 0)
|
||||
on-scroll (reanimated/on-scroll {:y y})]
|
||||
(fn []
|
||||
(let [{:keys [mnemonic]} @(re-frame/subscribe [:multiaccount])]
|
||||
[react/view {:flex 1}
|
||||
[accounts-options {:y y}]
|
||||
[reanimated/scroll-view {:on-scroll on-scroll
|
||||
:style {:padding-top styles/value-height}
|
||||
:scrollEventThrottle 1}
|
||||
[react/view {:margin-top 8}
|
||||
[accounts]]
|
||||
[quo/animated-header
|
||||
{:extended-header total-value
|
||||
:use-insets true
|
||||
:right-accessories [{:on-press #(request-camera-permissions)
|
||||
:icon :main-icons/qr
|
||||
:accessibility-label :accounts-qr-code}
|
||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (sheets/accounts-options mnemonic)}])
|
||||
:icon :main-icons/more
|
||||
:accessibility-label :accounts-more-options}]}
|
||||
[accounts]
|
||||
[assets]
|
||||
[react/view {:height 68}]]
|
||||
[send-button]])))
|
||||
|
|
|
@ -104,8 +104,7 @@ class ConfirmLogoutButton(BaseButton):
|
|||
class DefaultUserNameText(BaseText):
|
||||
def __init__(self, driver):
|
||||
super(DefaultUserNameText, self).__init__(driver)
|
||||
self.locator = self.Locator.xpath_selector(
|
||||
'//android.widget.ImageView[@content-desc="chat-icon"]/../android.widget.TextView')
|
||||
self.locator = self.Locator.accessibility_id('default-username')
|
||||
|
||||
class ENSusernames(BaseButton):
|
||||
def __init__(self, driver):
|
||||
|
|
Loading…
Reference in New Issue