list-item suppliment/fixes
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
d6b8065a7c
commit
f981dbb43b
|
@ -48,7 +48,7 @@
|
||||||
:height 40
|
:height 40
|
||||||
:border-radius 20
|
:border-radius 20
|
||||||
:background-color colors/green}]
|
:background-color colors/green}]
|
||||||
:accessories [:more]}]]
|
:accessories [:main-icons/more]}]]
|
||||||
[item "With radio button (TODO!)"
|
[item "With radio button (TODO!)"
|
||||||
[list-item/list-item
|
[list-item/list-item
|
||||||
{:title "George"
|
{:title "George"
|
||||||
|
|
|
@ -231,7 +231,11 @@
|
||||||
props
|
props
|
||||||
{:data (wrap-data data)})])
|
{:data (wrap-data data)})])
|
||||||
|
|
||||||
(defn flat-list-generic-render-fn [item _]
|
(defn flat-list-generic-render-fn
|
||||||
|
"A generic status-react specific `render-fn` for `list-item`.
|
||||||
|
Handles `list-item` `data` consiting any combination of
|
||||||
|
`list-item/list-item` config map and `companent`."
|
||||||
|
[item _]
|
||||||
(cond
|
(cond
|
||||||
(map? item) [list-item/list-item item]
|
(map? item) [list-item/list-item item]
|
||||||
(vector? item) item
|
(vector? item) item
|
||||||
|
|
|
@ -1,13 +1,53 @@
|
||||||
(ns status-im.ui.components.list-item.styles
|
(ns status-im.ui.components.list-item.styles
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(defn container [type]
|
(defn container [type selected?]
|
||||||
|
(merge
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:justify-content :flex-start
|
:justify-content :flex-start
|
||||||
:padding-horizontal 16
|
: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-top (if (= type :section-header) 14 10)
|
||||||
:padding-bottom (if (= type :section-header) 4 10)
|
:padding-bottom (if (= type :section-header) 4 10)
|
||||||
:align-items :center})
|
:align-items :center}
|
||||||
|
(when selected?
|
||||||
|
{:background-color colors/gray-transparent-40})))
|
||||||
|
|
||||||
(def icon-column-container
|
(def icon-column-container
|
||||||
{:margin-right 14
|
{:margin-right 14
|
||||||
|
@ -76,7 +116,6 @@
|
||||||
(if disabled?
|
(if disabled?
|
||||||
{:color colors/gray}
|
{:color colors/gray}
|
||||||
(case theme
|
(case theme
|
||||||
:blue {:color colors/white}
|
|
||||||
:action-destructive {:color colors/red}
|
:action-destructive {:color colors/red}
|
||||||
:action {:color colors/blue}
|
:action {:color colors/blue}
|
||||||
{}))))
|
{}))))
|
||||||
|
@ -111,7 +150,6 @@
|
||||||
{:color title-color-override}
|
{:color title-color-override}
|
||||||
;; else
|
;; else
|
||||||
(case theme
|
(case theme
|
||||||
:blue {:color colors/white}
|
|
||||||
:action-destructive {:color colors/red}
|
:action-destructive {:color colors/red}
|
||||||
:action {:color colors/blue}
|
:action {:color colors/blue}
|
||||||
{})))))
|
{})))))
|
||||||
|
@ -126,7 +164,7 @@
|
||||||
:justify-content :flex-start
|
:justify-content :flex-start
|
||||||
:align-self :stretch})
|
:align-self :stretch})
|
||||||
|
|
||||||
(defn subtitle [icon? theme subtitle-row-accessory]
|
(defn subtitle [icon? subtitle-row-accessory]
|
||||||
(cond-> {:margin-left (if icon? 2 0)
|
(cond-> {:margin-left (if icon? 2 0)
|
||||||
:flex 1
|
:flex 1
|
||||||
:align-self :stretch
|
:align-self :stretch
|
||||||
|
@ -135,8 +173,6 @@
|
||||||
;; as reasonably possible as it can be, and achieve the
|
;; as reasonably possible as it can be, and achieve the
|
||||||
;; intent of the design spec
|
;; intent of the design spec
|
||||||
:line-height 22}
|
:line-height 22}
|
||||||
(= :blue theme)
|
|
||||||
(assoc :color (colors/alpha colors/blue-light 0.6))
|
|
||||||
subtitle-row-accessory
|
subtitle-row-accessory
|
||||||
(assoc :margin-right 16)))
|
(assoc :margin-right 16)))
|
||||||
|
|
||||||
|
@ -150,22 +186,14 @@
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :flex-start})
|
:justify-content :flex-start})
|
||||||
|
|
||||||
(defn accessory-text [theme]
|
(defn accessory-text [width last]
|
||||||
{:color (if (= theme :blue)
|
{:color colors/gray
|
||||||
(colors/alpha colors/blue-light 0.6)
|
:max-width (if last (* @width 0.62) (* @width 0.55))
|
||||||
colors/gray)
|
|
||||||
;; we are doing the following to achieve pixel perfection
|
;; we are doing the following to achieve pixel perfection
|
||||||
;; as reasonably possible as it can be, and achieve the
|
;; as reasonably possible as it can be, and achieve the
|
||||||
;; intent of the design spec
|
;; intent of the design spec
|
||||||
:line-height 22})
|
:line-height 22})
|
||||||
|
|
||||||
(defn radius [size] (/ size 2))
|
|
||||||
|
|
||||||
(defn photo [size]
|
|
||||||
{:border-radius (radius size)
|
|
||||||
:width size
|
|
||||||
:height size})
|
|
||||||
|
|
||||||
(def error
|
(def error
|
||||||
{:bottom-value 0
|
{:bottom-value 0
|
||||||
:color colors/red-light
|
:color colors/red-light
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.list-item.styles :as styles]
|
[status-im.ui.components.list-item.styles :as styles]
|
||||||
[status-im.ui.components.tooltip.views :as tooltip]
|
[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.ui.screens.profile.db :as profile.db]
|
||||||
[status-im.utils.label :as utils.label]))
|
[status-im.utils.label :as utils.label]))
|
||||||
|
|
||||||
|
@ -23,15 +24,9 @@
|
||||||
(if disabled?
|
(if disabled?
|
||||||
{:container colors/gray-lighter
|
{:container colors/gray-lighter
|
||||||
:icon colors/gray-transparent-40}
|
:icon colors/gray-transparent-40}
|
||||||
(case theme
|
(if (= theme :action-destructive)
|
||||||
:action-destructive
|
|
||||||
{:container colors/red-light
|
{:container colors/red-light
|
||||||
:icon colors/red}
|
:icon colors/red}
|
||||||
|
|
||||||
:blue
|
|
||||||
{:container colors/white-transparent-10
|
|
||||||
:icon colors/white}
|
|
||||||
|
|
||||||
{:container nil
|
{:container nil
|
||||||
:icon nil}))]
|
:icon nil}))]
|
||||||
[react/view (styles/icon-container (:container colors))
|
[react/view (styles/icon-container (:container colors))
|
||||||
|
@ -39,9 +34,7 @@
|
||||||
|
|
||||||
(and (string? icon)
|
(and (string? icon)
|
||||||
(profile.db/base64-encoded-image-path? icon))
|
(profile.db/base64-encoded-image-path? icon))
|
||||||
[react/image {:source {:uri icon}
|
[photos/photo icon {:size 40}]
|
||||||
:resize-mode :cover
|
|
||||||
:style (styles/photo 40)}]
|
|
||||||
|
|
||||||
:else [icon])])
|
:else [icon])])
|
||||||
|
|
||||||
|
@ -78,7 +71,9 @@
|
||||||
title-prefix-width disabled?)}
|
title-prefix-width disabled?)}
|
||||||
(if title-prefix-width
|
(if title-prefix-width
|
||||||
(utils.label/stringify title-prefix)
|
(utils.label/stringify title-prefix)
|
||||||
(str (utils.label/stringify title-prefix) " "))]
|
(if (string? title)
|
||||||
|
(str (utils.label/stringify title-prefix) " ")
|
||||||
|
(utils.label/stringify title-prefix)))]
|
||||||
|
|
||||||
(vector? title-prefix)
|
(vector? title-prefix)
|
||||||
title-prefix
|
title-prefix
|
||||||
|
@ -124,19 +119,19 @@
|
||||||
[react/text {:style
|
[react/text {:style
|
||||||
(merge
|
(merge
|
||||||
(styles/subtitle
|
(styles/subtitle
|
||||||
icon? theme (pos? @subtitle-row-accessory-width)))
|
icon? (pos? @subtitle-row-accessory-width)))
|
||||||
:number-of-lines subtitle-max-lines
|
:number-of-lines subtitle-max-lines
|
||||||
:ellipsize-mode :tail}
|
:ellipsize-mode :tail}
|
||||||
(utils.label/stringify subtitle)]
|
(utils.label/stringify subtitle)]
|
||||||
|
|
||||||
(vector? subtitle)
|
(vector? subtitle)
|
||||||
[react/view
|
[react/view
|
||||||
(styles/subtitle icon? theme (pos? @subtitle-row-accessory-width))
|
(styles/subtitle icon? (pos? @subtitle-row-accessory-width))
|
||||||
subtitle]
|
subtitle]
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[react/view
|
[react/view
|
||||||
(styles/subtitle icon? theme (pos? @subtitle-row-accessory-width))
|
(styles/subtitle icon? (pos? @subtitle-row-accessory-width))
|
||||||
[subtitle]])
|
[subtitle]])
|
||||||
|
|
||||||
(when subtitle-row-accessory
|
(when subtitle-row-accessory
|
||||||
|
@ -168,7 +163,7 @@
|
||||||
content
|
content
|
||||||
[content])])])
|
[content])])])
|
||||||
|
|
||||||
(defn- accessories-column [accessories theme]
|
(defn- accessories-column [accessories theme width]
|
||||||
(let [last-accessory (peek accessories)
|
(let [last-accessory (peek accessories)
|
||||||
last-accessory-is-component (and (not (utils.label/stringify last-accessory))
|
last-accessory-is-component (and (not (utils.label/stringify last-accessory))
|
||||||
(not= :chevron last-accessory))
|
(not= :chevron last-accessory))
|
||||||
|
@ -186,34 +181,30 @@
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center}
|
:justify-content :center}
|
||||||
:resize-mode :center
|
:resize-mode :center
|
||||||
:color (if (= theme :blue)
|
:color colors/gray-transparent-40}]
|
||||||
(colors/alpha colors/white 0.4)
|
|
||||||
colors/gray-transparent-40)}]
|
|
||||||
|
|
||||||
(= :check accessory)
|
(and (qualified-keyword? accessory)
|
||||||
[icons/icon :main-icons/check
|
(= "main-icons" (namespace accessory)))
|
||||||
{:color (if (= theme :blue)
|
[icons/icon
|
||||||
(colors/alpha colors/white 0.4)
|
accessory
|
||||||
colors/gray)}]
|
{:color colors/gray-transparent-40
|
||||||
|
:container-style
|
||||||
(= :more accessory)
|
{:margin-right (if (= accessory last-accessory) 0 12)}}]
|
||||||
[icons/icon :main-icons/more
|
|
||||||
{:color (if (= theme :blue)
|
|
||||||
(colors/alpha colors/white 0.4)
|
|
||||||
colors/black)}]
|
|
||||||
|
|
||||||
:else
|
:else
|
||||||
[react/view (cond-> {:margin-right (if (= accessory last-accessory) 0 16)}
|
[react/view (cond-> {:margin-right (if (= accessory last-accessory) 0 16)}
|
||||||
;; `:chevron` container is 10px wide (see up)
|
;; `:chevron` container is 10px wide (see up)
|
||||||
;; but the chevron icon itself is 9px aligned in the
|
;; but the chevron icon itself is 9px aligned in the
|
||||||
;; container to the right - so 1px white-space on left
|
;; container to the right - so 1px white-space on left
|
||||||
;; that 1px + 15px margin makes 16px
|
;; thats 1px + 15px margin, which makes 16px
|
||||||
;; as intended in design spec
|
;; as intended in design spec
|
||||||
(= last-accessory :chevron)
|
(= last-accessory :chevron)
|
||||||
(assoc :margin-right 15))
|
(assoc :margin-right 15))
|
||||||
(cond
|
(cond
|
||||||
(or (string? accessory) (keyword? accessory) (number? accessory))
|
(or (string? accessory) (keyword? accessory) (number? accessory))
|
||||||
[react/text {:style (styles/accessory-text theme)
|
[react/text {:style
|
||||||
|
(styles/accessory-text width (= accessory last-accessory))
|
||||||
|
:ellipsize-mode :middle
|
||||||
:number-of-lines 1}
|
:number-of-lines 1}
|
||||||
(utils.label/stringify accessory)]
|
(utils.label/stringify accessory)]
|
||||||
|
|
||||||
|
@ -221,111 +212,150 @@
|
||||||
accessory
|
accessory
|
||||||
|
|
||||||
:else nil)])
|
:else nil)])
|
||||||
{:key accessory}))))))
|
{:key (name (gensym "accessory"))}))))))
|
||||||
|
|
||||||
;; every key is optional - use as needed
|
|
||||||
;; combination of around 4 related keys are enough for most cases
|
|
||||||
|
|
||||||
;; type
|
|
||||||
;; :default (default), :small, or :section-header
|
|
||||||
;; - :section-header
|
|
||||||
;; specifying only these is sufficient
|
|
||||||
;; {:title "Section title" :type :section-header}
|
|
||||||
;; optionally set `container-margin-top/bottom`
|
|
||||||
|
|
||||||
;; theme
|
|
||||||
;; :default(default), :action, :action-destructive
|
|
||||||
|
|
||||||
;; container-margin-top
|
|
||||||
;; container-margin-bottom
|
|
||||||
;; number - 0 by default
|
|
||||||
;; usually the first item has top margin
|
|
||||||
;; the last item has bottom margin
|
|
||||||
|
|
||||||
;; icon
|
|
||||||
;; any one of keyword representing :main-icon/icon, photo-path, 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(when it has 4px :margin-top)
|
|
||||||
;; any other vector-icon/icon is accepted though(when 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
|
|
||||||
;; TODO - consider removing, as it is redundant now that
|
|
||||||
;; title/subtitle elements can be component as well
|
|
||||||
;; just make sure to keep in mind the note made on
|
|
||||||
;; component case on those keys above
|
|
||||||
|
|
||||||
;; accessories
|
|
||||||
;; vector of :chevron, :check, :more, string, number, keyword or component
|
|
||||||
|
|
||||||
;; on-press/on-long-press
|
|
||||||
;; function - self explanatory
|
|
||||||
|
|
||||||
;; error
|
|
||||||
;; string - error tooltip
|
|
||||||
|
|
||||||
;; accessibility-label
|
|
||||||
;; :keyword - self explanatory
|
|
||||||
|
|
||||||
;; disabled?
|
|
||||||
;; boolean - false by default - self explanatory
|
|
||||||
|
|
||||||
(defn list-item
|
(defn list-item
|
||||||
[{:keys [type theme container-margin-top container-margin-bottom
|
"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."
|
||||||
|
|
||||||
|
[{:keys
|
||||||
|
[react-key type theme container-margin-top container-margin-bottom
|
||||||
icon title-prefix title-prefix-width title-prefix-height
|
icon title-prefix title-prefix-width title-prefix-height
|
||||||
title title-color-override title-row-accessory
|
title title-color-override title-row-accessory
|
||||||
title-accessibility-label subtitle subtitle-max-lines
|
title-accessibility-label subtitle subtitle-max-lines
|
||||||
subtitle-row-accessory content accessories on-press
|
subtitle-row-accessory content accessories on-press
|
||||||
on-long-press error accessibility-label disabled?]
|
on-long-press error accessibility-label disabled? selected?]
|
||||||
:or {type :default
|
:or {react-key (name (gensym "list-item"))
|
||||||
|
type :default
|
||||||
theme :default
|
theme :default
|
||||||
disabled? false
|
disabled? false
|
||||||
container-margin-top 0
|
container-margin-top 0
|
||||||
|
@ -342,17 +372,44 @@
|
||||||
subtitle-row-elements
|
subtitle-row-elements
|
||||||
{:subtitle subtitle
|
{:subtitle subtitle
|
||||||
:subtitle-max-lines subtitle-max-lines
|
:subtitle-max-lines subtitle-max-lines
|
||||||
:subtitle-row-accessory subtitle-row-accessory}]
|
:subtitle-row-accessory subtitle-row-accessory}
|
||||||
[react/view {:margin-top container-margin-top
|
width (reagent/atom 0)
|
||||||
|
radio-selected? (and (= theme :selectable) selected?)]
|
||||||
|
(reagent/create-class
|
||||||
|
{:reagent-render
|
||||||
|
(fn
|
||||||
|
[{:keys
|
||||||
|
[icon title-prefix title title-row-accessory subtitle
|
||||||
|
subtitle-max-lines subtitle-row-accessory content
|
||||||
|
accessories on-press on-long-press error disabled? selected?]
|
||||||
|
:or {subtitle-max-lines 1}}]
|
||||||
|
(let [title-row-elements
|
||||||
|
(merge title-row-elements
|
||||||
|
{:title title
|
||||||
|
:title-prefix title-prefix
|
||||||
|
:title-row-accessory title-row-accessory})
|
||||||
|
subtitle-row-elements
|
||||||
|
{:subtitle subtitle
|
||||||
|
:subtitle-max-lines subtitle-max-lines
|
||||||
|
:subtitle-row-accessory subtitle-row-accessory}
|
||||||
|
radio-selected?
|
||||||
|
(and (= theme :selectable) selected?)]
|
||||||
|
^{:key react-key}
|
||||||
|
(if (= type :divider)
|
||||||
|
divider
|
||||||
|
[react/view {:style {:margin-top container-margin-top
|
||||||
:margin-bottom container-margin-bottom}
|
:margin-bottom container-margin-bottom}
|
||||||
|
:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))}
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
(cond-> {:on-press on-press
|
(cond-> {:on-press (when (not= theme :selectable) on-press)
|
||||||
|
:on-press-in (when (= theme :selectable) on-press)
|
||||||
:on-long-press on-long-press
|
:on-long-press on-long-press
|
||||||
:underlay-color colors/gray-transparent-10
|
:underlay-color colors/gray-transparent-40
|
||||||
:disabled (or (not on-press) disabled?)}
|
:active-opacity (if (= theme :selectable) 1 0.85)
|
||||||
|
:disabled (or (not on-press) selected? disabled?)}
|
||||||
accessibility-label
|
accessibility-label
|
||||||
(assoc :accessibility-label accessibility-label))
|
(assoc :accessibility-label accessibility-label))
|
||||||
[react/view {:style (styles/container type)}
|
[react/view {:style (styles/container type radio-selected?)}
|
||||||
(when icon
|
(when icon
|
||||||
[icon-column icon theme disabled?])
|
[icon-column icon theme disabled?])
|
||||||
|
|
||||||
|
@ -362,6 +419,6 @@
|
||||||
type icon disabled? theme content accessories])
|
type icon disabled? theme content accessories])
|
||||||
|
|
||||||
(when accessories
|
(when accessories
|
||||||
[accessories-column accessories theme])]]
|
[accessories-column accessories theme width])]]
|
||||||
(when error
|
(when error
|
||||||
[tooltip/tooltip error styles/error])]))
|
[tooltip/tooltip error styles/error])])))})))
|
||||||
|
|
|
@ -12,19 +12,44 @@
|
||||||
|
|
||||||
(defn- data [app-version node-version]
|
(defn- data [app-version node-version]
|
||||||
[{:type :small
|
[{:type :small
|
||||||
:title (i18n/label :t/privacy-policy)
|
:title :t/privacy-policy
|
||||||
:accessibility-label :privacy-policy
|
:accessibility-label :privacy-policy
|
||||||
:on-press
|
:on-press
|
||||||
#(re-frame/dispatch
|
#(re-frame/dispatch
|
||||||
[:privacy-policy/privacy-policy-button-pressed])
|
[:privacy-policy/privacy-policy-button-pressed])
|
||||||
:accessories [:chevron]}
|
:accessories [:chevron]}
|
||||||
[copyable-text/copyable-text-view
|
[copyable-text/copyable-text-view
|
||||||
{:copied-text (str app-version "; " node-version)}
|
{:copied-text app-version}
|
||||||
[list-item/list-item
|
[list-item/list-item
|
||||||
{:type :small
|
{:type :small
|
||||||
:title (i18n/label :t/version)
|
:accessibility-label :app-version
|
||||||
:accessibility-label :version
|
:title-prefix :t/version
|
||||||
:accessories [(str app-version ";\n" 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}}
|
||||||
|
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/defview about-app []
|
||||||
(views/letsubs [app-version [:get-app-short-version]
|
(views/letsubs [app-version [:get-app-short-version]
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.list-item.views :as list-item]
|
|
||||||
[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.toolbar.view :as toolbar]))
|
[status-im.ui.components.toolbar.view :as toolbar]))
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
#(re-frame/dispatch
|
#(re-frame/dispatch
|
||||||
[:multiaccounts.ui/dev-mode-switched (not dev-mode?)])
|
[:multiaccounts.ui/dev-mode-switched (not dev-mode?)])
|
||||||
:disabled false}]]}
|
:disabled false}]]}
|
||||||
list-item/divider])
|
{:type :divider}])
|
||||||
|
|
||||||
(defn- dev-mode-settings-data [settings chaos-mode? supported-biometric-auth]
|
(defn- dev-mode-settings-data [settings chaos-mode? supported-biometric-auth]
|
||||||
[{:container-margin-top 8
|
[{:container-margin-top 8
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[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.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.ui.components.list-item.views :as list-item]
|
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.screens.dapps-permissions.styles :as styles]
|
[status-im.ui.screens.dapps-permissions.styles :as styles]
|
||||||
|
@ -28,7 +27,7 @@
|
||||||
constants/dapp-permission-web3 :t/wallet
|
constants/dapp-permission-web3 :t/wallet
|
||||||
constants/dapp-permission-contact-code :t/contact-code)
|
constants/dapp-permission-contact-code :t/contact-code)
|
||||||
:type :small
|
:type :small
|
||||||
:accessories [:check]})
|
:accessories [:main-icons/check]})
|
||||||
|
|
||||||
(views/defview dapps-permissions []
|
(views/defview dapps-permissions []
|
||||||
(views/letsubs [permissions [:dapps/permissions]]
|
(views/letsubs [permissions [:dapps/permissions]]
|
||||||
|
@ -37,9 +36,9 @@
|
||||||
[toolbar/simple-toolbar
|
[toolbar/simple-toolbar
|
||||||
(i18n/label :t/dapps-permissions)]
|
(i18n/label :t/dapps-permissions)]
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:data (map prepare-items (vals permissions))
|
{:data (vec (map prepare-items (vals permissions)))
|
||||||
:key-fn (fn [_ i] (str i))
|
:key-fn (fn [_ i] (str i))
|
||||||
:render-fn list-item/list-item}]]))
|
:render-fn list/flat-list-generic-render-fn}]]))
|
||||||
|
|
||||||
(views/defview manage []
|
(views/defview manage []
|
||||||
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]]
|
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]]
|
||||||
|
@ -47,9 +46,9 @@
|
||||||
[status-bar/status-bar]
|
[status-bar/status-bar]
|
||||||
[toolbar/simple-toolbar dapp]
|
[toolbar/simple-toolbar dapp]
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:data (map prepare-items-manage permissions)
|
{:data (vec (map prepare-items-manage permissions))
|
||||||
:key-fn (fn [_ i] (str i))
|
:key-fn (fn [_ i] (str i))
|
||||||
:render-fn list-item/list-item}]
|
:render-fn list/flat-list-generic-render-fn}]
|
||||||
[react/view {:padding-vertical 16}
|
[react/view {:padding-vertical 16}
|
||||||
[components.common/red-button {:label (i18n/label :t/revoke-access)
|
[components.common/red-button {:label (i18n/label :t/revoke-access)
|
||||||
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}]]]))
|
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}]]]))
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
(ns status-im.ui.screens.privacy-and-security-settings.views
|
(ns status-im.ui.screens.privacy-and-security-settings.views
|
||||||
(:require-macros [status-im.utils.views :as views])
|
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.string :as string]
|
||||||
|
[reagent.core :as reagent]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[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.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.list-item.views :as list-item]
|
|
||||||
[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.toolbar.view :as toolbar]))
|
[status-im.ui.components.toolbar.view :as toolbar])
|
||||||
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
(defn- list-data [show-backup-seed? settings]
|
(defn- list-data [show-backup-seed? settings]
|
||||||
[{:type :section-header
|
[{:type :section-header
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
;; :title :t/change-passcode
|
;; :title :t/change-passcode
|
||||||
;; :accessories [:chevron]
|
;; :accessories [:chevron]
|
||||||
;; :container-margin-bottom 8}
|
;; :container-margin-bottom 8}
|
||||||
list-item/divider
|
{:type :divider}
|
||||||
{:container-margin-top 8
|
{:container-margin-top 8
|
||||||
:type :section-header
|
:type :section-header
|
||||||
:title :t/privacy}
|
:title :t/privacy}
|
||||||
|
@ -45,10 +45,11 @@
|
||||||
:accessories [:chevron]}
|
:accessories [:chevron]}
|
||||||
{:type :small
|
{:type :small
|
||||||
:title :t/hide-content-when-switching-apps
|
:title :t/hide-content-when-switching-apps
|
||||||
|
:container-margin-bottom 8
|
||||||
:accessories
|
:accessories
|
||||||
[[react/switch
|
[[react/switch
|
||||||
{:track-color #js {:true colors/blue :false nil}
|
{:track-color #js {:true colors/blue :false nil}
|
||||||
:value (boolean (boolean (:preview-privacy? settings)))
|
:value (boolean (:preview-privacy? settings))
|
||||||
:on-value-change
|
:on-value-change
|
||||||
#(re-frame/dispatch
|
#(re-frame/dispatch
|
||||||
[:multiaccounts.ui/preview-privacy-mode-switched %])
|
[:multiaccounts.ui/preview-privacy-mode-switched %])
|
||||||
|
@ -56,9 +57,8 @@
|
||||||
:on-press
|
:on-press
|
||||||
#(re-frame/dispatch
|
#(re-frame/dispatch
|
||||||
[:multiaccounts.ui/preview-privacy-mode-switched
|
[:multiaccounts.ui/preview-privacy-mode-switched
|
||||||
((complement boolean) (:preview-privacy? settings))])
|
((complement boolean) (:preview-privacy? settings))])}
|
||||||
:container-margin-bottom 8}
|
{:type :divider}
|
||||||
list-item/divider
|
|
||||||
;; TODO - uncomment when implemented
|
;; TODO - uncomment when implemented
|
||||||
(comment
|
(comment
|
||||||
{:container-margin-top 8
|
{:container-margin-top 8
|
||||||
|
@ -71,13 +71,12 @@
|
||||||
(views/letsubs [{:keys [seed-backed-up? mnemonic]} [:multiaccount]
|
(views/letsubs [{:keys [seed-backed-up? mnemonic]} [:multiaccount]
|
||||||
settings [:multiaccount-settings]]
|
settings [:multiaccount-settings]]
|
||||||
(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)))]
|
||||||
data (list-data show-backup-seed? settings)]
|
|
||||||
[react/view {:flex 1 :background-color colors/white}
|
[react/view {:flex 1 :background-color colors/white}
|
||||||
[status-bar/status-bar]
|
[status-bar/status-bar]
|
||||||
[toolbar/simple-toolbar
|
[toolbar/simple-toolbar
|
||||||
(i18n/label :t/privacy-and-security)]
|
(i18n/label :t/privacy-and-security)]
|
||||||
[list/flat-list
|
[list/flat-list
|
||||||
{:data data
|
{:data (list-data show-backup-seed? settings)
|
||||||
:key-fn (fn [_ i] (str i))
|
:key-fn (fn [_ i] (str i))
|
||||||
:render-fn list/flat-list-generic-render-fn}]])))
|
:render-fn list/flat-list-generic-render-fn}]])))
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.list.views :as list]
|
[status-im.ui.components.list.views :as list]
|
||||||
[status-im.ui.components.list-item.views :as list-item]
|
|
||||||
[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.toolbar.view :as toolbar]))
|
[status-im.ui.components.toolbar.view :as toolbar]))
|
||||||
|
@ -23,13 +22,23 @@
|
||||||
#(re-frame/dispatch [:navigate-to :mobile-network-settings])
|
#(re-frame/dispatch [:navigate-to :mobile-network-settings])
|
||||||
:accessories [mobile-data-usage-state :chevron]}
|
:accessories [mobile-data-usage-state :chevron]}
|
||||||
{:type :small
|
{:type :small
|
||||||
:title :t/offline-messaging
|
|
||||||
:accessibility-label :offline-messages-settings-button
|
:accessibility-label :offline-messages-settings-button
|
||||||
|
:title-prefix :t/offline-messaging
|
||||||
|
:title
|
||||||
|
[react/text
|
||||||
|
{:number-of-lines 1
|
||||||
|
:ellipsize-mode :middle
|
||||||
|
:style
|
||||||
|
{:color colors/gray
|
||||||
|
:padding-left 16
|
||||||
|
:text-align :right
|
||||||
|
:line-height 22}}
|
||||||
|
mailserver-id]
|
||||||
:on-press
|
:on-press
|
||||||
#(re-frame/dispatch [:navigate-to :offline-messaging-settings])
|
#(re-frame/dispatch [:navigate-to :offline-messaging-settings])
|
||||||
:accessories [mailserver-id :chevron]
|
:accessories [:chevron]
|
||||||
:container-margin-bottom 8}
|
:container-margin-bottom 8}
|
||||||
list-item/divider
|
{:type :divider}
|
||||||
{:container-margin-top 8
|
{:container-margin-top 8
|
||||||
:type :section-header
|
:type :section-header
|
||||||
:title :t/device-syncing}
|
:title :t/device-syncing}
|
||||||
|
|
|
@ -759,7 +759,8 @@
|
||||||
"your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",
|
"your-contact-code": "Granting access authorizes this DApp to retrieve your chat key",
|
||||||
"password-placeholder": "At least 6 characters",
|
"password-placeholder": "At least 6 characters",
|
||||||
"clear-history-action": "Clear",
|
"clear-history-action": "Clear",
|
||||||
"version": "Version",
|
"version": "App version",
|
||||||
|
"node-version": "Node version",
|
||||||
"specify-mailserver-address": "Specify a mailserver address",
|
"specify-mailserver-address": "Specify a mailserver address",
|
||||||
"scan-qr-code": "Scan a QR code with a wallet address",
|
"scan-qr-code": "Scan a QR code with a wallet address",
|
||||||
"wallet-total-value": "Total value",
|
"wallet-total-value": "Total value",
|
||||||
|
|
Loading…
Reference in New Issue