parent
da120feef8
commit
f7076016d8
|
@ -80,6 +80,9 @@
|
||||||
(def animated-view-class
|
(def animated-view-class
|
||||||
(reagent/adapt-react-class (.-View animated)))
|
(reagent/adapt-react-class (.-View animated)))
|
||||||
|
|
||||||
|
(def animated-flat-list-class
|
||||||
|
(reagent/adapt-react-class (.-FlatList animated)))
|
||||||
|
|
||||||
(defn animated-view [props & content]
|
(defn animated-view [props & content]
|
||||||
(vec (conj content props animated-view-class)))
|
(vec (conj content props animated-view-class)))
|
||||||
|
|
||||||
|
|
|
@ -522,6 +522,7 @@ var TopLevel = {
|
||||||
"version" : function () {},
|
"version" : function () {},
|
||||||
"vibrate" : function () {},
|
"vibrate" : function () {},
|
||||||
"View" : function () {},
|
"View" : function () {},
|
||||||
|
"FlatList" : function () {},
|
||||||
"warn" : function () {},
|
"warn" : function () {},
|
||||||
"WebView" : function () {},
|
"WebView" : function () {},
|
||||||
"WebViewBridgeModule" : function () {},
|
"WebViewBridgeModule" : function () {},
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
(def react-native
|
(def react-native
|
||||||
#js {:NativeModules #js {}
|
#js {:NativeModules #js {}
|
||||||
:Animated #js {:View #js {}
|
:Animated #js {:View #js {}
|
||||||
|
:FlatList #js {}
|
||||||
:Text #js {}}
|
:Text #js {}}
|
||||||
:DeviceEventEmitter #js {:addListener (fn [])}
|
:DeviceEventEmitter #js {:addListener (fn [])}
|
||||||
:Dimensions #js {:get (fn [])}})
|
:Dimensions #js {:get (fn [])}})
|
||||||
|
|
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 537 B |
|
@ -87,11 +87,3 @@
|
||||||
(update :contacts/blocked disj public-key)
|
(update :contacts/blocked disj public-key)
|
||||||
(assoc-in [:contacts/contacts public-key] contact))}
|
(assoc-in [:contacts/contacts public-key] contact))}
|
||||||
(contacts-store/save-contact contact))))
|
(contacts-store/save-contact contact))))
|
||||||
|
|
||||||
(fx/defn block-contact-confirmation
|
|
||||||
[cofx public-key]
|
|
||||||
{:utils/show-confirmation
|
|
||||||
{:title (i18n/label :t/block-contact)
|
|
||||||
:content (i18n/label :t/block-contact-details)
|
|
||||||
:confirm-button-text (i18n/label :t/to-block)
|
|
||||||
:on-accept #(re-frame/dispatch [:contact.ui/block-contact-confirmed public-key])}})
|
|
||||||
|
|
|
@ -81,6 +81,17 @@
|
||||||
(send-contact-request contact)
|
(send-contact-request contact)
|
||||||
(mailserver/process-next-messages-request)))))
|
(mailserver/process-next-messages-request)))))
|
||||||
|
|
||||||
|
(fx/defn remove-contact
|
||||||
|
"Remove a contact from current account's contact list"
|
||||||
|
{:events [:contact.ui/remove-contact-pressed]}
|
||||||
|
[{:keys [db] :as cofx} {:keys [public-key] :as contact}]
|
||||||
|
(let [new-contact (update contact
|
||||||
|
:system-tags
|
||||||
|
(fnil #(disj % :contact/added) #{}))]
|
||||||
|
(fx/merge cofx
|
||||||
|
{:db (assoc-in db [:contacts/contacts public-key] new-contact)}
|
||||||
|
(contacts-store/save-contact new-contact))))
|
||||||
|
|
||||||
(fx/defn create-contact
|
(fx/defn create-contact
|
||||||
"Create entry in contacts"
|
"Create entry in contacts"
|
||||||
[{:keys [db] :as cofx} public-key]
|
[{:keys [db] :as cofx} public-key]
|
||||||
|
|
|
@ -1327,11 +1327,6 @@
|
||||||
(fn [cofx [_ public-key]]
|
(fn [cofx [_ public-key]]
|
||||||
(contact/add-contact cofx public-key)))
|
(contact/add-contact cofx public-key)))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
|
||||||
:contact.ui/block-contact-pressed
|
|
||||||
(fn [cofx [_ public-key]]
|
|
||||||
(contact.block/block-contact-confirmation cofx public-key)))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:contact.ui/block-contact-confirmed
|
:contact.ui/block-contact-confirmed
|
||||||
(fn [cofx [_ public-key]]
|
(fn [cofx [_ public-key]]
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
(defn anim-delay [duration]
|
(defn anim-delay [duration]
|
||||||
(.delay react/animated duration))
|
(.delay react/animated duration))
|
||||||
|
|
||||||
(defn event [config]
|
(defn event [mapping config]
|
||||||
(.event react/animated (clj->js [nil, config])))
|
(.event react/animated (clj->js mapping) (clj->js config)))
|
||||||
|
|
||||||
(defn add-listener [anim-value listener]
|
(defn add-listener [anim-value listener]
|
||||||
(.addListener anim-value listener))
|
(.addListener anim-value listener))
|
||||||
|
@ -60,6 +60,12 @@
|
||||||
(defn create-value [value]
|
(defn create-value [value]
|
||||||
(js/ReactNative.Animated.Value. value))
|
(js/ReactNative.Animated.Value. value))
|
||||||
|
|
||||||
|
(defn add [anim-x anim-y]
|
||||||
|
(js/ReactNative.Animated.add. anim-x anim-y))
|
||||||
|
|
||||||
|
(defn subtract [anim-x anim-y]
|
||||||
|
(js/ReactNative.Animated.subtract. anim-x anim-y))
|
||||||
|
|
||||||
(defn x [value-xy]
|
(defn x [value-xy]
|
||||||
(.-x value-xy))
|
(.-x value-xy))
|
||||||
|
|
||||||
|
|
|
@ -1,151 +0,0 @@
|
||||||
(ns status-im.ui.components.large-toolbar
|
|
||||||
(:require-macros [status-im.utils.views :as views])
|
|
||||||
(:require [cljs-bean.core :refer [->clj ->js]]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.ui.components.animation :as animation]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[status-im.ui.components.list.views :as list.views]
|
|
||||||
[status-im.ui.components.list-item.views :as list-item]
|
|
||||||
[status-im.ui.components.react :as react]
|
|
||||||
[status-im.ui.components.toolbar.styles :as toolbar.styles]
|
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
|
||||||
[status-im.utils.platform :as platform]))
|
|
||||||
|
|
||||||
(def hidden (reagent/atom 0))
|
|
||||||
(def shown (reagent/atom 100))
|
|
||||||
(def minimized-header-visible? (reagent/atom false))
|
|
||||||
(def initial-on-show-done? (volatile! false))
|
|
||||||
|
|
||||||
(defn animated-content-wrapper [header-in-toolbar has-nav? show?]
|
|
||||||
(let [anim-opacity (animation/create-value 0)
|
|
||||||
to-hide (reagent/atom false)]
|
|
||||||
(reagent/create-class
|
|
||||||
{:component-did-update
|
|
||||||
(fn [comp]
|
|
||||||
(let [new-argv (rest (reagent/argv comp))
|
|
||||||
show? (last new-argv)]
|
|
||||||
(cond
|
|
||||||
(and (not @to-hide) show?)
|
|
||||||
(animation/start
|
|
||||||
(animation/timing
|
|
||||||
anim-opacity
|
|
||||||
{:toValue 1
|
|
||||||
:duration 200
|
|
||||||
:easing (.-ease (animation/easing))
|
|
||||||
:useNativeDriver true})
|
|
||||||
#(reset! to-hide true))
|
|
||||||
|
|
||||||
(and @to-hide (not show?))
|
|
||||||
(animation/start
|
|
||||||
(animation/timing
|
|
||||||
anim-opacity
|
|
||||||
{:toValue 0
|
|
||||||
:duration 200
|
|
||||||
:easing (.-ease (animation/easing))
|
|
||||||
:useNativeDriver true})
|
|
||||||
#(reset! to-hide false)))))
|
|
||||||
|
|
||||||
:reagent-render
|
|
||||||
(fn [header-in-toolbar has-nav? _]
|
|
||||||
[react/animated-view
|
|
||||||
{:style (cond-> {:flex 1
|
|
||||||
:align-self :stretch
|
|
||||||
:opacity anim-opacity}
|
|
||||||
(false? has-nav?)
|
|
||||||
(assoc :margin-left -40 :margin-right 40))}
|
|
||||||
header-in-toolbar])})))
|
|
||||||
|
|
||||||
(defn on-viewable-items-changed [threshold interporlation-step]
|
|
||||||
(fn [info]
|
|
||||||
(let [changed (->> (->clj info)
|
|
||||||
:changed
|
|
||||||
(filter #(= 1 (:index %))))
|
|
||||||
viewable? (when (seq changed)
|
|
||||||
(->> changed
|
|
||||||
first
|
|
||||||
:isViewable))]
|
|
||||||
(when (and @initial-on-show-done? (not (nil? viewable?)))
|
|
||||||
(if (= threshold 0)
|
|
||||||
(if viewable?
|
|
||||||
(reset! minimized-header-visible? false)
|
|
||||||
(reset! minimized-header-visible? true))
|
|
||||||
(if viewable?
|
|
||||||
(do (swap! hidden - interporlation-step) (swap! shown + interporlation-step))
|
|
||||||
(do (swap! hidden + interporlation-step) (swap! shown - interporlation-step))))))))
|
|
||||||
|
|
||||||
(defonce viewability-config-callback-pairs
|
|
||||||
(let [interporlation-step 20]
|
|
||||||
(->js
|
|
||||||
(vec
|
|
||||||
(for [threshold (range 0 (+ 100 interporlation-step) interporlation-step)]
|
|
||||||
{:viewabilityConfig {:itemVisiblePercentThreshold threshold}
|
|
||||||
:onViewableItemsChanged (on-viewable-items-changed threshold interporlation-step)})))))
|
|
||||||
|
|
||||||
;; 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]
|
|
||||||
(let [has-nav? (boolean nav-item)]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:transparent? true
|
|
||||||
:style {:z-index 100
|
|
||||||
:elevation 9}}
|
|
||||||
nav-item
|
|
||||||
[animated-content-wrapper header-in-toolbar has-nav? @minimized-header-visible?]
|
|
||||||
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
|
|
||||||
(views/defview flat-list-with-large-header [header content list-ref]
|
|
||||||
(views/letsubs [window-width [:dimensions/window-width]]
|
|
||||||
{:component-did-mount #(do (reset! hidden 0) (reset! shown 100)
|
|
||||||
(reset! minimized-header-visible? false)
|
|
||||||
(vreset! initial-on-show-done? false))}
|
|
||||||
(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 {:height 16
|
|
||||||
:opacity (/ @shown 100)
|
|
||||||
:border-bottom-width 1
|
|
||||||
:border-bottom-color colors/gray-lighter}}]
|
|
||||||
wrapped-data (into [header-top-padding header header-bottom] content)
|
|
||||||
status-bar-height (get platform/platform-specific :status-bar-default-height)
|
|
||||||
toolbar-shadow-component-height
|
|
||||||
(+ 50 toolbar.styles/toolbar-height (if (zero? status-bar-height) 50 status-bar-height))]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
;; toolbar shadow
|
|
||||||
[react/animated-view
|
|
||||||
{:style
|
|
||||||
(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 (if (>= @hidden 40) (- (/ @hidden 10) 2) 0)
|
|
||||||
:background-color colors/white}
|
|
||||||
platform/ios?
|
|
||||||
(assoc :opacity (if (>= @hidden 40) (/ @hidden 100) 0)))}]
|
|
||||||
|
|
||||||
[list.views/flat-list
|
|
||||||
{:style {:z-index -1}
|
|
||||||
:data wrapped-data
|
|
||||||
:initial-num-to-render 3
|
|
||||||
:ref #(reset! list-ref %)
|
|
||||||
:render-fn list.views/flat-list-generic-render-fn
|
|
||||||
:key-fn (fn [item idx] (str idx))
|
|
||||||
:on-scroll-begin-drag #(when (false? @initial-on-show-done?)
|
|
||||||
(vreset! initial-on-show-done? true))
|
|
||||||
:viewabilityConfigCallbackPairs viewability-config-callback-pairs
|
|
||||||
:keyboard-should-persist-taps :handled}]])))
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
(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 (animation/easing))
|
||||||
|
:useNativeDriver true}))
|
||||||
|
|
||||||
|
(defn minimized-toolbar-fade-out [anim-opacity]
|
||||||
|
(animation/timing
|
||||||
|
anim-opacity
|
||||||
|
{:toValue 0
|
||||||
|
:duration 200
|
||||||
|
:easing (.-ease (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})
|
|
@ -0,0 +1,85 @@
|
||||||
|
(ns status-im.ui.components.large-toolbar.view
|
||||||
|
(:require [reagent.core :as reagent]
|
||||||
|
[cljs-bean.core :refer [->clj ->js]]
|
||||||
|
[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.utils.platform :as platform]
|
||||||
|
[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 %)))
|
||||||
|
: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 false)
|
||||||
|
anim-opacity (animation/create-value 0)
|
||||||
|
scroll-y (animation/create-value 0)]
|
||||||
|
(animation/add-listener scroll-y (fn [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]}))
|
|
@ -223,13 +223,15 @@
|
||||||
(defn flat-list
|
(defn flat-list
|
||||||
"A wrapper for FlatList.
|
"A wrapper for FlatList.
|
||||||
See https://facebook.github.io/react-native/docs/flatlist.html"
|
See https://facebook.github.io/react-native/docs/flatlist.html"
|
||||||
[{:keys [data] :as props}]
|
([props] (flat-list props nil))
|
||||||
|
([{:keys [data] :as props} {:keys [animated?]}]
|
||||||
|
(let [class (if animated? react/animated-flat-list-class flat-list-class)]
|
||||||
{:pre [(or (nil? data)
|
{:pre [(or (nil? data)
|
||||||
(sequential? data))]}
|
(sequential? data))]}
|
||||||
[flat-list-class
|
[class
|
||||||
(merge (base-list-props props)
|
(merge (base-list-props props)
|
||||||
props
|
props
|
||||||
{:data (wrap-data data)})])
|
{:data (wrap-data data)})])))
|
||||||
|
|
||||||
(defn flat-list-generic-render-fn
|
(defn flat-list-generic-render-fn
|
||||||
"A generic status-react specific `render-fn` for `list-item`.
|
"A generic status-react specific `render-fn` for `list-item`.
|
||||||
|
@ -283,13 +285,14 @@
|
||||||
[react/touchable-highlight {:on-press action}
|
[react/touchable-highlight {:on-press action}
|
||||||
[react/view {:accessibility-label accessibility-label}
|
[react/view {:accessibility-label accessibility-label}
|
||||||
[item
|
[item
|
||||||
|
(when icon
|
||||||
[item-icon {:icon icon
|
[item-icon {:icon icon
|
||||||
:style (merge styles/action
|
:style (merge styles/action
|
||||||
action-style
|
action-style
|
||||||
(when disabled? styles/action-disabled))
|
(when disabled? styles/action-disabled))
|
||||||
:icon-opts (merge {:color :white}
|
:icon-opts (merge {:color :white}
|
||||||
icon-opts
|
icon-opts
|
||||||
(when disabled? {:color colors/gray}))}]
|
(when disabled? {:color colors/gray}))}])
|
||||||
(if-not subtext
|
(if-not subtext
|
||||||
[item-primary-only {:style (merge styles/action-label
|
[item-primary-only {:style (merge styles/action-label
|
||||||
(action-label-style false)
|
(action-label-style false)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
(ns status-im.ui.screens.profile.components.sheets
|
||||||
|
(: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.list-item.views :as list-item]
|
||||||
|
[status-im.ui.screens.profile.components.styles :as styles])
|
||||||
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
|
(defn hide-sheet-and-dispatch [event]
|
||||||
|
(re-frame/dispatch [:bottom-sheet/hide-sheet])
|
||||||
|
(re-frame/dispatch event))
|
||||||
|
|
||||||
|
(views/defview add-contact []
|
||||||
|
(views/letsubs [{:keys [public-key]} [:bottom-sheet/options]]
|
||||||
|
[react/view
|
||||||
|
[react/text {:style styles/sheet-text}
|
||||||
|
(i18n/label :t/add-to-contacts-text)]
|
||||||
|
[list-item/list-item
|
||||||
|
{:theme :action
|
||||||
|
:title :t/add-to-contacts
|
||||||
|
:icon :main-icons/add-contact
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:contact.ui/add-to-contact-pressed public-key])}]]))
|
||||||
|
|
||||||
|
(views/defview remove-contact []
|
||||||
|
(views/letsubs [contact [:bottom-sheet/options]]
|
||||||
|
[react/view
|
||||||
|
[react/text {:style styles/sheet-text}
|
||||||
|
(i18n/label :t/remove-from-contacts-text)]
|
||||||
|
[list-item/list-item
|
||||||
|
{:theme :action-destructive
|
||||||
|
:title :t/remove-from-contacts
|
||||||
|
:icon :main-icons/remove-contact
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:contact.ui/remove-contact-pressed contact])}]]))
|
||||||
|
|
||||||
|
(views/defview block-contact []
|
||||||
|
(views/letsubs [{:keys [public-key]} [:bottom-sheet/options]]
|
||||||
|
[react/view
|
||||||
|
[react/text {:style styles/sheet-text}
|
||||||
|
(i18n/label :t/block-contact-details)]
|
||||||
|
[list-item/list-item
|
||||||
|
{:theme :action-destructive
|
||||||
|
:title :t/block-contact
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:contact.ui/block-contact-confirmed public-key])}]]))
|
|
@ -113,3 +113,11 @@
|
||||||
|
|
||||||
(def profile-form
|
(def profile-form
|
||||||
{:padding-vertical 16})
|
{:padding-vertical 16})
|
||||||
|
|
||||||
|
;; sheets
|
||||||
|
|
||||||
|
(def sheet-text
|
||||||
|
{:color colors/gray
|
||||||
|
:padding 24
|
||||||
|
:line-height 22
|
||||||
|
:font-size 15})
|
|
@ -2,28 +2,6 @@
|
||||||
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
(:require-macros [status-im.utils.styles :refer [defstyle]])
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(def network-info {:background-color :white})
|
|
||||||
|
|
||||||
(def profile-info-item
|
|
||||||
{:flex-direction :row
|
|
||||||
:align-items :center
|
|
||||||
:padding-left 16})
|
|
||||||
|
|
||||||
(defn profile-info-text-container [options]
|
|
||||||
{:flex 1
|
|
||||||
:padding-right (if options 16 40)})
|
|
||||||
|
|
||||||
(def profile-info-title
|
|
||||||
{:color colors/gray
|
|
||||||
:font-size 14})
|
|
||||||
|
|
||||||
(defstyle profile-setting-spacing
|
|
||||||
{:ios {:height 10}
|
|
||||||
:android {:height 7}})
|
|
||||||
|
|
||||||
(def profile-setting-text
|
|
||||||
{:font-size 17})
|
|
||||||
|
|
||||||
(def action-container
|
(def action-container
|
||||||
{:background-color colors/white})
|
{:background-color colors/white})
|
||||||
|
|
||||||
|
@ -51,20 +29,14 @@
|
||||||
(def action-icon-opts
|
(def action-icon-opts
|
||||||
{:color colors/blue})
|
{:color colors/blue})
|
||||||
|
|
||||||
(def block-action
|
(def block-action-label
|
||||||
{:background-color colors/red-transparent-10
|
{:color colors/red
|
||||||
:border-radius 50})
|
:padding-top 26
|
||||||
|
:margin-left 16})
|
||||||
|
|
||||||
(defn block-action-label [with-subtext?]
|
(def contact-profile-details-container
|
||||||
{:color colors/red})
|
|
||||||
|
|
||||||
(def block-action-icon-opts
|
|
||||||
{:color colors/red})
|
|
||||||
|
|
||||||
(def profile-setting-text-empty
|
|
||||||
(merge profile-setting-text
|
|
||||||
{:color colors/gray}))
|
|
||||||
|
|
||||||
(def contact-profile-info-container
|
|
||||||
{:padding-top 26
|
{:padding-top 26
|
||||||
:background-color colors/white})
|
:background-color colors/white})
|
||||||
|
|
||||||
|
(def contact-profile-detail-share-icon
|
||||||
|
{:color colors/gray-transparent-40})
|
||||||
|
|
|
@ -1,105 +1,145 @@
|
||||||
(ns status-im.ui.screens.profile.contact.views
|
(ns status-im.ui.screens.profile.contact.views
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[reagent.core :as reagent]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.ui.components.tabbar.styles :as tabs.styles]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.status-bar.view :as status-bar]
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
|
[status-im.ui.components.large-toolbar.view :as large-toolbar]
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
|
|
||||||
[status-im.ui.screens.profile.components.views :as profile.components]
|
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||||
[status-im.ui.screens.profile.contact.styles :as styles]
|
[status-im.ui.screens.profile.contact.styles :as styles]
|
||||||
[status-im.utils.platform :as platform])
|
[status-im.ui.components.list-item.views :as list-item]
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||||
|
[status-im.ui.screens.profile.components.sheets :as sheets]
|
||||||
(defn profile-contact-toolbar []
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[toolbar/toolbar {}
|
[status-im.multiaccounts.core :as multiaccounts])
|
||||||
toolbar/default-nav-back
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
[toolbar/content-title ""]])
|
|
||||||
|
|
||||||
(defn actions
|
(defn actions
|
||||||
[{:keys [public-key added? tribute-to-talk] :as contact}]
|
[{:keys [public-key added? tribute-to-talk] :as contact}]
|
||||||
(let [{:keys [tribute-status tribute-label]} tribute-to-talk]
|
(let [{:keys [tribute-status tribute-label]} tribute-to-talk]
|
||||||
(concat (if added?
|
(concat [(cond-> {:label (i18n/label :t/send-message)
|
||||||
[{:label (i18n/label :t/in-contacts)
|
|
||||||
:icon :main-icons/in-contacts
|
|
||||||
:disabled? true
|
|
||||||
:accessibility-label :in-contacts-button}]
|
|
||||||
[{:label (i18n/label :t/add-to-contacts)
|
|
||||||
:icon :main-icons/add-contact
|
|
||||||
:action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])
|
|
||||||
:accessibility-label :add-to-contacts-button}])
|
|
||||||
[(cond-> {:label (i18n/label :t/send-message)
|
|
||||||
:icon :main-icons/message
|
:icon :main-icons/message
|
||||||
:action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}])
|
:action #(re-frame/dispatch [:contact.ui/send-message-pressed {:public-key public-key}])
|
||||||
:accessibility-label :start-conversation-button}
|
:accessibility-label :start-conversation-button}
|
||||||
(not (#{:none :paid} tribute-status))
|
(not (#{:none :paid} tribute-status))
|
||||||
(assoc :subtext tribute-label))
|
(assoc :subtext tribute-label))]
|
||||||
;;TODO hide temporary for v1
|
;;TODO hide temporary for v1
|
||||||
#_{:label (i18n/label :t/send-transaction)
|
#_{:label (i18n/label :t/send-transaction)
|
||||||
:icon :main-icons/send
|
:icon :main-icons/send
|
||||||
:action #(re-frame/dispatch [:profile/send-transaction public-key])
|
:action #(re-frame/dispatch [:profile/send-transaction public-key])
|
||||||
:accessibility-label :send-transaction-button}
|
:accessibility-label :send-transaction-button}
|
||||||
{:label (i18n/label :t/share-profile-link)
|
(if added?
|
||||||
:icon :main-icons/share
|
[{:label (i18n/label :t/remove-from-contacts)
|
||||||
:action #(re-frame/dispatch [:profile/share-profile-link public-key])
|
:icon :main-icons/remove-contact
|
||||||
:accessibility-label :share-profile-link}])))
|
:accessibility-label :in-contacts-button
|
||||||
|
:action #(re-frame/dispatch [:contact.ui/remove-contact-pressed contact])}]
|
||||||
|
;; TODO sheets temporary disabled
|
||||||
|
;:action #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
; {:content sheets/remove-contact
|
||||||
|
; :content-height 150}
|
||||||
|
; contact])
|
||||||
|
[{:label (i18n/label :t/add-to-contacts)
|
||||||
|
:icon :main-icons/add-contact
|
||||||
|
:accessibility-label :add-to-contacts-button
|
||||||
|
:action #(re-frame/dispatch [:contact.ui/add-to-contact-pressed public-key])}]))))
|
||||||
|
;; TODO sheets temporary disabled
|
||||||
|
;:action #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
; {:content sheets/add-contact
|
||||||
|
; :content-height 150}
|
||||||
|
; contact])
|
||||||
|
|
||||||
(defn profile-info-item [{:keys [label value options accessibility-label]}]
|
(defn render-detail [{:keys [name public-key] :as detail}]
|
||||||
[react/view styles/profile-info-item
|
[list-item/list-item
|
||||||
[react/view (styles/profile-info-text-container options)
|
{:title name
|
||||||
[react/text {:style styles/profile-info-title}
|
:subtitle (utils/get-shortened-address public-key)
|
||||||
label]
|
:icon [chat-icon/contact-icon-contacts-tab detail]
|
||||||
[react/view styles/profile-setting-spacing]
|
|
||||||
[react/text {:style styles/profile-setting-text
|
|
||||||
:accessibility-label accessibility-label
|
|
||||||
:selectable true}
|
|
||||||
value]]])
|
|
||||||
|
|
||||||
(defn profile-info-contact-code-item [public-key]
|
|
||||||
[profile-info-item
|
|
||||||
{:label (i18n/label :t/contact-code)
|
|
||||||
:accessibility-label :profile-public-key
|
:accessibility-label :profile-public-key
|
||||||
:value public-key}])
|
:on-press #(re-frame/dispatch [:show-popover {:view :share-chat-key :address public-key}])
|
||||||
|
:accessories [[icons/icon :main-icons/share styles/contact-profile-detail-share-icon]]}])
|
||||||
|
|
||||||
(defn profile-info [{:keys [public-key]}]
|
(defn profile-details-list-view [contact]
|
||||||
|
[list/flat-list {:data [contact]
|
||||||
|
:default-separator? true
|
||||||
|
:key-fn :public-key
|
||||||
|
:render-fn render-detail}])
|
||||||
|
|
||||||
|
(defn profile-details [contact]
|
||||||
[react/view
|
[react/view
|
||||||
[profile-info-contact-code-item public-key]])
|
[list-item/list-item {:type :section-header
|
||||||
|
:title :t/profile-details
|
||||||
|
:title-accessibility-label :profile-details}]
|
||||||
|
[profile-details-list-view contact]])
|
||||||
|
|
||||||
(defn block-contact-action [{:keys [blocked? public-key]}]
|
(defn block-contact-action [{:keys [blocked? public-key] :as contact}]
|
||||||
[list/render-action
|
[react/touchable-highlight {:on-press (if blocked?
|
||||||
{:label (if blocked?
|
|
||||||
(i18n/label :t/unblock-contact)
|
|
||||||
(i18n/label :t/block-contact))
|
|
||||||
:icon :main-icons/cancel
|
|
||||||
:action (if blocked?
|
|
||||||
#(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key])
|
#(re-frame/dispatch [:contact.ui/unblock-contact-pressed public-key])
|
||||||
#(re-frame/dispatch [:contact.ui/block-contact-pressed public-key]))
|
#(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||||
|
{:content sheets/block-contact
|
||||||
|
:content-height 160}
|
||||||
|
contact]))}
|
||||||
|
[react/text {:style styles/block-action-label
|
||||||
:accessibility-label (if blocked?
|
:accessibility-label (if blocked?
|
||||||
:unblock-contact
|
:unblock-contact
|
||||||
:block-contact)}
|
:block-contact)}
|
||||||
{:action-style styles/block-action
|
(if blocked?
|
||||||
:action-label-style styles/block-action-label
|
(i18n/label :t/unblock-contact)
|
||||||
:icon-opts styles/block-action-icon-opts}])
|
(i18n/label :t/block-contact))]])
|
||||||
|
|
||||||
(defview profile []
|
(defn- header-in-toolbar [{:keys [photo-path] :as account}]
|
||||||
(letsubs [contact [:contacts/current-contact]]
|
(let [displayed-name (multiaccounts/displayed-name account)]
|
||||||
[react/view profile.components.styles/profile
|
[react/view {:flex 1
|
||||||
[status-bar/status-bar]
|
:flex-direction :row
|
||||||
[profile-contact-toolbar]
|
:align-items :center
|
||||||
[react/scroll-view
|
:align-self :stretch}
|
||||||
[react/view profile.components.styles/profile-form
|
[photos/photo photo-path {: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
|
[profile.components/profile-header
|
||||||
{:contact contact
|
{:contact account
|
||||||
:editing? false
|
:allow-icon-change? false
|
||||||
:allow-icon-change? false}]]
|
:include-remove-action? false}])
|
||||||
[list/action-list (actions contact)
|
|
||||||
|
(views/defview profile []
|
||||||
|
(views/letsubs [list-ref (reagent/atom nil)
|
||||||
|
contact [:contacts/current-contact]]
|
||||||
|
(let [header-in-toolbar (header-in-toolbar contact)
|
||||||
|
header (header contact)
|
||||||
|
content
|
||||||
|
[[list/action-list (actions contact)
|
||||||
{:container-style styles/action-container
|
{:container-style styles/action-container
|
||||||
:action-style styles/action
|
:action-style styles/action
|
||||||
:action-label-style styles/action-label
|
:action-label-style styles/action-label
|
||||||
:action-subtext-style styles/action-subtext
|
:action-subtext-style styles/action-subtext
|
||||||
:action-separator-style styles/action-separator
|
:action-separator-style styles/action-separator
|
||||||
:icon-opts styles/action-icon-opts}]
|
:icon-opts styles/action-icon-opts}]
|
||||||
[react/view {:style {:height 16}}]
|
[react/view styles/contact-profile-details-container
|
||||||
[block-contact-action contact]
|
[profile-details contact]]
|
||||||
[react/view styles/contact-profile-info-container
|
[block-contact-action contact]]
|
||||||
[profile-info contact]]]]))
|
generated-view (large-toolbar/generate-view
|
||||||
|
header-in-toolbar
|
||||||
|
toolbar/default-nav-back
|
||||||
|
nil
|
||||||
|
header
|
||||||
|
content
|
||||||
|
list-ref)]
|
||||||
|
[react/safe-area-view
|
||||||
|
{:style
|
||||||
|
(merge {:flex 1}
|
||||||
|
(when platform/ios?
|
||||||
|
{:margin-bottom tabs.styles/tabs-diff}))}
|
||||||
|
[status-bar/status-bar {:type :main}]
|
||||||
|
(:minimized-toolbar generated-view)
|
||||||
|
(:content-with-header generated-view)])))
|
|
@ -9,7 +9,8 @@
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.common.common :as components.common]
|
[status-im.ui.components.common.common :as components.common]
|
||||||
[status-im.ui.components.copyable-text :as copyable-text]
|
[status-im.ui.components.copyable-text :as copyable-text]
|
||||||
[status-im.ui.components.large-toolbar :as large-toolbar]
|
[status-im.ui.components.large-toolbar.view :as large-toolbar]
|
||||||
|
[status-im.ui.components.list-item.views :as list-item]
|
||||||
[status-im.ui.components.list-selection :as list-selection]
|
[status-im.ui.components.list-selection :as list-selection]
|
||||||
[status-im.ui.components.list.views :as list.views]
|
[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.qr-code-viewer.views :as qr-code-viewer]
|
||||||
|
@ -203,18 +204,30 @@
|
||||||
registrar [:ens.stateofus/registrar]]
|
registrar [:ens.stateofus/registrar]]
|
||||||
(let [show-backup-seed? (and (not seed-backed-up?)
|
(let [show-backup-seed? (and (not seed-backed-up?)
|
||||||
(not (string/blank? mnemonic)))
|
(not (string/blank? mnemonic)))
|
||||||
|
|
||||||
|
;; toolbar-contents
|
||||||
|
header-in-toolbar (header-in-toolbar multiaccount)
|
||||||
|
toolbar-action-items (toolbar-action-items public-key)
|
||||||
|
|
||||||
|
;; flatlist contents
|
||||||
|
header (header multiaccount)
|
||||||
content (flat-list-content
|
content (flat-list-content
|
||||||
preferred-name registrar tribute-to-talk
|
preferred-name registrar tribute-to-talk
|
||||||
active-contacts-count show-backup-seed?)]
|
active-contacts-count show-backup-seed?)
|
||||||
|
|
||||||
|
;; generated toolbar and content with header
|
||||||
|
generated-view (large-toolbar/generate-view
|
||||||
|
header-in-toolbar
|
||||||
|
nil
|
||||||
|
toolbar-action-items
|
||||||
|
header
|
||||||
|
content
|
||||||
|
list-ref)]
|
||||||
[react/safe-area-view
|
[react/safe-area-view
|
||||||
{:style
|
{:style
|
||||||
(merge {:flex 1}
|
(merge {:flex 1}
|
||||||
(when platform/ios?
|
(when platform/ios?
|
||||||
{:margin-bottom tabs.styles/tabs-diff}))}
|
{:margin-bottom tabs.styles/tabs-diff}))}
|
||||||
[status-bar/status-bar {:type :main}]
|
[status-bar/status-bar {:type :main}]
|
||||||
[large-toolbar/minimized-toolbar
|
(:minimized-toolbar generated-view)
|
||||||
(header-in-toolbar multiaccount)
|
(:content-with-header generated-view)])))
|
||||||
nil
|
|
||||||
(toolbar-action-items public-key)]
|
|
||||||
[large-toolbar/flat-list-with-large-header
|
|
||||||
(header multiaccount) content list-ref]])))
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
(def react-native
|
(def react-native
|
||||||
#js {:NativeModules #js {}
|
#js {:NativeModules #js {}
|
||||||
:Animated #js {:View #js {}
|
:Animated #js {:View #js {}
|
||||||
|
:FlatList #js {}
|
||||||
:Text #js {}}
|
:Text #js {}}
|
||||||
:DeviceEventEmitter #js {:addListener (fn [])}
|
:DeviceEventEmitter #js {:addListener (fn [])}
|
||||||
:Dimensions #js {:get (fn [])}})
|
:Dimensions #js {:get (fn [])}})
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
"add-members": "Add members",
|
"add-members": "Add members",
|
||||||
"add-network": "Add network",
|
"add-network": "Add network",
|
||||||
"add-to-contacts": "Add to contacts",
|
"add-to-contacts": "Add to contacts",
|
||||||
|
"add-to-contacts-text": "By adding a user to your contact list, you share your wallet address",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"advanced": "Advanced",
|
"advanced": "Advanced",
|
||||||
"advanced-settings": "Advanced settings",
|
"advanced-settings": "Advanced settings",
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
"blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name",
|
"blank-keycard-text": "You can proceed with your keycard once you've generated your keys and name",
|
||||||
"blank-keycard-title": "Looks like you’ve tapped \na blank keycard",
|
"blank-keycard-title": "Looks like you’ve tapped \na blank keycard",
|
||||||
"block": "Block",
|
"block": "Block",
|
||||||
"block-contact": "Block contact",
|
"block-contact": "Block this user",
|
||||||
"block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you",
|
"block-contact-details": "Blocking will delete this user's previous messages and stop new ones from reaching you",
|
||||||
"blocked-users": "Blocked users",
|
"blocked-users": "Blocked users",
|
||||||
"bootnode-address": "Bootnode address",
|
"bootnode-address": "Bootnode address",
|
||||||
|
@ -782,6 +783,7 @@
|
||||||
"processing": "Processing",
|
"processing": "Processing",
|
||||||
"product-information": "Product Information",
|
"product-information": "Product Information",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
|
"profile-details": "Profile details",
|
||||||
"public-chat": "Public chat",
|
"public-chat": "Public chat",
|
||||||
"public-chats": "Public chats",
|
"public-chats": "Public chats",
|
||||||
"public-group-status": "Public",
|
"public-group-status": "Public",
|
||||||
|
@ -825,6 +827,8 @@
|
||||||
"remind-me-later": "Remind me later",
|
"remind-me-later": "Remind me later",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"remove-from-chat": "Remove from chat",
|
"remove-from-chat": "Remove from chat",
|
||||||
|
"remove-from-contacts": "Remove from contacts",
|
||||||
|
"remove-from-contacts-text": "By removing a user from your contact list you do not hide your wallet address from them",
|
||||||
"remove-network": "Remove network",
|
"remove-network": "Remove network",
|
||||||
"remove-token": "Remove token",
|
"remove-token": "Remove token",
|
||||||
"removed": "removed",
|
"removed": "removed",
|
||||||
|
@ -1007,7 +1011,7 @@
|
||||||
"type-a-message": "Type a message...",
|
"type-a-message": "Type a message...",
|
||||||
"ulc-enabled": "ULC enabled",
|
"ulc-enabled": "ULC enabled",
|
||||||
"unable-to-read-this-code": "Unable to read this code",
|
"unable-to-read-this-code": "Unable to read this code",
|
||||||
"unblock-contact": "Unblock contact",
|
"unblock-contact": "Unblock this user",
|
||||||
"unknown-status-go-error": "Unknown status-go error",
|
"unknown-status-go-error": "Unknown status-go error",
|
||||||
"unlock": "Unlock",
|
"unlock": "Unlock",
|
||||||
"unpair-card": "Unpair card",
|
"unpair-card": "Unpair card",
|
||||||
|
|
Loading…
Reference in New Issue